Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CtrlUploads.cpp

Go to the documentation of this file.
00001 //
00002 // CtrlUploads.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Transfers.h"
00026 #include "UploadQueues.h"
00027 #include "UploadQueue.h"
00028 #include "UploadFiles.h"
00029 #include "UploadFile.h"
00030 #include "UploadTransfer.h"
00031 #include "UploadTransferBT.h"
00032 #include "CoolInterface.h"
00033 #include "ShellIcons.h"
00034 #include "FragmentBar.h"
00035 #include "Skin.h"
00036 #include "CtrlUploads.h"
00037 
00038 #include "Downloads.h"
00039 
00040 IMPLEMENT_DYNAMIC(CUploadsCtrl, CWnd)
00041 
00042 BEGIN_MESSAGE_MAP(CUploadsCtrl, CWnd)
00043         ON_WM_CREATE()
00044         ON_WM_DESTROY()
00045         ON_WM_SIZE()
00046         ON_WM_PAINT()
00047         ON_WM_VSCROLL()
00048         ON_WM_HSCROLL()
00049         ON_WM_MOUSEWHEEL()
00050         ON_NOTIFY(HDN_ITEMCHANGEDW, AFX_IDW_PANE_FIRST, OnChangeHeader)
00051         ON_NOTIFY(HDN_ITEMCHANGEDA, AFX_IDW_PANE_FIRST, OnChangeHeader)
00052         ON_NOTIFY(HDN_ENDDRAG, AFX_IDW_PANE_FIRST, OnChangeHeader)
00053         ON_WM_KEYDOWN()
00054         ON_WM_LBUTTONDOWN()
00055         ON_WM_RBUTTONDOWN()
00056         ON_WM_LBUTTONDBLCLK()
00057         ON_WM_MOUSEMOVE()
00058         ON_WM_LBUTTONUP()
00059         ON_WM_RBUTTONUP()
00060         ON_WM_SETFOCUS()
00061         ON_WM_KILLFOCUS()
00062 END_MESSAGE_MAP()
00063 
00064 #define HEADER_HEIGHT                   20
00065 #define ITEM_HEIGHT                             17
00066 
00067 #define UPLOAD_COLUMN_TITLE             0
00068 #define UPLOAD_COLUMN_USER              1
00069 #define UPLOAD_COLUMN_SIZE              2
00070 #define UPLOAD_COLUMN_PROGRESS  3
00071 #define UPLOAD_COLUMN_SPEED             4
00072 #define UPLOAD_COLUMN_CLIENT    5
00073 #define UPLOAD_COLUMN_RATING    6
00074 
00075 
00077 // CUploadsCtrl construction
00078 
00079 CUploadsCtrl::CUploadsCtrl()
00080 {
00081         // Try to get the number of lines to scroll when the mouse wheel is rotated
00082         if( !SystemParametersInfo ( SPI_GETWHEELSCROLLLINES, 0, &m_nScrollWheelLines, 0) )
00083         {
00084                 m_nScrollWheelLines = 3;
00085         }
00086 }
00087 
00088 CUploadsCtrl::~CUploadsCtrl()
00089 {
00090 }
00091 
00093 // CUploadsCtrl operations
00094 
00095 BOOL CUploadsCtrl::Create(CWnd* pParentWnd, UINT nID)
00096 {
00097         CRect rect( 0, 0, 0, 0 );
00098         return CWnd::Create( NULL, NULL, WS_CHILD|WS_CLIPSIBLINGS, rect, pParentWnd, nID, NULL );
00099 }
00100 
00101 BOOL CUploadsCtrl::Update()
00102 {
00103         OnSize( 1982, 0, 0 );
00104         return TRUE;
00105 }
00106 
00108 // CUploadsCtrl system message handlers
00109 
00110 int CUploadsCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
00111 {
00112         if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00113         
00114         CRect rect( 0, 0, 0, 0 );
00115         m_wndHeader.Create( WS_CHILD|HDS_DRAGDROP|HDS_HOTTRACK|HDS_FULLDRAG, rect, this, AFX_IDW_PANE_FIRST );
00116         m_wndHeader.SetFont( &theApp.m_gdiFont );
00117         
00118         m_wndTip.Create( this, &Settings.Interface.TipUploads );
00119         
00120         InsertColumn( UPLOAD_COLUMN_TITLE, _T("Uploaded File"), LVCFMT_LEFT, 210 );
00121         InsertColumn( UPLOAD_COLUMN_USER, _T("Remote User"), LVCFMT_LEFT, 100 );
00122         InsertColumn( UPLOAD_COLUMN_SIZE, _T("Size"), LVCFMT_CENTER, 80 );
00123         InsertColumn( UPLOAD_COLUMN_PROGRESS, _T("Progress"), LVCFMT_CENTER, 130 );
00124         InsertColumn( UPLOAD_COLUMN_SPEED, _T("Speed"), LVCFMT_CENTER, 80 );
00125         InsertColumn( UPLOAD_COLUMN_CLIENT, _T("Client"), LVCFMT_CENTER, 100 );
00126         InsertColumn( UPLOAD_COLUMN_RATING, _T("Rating"), LVCFMT_CENTER, 0 );
00127         
00128         
00129         LoadColumnState();
00130         
00131         CBitmap bmImages;
00132         bmImages.LoadBitmap( IDB_PROTOCOLS );
00133         if ( theApp.m_bRTL ) 
00134                 bmImages.m_hObject = CreateMirroredBitmap( (HBITMAP)bmImages.m_hObject );
00135         m_pProtocols.Create( 16, 16, ILC_COLOR16|ILC_MASK, 7, 1 );
00136         m_pProtocols.Add( &bmImages, RGB( 0, 255, 0 ) );
00137         
00138         m_nFocus        = 0;
00139         m_pDeselect     = NULL;
00140         
00141         return 0;
00142 }
00143 
00144 void CUploadsCtrl::OnDestroy()
00145 {
00146         SaveColumnState();
00147         CWnd::OnDestroy();
00148 }
00149 
00151 // CUploadsCtrl column helpers
00152 
00153 void CUploadsCtrl::InsertColumn(int nColumn, LPCTSTR pszCaption, int nFormat, int nWidth)
00154 {
00155         HDITEM pColumn;
00156         
00157         ZeroMemory( &pColumn, sizeof(pColumn) );
00158         
00159         pColumn.mask    = HDI_FORMAT | HDI_LPARAM | HDI_TEXT | HDI_WIDTH;
00160         pColumn.cxy             = nWidth;
00161         pColumn.pszText = (LPTSTR)pszCaption;
00162         pColumn.fmt             = nFormat;
00163         pColumn.lParam  = nColumn;
00164         
00165         m_wndHeader.InsertItem( m_wndHeader.GetItemCount(), &pColumn );
00166 }
00167 
00168 void CUploadsCtrl::SaveColumnState()
00169 {
00170         HDITEM pItem = { HDI_WIDTH|HDI_ORDER };
00171         
00172         CString strOrdering, strWidths, strItem;
00173         
00174         for ( int nColumns = 0 ; m_wndHeader.GetItem( nColumns, &pItem ) ; nColumns++ )
00175         {
00176                 m_wndHeader.GetItem( nColumns, &pItem );
00177                 
00178                 strItem.Format( _T("%.2x"), pItem.iOrder );
00179                 strOrdering += strItem;
00180                 
00181                 strItem.Format( _T("%.4x"), pItem.cxy );
00182                 strWidths += strItem;
00183         }
00184         
00185         theApp.WriteProfileString( _T("ListStates"), _T("CUploadCtrl.Ordering"), strOrdering );
00186         theApp.WriteProfileString( _T("ListStates"), _T("CUploadCtrl.Widths"), strWidths );
00187 }
00188 
00189 BOOL CUploadsCtrl::LoadColumnState()
00190 {
00191         CString strOrdering, strWidths, strItem;
00192         
00193         strOrdering = theApp.GetProfileString( _T("ListStates"), _T("CUploadCtrl.Ordering"), _T("") );
00194         strWidths = theApp.GetProfileString( _T("ListStates"), _T("CUploadCtrl.Widths"), _T("") );
00195         
00196         HDITEM pItem = { HDI_WIDTH|HDI_ORDER };
00197         
00198         if ( _tcsncmp( strWidths, _T("0000"), 4 ) == 0 &&
00199                  _tcsncmp( strOrdering, _T("00"), 2 ) == 0 )
00200         {
00201                 strWidths = strWidths.Mid( 4 );
00202                 strOrdering = strOrdering.Mid( 2 );
00203         }
00204         
00205         for ( int nColumns = 0 ; m_wndHeader.GetItem( nColumns, &pItem ) ; nColumns++ )
00206         {
00207                 if ( strWidths.GetLength() < 4 || strOrdering.GetLength() < 2 ) return FALSE;
00208                 
00209                 _stscanf( strWidths.Left( 4 ), _T("%x"), &pItem.cxy );
00210                 _stscanf( strOrdering.Left( 2 ), _T("%x"), &pItem.iOrder );
00211                 
00212                 strWidths = strWidths.Mid( 4 );
00213                 strOrdering = strOrdering.Mid( 2 );
00214                 
00215                 m_wndHeader.SetItem( nColumns, &pItem );
00216         }
00217         
00218         return TRUE;
00219 }
00220 
00222 // CUploadsCtrl item helpers
00223 
00224 void CUploadsCtrl::SelectTo(int nIndex)
00225 {
00226         CSingleLock pLock( &Transfers.m_pSection, TRUE );
00227         
00228         BOOL bShift             = GetAsyncKeyState( VK_SHIFT ) & 0x8000;
00229         BOOL bControl   = GetAsyncKeyState( VK_CONTROL ) & 0x8000;
00230         BOOL bRight             = GetAsyncKeyState( VK_RBUTTON ) & 0x8000;
00231         
00232         if ( ! bShift && ! bControl && ! bRight && m_pDeselect == NULL ) DeselectAll();
00233         
00234         Update();
00235         
00236         INT nMin, nMax;
00237         GetScrollRange( SB_VERT, &nMin, &nMax );
00238         nIndex = max( 0, min( nIndex, nMax - 1 ) );
00239         
00240         CUploadFile* pFile;
00241         CUploadQueue* pQueue;
00242         
00243         if ( bShift )
00244         {
00245                 if ( m_nFocus < nIndex )
00246                 {
00247                         for ( m_nFocus ++ ; m_nFocus <= nIndex ; m_nFocus ++ )
00248                         {
00249                                 GetAt( m_nFocus, &pQueue, &pFile );
00250                                 if ( pQueue != NULL ) pQueue->m_bSelected = TRUE;
00251                                 if ( pFile != NULL ) pFile->m_bSelected = TRUE;
00252                         }
00253                 }
00254                 else if ( m_nFocus > nIndex )
00255                 {
00256                         for ( m_nFocus -- ; m_nFocus >= nIndex ; m_nFocus -- )
00257                         {
00258                                 GetAt( m_nFocus, &pQueue, &pFile );
00259                                 if ( pQueue != NULL ) pQueue->m_bSelected = TRUE;
00260                                 if ( pFile != NULL ) pFile->m_bSelected = TRUE;
00261                         }
00262                 }
00263                 
00264                 m_nFocus = nIndex;
00265         }
00266         else
00267         {
00268                 m_nFocus = nIndex;
00269                 GetAt( m_nFocus, &pQueue, &pFile );
00270                 
00271                 if ( bControl )
00272                 {
00273                         if ( pQueue != NULL ) pQueue->m_bSelected = ! pQueue->m_bSelected;
00274                         if ( pFile != NULL ) pFile->m_bSelected = ! pFile->m_bSelected;
00275                 }
00276                 else
00277                 {
00278                         if ( pQueue != NULL ) pQueue->m_bSelected = TRUE;
00279                         if ( pFile != NULL ) pFile->m_bSelected = TRUE;
00280                 }
00281         }
00282         
00283         CRect rcClient;
00284         GetClientRect( &rcClient );
00285         
00286         int nScroll = GetScrollPos( SB_VERT );
00287         int nHeight = ( rcClient.bottom - HEADER_HEIGHT ) / ITEM_HEIGHT - 1;
00288         nHeight = max( 0, nHeight );
00289         
00290         if ( m_nFocus < nScroll )
00291         {
00292                 SetScrollPos( SB_VERT, m_nFocus );
00293                 Update();
00294         }
00295         else if ( m_nFocus > nScroll + nHeight )
00296         {
00297                 SetScrollPos( SB_VERT, max( 0, m_nFocus - nHeight ) );
00298                 Update();
00299         }
00300         else
00301         {
00302                 Invalidate();
00303         }
00304 }
00305 
00306 void CUploadsCtrl::DeselectAll(CUploadFile* pExcept)
00307 {
00308         CSingleLock pLock( &Transfers.m_pSection, TRUE );
00309         POSITION pos;
00310         
00311         UploadQueues.m_pTorrentQueue->m_bSelected = FALSE;
00312         UploadQueues.m_pHistoryQueue->m_bSelected = FALSE;
00313         
00314         for ( pos = UploadQueues.GetIterator() ; pos ; )
00315         {
00316                 CUploadQueue* pQueue = UploadQueues.GetNext( pos );
00317                 pQueue->m_bSelected = FALSE;
00318         }
00319         
00320         for ( pos = UploadFiles.GetIterator() ; pos ; )
00321         {
00322                 CUploadFile* pFile = UploadFiles.GetNext( pos );
00323                 pFile->m_bSelected = FALSE;
00324         }
00325         
00326         Invalidate();
00327 }
00328 
00329 BOOL CUploadsCtrl::HitTest(const CPoint& point, CUploadQueue** ppQueue, CUploadFile** ppFile, int* pnIndex, RECT* prcItem)
00330 {
00331         CRect rcClient, rcItem;
00332         
00333         GetClientRect( &rcClient );
00334         rcClient.top += HEADER_HEIGHT;
00335         
00336         rcItem.CopyRect( &rcClient );
00337         rcItem.left -= GetScrollPos( SB_HORZ );
00338         rcItem.bottom = rcItem.top + ITEM_HEIGHT;
00339         
00340         int nScroll = GetScrollPos( SB_VERT );
00341         int nIndex = 0;
00342         
00343         if ( ppQueue != NULL ) *ppQueue = NULL;
00344         if ( ppFile != NULL ) *ppFile = NULL;
00345         
00346         for ( POSITION posQueue = GetQueueIterator() ; posQueue && rcItem.top < rcClient.bottom ; )
00347         {
00348                 CUploadQueue* pQueue = GetNextQueue( posQueue );
00349                 
00350                 POSITION posFile = GetFileIterator( pQueue );
00351                 if ( posFile == NULL ) continue;
00352                 
00353                 if ( nScroll > 0 )
00354                 {
00355                         nScroll --;
00356                 }
00357                 else
00358                 {
00359                         if ( rcItem.PtInRect( point ) )
00360                         {
00361                                 if ( ppQueue != NULL ) *ppQueue = pQueue;
00362                                 if ( pnIndex != NULL ) *pnIndex = nIndex;
00363                                 if ( prcItem != NULL ) *prcItem = rcItem;
00364                                 return TRUE;
00365                         }
00366                         rcItem.OffsetRect( 0, ITEM_HEIGHT );
00367                 }
00368                 
00369                 nIndex ++;
00370                 if ( ! pQueue->m_bExpanded ) continue;
00371                 
00372                 while ( posFile && rcItem.top < rcClient.bottom )
00373                 {
00374                         CUploadFile* pFile = GetNextFile( pQueue, posFile );
00375                         if ( pFile == NULL ) continue;
00376                         
00377                         if ( nScroll > 0 )
00378                         {
00379                                 nScroll --;
00380                         }
00381                         else
00382                         {
00383                                 if ( rcItem.PtInRect( point ) )
00384                                 {
00385                                         if ( ppFile != NULL ) *ppFile = pFile;
00386                                         if ( pnIndex != NULL ) *pnIndex = nIndex;
00387                                         if ( prcItem != NULL ) *prcItem = rcItem;
00388                                         return TRUE;
00389                                 }
00390                                 rcItem.OffsetRect( 0, ITEM_HEIGHT );
00391                         }
00392                         
00393                         nIndex ++;
00394                 }
00395         }
00396         
00397         return FALSE;
00398 }
00399 
00400 BOOL CUploadsCtrl::GetAt(int nSelect, CUploadQueue** ppQueue, CUploadFile** ppFile)
00401 {
00402         int nScroll = GetScrollPos( SB_VERT );
00403         int nIndex = 0;
00404         
00405         if ( ppQueue != NULL ) *ppQueue = NULL;
00406         if ( ppFile != NULL ) *ppFile = NULL;
00407         
00408         for ( POSITION posQueue = GetQueueIterator() ; posQueue ; )
00409         {
00410                 CUploadQueue* pQueue = GetNextQueue( posQueue );
00411                 
00412                 POSITION posFile = GetFileIterator( pQueue );
00413                 if ( posFile == NULL ) continue;
00414                 
00415                 if ( nIndex++ == nSelect )
00416                 {
00417                         if ( ppQueue != NULL ) *ppQueue = pQueue;
00418                         return TRUE;
00419                 }
00420                 
00421                 if ( ! pQueue->m_bExpanded ) continue;
00422                 
00423                 while ( posFile )
00424                 {
00425                         CUploadFile* pFile = GetNextFile( pQueue, posFile );
00426                         if ( pFile == NULL ) continue;
00427                         
00428                         if ( nIndex++ == nSelect )
00429                         {
00430                                 if ( ppFile != NULL ) *ppFile = pFile;
00431                                 return TRUE;
00432                         }
00433                 }
00434         }
00435         
00436         return FALSE;
00437 }
00438 
00440 // CUploadsCtrl queue / file abstractation layer
00441 
00442 POSITION CUploadsCtrl::GetQueueIterator()
00443 {
00444         if ( Settings.Uploads.FilterMask & ULF_TORRENT )
00445         {
00446                 return (POSITION)UploadQueues.m_pTorrentQueue;
00447         }
00448         else if ( Settings.Uploads.FilterMask & ( ULF_ACTIVE | ULF_QUEUED ) )
00449         {
00450                 return UploadQueues.GetIterator();
00451         }
00452         else if ( Settings.Uploads.FilterMask & ULF_HISTORY )
00453         {
00454                 return (POSITION)UploadQueues.m_pHistoryQueue;
00455         }
00456         else
00457         {
00458                 return NULL;
00459         }
00460 }
00461 
00462 CUploadQueue* CUploadsCtrl::GetNextQueue(POSITION& pos)
00463 {
00464         ASSERT( pos != NULL );
00465         
00466         if ( pos == (POSITION)UploadQueues.m_pTorrentQueue )
00467         {
00468                 if ( Settings.Uploads.FilterMask & ( ULF_ACTIVE | ULF_QUEUED ) )
00469                 {
00470                         pos = UploadQueues.GetIterator();
00471                         if ( pos == NULL ) pos = (POSITION)UploadQueues.m_pHistoryQueue;
00472                 }
00473                 else if ( Settings.Uploads.FilterMask & ULF_HISTORY )
00474                 {
00475                         pos = (POSITION)UploadQueues.m_pHistoryQueue;
00476                 }
00477                 else
00478                 {
00479                         pos = NULL;
00480                 }
00481                 
00482                 return UploadQueues.m_pTorrentQueue;
00483         }
00484         else if ( pos == (POSITION)UploadQueues.m_pHistoryQueue )
00485         {
00486                 pos = NULL;
00487                 return UploadQueues.m_pHistoryQueue;
00488         }
00489         else
00490         {
00491                 CUploadQueue* pQueue = UploadQueues.GetNext( pos );
00492                 
00493                 if ( pos == NULL )
00494                 {
00495                         if ( Settings.Uploads.FilterMask & ULF_HISTORY )
00496                         {
00497                                 pos = (POSITION)UploadQueues.m_pHistoryQueue;
00498                         }
00499                 }
00500                 
00501                 return pQueue;
00502         }
00503 }
00504 
00505 POSITION CUploadsCtrl::GetFileIterator(CUploadQueue* pQueue)
00506 {
00507         if ( pQueue == UploadQueues.m_pTorrentQueue )
00508         {
00509                 for ( POSITION posNext = UploadFiles.GetIterator() ; posNext ; )
00510                 {
00511                         POSITION posThis = posNext;
00512                         CUploadFile* pFile = UploadFiles.GetNext( posNext );
00513                         CUploadTransfer* pTransfer = pFile->GetActive();
00514                         if ( pTransfer == NULL || pTransfer->m_nState == upsNull ) continue;
00515                         if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue;
00516                         return posThis;
00517                 }
00518                 
00519                 return NULL;
00520         }
00521         else if ( pQueue == UploadQueues.m_pHistoryQueue )
00522         {
00523                 for ( POSITION posNext = UploadFiles.GetIterator() ; posNext ; )
00524                 {
00525                         POSITION posThis = posNext;
00526                         CUploadFile* pFile = UploadFiles.GetNext( posNext );
00527                         CUploadTransfer* pTransfer = pFile->GetActive();
00528                         if ( pTransfer != NULL )
00529                         {
00530                                 if ( pTransfer->m_nProtocol == PROTOCOL_BT && pTransfer->m_nState != upsNull ) continue;
00531                                 if ( pTransfer->m_pQueue != NULL ) continue;
00532                         }
00533                         return posThis;
00534                 }
00535                 
00536                 return NULL;
00537         }
00538         else
00539         {
00540                 if ( Settings.Uploads.FilterMask & ULF_ACTIVE )
00541                 {
00542                         if ( pQueue->m_pActive.GetCount() > 0 )
00543                         {
00544                                 return pQueue->m_pActive.GetHeadPosition();
00545                         }
00546                 }
00547                 
00548                 if ( Settings.Uploads.FilterMask & ULF_QUEUED )
00549                 {
00550                         if ( pQueue->m_pQueued.GetCount() > 0 )
00551                         {
00552                                 return (POSITION)1;
00553                         }
00554                 }
00555                 
00556                 return NULL;
00557         }
00558 }
00559 
00560 CUploadFile* CUploadsCtrl::GetNextFile(CUploadQueue* pQueue, POSITION& pos, int* pnPosition)
00561 {
00562         ASSERT( pos != NULL );
00563         
00564         if ( pnPosition != NULL ) *pnPosition = -1;
00565         
00566         if ( pQueue == UploadQueues.m_pTorrentQueue )
00567         {
00568                 CUploadFile* pReturn = UploadFiles.GetNext( pos );
00569                 
00570                 for ( ; pos ; )
00571                 {
00572                         POSITION posThis = pos;
00573                         CUploadFile* pFile = UploadFiles.GetNext( pos );
00574                         CUploadTransfer* pTransfer = pFile->GetActive();
00575                         if ( pTransfer == NULL || pTransfer->m_nState == upsNull ) continue;
00576                         if ( pTransfer->m_nProtocol != PROTOCOL_BT ) continue;
00577                         pos = posThis;
00578                         break;
00579                 }
00580                 
00581                 return pReturn;
00582         }
00583         else if ( pQueue == UploadQueues.m_pHistoryQueue )
00584         {
00585                 CUploadFile* pReturn = UploadFiles.GetNext( pos );
00586                 
00587                 for ( ; pos ; )
00588                 {
00589                         POSITION posThis = pos;
00590                         CUploadFile* pFile = UploadFiles.GetNext( pos );
00591                         CUploadTransfer* pTransfer = pFile->GetActive();
00592                         if ( pTransfer != NULL )
00593                         {
00594                                 //if ( pTransfer->m_nProtocol == PROTOCOL_BT && pTransfer->m_nState != upsNull ) continue;
00595                                 if ( pTransfer->m_nState != upsNull ) continue;
00596                                 if ( pTransfer->m_pQueue != NULL ) continue;
00597                         }
00598                         pos = posThis;
00599                         break;
00600                 }
00601                 
00602                 return pReturn;
00603         }
00604         else if ( (int)pos > pQueue->m_pQueued.GetSize() )
00605         {
00606                 CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pActive.GetNext( pos );
00607                 
00608                 if ( pos == NULL )
00609                 {
00610                         if ( Settings.Uploads.FilterMask & ULF_QUEUED )
00611                         {
00612                                 if ( pQueue->m_pQueued.GetCount() > 0 )
00613                                 {
00614                                         pos = (POSITION)1;
00615                                 }
00616                         }
00617                 }
00618                 
00619                 if ( pnPosition != NULL ) *pnPosition = 0;
00620                 return pTransfer->m_pBaseFile;
00621         }
00622         else
00623         {
00624                 CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pQueued.GetAt( (int)pos - 1 );
00625                 if ( pnPosition != NULL ) *pnPosition = (int)pos;
00626                 pos = (POSITION)( (int)pos + 1 );
00627                 if ( (int)pos > pQueue->m_pQueued.GetSize() ) pos = NULL;
00628                 return pTransfer->m_pBaseFile;
00629         }
00630 }
00631 
00633 // CUploadsCtrl presentation message handlers
00634 
00635 void CUploadsCtrl::OnSize(UINT nType, int cx, int cy)
00636 {
00637         int nWidth = 0, nHeight = 0;
00638         CRect rcClient;
00639         HDITEM pColumn;
00640         
00641         if ( nType != 1982 ) CWnd::OnSize( nType, cx, cy );
00642         
00643         GetClientRect( &rcClient );
00644         
00645         ZeroMemory( &pColumn, sizeof(pColumn) );
00646         pColumn.mask = HDI_WIDTH;
00647         
00648         for ( int nColumn = 0 ; m_wndHeader.GetItem( nColumn, &pColumn ) ; nColumn ++ )
00649                 nWidth += pColumn.cxy;
00650         
00651         SCROLLINFO pScroll;
00652         ZeroMemory( &pScroll, sizeof(pScroll) );
00653         pScroll.cbSize  = sizeof(pScroll);
00654         pScroll.fMask   = SIF_RANGE|SIF_PAGE;
00655         pScroll.nMin    = 0;
00656         pScroll.nMax    = nWidth;
00657         pScroll.nPage   = rcClient.right;
00658         SetScrollInfo( SB_HORZ, &pScroll, TRUE );
00659         
00660         int nScroll = GetScrollPos( SB_HORZ );
00661         m_wndHeader.SetWindowPos( NULL, -nScroll, 0, rcClient.right + nScroll, HEADER_HEIGHT, SWP_SHOWWINDOW );
00662         
00663         CSingleLock pLock( &Transfers.m_pSection, TRUE );
00664         
00665         for ( POSITION posQueue = GetQueueIterator() ; posQueue ; )
00666         {
00667                 CUploadQueue* pQueue = GetNextQueue( posQueue );
00668                 
00669                 POSITION posFile = GetFileIterator( pQueue );
00670                 
00671                 if ( posFile == NULL )
00672                 {
00673                         pQueue->m_bSelected = FALSE;
00674                         continue;
00675                 }
00676                 
00677                 nHeight ++;
00678                 
00679                 if ( ! pQueue->m_bExpanded ) continue;
00680 
00681                 while ( posFile )
00682                 {
00683                         if ( GetNextFile( pQueue, posFile ) ) nHeight ++;
00684                 }
00685         }
00686         
00687         pLock.Unlock();
00688         
00689         ZeroMemory( &pScroll, sizeof(pScroll) );
00690         pScroll.cbSize  = sizeof(pScroll);
00691         pScroll.fMask   = SIF_RANGE|SIF_PAGE;
00692         pScroll.nMin    = 0;
00693         pScroll.nMax    = nHeight;
00694         pScroll.nPage   = ( rcClient.bottom - HEADER_HEIGHT ) / ITEM_HEIGHT + 1;
00695         SetScrollInfo( SB_VERT, &pScroll, TRUE );
00696         
00697         m_nFocus = min( m_nFocus, max( 0, nHeight - 1 ) );
00698         
00699         Invalidate();
00700 }
00701 
00703 // CUploadsCtrl painting
00704 
00705 void CUploadsCtrl::OnPaint()
00706 {
00707         CSingleLock pLock( &Transfers.m_pSection, TRUE );
00708         CRect rcClient, rcItem;
00709         CPaintDC dc( this );
00710         if ( theApp.m_bRTL ) dc.SetTextAlign( TA_RTLREADING );
00711 
00712         GetClientRect( &rcClient );
00713         rcClient.top += HEADER_HEIGHT;
00714         
00715         rcItem.CopyRect( &rcClient );
00716         rcItem.left -= GetScrollPos( SB_HORZ );
00717         rcItem.bottom = rcItem.top + ITEM_HEIGHT;
00718         
00719         int nScroll = GetScrollPos( SB_VERT );
00720         int nIndex = 0;
00721         
00722         CFont* pfOld = (CFont*)dc.SelectObject( &theApp.m_gdiFont );
00723         BOOL bFocus = ( GetFocus() == this );
00724 
00725         for ( POSITION posQueue = GetQueueIterator() ; posQueue && rcItem.top < rcClient.bottom ; )
00726         {
00727                 CUploadQueue* pQueue = GetNextQueue( posQueue );
00728                 
00729                 POSITION posFile = GetFileIterator( pQueue );
00730                 if ( posFile == NULL ) continue;
00731                 
00732                 if ( nScroll > 0 )
00733                 {
00734                         nScroll --;
00735                 }
00736                 else
00737                 {
00738                         PaintQueue( dc, rcItem, pQueue, bFocus && ( m_nFocus == nIndex ) );
00739                         rcItem.OffsetRect( 0, ITEM_HEIGHT );
00740                 }
00741                 
00742                 nIndex ++;
00743                 
00744                 if ( ! pQueue->m_bExpanded ) continue;
00745                 
00746                 while ( posFile && rcItem.top < rcClient.bottom && rcItem.top < rcClient.bottom )
00747                 {
00748                         int nPosition;
00749                         CUploadFile* pFile = GetNextFile( pQueue, posFile, &nPosition );
00750                         if ( pFile == NULL ) continue;
00751                         
00752                         if ( nScroll > 0 )
00753                         {
00754                                 nScroll --;
00755                         }
00756                         else
00757                         {
00758                                 PaintFile( dc, rcItem, pQueue, pFile, nPosition, bFocus && ( m_nFocus == nIndex ) );
00759                                 rcItem.OffsetRect( 0, ITEM_HEIGHT );
00760                         }
00761                         
00762                         nIndex ++;
00763                 }
00764         }
00765         
00766         dc.SelectObject( pfOld );
00767         
00768         rcClient.top = rcItem.top;
00769         if ( rcClient.top < rcClient.bottom )
00770                 dc.FillSolidRect( &rcClient, CoolInterface.m_crWindow );
00771 }
00772 
00773 void CUploadsCtrl::PaintQueue(CDC& dc, const CRect& rcRow, CUploadQueue* pQueue, BOOL bFocus)
00774 {
00775         COLORREF crNatural      = CoolInterface.m_crWindow;
00776         COLORREF crBack         = pQueue->m_bSelected ? CoolInterface.m_crBackSel : crNatural;
00777         
00778         dc.SetBkColor( crBack );
00779         dc.SetBkMode( OPAQUE );
00780         
00781         if ( pQueue->m_bSelected )
00782                 dc.SetTextColor( CoolInterface.m_crText );
00783         else
00784                 dc.SetTextColor( CoolInterface.m_crText );
00785         
00786         int nTextLeft = rcRow.right, nTextRight = rcRow.left;
00787         HDITEM pColumn;
00788         
00789         ZeroMemory( &pColumn, sizeof(pColumn) );
00790         pColumn.mask = HDI_FORMAT | HDI_LPARAM;
00791         
00792         dc.SelectObject( &theApp.m_gdiFontBold );
00793         
00794         for ( int nColumn = 0 ; m_wndHeader.GetItem( nColumn, &pColumn ) ; nColumn++ )
00795         {
00796                 CString strText;
00797                 CRect rcCell;
00798                 
00799                 m_wndHeader.GetItemRect( nColumn, &rcCell );
00800                 rcCell.left             += rcRow.left;
00801                 rcCell.right    += rcRow.left;
00802                 rcCell.top              = rcRow.top;
00803                 rcCell.bottom   = rcRow.bottom;
00804                 
00805                 switch ( pColumn.lParam )
00806                 {
00807                 case UPLOAD_COLUMN_TITLE:
00808                         dc.FillSolidRect( rcCell.left, rcCell.bottom - 1, 32, 1, crNatural );
00809                         ImageList_DrawEx( ShellIcons.GetHandle( 16 ), pQueue->m_bExpanded ? SHI_MINUS : SHI_PLUS, dc.GetSafeHdc(),
00810                                         rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, ILD_NORMAL );
00811                         rcCell.left += 16;
00812                         if ( pQueue == UploadQueues.m_pTorrentQueue )
00813                         {
00814                                 ImageList_DrawEx( m_pProtocols, PROTOCOL_BT, dc.GetSafeHdc(),
00815                                                 rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, pQueue->m_bSelected ? ILD_SELECTED : ILD_NORMAL );
00816                         }
00817                         else if ( pQueue->m_nProtocols == ( 1 << PROTOCOL_HTTP ) )
00818                         {
00819                                 ImageList_DrawEx( m_pProtocols, PROTOCOL_HTTP, dc.GetSafeHdc(),
00820                                                 rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, pQueue->m_bSelected ? ILD_SELECTED : ILD_NORMAL );
00821                         }
00822                         else if ( pQueue->m_nProtocols == ( 1 << PROTOCOL_ED2K ) )
00823                         {
00824                                 ImageList_DrawEx( m_pProtocols, PROTOCOL_ED2K, dc.GetSafeHdc(),
00825                                                 rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, pQueue->m_bSelected ? ILD_SELECTED : ILD_NORMAL );
00826                         }
00827                         else
00828                         {
00829                                 ImageList_DrawEx( ShellIcons.GetHandle( 16 ), pQueue->m_bExpanded ? SHI_FOLDER_OPEN : SHI_FOLDER_CLOSED, dc.GetSafeHdc(),
00830                                                 rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, pQueue->m_bSelected ? ILD_SELECTED : ILD_NORMAL );
00831                         }
00832                         rcCell.left += 16;
00833                         dc.FillSolidRect( rcCell.left, rcCell.top, 1, rcCell.Height(), crNatural );
00834                         rcCell.left += 1;
00835                         
00836                         strText = pQueue->m_sName;
00837                         break;
00838                         
00839                 case UPLOAD_COLUMN_SIZE:
00840                         if ( pQueue == UploadQueues.m_pTorrentQueue )
00841                                 strText.Format( _T("%i/%i"), pQueue->m_nMinTransfers, pQueue->m_nMaxTransfers ); //No. Clients was loaded into these variables
00842                         else if ( pQueue != UploadQueues.m_pHistoryQueue )
00843                                 strText.Format( _T("%i/%i"), pQueue->GetTransferCount(), pQueue->GetQueuedCount() );
00844                         break;
00845                         
00846                 case UPLOAD_COLUMN_SPEED:
00847                         if ( pQueue != UploadQueues.m_pHistoryQueue )
00848                                 strText = Settings.SmartVolume( pQueue->GetMeasuredSpeed() * 8, FALSE, TRUE );
00849                         break;
00850                 }
00851                 
00852                 nTextLeft       = min( nTextLeft, int(rcCell.left) );
00853                 nTextRight      = max( nTextRight, int(rcCell.right) );
00854                 
00855                 if ( rcCell.Width() < 8 ) strText.Empty();
00856                 
00857                 if ( dc.GetTextExtent( strText ).cx > rcCell.Width() - 8 )
00858                 {
00859                         while ( dc.GetTextExtent( strText + _T('\x2026') ).cx > ( rcCell.Width() - 8 ) && strText.GetLength() > 0 )
00860                         {
00861                                 strText.Truncate( strText.GetLength() - 1 );
00862                         }
00863                         
00864                         if ( strText.GetLength() > 0 ) strText += _T('\x2026');
00865                 }
00866                 
00867                 int nWidth              = dc.GetTextExtent( strText ).cx;
00868                 int nPosition   = 0;
00869                 
00870                 switch ( pColumn.fmt & LVCFMT_JUSTIFYMASK )
00871                 {
00872                 default:
00873                         nPosition = ( rcCell.left + 4 );
00874                         break;
00875                 case LVCFMT_CENTER:
00876                         nPosition = ( ( rcCell.left + rcCell.right ) / 2 ) - ( nWidth / 2 );
00877                         break;
00878                 case LVCFMT_RIGHT:
00879                         nPosition = ( rcCell.right - 4 - nWidth );
00880                         break;
00881                 }
00882                 
00883                 dc.SetBkColor( crBack );
00884                 dc.ExtTextOut( nPosition, rcCell.top + 2, ETO_CLIPPED|ETO_OPAQUE,
00885                         &rcCell, strText, NULL );
00886         }
00887         
00888         if ( nTextRight < rcRow.right )
00889         {
00890                 CRect rcBlank( nTextRight, rcRow.top, rcRow.right, rcRow.bottom );
00891                 dc.FillSolidRect( &rcBlank, crBack );
00892         }
00893         
00894         dc.SelectObject( &theApp.m_gdiFont );
00895         
00896         if ( bFocus )
00897         {
00898                 CRect rcFocus( nTextLeft, rcRow.top, max( int(rcRow.right), nTextRight ), rcRow.bottom );
00899                 dc.Draw3dRect( &rcFocus, CoolInterface.m_crBorder, CoolInterface.m_crBorder );
00900         }
00901 }
00902 
00903 void CUploadsCtrl::PaintFile(CDC& dc, const CRect& rcRow, CUploadQueue* pQueue, CUploadFile* pFile, int nPosition, BOOL bFocus)
00904 {
00905         CUploadTransfer* pTransfer = pFile->GetActive();
00906         
00907         COLORREF crNatural      = CoolInterface.m_crWindow;
00908         COLORREF crBack         = pFile->m_bSelected ? CoolInterface.m_crBackSel : crNatural;
00909         
00910         dc.SetBkColor( crBack );
00911         dc.SetBkMode( OPAQUE );
00912         
00913         if ( pFile->m_bSelected )
00914                 dc.SetTextColor( CoolInterface.m_crText );
00915         else if ( pTransfer == NULL || pTransfer->m_nState == upsNull )
00916                 dc.SetTextColor( CoolInterface.m_crDisabled );
00917         else
00918                 dc.SetTextColor( CoolInterface.m_crText );
00919         
00920         int nTextLeft = rcRow.right, nTextRight = rcRow.left;
00921         HDITEM pColumn;
00922         
00923         ZeroMemory( &pColumn, sizeof(pColumn) );
00924         pColumn.mask = HDI_FORMAT | HDI_LPARAM;
00925 
00926         for ( int nColumn = 0 ; m_wndHeader.GetItem( nColumn, &pColumn ) ; nColumn++ )
00927         {
00928                 CString strText;
00929                 CRect rcCell;
00930                 
00931                 m_wndHeader.GetItemRect( nColumn, &rcCell );
00932                 rcCell.left             += rcRow.left;
00933                 rcCell.right    += rcRow.left;
00934                 rcCell.top              = rcRow.top;
00935                 rcCell.bottom   = rcRow.bottom;
00936                 
00937                 switch ( pColumn.lParam )
00938                 {
00939                 case UPLOAD_COLUMN_TITLE:
00940                         dc.FillSolidRect( rcCell.left, rcCell.top, 24, rcCell.Height(), crNatural );
00941                         rcCell.left += 24;
00942                         dc.FillSolidRect( rcCell.left, rcCell.bottom - 1, 16, 1, crNatural );
00943                         ImageList_DrawEx( ShellIcons.GetHandle( 16 ), ShellIcons.Get( pFile->m_sName, 16 ), dc.GetSafeHdc(),
00944                                         rcCell.left, rcCell.top, 16, 16, crNatural, CLR_DEFAULT, pFile->m_bSelected ? ILD_SELECTED : ILD_NORMAL );
00945                         rcCell.left += 16;
00946                         dc.FillSolidRect( rcCell.left, rcCell.top, 1, rcCell.Height(), crNatural );
00947                         rcCell.left += 1;
00948                         strText = pFile->m_sName;
00949                         break;
00950                         
00951                 case UPLOAD_COLUMN_USER:
00952                         if ( pTransfer == NULL )
00953                                 strText.Empty();
00954                         else if ( pTransfer->m_sNick.IsEmpty() )
00955                                 strText = pTransfer->m_sAddress;
00956                         else
00957                                 strText = pTransfer->m_sNick + _T(" (") + pTransfer->m_sAddress + _T(")");
00958                         break;
00959                         
00960                 case UPLOAD_COLUMN_SIZE:
00961                         strText = Settings.SmartVolume( pFile->m_nSize, FALSE );
00962                         break;
00963                         
00964                 case UPLOAD_COLUMN_PROGRESS:
00965                         dc.Draw3dRect( &rcCell, crBack, crBack );
00966                         rcCell.DeflateRect( 1, 1 );
00967                         dc.Draw3dRect( &rcCell, crBack, crBack );
00968                         rcCell.DeflateRect( 0, 1 );
00969                         dc.Draw3dRect( &rcCell, RGB( 50, 50, 50 ), RGB( 50, 50, 50 ) );
00970                         rcCell.DeflateRect( 1, 1 );
00971                         CFragmentBar::DrawUpload( &dc, &rcCell, pFile, crNatural );
00972                         break;
00973                         
00974                 case UPLOAD_COLUMN_SPEED:
00975                         if ( pTransfer == NULL || pTransfer->m_nState == upsNull )
00976                                 LoadString( strText, IDS_STATUS_COMPLETED );
00977                         else if ( pTransfer->m_nProtocol == PROTOCOL_BT )
00978                         {
00979                                 CUploadTransferBT* pBT = (CUploadTransferBT*)pTransfer;
00980                                 
00981                                 if ( ! pBT->m_bInterested )
00982                                         LoadString( strText, IDS_STATUS_UNINTERESTED );
00983                                 else if ( pBT->m_bChoked )
00984                                         LoadString( strText, IDS_STATUS_CHOKED );
00985                                 else if ( DWORD nSpeed = pTransfer->GetMeasuredSpeed() * 8 )
00986                                         strText = Settings.SmartVolume( nSpeed, FALSE, TRUE );
00987                         }
00988                         else if ( nPosition > 0 )
00989                         {
00990                                 CString strQ;
00991                                 LoadString( strQ, IDS_STATUS_Q );
00992                                 strText.Format( _T("%s %i"), strQ, nPosition );
00993                         }
00994                         else if ( DWORD nSpeed = pTransfer->GetMeasuredSpeed() * 8 )
00995                                 strText = Settings.SmartVolume( nSpeed, FALSE, TRUE );
00996                         else
00997                                 LoadString( strText, IDS_STATUS_NEXT );
00998                         break;
00999                         
01000                 case UPLOAD_COLUMN_CLIENT:
01001                         if ( pTransfer != NULL ) strText = pTransfer->m_sUserAgent;
01002                         break;
01003                 case UPLOAD_COLUMN_RATING:
01004                         strText.Format(_T("%d"), pTransfer->m_nUserRating );
01005                         break;
01006                 }
01007                 
01008                 nTextLeft       = min( nTextLeft, int(rcCell.left) );
01009                 nTextRight      = max( nTextRight, int(rcCell.right) );
01010                 
01011                 if ( pColumn.lParam == UPLOAD_COLUMN_PROGRESS ) continue;
01012                 
01013                 if ( rcCell.Width() < 8 ) strText.Empty();
01014                 
01015                 if ( dc.GetTextExtent( strText ).cx > rcCell.Width() - 8 )
01016                 {
01017                         while ( dc.GetTextExtent( strText + _T('\x2026') ).cx > ( rcCell.Width() - 8 ) && strText.GetLength() > 0 )
01018                         {
01019                                 strText.Truncate( strText.GetLength() - 1 );
01020                         }
01021                         
01022                         if ( strText.GetLength() > 0 ) strText += _T('\x2026');
01023                 }
01024                 
01025                 int nWidth              = dc.GetTextExtent( strText ).cx;
01026                 int nPosition   = 0;
01027                 
01028                 switch ( pColumn.fmt & LVCFMT_JUSTIFYMASK )
01029                 {
01030                 default:
01031                         nPosition = ( rcCell.left + 4 );
01032                         break;
01033                 case LVCFMT_CENTER:
01034                         nPosition = ( ( rcCell.left + rcCell.right ) / 2 ) - ( nWidth / 2 );
01035                         break;
01036                 case LVCFMT_RIGHT:
01037                         nPosition = ( rcCell.right - 4 - nWidth );
01038                         break;
01039                 }
01040                 
01041                 dc.SetBkColor( crBack );
01042                 dc.ExtTextOut( nPosition, rcCell.top + 2, ETO_CLIPPED|ETO_OPAQUE,
01043                         &rcCell, strText, NULL );
01044         }
01045         
01046         if ( nTextRight < rcRow.right )
01047         {
01048                 CRect rcBlank( nTextRight, rcRow.top, rcRow.right, rcRow.bottom );
01049                 dc.FillSolidRect( &rcBlank, crBack );
01050         }
01051         
01052         if ( bFocus )
01053         {
01054                 CRect rcFocus( nTextLeft, rcRow.top, max( int(rcRow.right), nTextRight ), rcRow.bottom );
01055                 dc.Draw3dRect( &rcFocus, CoolInterface.m_crBorder, CoolInterface.m_crBorder );
01056         }
01057 }
01058 
01060 // CUploadsCtrl interaction message handlers
01061 
01062 void CUploadsCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
01063 {
01064         SCROLLINFO pInfo;
01065         
01066         pInfo.cbSize    = sizeof(pInfo);
01067         pInfo.fMask             = SIF_ALL & ~SIF_TRACKPOS;
01068         
01069         GetScrollInfo( SB_VERT, &pInfo );
01070         int nDelta = pInfo.nPos;
01071         
01072         switch ( nSBCode )
01073         {
01074         case SB_BOTTOM:
01075                 pInfo.nPos = pInfo.nMax - pInfo.nPage;
01076                 break;
01077         case SB_LINEDOWN:
01078                 pInfo.nPos ++;
01079                 break;
01080         case SB_LINEUP:
01081                 pInfo.nPos --;
01082                 break;
01083         case SB_PAGEDOWN:
01084                 pInfo.nPos += pInfo.nPage;
01085                 break;
01086         case SB_PAGEUP:
01087                 pInfo.nPos -= pInfo.nPage;
01088                 break;
01089         case SB_THUMBPOSITION:
01090         case SB_THUMBTRACK:
01091                 pInfo.nPos = nPos;
01092                 break;
01093         case SB_TOP:
01094                 pInfo.nPos = 0;
01095                 break;
01096         }
01097         
01098         pInfo.nPos = max( 0, min( pInfo.nPos, pInfo.nMax - (int)pInfo.nPage + 1 ) );
01099         if ( pInfo.nPos == nDelta ) return;
01100         
01101         SetScrollInfo( SB_VERT, &pInfo, TRUE );
01102         Invalidate();
01103 }
01104 
01105 void CUploadsCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
01106 {
01107         SCROLLINFO pInfo;
01108         
01109         pInfo.cbSize    = sizeof(pInfo);
01110         pInfo.fMask             = SIF_ALL & ~SIF_TRACKPOS;
01111         
01112         GetScrollInfo( SB_HORZ, &pInfo );
01113         int nDelta = pInfo.nPos;
01114         
01115         switch ( nSBCode )
01116         {
01117         case SB_BOTTOM:
01118                 pInfo.nPos = pInfo.nMax - pInfo.nPage;
01119                 break;
01120         case SB_LINEDOWN:
01121                 pInfo.nPos ++;
01122                 break;
01123         case SB_LINEUP:
01124                 pInfo.nPos --;
01125                 break;
01126         case SB_PAGEDOWN:
01127                 pInfo.nPos += pInfo.nPage;
01128                 break;
01129         case SB_PAGEUP:
01130                 pInfo.nPos -= pInfo.nPage;
01131                 break;
01132         case SB_THUMBPOSITION:
01133         case SB_THUMBTRACK:
01134                 pInfo.nPos = nPos;
01135                 break;
01136         case SB_TOP:
01137                 pInfo.nPos = 0;
01138                 break;
01139         }
01140         
01141         pInfo.nPos = max( 0, min( pInfo.nPos, pInfo.nMax - (int)pInfo.nPage + 1 ) );
01142         if ( pInfo.nPos == nDelta ) return;
01143         
01144         SetScrollInfo( SB_HORZ, &pInfo, TRUE );
01145         
01146         CRect rcClient;
01147         GetClientRect( &rcClient );
01148         
01149         m_wndHeader.SetWindowPos( NULL, -pInfo.nPos, 0,
01150                 rcClient.right + pInfo.nPos, HEADER_HEIGHT, SWP_NOZORDER );
01151         
01152         RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW );
01153 }
01154 
01155 BOOL CUploadsCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
01156 {
01157         OnVScroll( SB_THUMBPOSITION, (int)( GetScrollPos( SB_VERT ) - zDelta / WHEEL_DELTA * m_nScrollWheelLines ), NULL );
01158         return TRUE;
01159 }
01160 
01161 void CUploadsCtrl::OnChangeHeader(NMHDR* pNotifyStruct, LRESULT* pResult)
01162 {
01163         Update();
01164 }
01165 
01166 void CUploadsCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
01167 {
01168         CSingleLock pLock( &Transfers.m_pSection, TRUE );
01169         CUploadFile* pFile;
01170         CUploadQueue* pQueue;
01171         
01172         m_wndTip.Hide();
01173         
01174         switch ( nChar )
01175         {
01176         case VK_HOME:
01177                 SelectTo( 0 );
01178                 return;
01179         case VK_END:
01180                 {
01181                         INT nMin, nMax;
01182                         GetScrollRange( SB_VERT, &nMin, &nMax );
01183                         SelectTo( max( 0, nMax - 1 ) );
01184                 }
01185                 return;
01186         case VK_UP:
01187                 SelectTo( m_nFocus - 1 );
01188                 return;
01189         case VK_DOWN:
01190                 SelectTo( m_nFocus + 1 );
01191                 return;
01192         case VK_PRIOR:
01193                 SelectTo( m_nFocus - 10 );
01194                 return;
01195         case VK_NEXT:
01196                 SelectTo( m_nFocus + 10 );
01197                 return;
01198         case VK_LEFT:
01199         case '-':
01200                 if ( GetAt( m_nFocus, &pQueue, &pFile ) )
01201                 {
01202                         if ( pFile != NULL && pFile->GetActive() != NULL )
01203                                 pQueue = pFile->GetActive()->m_pQueue;
01204                         if ( pQueue != NULL && pQueue->m_bExpanded == TRUE )
01205                         {
01206                                 pQueue->m_bExpanded = FALSE;
01207                                 Update();
01208                         }
01209                 }
01210                 return;
01211         case VK_RIGHT:
01212         case '+':
01213                 if ( GetAt( m_nFocus, &pQueue, NULL ) && pQueue != NULL && pQueue->m_bExpanded == FALSE )
01214                 {
01215                         pQueue->m_bExpanded = TRUE;
01216                         Update();
01217                 }
01218                 return;
01219         }
01220         
01221         CWnd::OnKeyDown( nChar, nRepCnt, nFlags );
01222 }
01223 
01224 void CUploadsCtrl::OnLButtonDown(UINT nFlags, CPoint point)
01225 {
01226         CSingleLock pLock( &Transfers.m_pSection, TRUE );
01227         CUploadFile* pFile;
01228         CUploadQueue* pQueue;
01229         CRect rcItem;
01230         int nIndex;
01231         
01232         SetFocus();
01233         m_wndTip.Hide();
01234         
01235         if ( HitTest( point, &pQueue, &pFile, &nIndex, &rcItem ) )
01236         {
01237                 int nTitleStarts = GetExpandableColumnX();
01238                 if ( point.x > nTitleStarts && point.x <= nTitleStarts + rcItem.left + 16 )
01239                 {
01240                         if ( pQueue != NULL )
01241                         {
01242                                 pQueue->m_bExpanded = ! pQueue->m_bExpanded;
01243                                 
01244                                 if ( ! pQueue->m_bExpanded )
01245                                 {
01246                                         for ( POSITION posActive = pQueue->m_pActive.GetHeadPosition() ; posActive ; )
01247                                         {
01248                                                 CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pActive.GetNext( posActive );
01249                                                 if ( pTransfer->m_pBaseFile != NULL ) pTransfer->m_pBaseFile->m_bSelected = FALSE;
01250                                         }
01251                                         
01252                                         for ( int nPos = 0 ; nPos < pQueue->m_pQueued.GetSize() ; nPos ++ )
01253                                         {
01254                                                 CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pQueued.GetAt( nPos );
01255                                                 if ( pTransfer->m_pBaseFile != NULL ) pTransfer->m_pBaseFile->m_bSelected = FALSE;
01256                                         }
01257                                 }
01258                                 
01259                                 Update();
01260                         }
01261                 }
01262                 else
01263                 {
01264                         if ( pFile != NULL && pFile->m_bSelected )
01265                         {
01266                                 if ( ( nFlags & ( MK_SHIFT | MK_CONTROL | MK_RBUTTON ) ) == 0 )
01267                                 {
01268                                         m_pDeselect = pFile;
01269                                 }
01270                         }
01271                         else if ( nFlags & MK_RBUTTON )
01272                         {
01273                                 DeselectAll();
01274                         }
01275                         
01276                         SelectTo( nIndex );
01277                 }
01278         }
01279         else if ( ( nFlags & ( MK_SHIFT | MK_CONTROL ) ) == 0 )
01280         {
01281                 DeselectAll();
01282                 Update();
01283         }
01284 }
01285 
01286 void CUploadsCtrl::OnRButtonDown(UINT nFlags, CPoint point)
01287 {
01288         m_wndTip.Hide();
01289         OnLButtonDown( nFlags, point );
01290         CWnd::OnRButtonDown( nFlags, point );
01291 }
01292 
01293 void CUploadsCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
01294 {
01295         CSingleLock pLock( &Transfers.m_pSection, TRUE );
01296         CUploadFile* pFile;
01297         CUploadQueue* pQueue;
01298         CRect rcItem;
01299         
01300         SetFocus();
01301         
01302         if ( HitTest( point, &pQueue, &pFile, NULL, &rcItem ) )
01303         {
01304                 int nTitleStarts = GetExpandableColumnX();
01305                 if ( pQueue != NULL && point.x > nTitleStarts && point.x <= nTitleStarts + rcItem.left + 16 )
01306                 {
01307                         pQueue->m_bExpanded = ! pQueue->m_bExpanded;
01308                         
01309                         if ( ! pQueue->m_bExpanded )
01310                         {
01311                                 for ( POSITION posActive = pQueue->m_pActive.GetHeadPosition() ; posActive ; )
01312                                 {
01313                                         CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pActive.GetNext( posActive );
01314                                         if ( pTransfer->m_pBaseFile != NULL ) pTransfer->m_pBaseFile->m_bSelected = FALSE;
01315                                 }
01316                                 
01317                                 for ( int nPos = 0 ; nPos < pQueue->m_pQueued.GetSize() ; nPos ++ )
01318                                 {
01319                                         CUploadTransfer* pTransfer = (CUploadTransfer*)pQueue->m_pQueued.GetAt( nPos );
01320                                         if ( pTransfer->m_pBaseFile != NULL ) pTransfer->m_pBaseFile->m_bSelected = FALSE;
01321                                 }
01322                         }
01323                         
01324                         Update();
01325                 }
01326                 else if ( pQueue != NULL )
01327                 {
01328                         GetOwner()->PostMessage( WM_TIMER, 5 );
01329                         // GetOwner()->PostMessage( WM_COMMAND, ID_UPLOADS_QUEUE_PROPERTIES );
01330                 }
01331                 else if ( pFile != NULL )
01332                 {
01333                         GetOwner()->PostMessage( WM_TIMER, 5 );
01334                         GetOwner()->PostMessage( WM_COMMAND, ID_UPLOADS_LAUNCH );
01335                 }
01336         }
01337         
01338         CWnd::OnLButtonDblClk( nFlags, point );
01339 }
01340 
01341 void CUploadsCtrl::OnMouseMove(UINT nFlags, CPoint point)
01342 {
01343         CWnd::OnMouseMove( nFlags, point );
01344         
01345         if ( ( nFlags & ( MK_LBUTTON|MK_RBUTTON) ) == 0 )
01346         {
01347                 CUploadFile* pFile;
01348                 CRect rcItem;
01349                 
01350                 if ( HitTest( point, NULL, &pFile, NULL, &rcItem ) )
01351                 {
01352                         if ( pFile != NULL )
01353                         {
01354                                 m_wndTip.Show( pFile );
01355                                 return;
01356                         }
01357                 }
01358         }
01359         
01360         m_wndTip.Hide();
01361 }
01362 
01363 void CUploadsCtrl::OnLButtonUp(UINT nFlags, CPoint point)
01364 {
01365         if ( m_pDeselect != NULL )
01366         {
01367                 DeselectAll( m_pDeselect );
01368                 m_pDeselect = NULL;
01369         }
01370         
01371         CWnd::OnLButtonUp( nFlags, point );
01372 }
01373 
01374 void CUploadsCtrl::OnRButtonUp(UINT nFlags, CPoint point)
01375 {
01376         if ( m_pDeselect != NULL )
01377         {
01378                 DeselectAll( m_pDeselect );
01379                 m_pDeselect = NULL;
01380         }
01381         
01382         CWnd::OnRButtonUp( nFlags, point );
01383 }
01384 
01385 void CUploadsCtrl::OnSetFocus(CWnd* pOldWnd)
01386 {
01387         CWnd::OnSetFocus( pOldWnd );
01388         Invalidate();
01389 }
01390 
01391 void CUploadsCtrl::OnKillFocus(CWnd* pNewWnd)
01392 {
01393         CWnd::OnKillFocus( pNewWnd );
01394         Invalidate();
01395 }
01396 
01397 int CUploadsCtrl::GetExpandableColumnX() const
01398 {
01399         HDITEM pColumn;
01400         int nTitleStarts = 0;
01401         
01402         ZeroMemory( &pColumn, sizeof(pColumn) );
01403         pColumn.mask = HDI_LPARAM | HDI_WIDTH;
01404 
01405         for ( int nColumn = 0 ; m_wndHeader.GetItem( m_wndHeader.OrderToIndex( nColumn ), &pColumn ) ; nColumn++ )
01406         {
01407                 if ( pColumn.lParam == UPLOAD_COLUMN_TITLE ) break;
01408                 else nTitleStarts += pColumn.cxy;
01409         }
01410         return nTitleStarts;
01411 }

Generated on Thu Dec 15 10:39:38 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2