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

WndSearch.cpp

Go to the documentation of this file.
00001 //
00002 // WndSearch.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 "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 // CSearchWnd construction
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 // CSearchWnd message handlers
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         // pCmdUI->Enable( Network.IsWellConnected() );
00451         //pCmdUI->Enable( TRUE );
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         //The 'Search More' situation
00468         POSITION pos = m_pSearches.GetTailPosition();
00469         if( ( !m_bPaused ) && ( m_bWaitMore ) && ( pos ) )
00470         {
00471                 pSearch = (CManagedSearch*)m_pSearches.GetPrev( pos );
00472 
00473                 //Re-activate search window
00474                 theApp.Message( MSG_DEBUG, _T("Resuming Search") );
00475                 pSearch->m_bActive = TRUE;
00476                 m_bWaitMore = FALSE;
00477 
00478                 //Resume G2 search
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                 //Resume ED2K search
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         //End of 'Search More'
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 ) //Invalid search, open help window
00515                 {                               
00516                         // ToDo: If there was a previous search by hash, it was lost and won't re-search
00517                         // Maybe add a search by hash schema?
00518 
00519                         // Increment counter
00520                         m_nLastSearchHelp++;
00521                         // Open help window
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                 {       //Pause search
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 // CSearchWnd operations
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                         // Increment counter
00722                         m_nLastSearchHelp++;
00723                         // Open help window
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 // CSearchWnd event handlers
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 ) ||                                                          // The hits GUID matches the search
00864                                  ( ( pHits->m_pSearchID == (GGUID&)GUID_NULL ) && ( pManaged->IsLastED2KSearch() ) ) )  // The hits have no GUID and the search is the most recent ED2K text search
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 ) //If G2 is not active, pause the search now.
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                         // We need to keep the lock for now- release after we update the progress panel
00914                 }
00915                 else
00916                 {
00917                         // We don't need to hold the lock
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         // Unlock if we were locked
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 // CSearchWnd serialize
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 }

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