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 "QuerySearch.h"
00026 #include "QueryHit.h"
00027 #include "MatchObjects.h"
00028 #include "Network.h"
00029 #include "Packet.h"
00030 #include "Schema.h"
00031 #include "SchemaCache.h"
00032 #include "ManagedSearch.h"
00033 #include "CoolInterface.h"
00034 #include "ShellIcons.h"
00035 #include "Skin.h"
00036 #include "SHA.h"
00037 #include "ED2K.h"
00038 #include "XML.h"
00039
00040 #include "WndSearch.h"
00041 #include "WndMain.h"
00042 #include "DlgNewSearch.h"
00043 #include "DlgHitColumns.h"
00044 #include "DlgHelp.h"
00045 #include "Security.h"
00046
00047 #ifdef _DEBUG
00048 #define new DEBUG_NEW
00049 #undef THIS_FILE
00050 static char THIS_FILE[] = __FILE__;
00051 #endif
00052
00053 IMPLEMENT_DYNCREATE(CSearchWnd, CBaseMatchWnd)
00054
00055 BEGIN_MESSAGE_MAP(CSearchWnd, CBaseMatchWnd)
00056 ON_WM_CREATE()
00057 ON_WM_DESTROY()
00058 ON_WM_CONTEXTMENU()
00059 ON_WM_TIMER()
00060 ON_WM_NCLBUTTONUP()
00061 ON_WM_SIZE()
00062 ON_WM_PAINT()
00063 ON_WM_SYSCOMMAND()
00064 ON_WM_SETCURSOR()
00065 ON_WM_LBUTTONDOWN()
00066 ON_LBN_SELCHANGE(IDC_MATCHES, OnSelChangeMatches)
00067 ON_UPDATE_COMMAND_UI(ID_SEARCH_SEARCH, OnUpdateSearchSearch)
00068 ON_COMMAND(ID_SEARCH_SEARCH, OnSearchSearch)
00069 ON_COMMAND(ID_SEARCH_CLEAR, OnSearchClear)
00070 ON_UPDATE_COMMAND_UI(ID_SEARCH_STOP, OnUpdateSearchStop)
00071 ON_COMMAND(ID_SEARCH_STOP, OnSearchStop)
00072 ON_UPDATE_COMMAND_UI(ID_SEARCH_PANEL, OnUpdateSearchPanel)
00073 ON_COMMAND(ID_SEARCH_PANEL, OnSearchPanel)
00074 ON_UPDATE_COMMAND_UI(ID_SEARCH_CLEAR, OnUpdateSearchClear)
00075 ON_UPDATE_COMMAND_UI(ID_SEARCH_DETAILS, OnUpdateSearchDetails)
00076 ON_COMMAND(ID_SEARCH_DETAILS, OnSearchDetails)
00077 ON_WM_MDIACTIVATE()
00078 END_MESSAGE_MAP()
00079
00080 #define SIZE_INTERNAL 1982
00081 #define PANEL_WIDTH 200
00082 #define TOOLBAR_HEIGHT 28
00083 #define STATUS_HEIGHT 24
00084 #define SPLIT_SIZE 6
00085
00086
00088
00089
00090 CSearchWnd::CSearchWnd(CQuerySearch* pSearch)
00091 {
00092 if ( pSearch != NULL )
00093 {
00094 m_pSearches.AddTail( new CManagedSearch( pSearch ) );
00095 }
00096
00097 Create( IDR_SEARCHFRAME );
00098 }
00099
00100 CSearchWnd::~CSearchWnd()
00101 {
00102 CSingleLock pLock( &m_pMatches->m_pSection, TRUE );
00103
00104 for ( POSITION pos = m_pSearches.GetHeadPosition() ; pos ; )
00105 {
00106 delete (CManagedSearch*)m_pSearches.GetNext( pos );
00107 }
00108
00109 m_pSearches.RemoveAll();
00110 }
00111
00113
00114
00115 int CSearchWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
00116 {
00117 if ( CBaseMatchWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00118
00119 m_wndPanel.Create( this );
00120 m_wndDetails.Create( this );
00121
00122 CQuerySearch* pSearch = GetLastSearch();
00123
00124 if ( pSearch && pSearch->m_pSchema != NULL )
00125 {
00126 CPtrList pColumns;
00127 CSchemaColumnsDlg::LoadColumns( pSearch->m_pSchema, &pColumns );
00128 m_wndList.SelectSchema( pSearch->m_pSchema, &pColumns );
00129 }
00130 else if ( CSchema* pSchema = SchemaCache.Get( Settings.Search.BlankSchemaURI ) )
00131 {
00132 CPtrList pColumns;
00133 CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
00134 m_wndList.SelectSchema( pSchema, &pColumns );
00135 }
00136
00137 m_nCacheHubs = 0;
00138 m_nCacheLeaves = 0;
00139 m_bPanel = Settings.Search.SearchPanel;
00140 m_bDetails = Settings.Search.DetailPanelVisible;
00141 m_nDetails = Settings.Search.DetailPanelSize;
00142 m_nLastSearchHelp = 0;
00143
00144 m_bPaused = TRUE;
00145 m_bSetFocus = TRUE;
00146 m_bWaitMore = FALSE;
00147 m_nMaxResults = 0;
00148 m_nMaxED2KResults = 0;
00149 m_nMaxQueryCount = 0;
00150
00151 LoadState( _T("CSearchWnd"), TRUE );
00152
00153 ExecuteSearch();
00154
00155 if ( pSearch == NULL )
00156 {
00157 m_wndPanel.ShowSearch( NULL );
00158 }
00159 else
00160 {
00161 m_wndPanel.Disable();
00162 if ( m_bPanel && Settings.Search.HideSearchPanel )
00163 m_bPanel = FALSE;
00164 }
00165
00166 OnSkinChange();
00167
00168 PostMessage( WM_TIMER, 1 );
00169
00170 return 0;
00171 }
00172
00173 void CSearchWnd::OnDestroy()
00174 {
00175 CQuerySearch* pSearch = GetLastSearch();
00176
00177 if ( pSearch && pSearch->m_pSchema == NULL )
00178 {
00179 if ( m_wndList.m_pSchema != NULL )
00180 {
00181 Settings.Search.BlankSchemaURI = m_wndList.m_pSchema->m_sURI;
00182 }
00183 else
00184 {
00185 Settings.Search.BlankSchemaURI.Empty();
00186 }
00187 }
00188
00189 SaveState( _T("CSearchWnd") );
00190
00191 CBaseMatchWnd::OnDestroy();
00192 }
00193
00194 void CSearchWnd::OnSize(UINT nType, int cx, int cy)
00195 {
00196 if ( nType != SIZE_INTERNAL ) CPanelWnd::OnSize( nType, cx, cy );
00197
00198 CRect rc;
00199 GetClientRect( &rc );
00200
00201 if ( m_bPanel )
00202 {
00203 m_wndPanel.SetWindowPos( NULL, rc.left, rc.top, PANEL_WIDTH, rc.Height(),
00204 SWP_NOZORDER|SWP_SHOWWINDOW );
00205 rc.left += PANEL_WIDTH;
00206 }
00207 else if ( m_wndPanel.IsWindowVisible() )
00208 {
00209 m_wndPanel.ShowWindow( SW_HIDE );
00210 }
00211
00212 if ( ! (m_bPaused||m_bWaitMore) ) rc.top += STATUS_HEIGHT;
00213
00214 m_wndToolBar.SetWindowPos( NULL, rc.left, rc.bottom - TOOLBAR_HEIGHT, rc.Width(), TOOLBAR_HEIGHT, SWP_NOZORDER );
00215 rc.bottom -= TOOLBAR_HEIGHT;
00216
00217 if ( m_bDetails )
00218 {
00219 m_wndDetails.SetWindowPos( NULL, rc.left, rc.bottom - m_nDetails, rc.Width(),
00220 m_nDetails, SWP_NOZORDER|SWP_SHOWWINDOW );
00221 rc.bottom -= m_nDetails + SPLIT_SIZE;
00222 }
00223 else if ( m_wndDetails.IsWindowVisible() )
00224 {
00225 m_wndDetails.ShowWindow( SW_HIDE );
00226 }
00227
00228 m_wndList.SetWindowPos( NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER );
00229
00230 Invalidate();
00231 }
00232
00233 void CSearchWnd::OnSkinChange()
00234 {
00235 CBaseMatchWnd::OnSkinChange();
00236
00237 m_wndToolBar.Clear();
00238
00239 if ( ! Skin.CreateToolBar( m_bPanel ? _T("CSearchWnd.Panel") : _T("CSearchWnd.Full"), &m_wndToolBar ) )
00240 {
00241 Skin.CreateToolBar( _T("CSearchWnd"), &m_wndToolBar );
00242 }
00243
00244 OnSize( SIZE_INTERNAL, 0, 0 );
00245 UpdateMessages();
00246
00247 m_wndPanel.OnSkinChange();
00248 Skin.Translate( _T("CMatchCtrl"), &m_wndList.m_wndHeader );
00249 }
00250
00251 void CSearchWnd::OnContextMenu(CWnd* pWnd, CPoint point)
00252 {
00253 if ( m_bContextMenu )
00254 {
00255 TrackPopupMenu( _T("CSearchWnd"), point, ID_SEARCH_DOWNLOAD );
00256 }
00257 else
00258 {
00259 CBaseMatchWnd::OnContextMenu( pWnd, point );
00260 }
00261 }
00262
00263 void CSearchWnd::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
00264 {
00265 CBaseMatchWnd::OnMDIActivate( bActivate, pActivateWnd, pDeactivateWnd );
00266
00267 if ( bActivate )
00268 {
00269 if ( m_pMatches->m_nFiles > 0 )
00270 m_wndList.SetFocus();
00271 else if ( m_wndPanel.IsWindowVisible() )
00272 m_wndPanel.SetSearchFocus();
00273 else if ( m_wndList.IsWindowVisible() )
00274 m_wndList.SetFocus();
00275 }
00276 }
00277
00278 void CSearchWnd::OnPaint()
00279 {
00280 CPaintDC dc( this );
00281 CRect rcClient;
00282
00283 GetClientRect( &rcClient );
00284 rcClient.bottom -= TOOLBAR_HEIGHT;
00285
00286 if ( m_wndDetails.IsWindowVisible() )
00287 {
00288 CRect rcBar( rcClient.left,
00289 rcClient.bottom - m_nDetails - SPLIT_SIZE,
00290 rcClient.right,
00291 rcClient.bottom - m_nDetails );
00292
00293 if ( m_bPanel ) rcBar.left += PANEL_WIDTH;
00294
00295 dc.FillSolidRect( rcBar.left, rcBar.top, rcBar.Width(), 1, GetSysColor( COLOR_BTNFACE ) );
00296 dc.FillSolidRect( rcBar.left, rcBar.top + 1, rcBar.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
00297 dc.FillSolidRect( rcBar.left, rcBar.bottom - 1, rcBar.Width(), 1, GetSysColor( COLOR_3DSHADOW ) );
00298 dc.FillSolidRect( rcBar.left, rcBar.top + 2, rcBar.Width(), rcBar.Height() - 3,
00299 GetSysColor( COLOR_BTNFACE ) );
00300 }
00301
00302 if ( m_bPaused || m_bWaitMore) return;
00303
00304 CRect rc( &rcClient );
00305 rc.bottom = rc.top + STATUS_HEIGHT;
00306
00307 int nTop = rc.top + 4;
00308
00309 if ( m_bPanel )
00310 {
00311 rc.left += PANEL_WIDTH;
00312 rc.bottom --;
00313 dc.FillSolidRect( rc.left, rc.bottom, rc.Width(), 1, RGB( 255, 255, 255 ) );
00314 dc.Draw3dRect( &rc,
00315 CCoolInterface::CalculateColour( Skin.m_crBannerBack, RGB(255,255,255), 100 ),
00316 CCoolInterface::CalculateColour( Skin.m_crBannerBack, 0, 150 ) );
00317 rc.DeflateRect( 1, 1 );
00318 nTop --;
00319 }
00320
00321 ShellIcons.Draw( &dc, SHI_SEARCH, 16, rc.left + 4, nTop, Skin.m_crBannerBack );
00322 dc.ExcludeClipRect( rc.left + 4, nTop, rc.left + 4 + 16, nTop + 16 );
00323
00324 CFont* pFont = (CFont*)dc.SelectObject( &CoolInterface.m_fntNormal );
00325
00326 CString str;
00327 LoadString( str, IDS_SEARCH_ACTIVE );
00328
00329 dc.SetBkColor( Skin.m_crBannerBack );
00330 dc.SetTextColor( Skin.m_crBannerText );
00331 dc.ExtTextOut( rc.left + 8 + 16, nTop + 1, ETO_CLIPPED|ETO_OPAQUE,
00332 &rc, str, NULL );
00333
00334 dc.SelectObject( pFont );
00335 }
00336
00337 BOOL CSearchWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
00338 {
00339 if ( m_wndDetails.IsWindowVisible() )
00340 {
00341 CRect rcClient, rc;
00342 CPoint point;
00343
00344 GetCursorPos( &point );
00345 GetClientRect( &rcClient );
00346 ClientToScreen( &rcClient );
00347
00348 rc.SetRect( rcClient.left,
00349 rcClient.bottom - TOOLBAR_HEIGHT - m_nDetails - SPLIT_SIZE,
00350 rcClient.right,
00351 rcClient.bottom - TOOLBAR_HEIGHT - m_nDetails );
00352
00353 if ( m_bPanel )
00354 {
00355 if ( theApp.m_bRTL )
00356 rc.right -= PANEL_WIDTH;
00357 else
00358 rc.left += PANEL_WIDTH;
00359 }
00360
00361 if ( rc.PtInRect( point ) )
00362 {
00363 SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZENS ) );
00364 return TRUE;
00365 }
00366 }
00367
00368 return CBaseMatchWnd::OnSetCursor( pWnd, nHitTest, message );
00369 }
00370
00371 void CSearchWnd::OnLButtonDown(UINT nFlags, CPoint point)
00372 {
00373 CRect rcClient, rc;
00374 GetClientRect( &rcClient );
00375
00376 rc.SetRect( rcClient.left,
00377 rcClient.bottom - TOOLBAR_HEIGHT - m_nDetails - SPLIT_SIZE,
00378 rcClient.right,
00379 rcClient.bottom - TOOLBAR_HEIGHT - m_nDetails );
00380
00381 if ( m_bPanel ) rc.left += PANEL_WIDTH;
00382
00383 if ( m_wndDetails.IsWindowVisible() && rc.PtInRect( point ) )
00384 {
00385 DoSizeDetails();
00386 return;
00387 }
00388
00389 CBaseMatchWnd::OnLButtonDown( nFlags, point );
00390 }
00391
00392 BOOL CSearchWnd::DoSizeDetails()
00393 {
00394 MSG* pMsg = &AfxGetThreadState()->m_msgCur;
00395 CRect rcClient;
00396 CPoint point;
00397
00398 GetClientRect( &rcClient );
00399 if ( m_bPanel ) rcClient.left += PANEL_WIDTH;
00400 if ( ! (m_bPaused||m_bWaitMore) ) rcClient.top += STATUS_HEIGHT;
00401 rcClient.bottom -= TOOLBAR_HEIGHT;
00402 ClientToScreen( &rcClient );
00403 ClipCursor( &rcClient );
00404 SetCapture();
00405
00406 ScreenToClient( &rcClient );
00407
00408 int nOffset = 0xFFFF;
00409
00410 while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
00411 {
00412 while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
00413
00414 if ( ! AfxGetThread()->PumpMessage() )
00415 {
00416 AfxPostQuitMessage( 0 );
00417 break;
00418 }
00419
00420 GetCursorPos( &point );
00421 ScreenToClient( &point );
00422
00423 int nSplit = rcClient.bottom - point.y;
00424
00425 if ( nOffset == 0xFFFF ) nOffset = m_nDetails - nSplit;
00426 nSplit += nOffset;
00427
00428 if ( nSplit < 8 )
00429 nSplit = 0;
00430 if ( nSplit > rcClient.Height() - SPLIT_SIZE - 8 )
00431 nSplit = rcClient.Height() - SPLIT_SIZE;
00432
00433 if ( nSplit != m_nDetails )
00434 {
00435 m_nDetails = nSplit;
00436 Settings.Search.DetailPanelSize = nSplit;
00437 OnSize( SIZE_INTERNAL, 0, 0 );
00438 Invalidate();
00439 }
00440 }
00441
00442 ReleaseCapture();
00443 ClipCursor( NULL );
00444
00445 return TRUE;
00446 }
00447
00448 void CSearchWnd::OnUpdateSearchSearch(CCmdUI* pCmdUI)
00449 {
00450
00451
00452
00453 if( (m_bPaused) || ( m_bWaitMore ) )
00454 pCmdUI->Enable( TRUE );
00455 else
00456 pCmdUI->Enable( FALSE );
00457
00458 }
00459
00460 void CSearchWnd::OnSearchSearch()
00461 {
00462 CSingleLock pLock( &m_pMatches->m_pSection );
00463 CManagedSearch* pSearch = NULL;
00464
00465 if ( ! Network.IsWellConnected() ) Network.Connect( TRUE );
00466
00467
00468 POSITION pos = m_pSearches.GetTailPosition();
00469 if( ( !m_bPaused ) && ( m_bWaitMore ) && ( pos ) )
00470 {
00471 pSearch = (CManagedSearch*)m_pSearches.GetPrev( pos );
00472
00473
00474 theApp.Message( MSG_DEBUG, _T("Resuming Search") );
00475 pSearch->m_bActive = TRUE;
00476 m_bWaitMore = FALSE;
00477
00478
00479 m_nMaxResults = m_pMatches->m_nGnutellaHits + (DWORD)min( DWORD(300), Settings.Gnutella.MaxResults );
00480 m_nMaxQueryCount = pSearch->m_nQueryCount + (DWORD)min( Settings.Gnutella2.QueryLimit, DWORD(10000) );
00481
00482
00483 m_nMaxED2KResults = m_pMatches->m_nED2KHits + ( (DWORD)min( 201, Settings.eDonkey.MaxResults ) );
00484 pSearch->m_tLastED2K = GetTickCount();
00485 pSearch->m_tMoreResults = 0;
00486
00487 if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0x8000 )
00488 pSearch->m_nPriority = CManagedSearch::spMedium;
00489
00490 m_bUpdate = TRUE;
00491 UpdateMessages();
00492 return;
00493 }
00494
00495
00496 if ( m_pMatches->m_nFiles > 0 )
00497 {
00498 CString strMessage;
00499 LoadString( strMessage, IDS_SEARCH_CLEAR_PREVIOUS );
00500
00501 if ( AfxMessageBox( strMessage, MB_ICONQUESTION|MB_YESNO ) == IDYES )
00502 {
00503 pLock.Lock();
00504 m_pMatches->Clear();
00505 m_bUpdate = TRUE;
00506 PostMessage( WM_TIMER, 2 );
00507 pLock.Unlock();
00508 }
00509 }
00510
00511 if ( m_wndPanel.m_bSendSearch )
00512 {
00513 pSearch = m_wndPanel.GetSearch();
00514 if ( pSearch == NULL )
00515 {
00516
00517
00518
00519
00520 m_nLastSearchHelp++;
00521
00522 switch ( m_nLastSearchHelp )
00523 {
00524 case 1: CHelpDlg::Show( _T("SearchHelp.BadSearch1") );
00525 break;
00526 case 2: CHelpDlg::Show( _T("SearchHelp.BadSearch2") );
00527 break;
00528 default: CHelpDlg::Show( _T("SearchHelp.BadSearch3") );
00529 m_nLastSearchHelp = 0;
00530 }
00531
00532 return;
00533 }
00534
00535 if ( m_pMatches->m_nFiles == 0 && pSearch->m_pSearch->m_pSchema != NULL )
00536 {
00537 CPtrList pColumns;
00538 CSchemaColumnsDlg::LoadColumns( pSearch->m_pSearch->m_pSchema, &pColumns );
00539 m_wndList.SelectSchema( pSearch->m_pSearch->m_pSchema, &pColumns );
00540 }
00541 }
00542 else
00543 {
00544 CQuerySearch* pCriteria = GetLastSearch();
00545
00546 if ( pCriteria != NULL ) pCriteria = new CQuerySearch( pCriteria );
00547
00548 CNewSearchDlg dlg( NULL, pCriteria, FALSE, TRUE );
00549 if ( dlg.DoModal() != IDOK ) return;
00550
00551 pCriteria = dlg.GetSearch();
00552 pSearch = new CManagedSearch( pCriteria );
00553 }
00554
00555 Network.CreateID( pSearch->m_pSearch->m_pGUID );
00556
00557 pLock.Lock();
00558
00559 if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) != 0x8000 )
00560 {
00561 for ( POSITION pos = m_pSearches.GetHeadPosition() ; pos ; )
00562 {
00563 CManagedSearch* pManaged = (CManagedSearch*)m_pSearches.GetNext( pos );
00564 pManaged->Stop();
00565 }
00566 }
00567
00568 m_pSearches.AddTail( pSearch );
00569
00570 pLock.Unlock();
00571
00572 ExecuteSearch();
00573 }
00574
00575 void CSearchWnd::OnUpdateSearchClear(CCmdUI* pCmdUI)
00576 {
00577 pCmdUI->Enable( m_pMatches->m_nFiles > 0 );
00578 }
00579
00580 void CSearchWnd::OnSearchClear()
00581 {
00582 m_wndList.DestructiveUpdate();
00583 m_pMatches->Clear();
00584 m_bUpdate = TRUE;
00585 PostMessage( WM_TIMER, 2 );
00586
00587 m_nMaxResults = 0;
00588 m_nMaxED2KResults = 0;
00589 m_nMaxQueryCount = 0;
00590
00591 OnSearchStop();
00592 }
00593
00594 void CSearchWnd::OnUpdateSearchStop(CCmdUI* pCmdUI)
00595 {
00596 pCmdUI->Enable( ! m_bPaused );
00597 }
00598
00599 void CSearchWnd::OnSearchStop()
00600 {
00601 if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0x8000 )
00602 {
00603 if( ( !m_bPaused ) && ( !m_bWaitMore ) )
00604 {
00605 POSITION pos = m_pSearches.GetTailPosition();
00606 if( pos )
00607 {
00608 theApp.Message( MSG_DEBUG, _T("Pausing Search") );
00609 ((CManagedSearch*)m_pSearches.GetPrev( pos ))->m_bActive = FALSE;
00610 m_bWaitMore = TRUE;
00611 m_bUpdate = TRUE;
00612 return;
00613 }
00614 }
00615 }
00616
00617 CSingleLock pLock( &m_pMatches->m_pSection, TRUE );
00618
00619 for ( POSITION pos = m_pSearches.GetHeadPosition() ; pos ; )
00620 {
00621 CManagedSearch* pManaged = (CManagedSearch*)m_pSearches.GetNext( pos );
00622 pManaged->Stop();
00623 pManaged->m_bReceive = FALSE;
00624 }
00625
00626 m_bPaused = TRUE;
00627
00628 m_wndPanel.Enable();
00629 UpdateMessages();
00630 }
00631
00632 void CSearchWnd::OnUpdateSearchPanel(CCmdUI* pCmdUI)
00633 {
00634 CString sText;
00635 CCoolBarItem* pItem = m_wndToolBar.GetID( ID_SEARCH_PANEL );
00636 pItem->SetCheck( m_bPanel );
00637 LoadString( sText, m_bPanel ? IDS_SEARCH_PANEL_HIDE : IDS_SEARCH_PANEL_SHOW );
00638 pItem->SetTip( sText );
00639 }
00640
00641 void CSearchWnd::OnSearchPanel()
00642 {
00643 Settings.Search.SearchPanel = m_bPanel = ! m_bPanel;
00644 OnSkinChange();
00645 UpdateMessages();
00646 }
00647
00648 void CSearchWnd::OnUpdateSearchDetails(CCmdUI* pCmdUI)
00649 {
00650 pCmdUI->SetCheck( m_bDetails );
00651 }
00652
00653 void CSearchWnd::OnSearchDetails()
00654 {
00655 Settings.Search.DetailPanelVisible = m_bDetails = ! m_bDetails;
00656 OnSkinChange();
00657 }
00658
00659 void CSearchWnd::OnSysCommand(UINT nID, LPARAM lParam)
00660 {
00661 if ( ( ( nID & 0xFFF0 ) == SC_MAXIMIZE ) && m_bPanelMode )
00662 {
00663 PostMessage( WM_COMMAND, ID_SEARCH_SEARCH );
00664 }
00665 else
00666 {
00667 CBaseMatchWnd::OnSysCommand( nID, lParam );
00668 }
00669 }
00670
00672
00673
00674 CManagedSearch* CSearchWnd::GetLastManager()
00675 {
00676 CSingleLock pLock( &m_pMatches->m_pSection, TRUE );
00677 return m_pSearches.GetCount() ? (CManagedSearch*)m_pSearches.GetTail() : NULL;
00678 }
00679
00680 CQuerySearch* CSearchWnd::GetLastSearch()
00681 {
00682 CManagedSearch* pManaged = GetLastManager();
00683 return pManaged ? pManaged->m_pSearch : NULL;
00684 }
00685
00686 void CSearchWnd::ExecuteSearch()
00687 {
00688 CManagedSearch* pManaged = GetLastManager();
00689
00690 if ( pManaged )
00691 {
00692 if ( AdultFilter.IsSearchFiltered( pManaged->m_pSearch->m_sSearch ) )
00693 {
00694 CHelpDlg::Show( _T("SearchHelp.AdultSearch") );
00695 }
00696 else if ( pManaged->m_pSearch->CheckValid() )
00697 {
00698 m_bPaused = FALSE;
00699 m_tSearch = GetTickCount();
00700 m_bWaitMore = FALSE;
00701
00702 pManaged->Stop();
00703 pManaged->Start();
00704
00705 m_nMaxResults = m_pMatches->m_nGnutellaHits + (DWORD)min( DWORD(300), Settings.Gnutella.MaxResults );
00706 m_nMaxED2KResults = m_pMatches->m_nED2KHits + (DWORD)min( 201, Settings.eDonkey.MaxResults );
00707 m_nMaxQueryCount = pManaged->m_nQueryCount + (DWORD)min( Settings.Gnutella2.QueryLimit, DWORD(10000) );
00708
00709 m_wndPanel.ShowSearch( pManaged );
00710
00711 m_wndPanel.Disable();
00712
00713 if ( m_bPanel && Settings.Search.HideSearchPanel )
00714 {
00715 m_bPanel = FALSE;
00716 OnSkinChange();
00717 }
00718 }
00719 else
00720 {
00721
00722 m_nLastSearchHelp++;
00723
00724 switch ( m_nLastSearchHelp )
00725 {
00726 case 1: CHelpDlg::Show( _T("SearchHelp.BadSearch1") );
00727 break;
00728 case 2: CHelpDlg::Show( _T("SearchHelp.BadSearch2") );
00729 break;
00730 default: CHelpDlg::Show( _T("SearchHelp.BadSearch3") );
00731 m_nLastSearchHelp = 0;
00732 }
00733
00734 }
00735 }
00736
00737 UpdateMessages();
00738 }
00739
00740 void CSearchWnd::UpdateMessages(BOOL bActive)
00741 {
00742 CManagedSearch* pManaged = GetLastManager();
00743 UpdateMessages(bActive, pManaged);
00744
00745 }
00746
00747 void CSearchWnd::UpdateMessages(BOOL bActive, CManagedSearch* pManaged)
00748 {
00749 CQuerySearch* pSearch = pManaged ? pManaged->m_pSearch : NULL;
00750
00751 CString strCaption;
00752 Skin.LoadString( strCaption, IDR_SEARCHFRAME );
00753 if ( theApp.m_bRTL ) strCaption = _T("\x200F") + strCaption + _T("\x202E");
00754
00755 if ( pSearch != NULL )
00756 {
00757 strCaption += _T(" : ");
00758 if ( theApp.m_bRTL ) strCaption += _T("\x202B");
00759
00760 if ( pSearch->m_sSearch.GetLength() )
00761 {
00762 strCaption += pSearch->m_sSearch;
00763 }
00764 else if ( pSearch->m_pSchema != NULL && pSearch->m_pXML != NULL )
00765 {
00766 strCaption += pSearch->m_pSchema->GetIndexedWords( pSearch->m_pXML->GetFirstElement() );
00767 }
00768 else if ( pSearch->m_bSHA1 )
00769 {
00770 strCaption += CSHA::HashToString( &pSearch->m_pSHA1, TRUE );
00771 }
00772 else if ( pSearch->m_bED2K )
00773 {
00774 strCaption += CED2K::HashToString( &pSearch->m_pED2K, TRUE );
00775 }
00776
00777 if ( pSearch->m_pSchema )
00778 {
00779 strCaption += _T(" (") + pSearch->m_pSchema->m_sTitle + _T(")");
00780 }
00781
00782 if ( m_pMatches->m_nFilteredFiles || m_pMatches->m_nFilteredHits )
00783 {
00784 CString strStats;
00785 strStats.Format( _T(" [%lu/%lu]"), m_pMatches->m_nFilteredFiles, m_pMatches->m_nFilteredHits );
00786 if ( theApp.m_bRTL ) strStats = _T("\x200F") + strStats;
00787 strCaption += strStats;
00788 pManaged->m_nHits = m_pMatches->m_nFilteredHits;
00789 }
00790 }
00791
00792 CString strOld;
00793 GetWindowText( strOld );
00794
00795 if ( strOld != strCaption )
00796 {
00797 SetWindowText( strCaption );
00798 m_sCaption = strCaption;
00799 }
00800
00801 if ( pManaged != NULL )
00802 {
00803 if ( m_nCacheHubs != pManaged->m_nHubs ||
00804 m_nCacheLeaves != pManaged->m_nLeaves )
00805 {
00806 m_nCacheHubs = pManaged->m_nHubs;
00807 m_nCacheLeaves = pManaged->m_nLeaves;
00808 bActive = TRUE;
00809 }
00810 }
00811
00812 if ( bActive )
00813 {
00814 m_wndPanel.ShowStatus( ! m_bPaused, !m_bWaitMore,
00815 m_pMatches->m_nFilteredFiles,
00816 m_pMatches->m_nFilteredHits,
00817 m_nCacheHubs, m_nCacheLeaves );
00818
00819 CRect rcList;
00820 m_wndList.GetWindowRect( &rcList );
00821 ScreenToClient( &rcList );
00822 if ( ( rcList.top == 0 ) != (m_bPaused||m_bWaitMore) ) OnSize( SIZE_INTERNAL, 0, 0 );
00823 }
00824
00825 if ( m_pMatches->m_nFilteredFiles == 0 )
00826 {
00827 if ( m_pMatches->m_nFiles > 0 )
00828 {
00829 m_wndList.SetMessage( IDS_SEARCH_FILTERED, ! m_bPanel );
00830 }
00831 else if ( m_bPaused )
00832 {
00833 m_wndList.SetMessage( IDS_SEARCH_NONE, ! m_bPanel );
00834 }
00835 else if ( GetTickCount() - m_tSearch < 16000 )
00836 {
00837 m_wndList.SetMessage( IDS_SEARCH_WORKING, FALSE );
00838 }
00839 else
00840 {
00841 m_wndList.SetMessage( IDS_SEARCH_EMPTY, ! m_bPanel );
00842 }
00843 }
00844 }
00845
00847
00848
00849 BOOL CSearchWnd::OnQueryHits(CQueryHit* pHits)
00850 {
00851 if ( m_bPaused || m_hWnd == NULL ) return FALSE;
00852
00853 CSingleLock pLock( &m_pMatches->m_pSection );
00854 if ( ! pLock.Lock( 100 ) || m_bPaused ) return FALSE;
00855
00856 for ( POSITION pos = m_pSearches.GetTailPosition() ; pos ; )
00857 {
00858 CManagedSearch* pManaged = (CManagedSearch*)m_pSearches.GetPrev( pos );
00859 BOOL bNull = FALSE;
00860
00861 if ( pManaged->m_bReceive )
00862 {
00863 if ( ( pManaged->m_pSearch->m_pGUID == pHits->m_pSearchID ) ||
00864 ( ( pHits->m_pSearchID == (GGUID&)GUID_NULL ) && ( pManaged->IsLastED2KSearch() ) ) )
00865 {
00866 m_pMatches->AddHits( pHits, pManaged->m_pSearch, bNull );
00867 m_bUpdate = TRUE;
00868
00869 if ( ( m_pMatches->m_nED2KHits >= m_nMaxED2KResults ) && ( pManaged->m_tLastED2K != 0xFFFFFFFF ) )
00870 {
00871 if( !pManaged->m_bAllowG2 )
00872 {
00873 m_bWaitMore = TRUE;
00874 pManaged->m_bActive = FALSE;
00875 }
00876 pManaged->m_tLastED2K = 0xFFFFFFFF;
00877 theApp.Message( MSG_DEBUG, _T("ED2K Search Reached Maximum Number of Files") );
00878 }
00879
00880 if ( !m_bWaitMore && ( m_pMatches->m_nGnutellaHits >= m_nMaxResults ) )
00881 {
00882 m_bWaitMore = TRUE;
00883 pManaged->m_bActive = FALSE;
00884 theApp.Message( MSG_DEBUG, _T("Gnutella Search Reached Maximum Number of Files") );
00885 }
00886
00887 return TRUE;
00888 }
00889 }
00890 }
00891
00892 return FALSE;
00893 }
00894
00895 void CSearchWnd::OnTimer(UINT nIDEvent)
00896 {
00897 CManagedSearch* pManaged = NULL;
00898 CSingleLock pLock( &m_pMatches->m_pSection );
00899
00900 if ( pLock.Lock( 100 ) )
00901 {
00902 if ( m_pSearches.GetCount() ) pManaged = (CManagedSearch*)m_pSearches.GetTail();
00903
00904 if( pManaged )
00905 {
00906 if( ( pManaged->m_bActive ) && (pManaged->m_nQueryCount > m_nMaxQueryCount) )
00907 {
00908 m_bWaitMore = TRUE;
00909 pManaged->m_bActive = FALSE;
00910 theApp.Message( MSG_DEBUG, _T("Search Reached Maximum Duration") );
00911 m_bUpdate = TRUE;
00912 }
00913
00914 }
00915 else
00916 {
00917
00918 pLock.Unlock();
00919 }
00920 }
00921
00922
00923 if ( ( IsPartiallyVisible() ) && ( nIDEvent == 1 ) )
00924 {
00925 if ( m_bSetFocus )
00926 {
00927 if ( m_bPanel && m_bPaused ) m_wndPanel.SetSearchFocus();
00928 else m_wndList.SetFocus();
00929 m_bSetFocus = FALSE;
00930 }
00931
00932 if ( pManaged )
00933 {
00934 if ( m_nCacheHubs != pManaged->m_nHubs ||
00935 m_nCacheLeaves != pManaged->m_nLeaves )
00936 {
00937 UpdateMessages(TRUE, pManaged);
00938 }
00939 }
00940 }
00941
00942
00943 if ( pManaged ) pLock.Unlock();
00944
00945 CBaseMatchWnd::OnTimer( nIDEvent );
00946
00947 if ( m_pMatches->m_nFilteredHits == 0 ) m_wndDetails.Update( NULL );
00948 }
00949
00950 void CSearchWnd::OnSelChangeMatches()
00951 {
00952 CSingleLock pLock( &m_pMatches->m_pSection, TRUE );
00953 m_wndDetails.Update( m_pMatches->GetSelectedFile( TRUE ) );
00954 }
00955
00957
00958
00959 void CSearchWnd::Serialize(CArchive& ar)
00960 {
00961 CSingleLock pLock( &m_pMatches->m_pSection, TRUE );
00962 CString strSchema;
00963 int nVersion = 1;
00964
00965 if ( ar.IsStoring() )
00966 {
00967 ar << nVersion;
00968
00969 ar.WriteCount( m_pSearches.GetCount() );
00970
00971 for ( POSITION pos = m_pSearches.GetHeadPosition() ; pos ; )
00972 {
00973 CManagedSearch* pSearch = (CManagedSearch*)m_pSearches.GetNext( pos );
00974 pSearch->Serialize( ar );
00975 }
00976
00977 if ( m_pMatches->m_pSchema )
00978 {
00979 ar << m_pMatches->m_pSchema->m_sURI;
00980 }
00981 else
00982 {
00983 ar << strSchema;
00984 }
00985 }
00986 else
00987 {
00988 ar >> nVersion;
00989 if ( nVersion != 1 ) AfxThrowUserException();
00990
00991 m_bPaused = TRUE;
00992
00993 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00994 {
00995 CManagedSearch* pSearch = new CManagedSearch();
00996 pSearch->Serialize( ar );
00997 m_pSearches.AddTail( pSearch );
00998 }
00999
01000 ar >> strSchema;
01001
01002 if ( CSchema* pSchema = SchemaCache.Get( strSchema ) )
01003 {
01004 CPtrList pColumns;
01005 CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
01006 m_wndList.SelectSchema( pSchema, &pColumns );
01007 }
01008
01009 if ( m_pSearches.GetCount() ) m_wndPanel.ShowSearch( GetLastManager() );
01010 }
01011
01012 try
01013 {
01014 m_pMatches->Serialize( ar );
01015 }
01016 catch ( CException* pException )
01017 {
01018 pException->Delete();
01019 m_pMatches->Clear();
01020 }
01021
01022 if ( ar.IsLoading() )
01023 {
01024 m_bUpdate = TRUE;
01025 PostMessage( WM_TIMER, 1 );
01026 SendMessage( WM_TIMER, 2 );
01027 SetAlert( FALSE );
01028 }
01029 }