📄 ctrldownloads.cpp
字号:
//
// CtrlDownloads.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Transfers.h"
#include "Downloads.h"
#include "Download.h"
#include "DownloadSource.h"
#include "DownloadTransfer.h"
#include "CoolInterface.h"
#include "ShellIcons.h"
#include "FragmentBar.h"
#include "Skin.h"
#include "CtrlDownloads.h"
#include "WndDownloads.h"
IMPLEMENT_DYNAMIC(CDownloadsCtrl, CWnd)
BEGIN_MESSAGE_MAP(CDownloadsCtrl, CWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_WM_MOUSEWHEEL()
ON_NOTIFY(HDN_ITEMCHANGEDW, AFX_IDW_PANE_FIRST, OnChangeHeader)
ON_NOTIFY(HDN_ITEMCHANGEDA, AFX_IDW_PANE_FIRST, OnChangeHeader)
ON_NOTIFY(HDN_ENDDRAG, AFX_IDW_PANE_FIRST, OnChangeHeader)
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
#define HEADER_HEIGHT 20
#define ITEM_HEIGHT 17
#define DOWNLOAD_COLUMN_TITLE 0
#define DOWNLOAD_COLUMN_SIZE 1
#define DOWNLOAD_COLUMN_PROGRESS 2
#define DOWNLOAD_COLUMN_SPEED 3
#define DOWNLOAD_COLUMN_STATUS 4
#define DOWNLOAD_COLUMN_CLIENT 5
//////////////////////////////////////////////////////////////////////////////
// CDownloadsCtrl construction
CDownloadsCtrl::CDownloadsCtrl()
{
}
CDownloadsCtrl::~CDownloadsCtrl()
{
}
//////////////////////////////////////////////////////////////////////////////
// CDownloadsCtrl operations
BOOL CDownloadsCtrl::Create(CWnd* pParentWnd, UINT nID)
{
CRect rect( 0, 0, 0, 0 );
return CWnd::Create( NULL, NULL, WS_CHILD|WS_CLIPSIBLINGS, rect, pParentWnd, nID, NULL );
}
BOOL CDownloadsCtrl::Update()
{
OnSize( 1982, 0, 0 );
return TRUE;
}
BOOL CDownloadsCtrl::Update(int nGroupCookie)
{
m_nGroupCookie = nGroupCookie;
OnSize( 1982, 0, 0 );
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// CDownloadsCtrl system message handlers
int CDownloadsCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
CRect rect( 0, 0, 0, 0 );
m_wndHeader.Create( WS_CHILD|HDS_DRAGDROP|HDS_HOTTRACK|HDS_FULLDRAG, rect, this, AFX_IDW_PANE_FIRST );
m_wndHeader.SetFont( &theApp.m_gdiFont );
m_wndTip.Create( this, &Settings.Interface.TipDownloads );
InsertColumn( DOWNLOAD_COLUMN_TITLE, _T("Downloaded File"), LVCFMT_LEFT, 210 );
InsertColumn( DOWNLOAD_COLUMN_SIZE, _T("Size"), LVCFMT_CENTER, 80 );
InsertColumn( DOWNLOAD_COLUMN_PROGRESS, _T("Progress"), LVCFMT_CENTER, 130 );
InsertColumn( DOWNLOAD_COLUMN_SPEED, _T("Speed"), LVCFMT_CENTER, 80 );
InsertColumn( DOWNLOAD_COLUMN_STATUS, _T("Status"), LVCFMT_CENTER, 80 );
InsertColumn( DOWNLOAD_COLUMN_CLIENT, _T("Client"), LVCFMT_CENTER, 80 );
Skin.Translate( _T("CDownloadCtrl"), &m_wndHeader );
LoadColumnState();
CBitmap bmImages;
bmImages.LoadBitmap( IDB_PROTOCOLS );
m_pProtocols.Create( 16, 16, ILC_COLOR16|ILC_MASK, 7, 1 );
m_pProtocols.Add( &bmImages, RGB( 0, 255, 0 ) );
m_nGroupCookie = 0;
m_nFocus = 0;
m_bCreateDragImage = FALSE;
m_pDragDrop = NULL;
m_bDrag = FALSE;
m_pDeselect1 = NULL;
m_pDeselect2 = NULL;
return 0;
}
void CDownloadsCtrl::OnDestroy()
{
SaveColumnState();
CWnd::OnDestroy();
}
//////////////////////////////////////////////////////////////////////////////
// CDownloadsCtrl column helpers
void CDownloadsCtrl::InsertColumn(int nColumn, LPCTSTR pszCaption, int nFormat, int nWidth)
{
HDITEM pColumn;
ZeroMemory( &pColumn, sizeof(pColumn) );
pColumn.mask = HDI_FORMAT | HDI_LPARAM | HDI_TEXT | HDI_WIDTH;
pColumn.cxy = nWidth;
pColumn.pszText = (LPTSTR)pszCaption;
pColumn.fmt = nFormat;
pColumn.lParam = nColumn;
m_wndHeader.InsertItem( m_wndHeader.GetItemCount(), &pColumn );
}
void CDownloadsCtrl::SaveColumnState()
{
HDITEM pItem = { HDI_WIDTH|HDI_ORDER };
CString strOrdering, strWidths, strItem;
for ( int nColumns = 0 ; m_wndHeader.GetItem( nColumns, &pItem ) ; nColumns++ )
{
m_wndHeader.GetItem( nColumns, &pItem );
strItem.Format( _T("%.2x"), pItem.iOrder );
strOrdering += strItem;
strItem.Format( _T("%.4x"), pItem.cxy );
strWidths += strItem;
}
theApp.WriteProfileString( _T("ListStates"), _T("CDownloadCtrl.Ordering"), strOrdering );
theApp.WriteProfileString( _T("ListStates"), _T("CDownloadCtrl.Widths"), strWidths );
}
BOOL CDownloadsCtrl::LoadColumnState()
{
CString strOrdering, strWidths, strItem;
strOrdering = theApp.GetProfileString( _T("ListStates"), _T("CDownloadCtrl.Ordering"), _T("") );
strWidths = theApp.GetProfileString( _T("ListStates"), _T("CDownloadCtrl.Widths"), _T("") );
HDITEM pItem = { HDI_WIDTH|HDI_ORDER };
if ( _tcsncmp( strWidths, _T("0000"), 4 ) == 0 &&
_tcsncmp( strOrdering, _T("00"), 2 ) == 0 )
{
strWidths = strWidths.Mid( 4 );
strOrdering = strOrdering.Mid( 2 );
}
for ( int nColumns = 0 ; m_wndHeader.GetItem( nColumns, &pItem ) ; nColumns++ )
{
if ( strWidths.GetLength() < 4 || strOrdering.GetLength() < 2 ) return FALSE;
_stscanf( strWidths.Left( 4 ), _T("%x"), &pItem.cxy );
_stscanf( strOrdering.Left( 2 ), _T("%x"), &pItem.iOrder );
strWidths = strWidths.Mid( 4 );
strOrdering = strOrdering.Mid( 2 );
m_wndHeader.SetItem( nColumns, &pItem );
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// CDownloadsCtrl item helpers
BOOL CDownloadsCtrl::IsFiltered(CDownload* pDownload)
{
DWORD nFilterMask = Settings.Downloads.FilterMask;
if ( Settings.General.GUIMode == GUI_BASIC ) nFilterMask = 0xFFFFFFFF;
if ( pDownload->IsMoving() )
{
return ( ( nFilterMask & DLF_ACTIVE ) == 0 );
}
else if ( pDownload->IsPaused() )
{
return ( ( nFilterMask & DLF_PAUSED ) == 0 );
}
else if ( pDownload->IsDownloading() )
{
return ( ( nFilterMask & DLF_ACTIVE ) == 0 );
}
else if ( pDownload->GetSourceCount() > 0 )
{
if ( pDownload->IsStarted() )
{
return ( ( nFilterMask & DLF_ACTIVE ) == 0 );
}
else
{
return ( ( nFilterMask & DLF_QUEUED ) == 0 );
}
}
else if ( pDownload->m_nSize == SIZE_UNKNOWN )
{
return ( ( nFilterMask & DLF_SOURCES ) == 0 );
}
else
{
return ( ( nFilterMask & DLF_SOURCES ) == 0 );
}
return FALSE;
}
BOOL CDownloadsCtrl::IsExpandable(CDownload* pDownload)
{
if ( Settings.Downloads.ShowSources )
{
return ( pDownload->GetSourceCount() > 0 );
}
else
{
for ( CDownloadSource* pSource = pDownload->GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
{
if ( pSource->m_pTransfer != NULL && pSource->m_pTransfer->m_nState > dtsConnecting )
{
return TRUE;
}
}
return FALSE;
}
}
void CDownloadsCtrl::SelectTo(int nIndex)
{
CSingleLock pLock( &Transfers.m_pSection, TRUE );
BOOL bShift = GetAsyncKeyState( VK_SHIFT ) & 0x8000;
BOOL bControl = GetAsyncKeyState( VK_CONTROL ) & 0x8000;
BOOL bRight = GetAsyncKeyState( VK_RBUTTON ) & 0x8000;
if ( ! bShift && ! bControl && ! bRight )
{
if ( m_pDeselect1 == NULL && m_pDeselect2 == NULL ) DeselectAll();
}
Update();
INT nMin, nMax;
GetScrollRange( SB_VERT, &nMin, &nMax );
nIndex = max( 0, min( nIndex, nMax - 1 ) );
CDownloadSource* pSource;
CDownload* pDownload;
if ( bShift )
{
if ( m_nFocus < nIndex )
{
for ( m_nFocus ++ ; m_nFocus <= nIndex ; m_nFocus ++ )
{
GetAt( m_nFocus, &pDownload, &pSource );
if ( pDownload != NULL ) pDownload->m_bSelected = TRUE;
if ( pSource != NULL ) pSource->m_bSelected = TRUE;
}
}
else if ( m_nFocus > nIndex )
{
for ( m_nFocus -- ; m_nFocus >= nIndex ; m_nFocus -- )
{
GetAt( m_nFocus, &pDownload, &pSource );
if ( pDownload != NULL ) pDownload->m_bSelected = TRUE;
if ( pSource != NULL ) pSource->m_bSelected = TRUE;
}
}
m_nFocus = nIndex;
}
else
{
m_nFocus = nIndex;
GetAt( m_nFocus, &pDownload, &pSource );
if ( bControl )
{
if ( pDownload != NULL ) pDownload->m_bSelected = ! pDownload->m_bSelected;
if ( pSource != NULL ) pSource->m_bSelected = ! pSource->m_bSelected;
}
else
{
if ( pDownload != NULL ) pDownload->m_bSelected = TRUE;
if ( pSource != NULL ) pSource->m_bSelected = TRUE;
}
}
CRect rcClient;
GetClientRect( &rcClient );
int nScroll = GetScrollPos( SB_VERT );
int nHeight = ( rcClient.bottom - HEADER_HEIGHT ) / ITEM_HEIGHT - 1;
nHeight = max( 0, nHeight );
if ( m_nFocus < nScroll )
{
SetScrollPos( SB_VERT, m_nFocus );
Update();
}
else if ( m_nFocus > nScroll + nHeight )
{
SetScrollPos( SB_VERT, max( 0, m_nFocus - nHeight ) );
Update();
}
else
{
Invalidate();
}
}
void CDownloadsCtrl::DeselectAll(CDownload* pExcept1, CDownloadSource* pExcept2)
{
CSingleLock pLock( &Transfers.m_pSection, TRUE );
for ( POSITION pos = Downloads.GetIterator() ; pos != NULL ; )
{
CDownload* pDownload = Downloads.GetNext( pos );
if ( pDownload != pExcept1 ) pDownload->m_bSelected = FALSE;
for ( CDownloadSource* pSource = pDownload->GetFirstSource() ; pSource != NULL ; pSource = pSource->m_pNext )
{
if ( pSource != pExcept2 ) pSource->m_bSelected = FALSE;
}
}
Invalidate();
}
int CDownloadsCtrl::GetSelectedCount()
{
CSingleLock pLock( &Transfers.m_pSection, TRUE );
int nCount = 0;
for ( POSITION pos = Downloads.GetIterator() ; pos ; )
{
CDownload* pDownload = Downloads.GetNext( pos );
if ( pDownload->m_bSelected ) nCount ++;
for ( CDownloadSource* pSource = pDownload->GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
if ( pSource->m_bSelected ) nCount ++;
}
pLock.Unlock();
return nCount;
}
BOOL CDownloadsCtrl::HitTest(const CPoint& point, CDownload** ppDownload, CDownloadSource** ppSource, int* pnIndex, RECT* prcItem)
{
CRect rcClient, rcItem;
GetClientRect( &rcClient );
rcClient.top += HEADER_HEIGHT;
rcItem.CopyRect( &rcClient );
rcItem.left -= GetScrollPos( SB_HORZ );
rcItem.bottom = rcItem.top + ITEM_HEIGHT;
int nScroll = GetScrollPos( SB_VERT );
int nIndex = 0;
if ( ppDownload != NULL ) *ppDownload = NULL;
if ( ppSource != NULL ) *ppSource = NULL;
for ( POSITION posDownload = Downloads.GetIterator() ; posDownload && rcItem.top < rcClient.bottom ; )
{
CDownload* pDownload = Downloads.GetNext( posDownload );
if ( m_nGroupCookie != 0 && m_nGroupCookie != pDownload->m_nGroupCookie ) continue;
if ( IsFiltered( pDownload ) ) continue;
if ( nScroll > 0 )
{
nScroll --;
}
else
{
if ( rcItem.PtInRect( point ) )
{
if ( ppDownload != NULL ) *ppDownload = pDownload;
if ( pnIndex != NULL ) *pnIndex = nIndex;
if ( prcItem != NULL ) *prcItem = rcItem;
return TRUE;
}
rcItem.OffsetRect( 0, ITEM_HEIGHT );
}
nIndex ++;
if ( ! pDownload->m_bExpanded ) continue;
if ( Settings.Downloads.ShowSources )
{
int nSources = pDownload->GetSourceCount();
if ( nScroll >= nSources )
{
nScroll -= nSources;
nIndex += nSources;
continue;
}
}
for ( CDownloadSource* pSource = pDownload->GetFirstSource() ; pSource ; pSource = pSource->m_pNext )
{
if ( Settings.Downloads.ShowSources || ( pSource->m_pTransfer != NULL && pSource->m_pTransfer->m_nState > dtsConnecting ) )
{
if ( nScroll > 0 )
{
nScroll --;
}
else
{
if ( rcItem.PtInRect( point ) )
{
if ( ppSource != NULL ) *ppSource = pSource;
if ( pnIndex != NULL ) *pnIndex = nIndex;
if ( prcItem != NULL ) *prcItem = rcItem;
return TRUE;
}
rcItem.OffsetRect( 0, ITEM_HEIGHT );
}
nIndex ++;
}
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -