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 "CtrlCoolTip.h"
00026 #include "CtrlMatchTip.h"
00027 #include "CoolInterface.h"
00028 #include "ShellIcons.h"
00029 #include "Library.h"
00030 #include "SharedFile.h"
00031 #include "MatchObjects.h"
00032 #include "QueryHit.h"
00033 #include "Schema.h"
00034 #include "SchemaCache.h"
00035 #include "VendorCache.h"
00036 #include "TigerTree.h"
00037 #include "SHA.h"
00038 #include "ED2K.h"
00039
00040 #ifdef _DEBUG
00041 #define new DEBUG_NEW
00042 #undef THIS_FILE
00043 static char THIS_FILE[] = __FILE__;
00044 #endif
00045
00046 BEGIN_MESSAGE_MAP(CMatchTipCtrl, CWnd)
00047
00048 ON_WM_TIMER()
00049 ON_WM_ERASEBKGND()
00050 ON_WM_PAINT()
00051 ON_WM_CREATE()
00052 ON_WM_DESTROY()
00053 ON_WM_MOUSEMOVE()
00054 ON_WM_KEYDOWN()
00055
00056 END_MESSAGE_MAP()
00057
00058 #define TIP_DELAY 500
00059 #define TIP_OFFSET_X 0
00060 #define TIP_OFFSET_Y 24
00061 #define TIP_MARGIN 6
00062 #define TIP_TEXTHEIGHT 14
00063 #define TIP_ICONHEIGHT 16
00064
00065
00067
00068
00069 CMatchTipCtrl::CMatchTipCtrl()
00070 {
00071 m_pOwner = NULL;
00072 m_bVisible = FALSE;
00073 m_pFile = NULL;
00074 m_pHit = NULL;
00075 m_tOpen = 0;
00076 m_nIcon = 0;
00077
00078 if ( m_hUser32 = LoadLibrary( _T("User32.dll") ) )
00079 {
00080 (FARPROC&)m_pfnSetLayeredWindowAttributes = GetProcAddress(
00081 m_hUser32, "SetLayeredWindowAttributes" );
00082 }
00083 else
00084 {
00085 m_pfnSetLayeredWindowAttributes = NULL;
00086 }
00087
00088 if ( ! m_hClass ) m_hClass = AfxRegisterWndClass( CS_SAVEBITS );
00089
00090 m_crBack = CoolInterface.m_crTipBack;
00091 m_crText = CoolInterface.m_crTipText;
00092 m_crBorder = CCoolInterface::CalculateColour( m_crBack, (COLORREF)0, 100 );
00093 m_crWarnings = CoolInterface.m_crTipWarnings;
00094
00095 if ( m_brBack.m_hObject ) m_brBack.DeleteObject();
00096 m_brBack.CreateSolidBrush( m_crBack );
00097 }
00098
00099 CMatchTipCtrl::~CMatchTipCtrl()
00100 {
00101 if ( m_hUser32 ) FreeLibrary( m_hUser32 );
00102 }
00103
00104 LPCTSTR CMatchTipCtrl::m_hClass = NULL;
00105 CBrush CMatchTipCtrl::m_brBack;
00106 COLORREF CMatchTipCtrl::m_crBack;
00107 COLORREF CMatchTipCtrl::m_crText;
00108 COLORREF CMatchTipCtrl::m_crBorder;
00109 COLORREF CMatchTipCtrl::m_crWarnings;
00110
00112
00113
00114 BOOL CMatchTipCtrl::Create(CWnd* pParentWnd)
00115 {
00116 CRect rc( 0, 0, 0, 0 );
00117 m_pOwner = pParentWnd;
00118 DWORD dwStylesEx = WS_EX_TOPMOST | ( theApp.m_bRTL ? WS_EX_LAYOUTRTL : 0 );
00119 return CWnd::CreateEx( dwStylesEx, m_hClass, NULL, WS_POPUP|WS_DISABLED, rc, pParentWnd, 0, NULL );
00120 }
00121
00122 void CMatchTipCtrl::Show(CMatchFile* pFile, CQueryHit* pHit)
00123 {
00124 if ( AfxGetMainWnd() != GetForegroundWindow() ) return;
00125 if ( ! Settings.Interface.TipSearch ) return;
00126
00127 CPoint point;
00128 GetCursorPos( &point );
00129
00130 if ( m_bVisible )
00131 {
00132 if ( pFile == m_pFile && pHit == m_pHit ) return;
00133
00134 Hide();
00135
00136 m_pFile = pFile;
00137 m_pHit = pHit;
00138
00139 ShowInternal();
00140 }
00141 else if ( point != m_pOpen )
00142 {
00143 m_pFile = pFile;
00144 m_pHit = pHit;
00145 m_pOpen = point;
00146 m_tOpen = GetTickCount() + TIP_DELAY;
00147 }
00148 }
00149
00150 void CMatchTipCtrl::Hide()
00151 {
00152 m_pFile = NULL;
00153 m_pHit = NULL;
00154 m_tOpen = 0;
00155
00156 if ( m_bVisible )
00157 {
00158 ShowWindow( SW_HIDE );
00159 ModifyStyleEx( WS_EX_LAYERED, 0 );
00160 m_bVisible = FALSE;
00161 GetCursorPos( &m_pOpen );
00162 }
00163 }
00164
00166
00167
00168 int CMatchTipCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
00169 {
00170 if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00171
00172 SetTimer( 1, 250, NULL );
00173
00174 return 0;
00175 }
00176
00177 void CMatchTipCtrl::OnDestroy()
00178 {
00179 KillTimer( 1 );
00180 CWnd::OnDestroy();
00181 }
00182
00184
00185
00186 void CMatchTipCtrl::OnTimer(UINT nIDEvent)
00187 {
00188 CPoint point;
00189 GetCursorPos( &point );
00190
00191 if ( WindowFromPoint( point ) != m_pOwner )
00192 {
00193 if ( m_bVisible ) Hide();
00194 return;
00195 }
00196 else
00197 {
00198 CWnd* pWnd = GetForegroundWindow();
00199
00200 if ( pWnd != this && pWnd != AfxGetMainWnd() )
00201 {
00202 if ( m_bVisible ) Hide();
00203 return;
00204 }
00205 }
00206
00207 if ( ! m_bVisible && m_tOpen && GetTickCount() >= m_tOpen )
00208 {
00209 m_tOpen = 0;
00210 if ( point == m_pOpen ) ShowInternal();
00211 }
00212 }
00213
00214 void CMatchTipCtrl::ShowInternal()
00215 {
00216 if ( m_bVisible ) return;
00217
00218 if ( m_pHit != NULL )
00219 {
00220 LoadFromHit();
00221 }
00222 else if ( m_pFile != NULL )
00223 {
00224 LoadFromFile();
00225 }
00226 else
00227 {
00228 return;
00229 }
00230
00231 if ( m_sName.GetLength() > 128 ) m_sName = m_sName.Left( 128 );
00232
00233 m_bVisible = TRUE;
00234
00235 CSize sz = ComputeSize();
00236
00237
00238 HMONITOR hMonitor = NULL;
00239 MONITORINFO mi = {0};
00240 CRect rcMonitor( 0, 0, 0, 0 );
00241
00242 CRect rc( m_pOpen.x + TIP_OFFSET_X, m_pOpen.y + TIP_OFFSET_Y, 0, 0 );
00243 rc.right = rc.left + sz.cx;
00244 rc.bottom = rc.top + sz.cy;
00245
00246
00247 if ( ( theApp.m_dwWindowsVersion >= 5 ) && (GetSystemMetrics( SM_CMONITORS ) > 1) && (theApp.m_pfnMonitorFromRect) )
00248 {
00249 mi.cbSize = sizeof(MONITORINFO);
00250
00251 hMonitor = theApp.m_pfnMonitorFromRect( rc, MONITOR_DEFAULTTONEAREST );
00252 if (NULL != hMonitor)
00253 {
00254 if ( theApp.m_pfnGetMonitorInfoA(hMonitor, &mi) )
00255 rcMonitor = mi.rcWork;
00256 else
00257 hMonitor = NULL;
00258 }
00259
00260 }
00261
00262 if ( NULL == hMonitor )
00263 {
00264
00265 rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
00266 rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
00267 }
00268
00269 if ( rc.right >= rcMonitor.right)
00270 {
00271 rc.OffsetRect( rcMonitor.right - rc.right - 4, 0 );
00272 }
00273
00274 if ( rc.bottom >= rcMonitor.bottom )
00275 {
00276 rc.OffsetRect( 0, -sz.cy - TIP_OFFSET_Y - 4 );
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 if ( Settings.Interface.TipAlpha == 255 || m_pfnSetLayeredWindowAttributes == NULL )
00295 {
00296 ModifyStyleEx( WS_EX_LAYERED, 0 );
00297 }
00298 else
00299 {
00300 ModifyStyleEx( 0, WS_EX_LAYERED );
00301 (*m_pfnSetLayeredWindowAttributes)( GetSafeHwnd(),
00302 0, (BYTE)Settings.Interface.TipAlpha, LWA_ALPHA );
00303 }
00304
00305 SetWindowPos( &wndTopMost, rc.left, rc.top, rc.Width(), rc.Height(),
00306 SWP_SHOWWINDOW|SWP_NOACTIVATE );
00307 UpdateWindow();
00308 }
00309
00311
00312
00313 void CMatchTipCtrl::LoadFromFile()
00314 {
00315 m_sName = m_pFile->m_pBest->m_sName;
00316 m_sSize = m_pFile->m_sSize;
00317 LoadTypeInfo();
00318
00319 if ( m_pFile->m_bSHA1 && Settings.General.GUIMode != GUI_BASIC)
00320 {
00321 m_sSHA1 = _T("sha1:") + CSHA::HashToString( &m_pFile->m_pSHA1 );
00322 }
00323 else
00324 {
00325 m_sSHA1.Empty();
00326 }
00327
00328 if ( m_pFile->m_bTiger && Settings.General.GUIMode != GUI_BASIC)
00329 {
00330 m_sTiger = _T("tree:tiger/:") + CTigerNode::HashToString( &m_pFile->m_pTiger );
00331 }
00332 else
00333 {
00334 m_sTiger.Empty();
00335 }
00336
00337 if ( m_pFile->m_bED2K && Settings.General.GUIMode != GUI_BASIC)
00338 {
00339 m_sED2K = _T("ed2k:") + CED2K::HashToString( &m_pFile->m_pED2K );
00340 }
00341 else
00342 {
00343 m_sED2K.Empty();
00344 }
00345
00346 if ( m_pFile->m_nFiltered == 1 && m_pFile->m_pBest->m_nPartial )
00347 {
00348 CString strFormat;
00349 LoadString( strFormat, IDS_TIP_PARTIAL );
00350 m_sPartial.Format( strFormat, 100.0f * (float)m_pFile->m_pBest->m_nPartial / (float)m_pFile->m_nSize );
00351 }
00352 else
00353 {
00354 m_sPartial.Empty();
00355 }
00356
00357 if ( m_pFile->m_nFiltered == 1 && m_pFile->m_pBest->m_nUpSlots )
00358 {
00359 CString strFormat;
00360 LoadString( strFormat, IDS_TIP_QUEUE );
00361 m_sQueue.Format( strFormat, m_pFile->m_pBest->m_nUpSlots,
00362 max( 0, m_pFile->m_pBest->m_nUpQueue - m_pFile->m_pBest->m_nUpSlots ) );
00363 }
00364 else
00365 {
00366 m_sQueue.Empty();
00367 }
00368
00369 m_pSchema = NULL;
00370
00371 for ( CQueryHit* pHit = m_pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
00372 {
00373 m_pSchema = SchemaCache.Get( pHit->m_sSchemaURI );
00374 if ( m_pSchema ) break;
00375 }
00376
00377 m_pMetadata.Setup( m_pSchema );
00378
00379 if ( m_pSchema != NULL )
00380 {
00381 for ( CQueryHit* pHit = m_pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
00382 {
00383 if ( pHit->m_pXML && m_pSchema->CheckURI( pHit->m_sSchemaURI ) )
00384 {
00385 m_pMetadata.Combine( pHit->m_pXML );
00386 }
00387 }
00388
00389 m_pMetadata.Vote();
00390 m_pMetadata.Clean( 72 );
00391 }
00392
00393 m_nRating = m_pFile->m_nRated ? m_pFile->m_nRating / m_pFile->m_nRated : 0;
00394
00395 m_sStatus.Empty();
00396
00397 if ( m_pFile->m_bExisting )
00398 {
00399 CLibraryFile* pExisting = NULL;
00400
00401 CQuickLock oLock( Library.m_pSection );
00402 if ( pExisting == NULL && m_pFile->m_bSHA1 == TRUE )
00403 pExisting = LibraryMaps.LookupFileBySHA1( &m_pFile->m_pSHA1 );
00404 if ( pExisting == NULL && m_pFile->m_bTiger == TRUE )
00405 pExisting = LibraryMaps.LookupFileByTiger( &m_pFile->m_pTiger );
00406 if ( pExisting == NULL && m_pFile->m_bED2K == TRUE )
00407 pExisting = LibraryMaps.LookupFileByED2K( &m_pFile->m_pED2K );
00408
00409 if ( pExisting != NULL )
00410 {
00411 if ( pExisting->IsAvailable() )
00412 {
00413 LoadString( m_sStatus, IDS_TIP_EXISTS_LIBRARY );
00414 m_crStatus = RGB( 0, 128, 0 );
00415 }
00416 else
00417 {
00418 LoadString( m_sStatus, IDS_TIP_EXISTS_DELETED );
00419 m_crStatus = RGB( 255, 0, 0 );
00420
00421 if ( pExisting->m_sComments.GetLength() )
00422 {
00423 LoadString( m_sStatus, IDS_TIP_EXISTS_BLACKLISTED );
00424 m_sStatus += pExisting->m_sComments;
00425 }
00426 }
00427
00428 }
00429 }
00430 else if ( m_pFile->m_bDownload || m_pFile->m_pBest->m_bDownload )
00431 {
00432 LoadString( m_sStatus, IDS_TIP_EXISTS_DOWNLOAD );
00433 m_crStatus = RGB( 0, 0, 160 );
00434 }
00435 else if ( m_pFile->m_pBest->m_bBogus || ! m_pFile->m_bOneValid )
00436 {
00437 LoadString( m_sStatus, IDS_TIP_BOGUS );
00438 m_crStatus = RGB( 255, 0, 0 );
00439 }
00440
00441 if ( m_pFile->m_nFiltered == 1 )
00442 {
00443 if ( m_pFile->m_pBest->m_sNick.GetLength() )
00444 {
00445 m_sUser.Format( _T("%s (%s - %s)"),
00446 (LPCTSTR)m_pFile->m_pBest->m_sNick,
00447 (LPCTSTR)CString( inet_ntoa( m_pFile->m_pBest->m_pAddress ) ),
00448 (LPCTSTR)m_pFile->m_pBest->m_pVendor->m_sName );
00449 }
00450 else
00451 {
00452 if( ( m_pFile->m_pBest->m_nProtocol == PROTOCOL_ED2K ) && ( m_pFile->m_pBest->m_bPush == TS_TRUE ) )
00453 {
00454 m_sUser.Format( _T("%lu@%s - %s"), m_pFile->m_pBest->m_pClientID.w[2],
00455 (LPCTSTR)CString( inet_ntoa( (IN_ADDR&)m_pFile->m_pBest->m_pClientID.w[0]) ),
00456 (LPCTSTR)m_pFile->m_pBest->m_pVendor->m_sName );
00457 }
00458 else
00459 {
00460 m_sUser.Format( _T("%s - %s"),
00461 (LPCTSTR)CString( inet_ntoa( m_pFile->m_pBest->m_pAddress ) ),
00462 (LPCTSTR)m_pFile->m_pBest->m_pVendor->m_sName );
00463 }
00464 }
00465 }
00466 else
00467 {
00468 m_sUser.Empty();
00469 }
00470
00471 if (m_pFile->m_bBusy == 2)
00472 {
00473 LoadString( m_sBusy, IDS_TIP_FILE_BUSY );
00474 }
00475 else
00476 {
00477 m_sBusy.Empty();
00478 }
00479 if (m_pFile->m_bPush == 2)
00480 {
00481 LoadString( m_sPush, IDS_TIP_FILE_FIREWALLED );
00482 }
00483 else
00484 {
00485 m_sPush.Empty();
00486 }
00487 if (m_pFile->m_bStable == 1)
00488 {
00489 LoadString( m_sUnstable, IDS_TIP_FILE_UNSTABLE );
00490 }
00491 else
00492 {
00493 m_sUnstable.Empty();
00494 }
00495 }
00496
00497 void CMatchTipCtrl::LoadFromHit()
00498 {
00499 m_sName = m_pHit->m_sName;
00500 m_sSize = Settings.SmartVolume( m_pHit->m_nSize, FALSE );
00501 LoadTypeInfo();
00502
00503 if ( m_pHit->m_bSHA1 && Settings.General.GUIMode != GUI_BASIC)
00504 {
00505 m_sSHA1 = _T("sha1:") + CSHA::HashToString( &m_pHit->m_pSHA1 );
00506 }
00507 else
00508 {
00509 m_sSHA1.Empty();
00510 }
00511
00512 if ( m_pHit->m_bTiger && Settings.General.GUIMode != GUI_BASIC)
00513 {
00514 m_sTiger = _T("tree:tiger/:") + CTigerNode::HashToString( &m_pHit->m_pTiger );
00515 }
00516 else
00517 {
00518 m_sTiger.Empty();
00519 }
00520
00521 if ( m_pHit->m_bED2K && Settings.General.GUIMode != GUI_BASIC)
00522 {
00523 m_sED2K = _T("ed2k:") + CED2K::HashToString( &m_pHit->m_pED2K );
00524 }
00525 else
00526 {
00527 m_sED2K.Empty();
00528 }
00529
00530 if ( m_pHit->m_nPartial )
00531 {
00532 CString strFormat;
00533 LoadString( strFormat, IDS_TIP_PARTIAL );
00534 m_sPartial.Format( strFormat, 100.0f * (float)m_pHit->m_nPartial / (float)m_pHit->m_nSize );
00535 }
00536 else
00537 {
00538 m_sPartial.Empty();
00539 }
00540
00541 if ( m_pHit->m_nUpSlots )
00542 {
00543 CString strFormat;
00544 LoadString( strFormat, IDS_TIP_QUEUE );
00545 m_sQueue.Format( strFormat, m_pHit->m_nUpSlots,
00546 max( 0, m_pHit->m_nUpQueue - m_pHit->m_nUpSlots ) );
00547 }
00548 else
00549 {
00550 m_sQueue.Empty();
00551 }
00552
00553 m_pSchema = SchemaCache.Get( m_pHit->m_sSchemaURI );
00554
00555 m_pMetadata.Setup( m_pSchema );
00556
00557 if ( m_pSchema != NULL )
00558 {
00559 if ( m_pHit->m_pXML && m_pSchema->CheckURI( m_pHit->m_sSchemaURI ) )
00560 {
00561 m_pMetadata.Combine( m_pHit->m_pXML );
00562 }
00563 m_pMetadata.Clean( 72 );
00564 }
00565
00566 m_nRating = m_pHit->m_nRating;
00567
00568 m_sStatus.Empty();
00569
00570 if ( m_pFile->m_bExisting )
00571 {
00572 LoadString( m_sStatus, IDS_TIP_EXISTS_LIBRARY );
00573 m_crStatus = RGB( 0, 128, 0 );
00574 }
00575 else if ( m_pFile->m_bDownload || m_pHit->m_bDownload )
00576 {
00577 LoadString( m_sStatus, IDS_TIP_EXISTS_DOWNLOAD );
00578 m_crStatus = RGB( 0, 128, 0 );
00579 }
00580 else if ( m_pHit->m_bBogus )
00581 {
00582 LoadString( m_sStatus, IDS_TIP_BOGUS );
00583 m_crStatus = RGB( 255, 0, 0 );
00584 }
00585
00586 if ( m_pHit->m_sNick.GetLength() )
00587 {
00588 m_sUser.Format( _T("%s (%s - %s)"),
00589 (LPCTSTR)m_pHit->m_sNick,
00590 (LPCTSTR)CString( inet_ntoa( m_pHit->m_pAddress ) ),
00591 (LPCTSTR)m_pHit->m_pVendor->m_sName );
00592 }
00593 else
00594 {
00595 if( ( m_pHit->m_nProtocol == PROTOCOL_ED2K ) && ( m_pHit->m_bPush == TS_TRUE ) )
00596 {
00597 m_sUser.Format( _T("%lu@%s - %s"),
00598 m_pHit->m_pClientID.w[2],
00599 (LPCTSTR)CString( inet_ntoa( (IN_ADDR&)m_pHit->m_pClientID.w[0]) ),
00600 (LPCTSTR)m_pHit->m_pVendor->m_sName );
00601 }
00602 else
00603 {
00604 m_sUser.Format( _T("%s - %s"),
00605 (LPCTSTR)CString( inet_ntoa( m_pHit->m_pAddress ) ),
00606 (LPCTSTR)m_pHit->m_pVendor->m_sName );
00607 }
00608 }
00609
00610 if (m_pHit->m_bBusy == 2)
00611 {
00612 LoadString( m_sBusy, IDS_TIP_SOURCE_BUSY );
00613 }
00614 else
00615 {
00616 m_sBusy.Empty();
00617 }
00618 if (m_pHit->m_bPush == 2)
00619 {
00620 LoadString( m_sPush, IDS_TIP_SOURCE_FIREWALLED );
00621 }
00622 else
00623 {
00624 m_sPush.Empty();
00625 }
00626 if (m_pHit->m_bStable == 1)
00627 {
00628 LoadString( m_sUnstable, IDS_TIP_SOURCE_UNSTABLE );
00629 }
00630 else
00631 {
00632 m_sUnstable.Empty();
00633 }
00634 }
00635
00636 BOOL CMatchTipCtrl::LoadTypeInfo()
00637 {
00638 int nPeriod = m_sName.ReverseFind( '.' );
00639
00640 m_sType.Empty();
00641 m_nIcon = 0;
00642
00643 if ( nPeriod > 0 )
00644 {
00645 CString strType = m_sName.Mid( nPeriod );
00646 CString strName, strMime;
00647
00648 ShellIcons.Lookup( strType, NULL, NULL, &strName, &strMime );
00649 m_nIcon = ShellIcons.Get( strType, 32 );
00650
00651 if ( strName.GetLength() )
00652 {
00653 m_sType = strName;
00654 if ( strMime.GetLength() ) m_sType += _T(" (") + strMime + _T(")");
00655 }
00656 else
00657 {
00658 m_sType = strType.Mid( 1 );
00659 }
00660 }
00661
00662 if ( m_sType.IsEmpty() ) m_sType = _T("Unknown");
00663
00664 return FALSE;
00665 }
00666
00668
00669
00670 CSize CMatchTipCtrl::ComputeSize()
00671 {
00672 CClientDC dc( this );
00673 CSize sz( 0, 0 );
00674
00675 CFont* pOldFont = (CFont*)dc.SelectObject( &CoolInterface.m_fntBold );
00676
00677 ExpandSize( dc, sz, m_sName );
00678 sz.cy += TIP_TEXTHEIGHT;
00679
00680 dc.SelectObject( &CoolInterface.m_fntNormal );
00681
00682 if ( m_sUser.GetLength() )
00683 {
00684 ExpandSize( dc, sz, m_sUser );
00685 sz.cy += TIP_TEXTHEIGHT;
00686 }
00687
00688 sz.cy += 5 + 6;
00689
00690 if ( m_sStatus.GetLength() )
00691 {
00692 dc.SelectObject( &CoolInterface.m_fntBold );
00693 ExpandSize( dc, sz, m_sStatus );
00694 dc.SelectObject( &CoolInterface.m_fntNormal );
00695 sz.cy += TIP_TEXTHEIGHT;
00696 sz.cy += 5 + 6;
00697 }
00698
00699 sz.cy += 32;
00700 CString strTest;
00701 LoadString( strTest, IDS_TIP_SIZE );
00702 strTest.Append( _T(": ") );
00703 ExpandSize( dc, sz, strTest + m_sSize, 40 );
00704 LoadString( strTest, IDS_TIP_TYPE );
00705 strTest.Append( _T(": ") );
00706 ExpandSize( dc, sz, strTest + m_sType, 40 );
00707
00708 if ( m_sSHA1.GetLength() || m_sTiger.GetLength() || m_sED2K.GetLength() )
00709 {
00710 sz.cy += 5 + 6;
00711
00712 if ( m_sSHA1.GetLength() )
00713 {
00714 ExpandSize( dc, sz, m_sSHA1 );
00715 sz.cy += TIP_TEXTHEIGHT;
00716 }
00717
00718 if ( m_sTiger.GetLength() )
00719 {
00720 ExpandSize( dc, sz, m_sTiger );
00721 sz.cy += TIP_TEXTHEIGHT;
00722 }
00723
00724 if ( m_sED2K.GetLength() )
00725 {
00726 ExpandSize( dc, sz, m_sED2K );
00727 sz.cy += TIP_TEXTHEIGHT;
00728 }
00729 }
00730
00731 if ( m_pMetadata.GetCount() )
00732 {
00733 sz.cy += 5 + 6;
00734
00735 int nValueWidth = 0;
00736 m_nKeyWidth = 0;
00737
00738 m_pMetadata.ComputeWidth( &dc, m_nKeyWidth, nValueWidth );
00739
00740 if ( m_nKeyWidth ) m_nKeyWidth += TIP_MARGIN;
00741 sz.cx = max( sz.cx, LONG(m_nKeyWidth + nValueWidth) );
00742 sz.cy += TIP_TEXTHEIGHT * m_pMetadata.GetCount();
00743 }
00744
00745
00746 if ( m_sBusy.GetLength() || m_sPush.GetLength() || m_sUnstable.GetLength() || m_sQueue.GetLength() )
00747 {
00748 sz.cy += 11;
00749
00750 if ( m_sBusy.GetLength() )
00751 {
00752 dc.SelectObject( &CoolInterface.m_fntBold );
00753 ExpandSize( dc, sz, m_sBusy, 20 );
00754 dc.SelectObject( &CoolInterface.m_fntNormal );
00755 sz.cy += TIP_ICONHEIGHT;
00756 }
00757
00758 if ( m_sQueue.GetLength() )
00759 {
00760 if ( m_sBusy.GetLength() )
00761 ExpandSize( dc, sz, m_sQueue, 20 );
00762 else
00763 ExpandSize( dc, sz, m_sQueue );
00764 sz.cy += TIP_TEXTHEIGHT;
00765 }
00766
00767 if ( m_sPush.GetLength() )
00768 {
00769 dc.SelectObject( &CoolInterface.m_fntBold );
00770 ExpandSize( dc, sz, m_sPush, 20 );
00771 dc.SelectObject( &CoolInterface.m_fntNormal );
00772 sz.cy += TIP_ICONHEIGHT;
00773 }
00774
00775 if ( m_sUnstable.GetLength() )
00776 {
00777 dc.SelectObject( &CoolInterface.m_fntBold );
00778 ExpandSize( dc, sz, m_sUnstable, 20 );
00779 dc.SelectObject( &CoolInterface.m_fntNormal );
00780 sz.cy += TIP_ICONHEIGHT;
00781 }
00782 }
00783
00784
00785 if ( m_sPartial.GetLength() )
00786 {
00787 sz.cy += 5 + 6;
00788
00789 ExpandSize( dc, sz, m_sPartial );
00790 sz.cy += TIP_TEXTHEIGHT;
00791 }
00792
00793
00794 dc.SelectObject( pOldFont );
00795
00796 sz.cx += TIP_MARGIN * 2;
00797 sz.cy += TIP_MARGIN * 2;
00798
00799 return sz;
00800 }
00801
00802 void CMatchTipCtrl::ExpandSize(CDC& dc, CSize& sz, LPCTSTR pszText, int nBase)
00803 {
00804 CSize szText = dc.GetTextExtent( pszText, _tcslen( pszText ) );
00805 szText.cx += nBase;
00806 sz.cx = max( sz.cx, szText.cx );
00807 }
00808
00810
00811
00812 BOOL CMatchTipCtrl::OnEraseBkgnd(CDC* pDC)
00813 {
00814 return TRUE;
00815 }
00816
00817 void CMatchTipCtrl::OnPaint()
00818 {
00819 CPaintDC dc( this );
00820 CString str;
00821 CRect rc;
00822
00823 GetClientRect( &rc );
00824
00825 dc.Draw3dRect( &rc, m_crBorder, m_crBorder );
00826 rc.DeflateRect( 1, 1 );
00827
00828 CFont* pOldFont = (CFont*)dc.SelectObject( &CoolInterface.m_fntBold );
00829 CPoint pt( TIP_MARGIN, TIP_MARGIN );
00830
00831 dc.SetTextColor( m_crText );
00832
00833 DrawText( dc, pt, m_sName );
00834 pt.y += TIP_TEXTHEIGHT;
00835
00836 dc.SelectObject( &CoolInterface.m_fntNormal );
00837
00838 if ( m_sUser.GetLength() )
00839 {
00840 DrawText( dc, pt, m_sUser );
00841 pt.y += TIP_TEXTHEIGHT;
00842 }
00843
00844 pt.y += 5;
00845 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
00846 m_crBorder, m_crBorder );
00847 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
00848 pt.y += 6;
00849
00850 if ( m_sStatus.GetLength() )
00851 {
00852 dc.SetTextColor( m_crStatus );
00853 dc.SelectObject( &CoolInterface.m_fntBold );
00854 DrawText( dc, pt, m_sStatus );
00855 dc.SelectObject( &CoolInterface.m_fntNormal );
00856 dc.SetTextColor( m_crText );
00857 pt.y += TIP_TEXTHEIGHT;
00858
00859 pt.y += 5;
00860 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
00861 m_crBorder, m_crBorder );
00862 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
00863 pt.y += 6;
00864 }
00865
00866 ShellIcons.Draw( &dc, m_nIcon, 32, pt.x, pt.y, m_crBack );
00867
00868 if ( m_nRating > 1 )
00869 {
00870 CPoint ptStar( rc.right - 3, pt.y - 2 );
00871
00872 for ( int nRating = m_nRating - 1 ; nRating ; nRating-- )
00873 {
00874 ptStar.x -= 16;
00875 ShellIcons.Draw( &dc, SHI_STAR, 16, ptStar.x, ptStar.y, m_crBack );
00876 }
00877 }
00878
00879 pt.x += 40;
00880 LoadString( str, IDS_TIP_SIZE );
00881 str.Append( _T(": ") );
00882 DrawText( dc, pt, str );
00883 CSize sz = dc.GetTextExtent( str, str.GetLength() );
00884 pt.x += sz.cx;
00885 DrawText( dc, pt, m_sSize );
00886 pt.x -= sz.cx;
00887 pt.y += 16;
00888 LoadString( str, IDS_TIP_TYPE );
00889 str.Append( _T(": ") );
00890 DrawText( dc, pt, str );
00891 sz = dc.GetTextExtent( str, str.GetLength() );
00892 pt.x += sz.cx;
00893 DrawText( dc, pt, m_sType );
00894 pt.x -= sz.cx;
00895 pt.x -= 40;
00896 pt.y += 16;
00897
00898
00899 if ( m_sSHA1.GetLength() || m_sTiger.GetLength() || m_sED2K.GetLength() )
00900 {
00901 pt.y += 5;
00902 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
00903 m_crBorder, m_crBorder );
00904 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
00905 pt.y += 6;
00906
00907 if ( m_sSHA1.GetLength() )
00908 {
00909 DrawText( dc, pt, m_sSHA1 );
00910 pt.y += TIP_TEXTHEIGHT;
00911 }
00912
00913 if ( m_sTiger.GetLength() )
00914 {
00915 DrawText( dc, pt, m_sTiger );
00916 pt.y += TIP_TEXTHEIGHT;
00917 }
00918
00919 if ( m_sED2K.GetLength() )
00920 {
00921 DrawText( dc, pt, m_sED2K );
00922 pt.y += TIP_TEXTHEIGHT;
00923 }
00924 }
00925
00926
00927 if (m_sBusy.GetLength() || m_sPush.GetLength() || m_sUnstable.GetLength() || m_sQueue.GetLength())
00928 {
00929 pt.y += 5;
00930 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
00931 m_crBorder, m_crBorder );
00932 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
00933 pt.y += 6;
00934
00935 dc.SetTextColor( m_crWarnings );
00936 dc.SelectObject( &CoolInterface.m_fntBold );
00937
00938
00939 if (m_sBusy.GetLength())
00940 {
00941 ShellIcons.Draw( &dc, SHI_BUSY, TIP_ICONHEIGHT, pt.x, pt.y, m_crBack );
00942
00943 CPoint ptTextWithIcon = pt;
00944 ptTextWithIcon.x += 20;
00945 ptTextWithIcon.y += 1;
00946
00947 DrawText ( dc, ptTextWithIcon, m_sBusy);
00948 pt.y += TIP_ICONHEIGHT;
00949 }
00950
00951 dc.SetTextColor( m_crText );
00952 dc.SelectObject( &CoolInterface.m_fntNormal );
00953
00954
00955 if ( m_sQueue.GetLength() )
00956 {
00957 CPoint ptTextWithIcon = pt;
00958 ptTextWithIcon.x += 20;
00959
00960 if ( m_sBusy.GetLength() )
00961 DrawText( dc, ptTextWithIcon, m_sQueue );
00962 else
00963 DrawText( dc, pt, m_sQueue );
00964
00965 pt.y += TIP_TEXTHEIGHT;
00966 }
00967
00968 dc.SetTextColor( m_crWarnings );
00969 dc.SelectObject( &CoolInterface.m_fntBold );
00970
00971
00972 if (m_sPush.GetLength())
00973 {
00974 ShellIcons.Draw( &dc, SHI_FIREWALL, TIP_ICONHEIGHT, pt.x, pt.y, m_crBack );
00975
00976 CPoint ptTextWithIcon = pt;
00977 ptTextWithIcon.x += 20;
00978 ptTextWithIcon.y += 1;
00979
00980 DrawText ( dc, ptTextWithIcon, m_sPush);
00981 pt.y += TIP_ICONHEIGHT;
00982 }
00983
00984
00985 if (m_sUnstable.GetLength())
00986 {
00987 ShellIcons.Draw( &dc, SHI_UNSTABLE, TIP_ICONHEIGHT, pt.x, pt.y, m_crBack );
00988
00989 CPoint ptTextWithIcon = pt;
00990 ptTextWithIcon.x += 20;
00991 ptTextWithIcon.y += 1;
00992
00993 DrawText ( dc, ptTextWithIcon, m_sUnstable);
00994 pt.y += TIP_ICONHEIGHT;
00995 }
00996 dc.SetTextColor( m_crText );
00997 dc.SelectObject( &CoolInterface.m_fntNormal );
00998 }
00999
01000
01001 if ( m_sPartial.GetLength() )
01002 {
01003 pt.y += 5;
01004 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
01005 m_crBorder, m_crBorder );
01006 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
01007 pt.y += 6;
01008
01009 DrawText( dc, pt, m_sPartial );
01010 pt.y += TIP_TEXTHEIGHT;
01011 }
01012
01013
01014 if ( m_pMetadata.GetCount() )
01015 {
01016 pt.y += 5;
01017 dc.Draw3dRect( rc.left + 2, pt.y, rc.Width() - 4, 1,
01018 m_crBorder, m_crBorder );
01019 dc.ExcludeClipRect( rc.left + 2, pt.y, rc.right - 2, pt.y + 1 );
01020 pt.y += 6;
01021
01022 for ( POSITION pos = m_pMetadata.GetIterator() ; pos ; )
01023 {
01024 CMetaItem* pItem = m_pMetadata.GetNext( pos );
01025
01026 DrawText( dc, pt, theApp.m_bRTL ? ':' + pItem->m_sKey : pItem->m_sKey + ':' );
01027 pt.x += m_nKeyWidth;
01028 DrawText( dc, pt, pItem->m_sValue );
01029 pt.x -= m_nKeyWidth;
01030 pt.y += TIP_TEXTHEIGHT;
01031 }
01032 }
01033
01034 dc.SelectObject( pOldFont );
01035 dc.FillSolidRect( &rc, m_crBack );
01036 }
01037
01038 void CMatchTipCtrl::DrawText(CDC& dc, CPoint& pt, LPCTSTR pszText)
01039 {
01040 DWORD dwFlags = ( theApp.m_bRTL ? ETO_RTLREADING : 0 );
01041 short nExtraPoint = ( theApp.m_bRTL ? 1 : 0 );
01042 CSize sz = dc.GetTextExtent( pszText, _tcslen( pszText ) );
01043 CRect rc( pt.x, pt.y, pt.x + sz.cx + nExtraPoint, pt.y + sz.cy );
01044
01045 dc.SetBkColor( m_crBack );
01046 dc.ExtTextOut( pt.x, pt.y, ETO_CLIPPED|ETO_OPAQUE|dwFlags, &rc, pszText, _tcslen( pszText ), NULL );
01047 dc.ExcludeClipRect( &rc );
01048 }
01049
01050 void CMatchTipCtrl::OnMouseMove(UINT nFlags, CPoint point)
01051 {
01052 Hide();
01053 }
01054
01055 void CMatchTipCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
01056 {
01057 Hide();
01058 CWnd::OnKeyDown( nChar, nRepCnt, nFlags );
01059 }