00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Network.h"
00026 #include "HostCache.h"
00027 #include "HubHorizon.h"
00028 #include "Neighbours.h"
00029 #include "Neighbour.h"
00030 #include "VendorCache.h"
00031 #include "WndHostCache.h"
00032 #include "DlgDonkeyServers.h"
00033 #include "LiveList.h"
00034 #include "Skin.h"
00035
00036 #ifdef _DEBUG
00037 #define new DEBUG_NEW
00038 #undef THIS_FILE
00039 static char THIS_FILE[] = __FILE__;
00040 #endif
00041
00042 IMPLEMENT_SERIAL(CHostCacheWnd, CPanelWnd, 0)
00043
00044 BEGIN_MESSAGE_MAP(CHostCacheWnd, CPanelWnd)
00045
00046 ON_WM_CREATE()
00047 ON_WM_SIZE()
00048 ON_WM_NCMOUSEMOVE()
00049 ON_NOTIFY(NM_CUSTOMDRAW, IDC_HOSTS, OnCustomDrawList)
00050 ON_NOTIFY(NM_DBLCLK, IDC_HOSTS, OnDblClkList)
00051 ON_NOTIFY(LVN_COLUMNCLICK, IDC_HOSTS, OnSortList)
00052 ON_WM_TIMER()
00053 ON_WM_CONTEXTMENU()
00054 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_CONNECT, OnUpdateHostCacheConnect)
00055 ON_COMMAND(ID_HOSTCACHE_CONNECT, OnHostCacheConnect)
00056 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_DISCONNECT, OnUpdateHostCacheDisconnect)
00057 ON_COMMAND(ID_HOSTCACHE_DISCONNECT, OnHostCacheDisconnect)
00058 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_REMOVE, OnUpdateHostCacheRemove)
00059 ON_COMMAND(ID_HOSTCACHE_REMOVE, OnHostCacheRemove)
00060 ON_WM_DESTROY()
00061 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_G2_HORIZON, OnUpdateHostcacheG2Horizon)
00062 ON_COMMAND(ID_HOSTCACHE_G2_HORIZON, OnHostcacheG2Horizon)
00063 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_G2_CACHE, OnUpdateHostcacheG2Cache)
00064 ON_COMMAND(ID_HOSTCACHE_G2_CACHE, OnHostcacheG2Cache)
00065 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_G1_CACHE, OnUpdateHostcacheG1Cache)
00066 ON_COMMAND(ID_HOSTCACHE_G1_CACHE, OnHostcacheG1Cache)
00067 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_ED2K_CACHE, OnUpdateHostcacheEd2kCache)
00068 ON_COMMAND(ID_HOSTCACHE_ED2K_CACHE, OnHostcacheEd2kCache)
00069 ON_COMMAND(ID_HOSTCACHE_IMPORT, OnHostcacheImport)
00070 ON_COMMAND(ID_HOSTCACHE_ED2K_DOWNLOAD, OnHostcacheEd2kDownload)
00071 ON_UPDATE_COMMAND_UI(ID_HOSTCACHE_PRIORITY, OnUpdateHostcachePriority)
00072 ON_COMMAND(ID_HOSTCACHE_PRIORITY, OnHostcachePriority)
00073
00074 END_MESSAGE_MAP()
00075
00076
00078
00079
00080 CHostCacheWnd::CHostCacheWnd()
00081 {
00082 Create( IDR_HOSTCACHEFRAME );
00083 }
00084
00085 CHostCacheWnd::~CHostCacheWnd()
00086 {
00087 }
00088
00090
00091
00092 int CHostCacheWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
00093 {
00094 if ( Settings.Gnutella.HostCacheView < PROTOCOL_NULL || Settings.Gnutella.HostCacheView > PROTOCOL_ED2K )
00095 Settings.Gnutella.HostCacheView = PROTOCOL_G2;
00096
00097 m_nMode = Settings.Gnutella.HostCacheView;
00098
00099 if ( CPanelWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00100
00101 if ( ! m_wndToolBar.Create( this, WS_CHILD|WS_VISIBLE|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
00102 m_wndToolBar.SetBarStyle( m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_BORDER_TOP );
00103 m_wndToolBar.SetSyncObject( &Network.m_pSection );
00104
00105 m_wndList.Create( WS_VISIBLE|LVS_ICON|LVS_AUTOARRANGE|LVS_REPORT|LVS_SHOWSELALWAYS,
00106 rectDefault, this, IDC_HOSTS );
00107 m_pSizer.Attach( &m_wndList );
00108
00109 m_wndList.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
00110 LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP,
00111 LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP );
00112
00113 CBitmap bmImages;
00114 bmImages.LoadBitmap( IDB_PROTOCOLS );
00115 if ( theApp.m_bRTL )
00116 bmImages.m_hObject = CreateMirroredBitmap( (HBITMAP)bmImages.m_hObject );
00117 m_gdiImageList.Create( 16, 16, ILC_COLOR16|ILC_MASK, 7, 1 );
00118 m_gdiImageList.Add( &bmImages, RGB( 0, 255, 0 ) );
00119 m_wndList.SetImageList( &m_gdiImageList, LVSIL_SMALL );
00120
00121 m_wndList.InsertColumn( 0, _T("Address"), LVCFMT_LEFT, 140, -1 );
00122 m_wndList.InsertColumn( 1, _T("Port"), LVCFMT_CENTER, 60, 0 );
00123 m_wndList.InsertColumn( 2, _T("Client"), LVCFMT_CENTER, 100, 1 );
00124 m_wndList.InsertColumn( 3, _T("Last Seen"), LVCFMT_CENTER, 130, 2 );
00125 m_wndList.InsertColumn( 4, _T("Name"), LVCFMT_LEFT, 130, 3 );
00126 m_wndList.InsertColumn( 5, _T("Description"), LVCFMT_LEFT, 130, 4 );
00127 m_wndList.InsertColumn( 6, _T("CurUsers"), LVCFMT_CENTER, 60, 5 );
00128 m_wndList.InsertColumn( 7, _T("MaxUsers"), LVCFMT_CENTER, 60, 6 );
00129
00130 m_wndList.SetFont( &theApp.m_gdiFont );
00131
00132 Settings.LoadList( _T("CHostCacheWnd"), &m_wndList );
00133 LoadState( _T("CHostCacheWnd"), TRUE );
00134
00135 CWaitCursor pCursor;
00136 m_bAllowUpdates = TRUE;
00137 Update( TRUE );
00138
00139 return 0;
00140 }
00141
00142 void CHostCacheWnd::OnDestroy()
00143 {
00144 CSingleLock pLock( &Network.m_pSection );
00145
00146 if ( pLock.Lock( 250 ) ) HostCache.Save();
00147
00148 Settings.SaveList( _T("CHostCacheWnd"), &m_wndList );
00149 SaveState( _T("CHostCacheWnd") );
00150
00151 CPanelWnd::OnDestroy();
00152 }
00153
00155
00156
00157 void CHostCacheWnd::Update(BOOL bForce)
00158 {
00159 if ( !bForce )
00160 if ( !m_bAllowUpdates ) return;
00161
00162 CSingleLock pLock( &Network.m_pSection );
00163 if ( ! pLock.Lock( 50 ) ) return;
00164
00165 m_wndList.ModifyStyle( WS_VISIBLE, 0 );
00166
00167 CLiveList pLiveList( 8 );
00168
00169 PROTOCOLID nEffective = m_nMode ? m_nMode : PROTOCOL_G2;
00170
00171 CHostCacheList* pCache = HostCache.ForProtocol( nEffective );
00172
00173 m_nCookie = pCache->m_nCookie;
00174 int nProtocolRev = m_gdiImageList.GetImageCount() - 1;
00175
00176 for ( CHostCacheHost* pHost = pCache->GetNewest() ; pHost ; pHost = pHost->m_pPrevTime )
00177 {
00178
00179
00180 if ( !m_bAllowUpdates && !bForce ) break;
00181 if ( m_nMode == PROTOCOL_NULL )
00182 {
00183 if ( HubHorizonPool.Find( &pHost->m_pAddress ) == NULL ) continue;
00184 }
00185
00186 CLiveItem* pItem = pLiveList.Add( pHost );
00187
00188 pItem->m_nImage = theApp.m_bRTL ? nProtocolRev - pHost->m_nProtocol : pHost->m_nProtocol;
00189 pItem->m_nMaskOverlay = pHost->m_bPriority;
00190
00191 pItem->Set( 0, CString( inet_ntoa( pHost->m_pAddress ) ) );
00192 pItem->Format( 1, _T("%hu"), pHost->m_nPort );
00193
00194 #ifdef _DEBUG
00195 pItem->Format( 2, _T("K:%u A:%u Q:%u"),
00196 pHost->m_nKeyValue, pHost->m_tAck, pHost->m_tQuery );
00197 #else
00198 if ( pHost->m_pVendor )
00199 pItem->Set( 2, pHost->m_pVendor->m_sName );
00200 else if ( pHost->m_nProtocol == PROTOCOL_G2 )
00201 pItem->Set( 2, _T("(Gnutella2)") );
00202 else if ( pHost->m_nProtocol == PROTOCOL_ED2K )
00203 pItem->Set( 2, _T("(eDonkey Server)") );
00204 #endif
00205
00206 CTime pTime( (time_t)pHost->m_tSeen );
00207 pItem->Set( 3, pTime.Format( _T("%Y-%m-%d %H:%M:%S") ) );
00208
00209 pItem->Set( 4, pHost->m_sName );
00210 pItem->Set( 5, pHost->m_sDescription );
00211
00212 if ( pHost->m_nUserCount ) pItem->Format( 6, _T("%u"), pHost->m_nUserCount );
00213 if ( pHost->m_nUserLimit ) pItem->Format( 7, _T("%u"), pHost->m_nUserLimit );
00214 }
00215
00216 if ( !m_bAllowUpdates && !bForce ) return;
00217 pLiveList.Apply( &m_wndList, TRUE );
00218 m_wndList.ShowWindow( SW_SHOW );
00219
00220 tLastUpdate = GetTickCount();
00221 }
00222
00223 CHostCacheHost* CHostCacheWnd::GetItem(int nItem)
00224 {
00225 if ( m_wndList.GetItemState( nItem, LVIS_SELECTED ) )
00226 {
00227 CHostCacheHost* pHost = (CHostCacheHost*)m_wndList.GetItemData( nItem );
00228 if ( HostCache.Check( pHost ) ) return pHost;
00229 }
00230
00231 return NULL;
00232 }
00233
00234 void CHostCacheWnd::OnSkinChange()
00235 {
00236 CPanelWnd::OnSkinChange();
00237 Settings.LoadList( _T("CHostCacheWnd"), &m_wndList );
00238 Skin.CreateToolBar( _T("CHostCacheWnd"), &m_wndToolBar );
00239 if ( Settings.General.GUIMode == GUI_BASIC)
00240 {
00241 m_nMode = Settings.Gnutella.HostCacheView = PROTOCOL_G2;
00242 }
00243
00244 }
00245
00247
00248
00249 void CHostCacheWnd::OnSize(UINT nType, int cx, int cy)
00250 {
00251 CPanelWnd::OnSize( nType, cx, cy );
00252 m_pSizer.Resize( cx );
00253 SizeListAndBar( &m_wndList, &m_wndToolBar );
00254 }
00255
00256 void CHostCacheWnd::OnTimer(UINT nIDEvent)
00257 {
00258 if ( nIDEvent == 1 && IsPartiallyVisible() )
00259 {
00260 PROTOCOLID nEffective = m_nMode ? m_nMode : PROTOCOL_G2;
00261
00262 if ( ( nEffective != PROTOCOL_G1 ) && ( nEffective != PROTOCOL_G2 ) && ( nEffective != PROTOCOL_ED2K ) )
00263 nEffective = PROTOCOL_G2;
00264
00265 CHostCacheList* pCache = HostCache.ForProtocol( nEffective );
00266 DWORD tTicks = GetTickCount();
00267
00268
00269 if ( ( pCache->m_nCookie != m_nCookie ) && ( ( tTicks - tLastUpdate ) > 5000 ) ) Update();
00270 }
00271 }
00272
00273 void CHostCacheWnd::OnCustomDrawList(NMHDR* pNMHDR, LRESULT* pResult)
00274 {
00275 NMLVCUSTOMDRAW* pDraw = (NMLVCUSTOMDRAW*)pNMHDR;
00276
00277 if ( pDraw->nmcd.dwDrawStage == CDDS_PREPAINT )
00278 {
00279 *pResult = ( m_nMode == PROTOCOL_ED2K ) ? CDRF_NOTIFYITEMDRAW : CDRF_DODEFAULT;
00280 }
00281 else if ( pDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT )
00282 {
00283 LV_ITEM pItem = { LVIF_STATE, pDraw->nmcd.dwItemSpec, 0, 0, LVIS_OVERLAYMASK };
00284 m_wndList.GetItem( &pItem );
00285
00286 if ( pItem.state & LVIS_OVERLAYMASK )
00287 pDraw->clrText = GetSysColor( COLOR_ACTIVECAPTION );
00288
00289 *pResult = CDRF_DODEFAULT;
00290 }
00291 }
00292
00293 void CHostCacheWnd::OnDblClkList(NMHDR* pNMHDR, LRESULT* pResult)
00294 {
00295 OnHostCacheConnect();
00296 *pResult = 0;
00297 }
00298
00299 void CHostCacheWnd::OnSortList(NMHDR* pNotifyStruct, LRESULT *pResult)
00300 {
00301 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNotifyStruct;
00302 CLiveList::Sort( &m_wndList, pNMListView->iSubItem );
00303 *pResult = 0;
00304 }
00305
00306 void CHostCacheWnd::OnContextMenu(CWnd* pWnd, CPoint point)
00307 {
00308
00309 m_bAllowUpdates = FALSE;
00310 TrackPopupMenu( _T("CHostCacheWnd"), point, ID_HOSTCACHE_CONNECT );
00311 m_bAllowUpdates = TRUE;
00312 }
00313
00314 void CHostCacheWnd::OnNcMouseMove(UINT nHitTest, CPoint point)
00315 {
00316
00317 m_bAllowUpdates = FALSE;
00318 }
00319
00320 void CHostCacheWnd::OnUpdateHostCacheConnect(CCmdUI* pCmdUI)
00321 {
00322 pCmdUI->Enable( ( m_wndList.GetSelectedCount() > 0 ) &&
00323 ( ( m_nMode != PROTOCOL_ED2K ) || ( Settings.GetOutgoingBandwidth() >= 2 ) ) );
00324 }
00325
00326 void CHostCacheWnd::OnHostCacheConnect()
00327 {
00328 CSingleLock pLock( &Network.m_pSection, TRUE );
00329
00330 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00331 while( pos )
00332 {
00333 int nItem = m_wndList.GetNextSelectedItem( pos );
00334 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00335 {
00336 pHost->ConnectTo();
00337 }
00338 }
00339 }
00340
00341 void CHostCacheWnd::OnUpdateHostCacheDisconnect(CCmdUI* pCmdUI)
00342 {
00343 CSingleLock pLock( &Network.m_pSection );
00344
00345 if ( pLock.Lock( 50 ) )
00346 {
00347 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00348 while( pos )
00349 {
00350 int nItem = m_wndList.GetNextSelectedItem( pos );
00351 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00352 {
00353 CNeighbour* pNeighbour = Neighbours.Get( &pHost->m_pAddress );
00354 if ( pNeighbour )
00355 {
00356 pCmdUI->Enable( TRUE );
00357 return;
00358 }
00359 }
00360 }
00361
00362 pCmdUI->Enable( FALSE );
00363 }
00364 }
00365
00366 void CHostCacheWnd::OnHostCacheDisconnect()
00367 {
00368 CSingleLock pLock( &Network.m_pSection, TRUE );
00369
00370 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00371 while( pos )
00372 {
00373 int nItem = m_wndList.GetNextSelectedItem( pos );
00374 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00375 {
00376 CNeighbour* pNeighbour = Neighbours.Get( &pHost->m_pAddress );
00377 if ( pNeighbour ) pNeighbour->Close();
00378 }
00379 }
00380 }
00381
00382 void CHostCacheWnd::OnUpdateHostcachePriority(CCmdUI* pCmdUI)
00383 {
00384 if ( m_nMode != PROTOCOL_ED2K || m_wndList.GetSelectedCount() == 0 )
00385 {
00386 pCmdUI->Enable( FALSE );
00387 pCmdUI->SetCheck( FALSE );
00388 return;
00389 }
00390
00391 CSingleLock pLock( &Network.m_pSection, TRUE );
00392 pCmdUI->Enable( TRUE );
00393
00394 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00395 while( pos )
00396 {
00397 int nItem = m_wndList.GetNextSelectedItem( pos );
00398 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00399 {
00400 if ( pHost->m_bPriority )
00401 {
00402 pCmdUI->SetCheck( TRUE );
00403 return;
00404 }
00405 }
00406 }
00407
00408 pCmdUI->SetCheck( FALSE );
00409 }
00410
00411 void CHostCacheWnd::OnHostcachePriority()
00412 {
00413 if ( m_nMode != PROTOCOL_ED2K) return;
00414
00415 CSingleLock pLock( &Network.m_pSection, TRUE );
00416
00417 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00418 while( pos )
00419 {
00420 int nItem = m_wndList.GetNextSelectedItem( pos );
00421 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00422 {
00423 pHost->m_bPriority = ! pHost->m_bPriority;
00424 }
00425 }
00426
00427 HostCache.eDonkey.m_nCookie ++;
00428 }
00429
00430 void CHostCacheWnd::OnUpdateHostCacheRemove(CCmdUI* pCmdUI)
00431 {
00432 pCmdUI->Enable( m_wndList.GetSelectedCount() > 0 );
00433 }
00434
00435 void CHostCacheWnd::OnHostCacheRemove()
00436 {
00437 CSingleLock pLock( &Network.m_pSection, TRUE );
00438
00439 POSITION pos = m_wndList.GetFirstSelectedItemPosition();
00440 while( pos )
00441 {
00442 int nItem = m_wndList.GetNextSelectedItem( pos );
00443 if ( CHostCacheHost* pHost = GetItem( nItem ) )
00444 {
00445 HostCache.Remove( pHost );
00446 }
00447 }
00448 }
00449
00450 void CHostCacheWnd::OnUpdateHostcacheG2Horizon(CCmdUI* pCmdUI)
00451 {
00452 pCmdUI->SetCheck( m_nMode == PROTOCOL_NULL );
00453 }
00454
00455 void CHostCacheWnd::OnHostcacheG2Horizon()
00456 {
00457 Settings.Gnutella.HostCacheView = m_nMode = PROTOCOL_NULL;
00458 m_wndList.DeleteAllItems();
00459 Update( TRUE );
00460 }
00461
00462 void CHostCacheWnd::OnUpdateHostcacheG2Cache(CCmdUI* pCmdUI)
00463 {
00464 pCmdUI->SetCheck( m_nMode == PROTOCOL_G2 );
00465 }
00466
00467 void CHostCacheWnd::OnHostcacheG2Cache()
00468 {
00469 Settings.Gnutella.HostCacheView = m_nMode = PROTOCOL_G2;
00470 m_wndList.DeleteAllItems();
00471 Update( TRUE );
00472 }
00473
00474 void CHostCacheWnd::OnUpdateHostcacheG1Cache(CCmdUI* pCmdUI)
00475 {
00476 pCmdUI->SetCheck( m_nMode == PROTOCOL_G1 );
00477 }
00478
00479 void CHostCacheWnd::OnHostcacheG1Cache()
00480 {
00481 Settings.Gnutella.HostCacheView = m_nMode = PROTOCOL_G1;
00482 m_wndList.DeleteAllItems();
00483 Update( TRUE );
00484 }
00485
00486 void CHostCacheWnd::OnUpdateHostcacheEd2kCache(CCmdUI* pCmdUI)
00487 {
00488 pCmdUI->SetCheck( m_nMode == PROTOCOL_ED2K );
00489 }
00490
00491 void CHostCacheWnd::OnHostcacheEd2kCache()
00492 {
00493 Settings.Gnutella.HostCacheView = m_nMode = PROTOCOL_ED2K;
00494 m_wndList.DeleteAllItems();
00495 Update( TRUE );
00496 }
00497
00498 void CHostCacheWnd::OnHostcacheImport()
00499 {
00500 CFileDialog dlg( TRUE, _T("met"), NULL, OFN_HIDEREADONLY,
00501 _T("eDonkey2000 MET files|*.met|All Files|*.*||"), this );
00502
00503 if ( dlg.DoModal() != IDOK ) return;
00504
00505 CWaitCursor pCursor;
00506 HostCache.eDonkey.Import( dlg.GetPathName() );
00507 HostCache.Save();
00508 Update( TRUE );
00509 }
00510
00511 void CHostCacheWnd::OnHostcacheEd2kDownload()
00512 {
00513 CDonkeyServersDlg dlg;
00514 if ( dlg.DoModal() == IDOK ) Update( TRUE );
00515 }
00516
00517 BOOL CHostCacheWnd::PreTranslateMessage(MSG* pMsg)
00518 {
00519 if ( pMsg->message == WM_TIMER )
00520 {
00521
00522 m_bAllowUpdates = IsActive();
00523 }
00524 else if ( pMsg->message == WM_KEYDOWN )
00525 {
00526 if ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 )
00527 {
00528 if ( pMsg->wParam == 'A' )
00529 {
00530 for ( int nItem = m_wndList.GetItemCount() - 1 ; nItem >= 0 ; nItem-- )
00531 {
00532 m_wndList.SetItemState( nItem, LVIS_SELECTED, LVIS_SELECTED );
00533 }
00534 return TRUE;
00535 }
00536 }
00537 else if ( pMsg->wParam == VK_DELETE )
00538 {
00539 OnHostCacheRemove();
00540 }
00541 }
00542 else if ( pMsg->message == WM_MOUSEWHEEL )
00543 {
00544 m_bAllowUpdates = FALSE;
00545 }
00546 return CPanelWnd::PreTranslateMessage( pMsg );
00547 }
00548
00549 void CHostCacheWnd::RecalcLayout(BOOL bNotify)
00550 {
00551 m_bAllowUpdates = FALSE;
00552
00553 CPanelWnd::RecalcLayout(bNotify);
00554 }