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 "Library.h"
00026 #include "LibraryBuilder.h"
00027 #include "AlbumFolder.h"
00028 #include "SharedFile.h"
00029 #include "QuerySearch.h"
00030 #include "Schema.h"
00031 #include "XML.h"
00032
00033 #include "CtrlLibraryFrame.h"
00034 #include "DlgNewSearch.h"
00035 #include "Skin.h"
00036
00037 #include "CtrlLibraryView.h"
00038 #include "CtrlLibraryCollectionView.h"
00039 #include "CtrlLibraryDetailView.h"
00040 #include "CtrlLibraryThumbView.h"
00041 #include "CtrlLibraryAlbumView.h"
00042 #include "CtrlLibraryTileView.h"
00043 #include "CtrlLibraryHomeView.h"
00044
00045 #include "CtrlLibraryPanel.h"
00046 #include "CtrlLibraryMetaPanel.h"
00047 #include "CtrlLibraryHistoryPanel.h"
00048
00049 #ifdef _DEBUG
00050 #define new DEBUG_NEW
00051 #undef THIS_FILE
00052 static char THIS_FILE[] = __FILE__;
00053 #endif
00054
00055 IMPLEMENT_DYNAMIC(CLibraryFrame, CWnd)
00056
00057 BEGIN_MESSAGE_MAP(CLibraryFrame, CWnd)
00058 ON_WM_CREATE()
00059 ON_WM_DESTROY()
00060 ON_WM_SIZE()
00061 ON_WM_PAINT()
00062 ON_WM_LBUTTONDOWN()
00063 ON_WM_SETCURSOR()
00064 ON_WM_MOUSEMOVE()
00065 ON_WM_LBUTTONUP()
00066 ON_WM_RBUTTONDOWN()
00067 ON_WM_TIMER()
00068 ON_WM_CONTEXTMENU()
00069 ON_WM_KEYDOWN()
00070 ON_WM_KEYUP()
00071 ON_WM_MEASUREITEM()
00072 ON_COMMAND(ID_LIBRARY_REFRESH, OnLibraryRefresh)
00073 ON_UPDATE_COMMAND_UI(ID_LIBRARY_TREE_PHYSICAL, OnUpdateLibraryTreePhysical)
00074 ON_COMMAND(ID_LIBRARY_TREE_PHYSICAL, OnLibraryTreePhysical)
00075 ON_UPDATE_COMMAND_UI(ID_LIBRARY_TREE_VIRTUAL, OnUpdateLibraryTreeVirtual)
00076 ON_COMMAND(ID_LIBRARY_TREE_VIRTUAL, OnLibraryTreeVirtual)
00077 ON_UPDATE_COMMAND_UI(ID_LIBRARY_PANEL, OnUpdateLibraryPanel)
00078 ON_COMMAND(ID_LIBRARY_PANEL, OnLibraryPanel)
00079 ON_COMMAND(ID_LIBRARY_SEARCH, OnLibrarySearch)
00080 ON_COMMAND(ID_LIBRARY_SEARCH_QUICK, OnLibrarySearchQuick)
00081 ON_NOTIFY(LTN_SELCHANGED, IDC_LIBRARY_TREE, OnTreeSelection)
00082 ON_CBN_CLOSEUP(AFX_IDW_TOOLBAR, OnFilterTypes)
00083 ON_BN_CLICKED(AFX_IDW_TOOLBAR, OnToolbarReturn)
00084 ON_BN_DOUBLECLICKED(AFX_IDW_TOOLBAR, OnToolbarEscape)
00085 ON_WM_SETFOCUS()
00086 END_MESSAGE_MAP()
00087
00088 #define BAR_HEIGHT 28
00089 #define SPLIT_SIZE 6
00090
00091
00093
00094
00095 CLibraryFrame::CLibraryFrame()
00096 {
00097 m_pViews.AddTail( new CLibraryDetailView() );
00098 m_pViews.AddTail( new CLibraryListView() );
00099 m_pViews.AddTail( new CLibraryIconView() );
00100 m_pViews.AddTail( new CLibraryThumbView() );
00101 m_pViews.AddTail( new CLibraryAlbumView() );
00102 m_pViews.AddTail( new CLibraryTileView() );
00103 m_pViews.AddTail( new CLibraryHomeView() );
00104 m_pViews.AddTail( new CLibraryCollectionView() );
00105
00106 m_pPanels.AddTail( new CLibraryMetaPanel() );
00107 m_pPanels.AddTail( new CLibraryHistoryPanel() );
00108
00109 m_pView = NULL;
00110 m_pPanel = NULL;
00111 m_nTreeSize = Settings.Library.TreeSize;
00112 m_nPanelSize = Settings.Library.PanelSize;
00113 m_bPanelShow = Settings.Library.ShowPanel;
00114 m_nHeaderSize = 0;
00115 m_bUpdating = FALSE;
00116
00117 m_pDragList = NULL;
00118 m_pDragImage = NULL;
00119 m_hCursMove = theApp.LoadCursor( IDC_MOVE );
00120 m_hCursCopy = theApp.LoadCursor( IDC_COPY );
00121 }
00122
00123 CLibraryFrame::~CLibraryFrame()
00124 {
00125 for ( POSITION pos = m_pViews.GetHeadPosition() ; pos ; )
00126 {
00127 delete (CLibraryView*)m_pViews.GetNext( pos );
00128 }
00129
00130 for ( POSITION pos = m_pPanels.GetHeadPosition() ; pos ; )
00131 {
00132 delete (CLibraryPanel*)m_pPanels.GetNext( pos );
00133 }
00134 }
00135
00137
00138
00139 BOOL CLibraryFrame::Create(CWnd* pParentWnd)
00140 {
00141 CRect rect;
00142 return CWnd::Create( NULL, _T("CLibraryFrame"),
00143 WS_CHILD|WS_VISIBLE|WS_TABSTOP, rect, pParentWnd, IDC_LIBRARY_FRAME, NULL );
00144 }
00145
00146 int CLibraryFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
00147 {
00148 if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
00149
00150 if ( ! m_wndTreeTop.Create( this, WS_CHILD|WS_VISIBLE|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
00151 m_wndTreeTop.SetBarStyle( m_wndTreeTop.GetBarStyle() | CBRS_TOOLTIPS|CBRS_BORDER_BOTTOM );
00152 m_wndTreeTop.SetOwner( GetOwner() );
00153
00154 if ( ! m_wndTreeBottom.Create( this, WS_CHILD|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
00155 m_wndTreeBottom.SetBarStyle( m_wndTreeBottom.GetBarStyle() | CBRS_TOOLTIPS|CBRS_BORDER_TOP );
00156 m_wndTreeBottom.SetOwner( GetOwner() );
00157
00158 CRect rcTypes( 0, 0, 128, BAR_HEIGHT );
00159 if ( ! m_wndTreeTypes.Create( WS_CHILD, rcTypes, this, AFX_IDW_TOOLBAR ) ) return -1;
00160 m_wndTreeTypes.GetWindowRect( &rcTypes );
00161 m_nTreeTypesHeight = rcTypes.Height();
00162
00163 if ( ! m_wndViewTop.Create( this, WS_CHILD|WS_VISIBLE|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
00164 m_wndViewTop.SetBarStyle( m_wndViewTop.GetBarStyle() | CBRS_TOOLTIPS );
00165 m_wndViewTop.SetOwner( GetOwner() );
00166
00167 if ( ! m_wndViewBottom.Create( this, WS_CHILD|WS_VISIBLE|CBRS_NOALIGN, AFX_IDW_TOOLBAR ) ) return -1;
00168 m_wndViewBottom.SetBarStyle( m_wndViewBottom.GetBarStyle() | CBRS_TOOLTIPS|CBRS_BORDER_TOP );
00169 m_wndViewBottom.SetOwner( GetOwner() );
00170
00171 if ( ! m_wndSearch.Create( WS_CHILD|ES_AUTOHSCROLL, rcTypes, &m_wndViewBottom, IDC_SEARCH_BOX ) ) return -1;
00172 m_wndSearch.SetFont( &theApp.m_gdiFont );
00173
00174 m_wndTree.Create( this );
00175 m_wndHeader.Create( this );
00176 m_wndViewTip.Create( this, &Settings.Interface.TipLibrary );
00177
00178 return 0;
00179 }
00180
00181 void CLibraryFrame::OnDestroy()
00182 {
00183 CancelDrag();
00184
00185 if ( m_wndViewTip.m_hWnd ) m_wndViewTip.DestroyWindow();
00186
00187 Settings.Library.TreeSize = m_nTreeSize;
00188 Settings.Library.PanelSize = m_nPanelSize;
00189 Settings.Library.ShowPanel = m_bPanelShow;
00190
00191 CWnd::OnDestroy();
00192 }
00193
00194 BOOL CLibraryFrame::PreTranslateMessage(MSG* pMsg)
00195 {
00196 if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB )
00197 {
00198 CWnd* pFocus = GetFocus();
00199
00200 if ( pFocus == &m_wndTree && m_pView != NULL )
00201 {
00202 m_pView->SetFocus();
00203 return TRUE;
00204 }
00205 else
00206 {
00207 m_wndTree.SetFocus();
00208 return TRUE;
00209 }
00210 }
00211
00212 return CWnd::PreTranslateMessage( pMsg );
00213 }
00214
00216
00217
00218 void CLibraryFrame::OnSkinChange()
00219 {
00220 m_wndTree.SetVirtual( Settings.Library.ShowVirtual );
00221
00222 Skin.CreateToolBar( _T("CLibraryTree.Top"), &m_wndTreeTop );
00223
00224 if ( Settings.Library.ShowVirtual )
00225 {
00226 Skin.CreateToolBar( _T("CLibraryHeaderBar.Virtual"), &m_wndViewTop );
00227 Skin.CreateToolBar( _T("CLibraryTree.Virtual"), &m_wndTreeBottom );
00228 }
00229 else
00230 {
00231 Skin.CreateToolBar( _T("CLibraryHeaderBar.Physical"), &m_wndViewTop );
00232 Skin.CreateToolBar( _T("CLibraryTree.Physical"), &m_wndTreeBottom );
00233
00234 m_wndTreeTypes.SetEmptyString( IDS_LIBRARY_TYPE_FILTER_ALL );
00235 m_wndTreeTypes.Load( Settings.Library.FilterURI );
00236 }
00237
00238 m_wndTreeBottom.ShowWindow( Settings.Library.ShowVirtual ? SW_SHOW : SW_HIDE );
00239 m_wndTreeTypes.ShowWindow( Settings.Library.ShowVirtual ? SW_HIDE : SW_SHOW );
00240 m_wndHeader.OnSkinChange();
00241
00242 CLibraryView* pView = m_pView;
00243 CLibraryPanel* pPanel = m_pPanel;
00244
00245 SetView( NULL, TRUE, FALSE );
00246 SetView( pView, TRUE, FALSE );
00247 SetPanel( pPanel );
00248 }
00249
00251
00252
00253 BOOL CLibraryFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
00254 {
00255 if ( m_wndTreeTop.m_hWnd )
00256 {
00257 if ( m_wndTreeTop.OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00258 }
00259 if ( m_wndTreeBottom.m_hWnd )
00260 {
00261 if ( m_wndTreeBottom.OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00262 }
00263 if ( m_wndViewTop.m_hWnd )
00264 {
00265 if ( m_wndViewTop.OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00266 }
00267 if ( m_wndViewBottom.m_hWnd )
00268 {
00269 if ( m_wndViewBottom.OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00270 }
00271 if ( m_wndTree.m_hWnd )
00272 {
00273 if ( m_wndTree.OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00274 }
00275 if ( m_pView && m_pView->m_hWnd )
00276 {
00277 if ( m_pView->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00278 }
00279 if ( m_pPanel && m_pPanel->m_hWnd )
00280 {
00281 if ( m_pPanel->OnCmdMsg( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE;
00282 }
00283
00284 return CWnd::OnCmdMsg( nID, nCode, pExtra, pHandlerInfo );
00285 }
00286
00287 void CLibraryFrame::OnSize(UINT nType, int cx, int cy)
00288 {
00289 if ( nType != 1982 ) CWnd::OnSize( nType, cx, cy );
00290
00291 CRect rc;
00292 GetClientRect( &rc );
00293
00294 if ( rc.Width() < 32 || rc.Height() < 32 ) return;
00295
00296 if ( rc.Width() < m_nTreeSize + SPLIT_SIZE )
00297 {
00298 m_nTreeSize = max( 0, rc.Width() - SPLIT_SIZE );
00299 }
00300 if ( rc.Height() - BAR_HEIGHT * 2 - m_nHeaderSize < m_nPanelSize + SPLIT_SIZE )
00301 {
00302 m_nPanelSize = max( 0, rc.Height() - BAR_HEIGHT * 2 - m_nHeaderSize - SPLIT_SIZE );
00303 }
00304
00305 HDWP hDWP = BeginDeferWindowPos(
00306 6 + ( m_pView != NULL ) + ( m_pPanel != NULL ) + ( m_nHeaderSize > 0 ) );
00307
00308 DeferWindowPos( hDWP, m_wndTreeTop.GetSafeHwnd(), NULL,
00309 rc.left, rc.top, m_nTreeSize, BAR_HEIGHT, SWP_NOZORDER );
00310
00311 DeferWindowPos( hDWP, m_wndTreeBottom.GetSafeHwnd(), NULL,
00312 rc.left, rc.bottom - BAR_HEIGHT, m_nTreeSize, BAR_HEIGHT, SWP_NOZORDER );
00313
00314 DeferWindowPos( hDWP, m_wndTreeTypes.GetSafeHwnd(), NULL,
00315 rc.left, rc.bottom - m_nTreeTypesHeight, m_nTreeSize, 256, SWP_NOZORDER );
00316
00317 DeferWindowPos( hDWP, m_wndViewTop.GetSafeHwnd(), NULL,
00318 rc.left + m_nTreeSize + SPLIT_SIZE, rc.top,
00319 rc.Width() - m_nTreeSize - SPLIT_SIZE, BAR_HEIGHT - 1, SWP_NOZORDER );
00320
00321 DeferWindowPos( hDWP, m_wndViewBottom.GetSafeHwnd(), NULL,
00322 rc.left + m_nTreeSize + SPLIT_SIZE, rc.bottom - BAR_HEIGHT,
00323 rc.Width() - m_nTreeSize - SPLIT_SIZE, BAR_HEIGHT, SWP_NOZORDER );
00324
00325 DeferWindowPos( hDWP, m_wndTree.GetSafeHwnd(), NULL,
00326 rc.left, rc.top + BAR_HEIGHT, m_nTreeSize, rc.Height() - BAR_HEIGHT * 2, SWP_NOZORDER );
00327
00328 if ( m_pView != NULL )
00329 {
00330 int nTop = rc.top + BAR_HEIGHT - 1;
00331
00332 if ( m_nHeaderSize > 0 )
00333 {
00334 DeferWindowPos( hDWP, m_wndHeader.GetSafeHwnd(), NULL,
00335 rc.left + m_nTreeSize + SPLIT_SIZE, nTop,
00336 rc.Width() - m_nTreeSize - SPLIT_SIZE, m_nHeaderSize,
00337 SWP_NOZORDER|SWP_SHOWWINDOW );
00338 nTop += m_nHeaderSize + 1;
00339 }
00340
00341 int nHeight = rc.bottom - BAR_HEIGHT - nTop;
00342 if ( m_pPanel ) nHeight -= m_nPanelSize + SPLIT_SIZE;
00343
00344 DeferWindowPos( hDWP, m_pView->GetSafeHwnd(), NULL,
00345 rc.left + m_nTreeSize + SPLIT_SIZE, nTop,
00346 rc.Width() - m_nTreeSize - SPLIT_SIZE, nHeight, SWP_NOZORDER|SWP_SHOWWINDOW );
00347 }
00348
00349 if ( m_pPanel != NULL )
00350 {
00351 DeferWindowPos( hDWP, m_pPanel->GetSafeHwnd(), NULL,
00352 rc.left + m_nTreeSize + SPLIT_SIZE, rc.bottom - BAR_HEIGHT - m_nPanelSize,
00353 rc.Width() - m_nTreeSize - SPLIT_SIZE, m_nPanelSize, SWP_NOZORDER|SWP_SHOWWINDOW );
00354 }
00355
00356 EndDeferWindowPos( hDWP );
00357 }
00358
00359 void CLibraryFrame::OnPaint()
00360 {
00361 CPaintDC dc( this );
00362 CRect rcClient, rc;
00363
00364 GetClientRect( &rcClient );
00365
00366 rc.SetRect( rcClient.left + m_nTreeSize,
00367 rcClient.top,
00368 rcClient.left + m_nTreeSize + SPLIT_SIZE,
00369 rcClient.bottom );
00370
00371 dc.FillSolidRect( rc.left, rc.top, 1, rc.Height(), GetSysColor( COLOR_BTNFACE ) );
00372 dc.FillSolidRect( rc.left + 1, rc.top, 1, rc.Height(), GetSysColor( COLOR_3DHIGHLIGHT ) );
00373 dc.FillSolidRect( rc.right - 1, rc.top, 1, rc.Height(), GetSysColor( COLOR_3DSHADOW ) );
00374 dc.FillSolidRect( rc.left + 2, rc.top, rc.Width() - 3, rc.Height(),
00375 GetSysColor( COLOR_BTNFACE ) );
00376
00377 if ( m_nHeaderSize > 0 )
00378 {
00379 dc.FillSolidRect( rc.right, rcClient.top + BAR_HEIGHT - 1 + m_nHeaderSize,
00380 rcClient.right - rc.right, 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
00381 }
00382
00383 if ( Settings.Library.ShowVirtual == FALSE )
00384 {
00385 rc.SetRect( rcClient.left, rcClient.bottom - BAR_HEIGHT,
00386 rcClient.left + m_nTreeSize, rcClient.bottom - m_nTreeTypesHeight );
00387 dc.FillSolidRect( rc.left, rc.top, rc.Width(), 1, GetSysColor( COLOR_3DSHADOW ) );
00388 dc.FillSolidRect( rc.left, rc.top + 1, rc.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
00389 dc.FillSolidRect( rc.left, rc.top + 2, rc.Width(), rc.Height() - 2, GetSysColor( COLOR_BTNFACE ) );
00390 }
00391
00392 if ( m_pPanel != NULL )
00393 {
00394 rc.SetRect( rcClient.left + m_nTreeSize + SPLIT_SIZE,
00395 rcClient.bottom - BAR_HEIGHT - m_nPanelSize - SPLIT_SIZE,
00396 rcClient.right,
00397 rcClient.bottom - BAR_HEIGHT - m_nPanelSize );
00398
00399 dc.FillSolidRect( rc.left, rc.top, rc.Width(), 1, GetSysColor( COLOR_BTNFACE ) );
00400 dc.FillSolidRect( rc.left, rc.top + 1, rc.Width(), 1, GetSysColor( COLOR_3DHIGHLIGHT ) );
00401 dc.FillSolidRect( rc.left, rc.bottom - 1, rc.Width(), 1, GetSysColor( COLOR_3DSHADOW ) );
00402 dc.FillSolidRect( rc.left, rc.top + 2, rc.Width(), rc.Height() - 3,
00403 GetSysColor( COLOR_BTNFACE ) );
00404 }
00405 }
00406
00407 void CLibraryFrame::OnContextMenu(CWnd* pWnd, CPoint point)
00408 {
00409 if ( m_pView ) m_pView->SendMessage( (WPARAM)pWnd->GetSafeHwnd(), MAKELONG( point.x, point.y ) );
00410 }
00411
00412 void CLibraryFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
00413 {
00414 lpMeasureItemStruct->itemHeight = 18;
00415 }
00416
00418
00419
00420 BOOL CLibraryFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
00421 {
00422 if ( m_pDragList != NULL )
00423 {
00424 if ( Settings.Library.ShowVirtual )
00425 {
00426 if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 )
00427 SetCursor( m_hCursMove );
00428 else
00429 SetCursor( m_hCursCopy );
00430 }
00431 else
00432 {
00433 if ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 )
00434 SetCursor( m_hCursCopy );
00435 else
00436 SetCursor( m_hCursMove );
00437 }
00438 return TRUE;
00439 }
00440
00441 CRect rcClient, rc;
00442 CPoint point;
00443
00444 GetCursorPos( &point );
00445 GetClientRect( &rcClient );
00446 ClientToScreen( &rcClient );
00447
00448
00449 rc.SetRect( theApp.m_bRTL ? rcClient.right - m_nTreeSize - SPLIT_SIZE :
00450 rcClient.left + m_nTreeSize,
00451 rcClient.top,
00452 theApp.m_bRTL ? rcClient.right - m_nTreeSize :
00453 rcClient.left + m_nTreeSize + SPLIT_SIZE,
00454 rcClient.bottom );
00455
00456 if ( rc.PtInRect( point ) )
00457 {
00458 SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZEWE ) );
00459 return TRUE;
00460 }
00461
00462 if ( m_pPanel != NULL )
00463 {
00464 rc.SetRect( theApp.m_bRTL ? rcClient.left :
00465 rcClient.left + m_nTreeSize + SPLIT_SIZE,
00466 rcClient.bottom - BAR_HEIGHT - m_nPanelSize - SPLIT_SIZE,
00467 theApp.m_bRTL ? rcClient.right - m_nTreeSize : rcClient.right,
00468 rcClient.bottom - BAR_HEIGHT - m_nPanelSize );
00469
00470 if ( rc.PtInRect( point ) )
00471 {
00472 SetCursor( AfxGetApp()->LoadStandardCursor( IDC_SIZENS ) );
00473 return TRUE;
00474 }
00475 }
00476
00477 return CWnd::OnSetCursor( pWnd, nHitTest, message );
00478 }
00479
00480 void CLibraryFrame::OnLButtonDown(UINT nFlags, CPoint point)
00481 {
00482 CRect rcClient, rc;
00483
00484 GetClientRect( &rcClient );
00485
00486 rc.SetRect( rcClient.left + m_nTreeSize,
00487 rcClient.top,
00488 rcClient.left + m_nTreeSize + SPLIT_SIZE,
00489 rcClient.bottom );
00490
00491 if ( rc.PtInRect( point ) )
00492 {
00493 DoSizeTree();
00494 return;
00495 }
00496
00497 if ( m_pPanel != NULL )
00498 {
00499 rc.SetRect( rcClient.left + m_nTreeSize + SPLIT_SIZE,
00500 rcClient.bottom - BAR_HEIGHT - m_nPanelSize - SPLIT_SIZE,
00501 rcClient.right,
00502 rcClient.bottom - BAR_HEIGHT - m_nPanelSize );
00503
00504 if ( rc.PtInRect( point ) )
00505 {
00506 DoSizePanel();
00507 return;
00508 }
00509 }
00510
00511 CWnd::OnLButtonDown( nFlags, point );
00512 }
00513
00514 BOOL CLibraryFrame::DoSizeTree()
00515 {
00516 MSG* pMsg = &AfxGetThreadState()->m_msgCur;
00517 CRect rcClient;
00518 CPoint point;
00519
00520 GetClientRect( &rcClient );
00521 ClientToScreen( &rcClient );
00522 ClipCursor( &rcClient );
00523 SetCapture();
00524
00525 GetClientRect( &rcClient );
00526
00527 int nOffset = 0xFFFF;
00528
00529 while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
00530 {
00531 while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
00532
00533 if ( ! AfxGetThread()->PumpMessage() )
00534 {
00535 AfxPostQuitMessage( 0 );
00536 break;
00537 }
00538
00539 GetCursorPos( &point );
00540 ScreenToClient( &point );
00541
00542 int nSplit = point.x - rcClient.left;
00543
00544 if ( nOffset == 0xFFFF ) nOffset = m_nTreeSize - nSplit;
00545 nSplit += nOffset;
00546
00547 nSplit = max( nSplit, 0 );
00548 nSplit = min( nSplit, int(rcClient.right - SPLIT_SIZE) );
00549
00550 if ( nSplit < 8 )
00551 nSplit = 0;
00552 if ( nSplit > rcClient.right - SPLIT_SIZE - 8 )
00553 nSplit = rcClient.right - SPLIT_SIZE;
00554
00555 if ( nSplit != m_nTreeSize )
00556 {
00557 m_nTreeSize = nSplit;
00558 OnSize( 1982, 0, 0 );
00559 Invalidate();
00560 }
00561 }
00562
00563 ReleaseCapture();
00564 ClipCursor( NULL );
00565
00566 return TRUE;
00567 }
00568
00569 BOOL CLibraryFrame::DoSizePanel()
00570 {
00571 MSG* pMsg = &AfxGetThreadState()->m_msgCur;
00572 CRect rcClient;
00573 CPoint point;
00574
00575 GetClientRect( &rcClient );
00576 rcClient.left += m_nTreeSize + SPLIT_SIZE;
00577 rcClient.top += BAR_HEIGHT + m_nHeaderSize;
00578 rcClient.bottom -= BAR_HEIGHT;
00579 ClientToScreen( &rcClient );
00580 ClipCursor( &rcClient );
00581 SetCapture();
00582
00583 ScreenToClient( &rcClient );
00584
00585 int nOffset = 0xFFFF;
00586
00587 while ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
00588 {
00589 while ( ::PeekMessage( pMsg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) );
00590
00591 if ( ! AfxGetThread()->PumpMessage() )
00592 {
00593 AfxPostQuitMessage( 0 );
00594 break;
00595 }
00596
00597 GetCursorPos( &point );
00598 ScreenToClient( &point );
00599
00600 int nSplit = rcClient.bottom - point.y;
00601
00602 if ( nOffset == 0xFFFF ) nOffset = m_nPanelSize - nSplit;
00603 nSplit += nOffset;
00604
00605 if ( nSplit < 8 )
00606 nSplit = 0;
00607 if ( nSplit > rcClient.Height() - SPLIT_SIZE - 8 )
00608 nSplit = rcClient.Height() - SPLIT_SIZE;
00609
00610 if ( nSplit != m_nPanelSize )
00611 {
00612 m_nPanelSize = nSplit;
00613 OnSize( 1982, 0, 0 );
00614 Invalidate();
00615 }
00616 }
00617
00618 ReleaseCapture();
00619 ClipCursor( NULL );
00620
00621 return TRUE;
00622 }
00623
00625
00626
00627 void CLibraryFrame::SetView(CLibraryView* pView, BOOL bUpdate, BOOL bUser)
00628 {
00629 CSingleLock pLock( &Library.m_pSection, TRUE );
00630
00631 if ( bUser && pView != NULL )
00632 {
00633 for ( CLibraryTreeItem* pItem = m_pFolderSelection ; pItem ;
00634 pItem = pItem->m_pSelNext )
00635 {
00636 if ( pItem->m_pVirtual != NULL )
00637 {
00638 pItem->m_pVirtual->m_sBestView = pView->GetRuntimeClass()->m_lpszClassName;
00639 }
00640 }
00641 }
00642
00643 if ( m_pView == pView )
00644 {
00645 if ( m_pView )
00646 {
00647 m_pView->Update();
00648 m_pView->ShowWindow( SW_SHOW );
00649 m_wndViewTop.Update( m_pView );
00650 }
00651
00652 return;
00653 }
00654
00655 m_wndViewTip.Hide();
00656 m_wndViewTip.SetOwner( this );
00657
00658 CWnd* pFocus = GetFocus();
00659 BOOL bViewSel = ( pFocus == m_pView || ( pFocus && pFocus->GetParent() == m_pView ) );
00660
00661 CLibraryView* pOld = m_pView;
00662 m_pView = pView;
00663
00664 if ( m_pView ) m_pView->Create( this );
00665 OnSize( 1982, 0, 0 );
00666
00667 if ( m_pView && ! bUpdate ) m_pView->Update();
00668
00669 if ( pOld ) pOld->ShowWindow( SW_HIDE );
00670 if ( m_pView ) m_pView->ShowWindow( SW_SHOW );
00671 if ( pOld ) pOld->DestroyWindow();
00672
00673 if ( m_pView && bUpdate ) Update( TRUE );
00674
00675 m_wndViewTop.Update( m_pView );
00676
00677 if ( m_pView )
00678 {
00679 CString strBar( m_pView->m_pszToolBar );
00680 strBar += Settings.Library.ShowVirtual ? _T(".Virtual") : _T(".Physical");
00681 Skin.CreateToolBar( strBar, &m_wndViewBottom );
00682 m_wndViewTip.SetOwner( m_pView );
00683
00684 if ( bViewSel ) m_pView->SetFocus();
00685 }
00686
00687 Invalidate();
00688 }
00689
00690 void CLibraryFrame::SetPanel(CLibraryPanel* pPanel)
00691 {
00692 if ( pPanel == m_pPanel )
00693 {
00694 if ( m_pPanel )
00695 {
00696 m_pPanel->Update();
00697 m_pPanel->ShowWindow( SW_SHOW );
00698 }
00699 return;
00700 }
00701
00702 CLibraryPanel* pOld = m_pPanel;
00703 m_pPanel = pPanel;
00704
00705 if ( m_pPanel ) m_pPanel->Create( this );
00706 OnSize( 1982, 0, 0 );
00707
00708 if ( m_pPanel ) m_pPanel->Update();
00709
00710 if ( pOld ) pOld->ShowWindow( SW_HIDE );
00711 if ( m_pPanel ) m_pPanel->ShowWindow( SW_SHOW );
00712 if ( pOld ) pOld->DestroyWindow();
00713 }
00714
00716
00717
00718 BOOL CLibraryFrame::Update(BOOL bForce, BOOL bBestView)
00719 {
00720 CSingleLock pLock( &Library.m_pSection );
00721 if ( ! pLock.Lock( bForce ? 500 : 50 ) ) return FALSE;
00722
00723 if ( ! bForce && m_nLibraryCookie == Library.m_nUpdateCookie ) return FALSE;
00724 m_nLibraryCookie = Library.m_nUpdateCookie;
00725
00726 m_bUpdating = TRUE;
00727
00728 m_nFolderCookie = GetTickCount();
00729 m_wndTree.Update( m_nFolderCookie );
00730 m_pFolderSelection = m_wndTree.GetFirstSelected();
00731
00732 CLibraryView* pFirstView = NULL;
00733 CLibraryView* pBestView = NULL;
00734 CString strBest;
00735
00736 if ( m_pFolderSelection != NULL && m_pFolderSelection->m_pVirtual != NULL )
00737 strBest = m_pFolderSelection->m_pVirtual->GetBestView();
00738
00739 for ( POSITION pos = m_pViews.GetHeadPosition() ; pos ; )
00740 {
00741 CLibraryView* pView = (CLibraryView*)m_pViews.GetNext( pos );
00742
00743 if ( pView->CheckAvailable( m_pFolderSelection ) )
00744 {
00745 if ( pFirstView == NULL ) pFirstView = pView;
00746 if ( strBest.CompareNoCase( CString( pView->GetRuntimeClass()->m_lpszClassName ) ) == 0 )
00747 pBestView = pView;
00748 }
00749 }
00750
00751 int nHeaderSize = m_wndHeader.Update();
00752
00753 if ( bBestView && pBestView != NULL )
00754 {
00755 if ( pBestView->IsKindOf( RUNTIME_CLASS(CLibraryCollectionView) ) )
00756 nHeaderSize = 0;
00757 }
00758
00759 if ( nHeaderSize != m_nHeaderSize )
00760 {
00761 m_nHeaderSize = nHeaderSize;
00762 if ( m_nHeaderSize == 0 ) m_wndHeader.ShowWindow( SW_HIDE );
00763 OnSize( 1982, 0, 0 );
00764 }
00765
00766 if ( pFirstView == NULL )
00767 {
00768 ASSERT( FALSE );
00769 m_bUpdating = FALSE;
00770 return TRUE;
00771 }
00772
00773 if ( pBestView != NULL && bBestView )
00774 {
00775 SetView( pBestView, FALSE, FALSE );
00776 }
00777 else if ( m_pView == NULL || m_pView->m_bAvailable == FALSE )
00778 {
00779 SetView( pFirstView, FALSE, FALSE );
00780 }
00781 else
00782 {
00783 SetView( m_pView, FALSE, FALSE );
00784 }
00785
00786 UpdatePanel( TRUE );
00787
00788 m_bUpdating = FALSE;
00789
00790 return TRUE;
00791 }
00792
00793 void CLibraryFrame::UpdatePanel(BOOL bForce)
00794 {
00795 if ( ! bForce && ! m_bViewSelection ) return;
00796 m_bViewSelection = FALSE;
00797
00798 m_pViewSelection = m_pView ? &m_pView->m_pSelection : &m_pViewEmpty;
00799 CLibraryPanel* pFirstPanel = NULL;
00800
00801 for ( POSITION pos = m_pPanels.GetHeadPosition() ; pos ; )
00802 {
00803 CLibraryPanel* pPanel = (CLibraryPanel*)m_pPanels.GetNext( pos );
00804
00805 if ( pPanel->CheckAvailable( m_pFolderSelection, m_pViewSelection )
00806 && pFirstPanel == NULL ) pFirstPanel = pPanel;
00807 }
00808
00809 if ( m_bPanelShow )
00810 {
00811 if ( m_pPanel == NULL || m_pPanel->m_bAvailable == FALSE )
00812 {
00813 SetPanel( pFirstPanel );
00814 }
00815 else
00816 {
00817 SetPanel( m_pPanel );
00818 }
00819 }
00820 }
00821
00822 BOOL CLibraryFrame::Display(CLibraryFolder* pFolder)
00823 {
00824 if ( Settings.Library.ShowVirtual != FALSE ) OnLibraryTreePhysical();
00825 return m_wndTree.SelectFolder( pFolder );
00826 }
00827
00828 BOOL CLibraryFrame::Display(CAlbumFolder* pFolder)
00829 {
00830 if ( Settings.Library.ShowVirtual != TRUE ) OnLibraryTreeVirtual();
00831 return m_wndTree.SelectFolder( pFolder );
00832 }
00833
00834 BOOL CLibraryFrame::Display(CLibraryFile* pFile)
00835 {
00836 if ( Settings.Library.ShowVirtual )
00837 {
00838 if ( CAlbumFolder* pFolder = Library.GetAlbumRoot()->FindFile( pFile ) )
00839 {
00840 Display( pFolder );
00841 }
00842 else
00843 {
00844 Display( pFile->m_pFolder );
00845 }
00846 }
00847 else
00848 {
00849 Settings.Library.FilterURI.Empty();
00850 Display( pFile->m_pFolder );
00851 }
00852
00853 return Select( pFile->m_nIndex );
00854 }
00855
00856 BOOL CLibraryFrame::Select(DWORD nObject)
00857 {
00858 if ( m_pView == NULL ) return FALSE;
00859 return m_pView->Select( nObject );
00860 }
00861
00863
00864
00865 CLibraryTreeItem* CLibraryFrame::GetFolderSelection() const
00866 {
00867 return m_pFolderSelection;
00868 }
00869
00870 CLibraryList* CLibraryFrame::GetViewSelection() const
00871 {
00872 return m_pViewSelection;
00873 }
00874
00875 void CLibraryFrame::OnTreeSelection(NMHDR* pNotify, LRESULT* pResult)
00876 {
00877 if ( ! m_bUpdating ) Update( TRUE, TRUE );
00878 *pResult = 0;
00879 }
00880
00881 void CLibraryFrame::OnViewSelection()
00882 {
00883 if ( m_bUpdating ) return;
00884 m_bViewSelection = TRUE;
00885 PostMessage( WM_TIMER, 1 );
00886 }
00887
00888 void CLibraryFrame::OnTimer(UINT nIDEvent)
00889 {
00890 if ( m_bViewSelection ) UpdatePanel( FALSE );
00891 }
00892
00893 void CLibraryFrame::OnFilterTypes()
00894 {
00895 if ( CSchema* pSchema = m_wndTreeTypes.GetSelected() )
00896 {
00897 Settings.Library.FilterURI = pSchema->m_sURI;
00898 }
00899 else
00900 {
00901 Settings.Library.FilterURI.Empty();
00902 }
00903
00904 Update();
00905 }
00906
00908
00909
00910 void CLibraryFrame::DragObjects(CLibraryList* pList, CImageList* pImage, const CPoint& ptMouse)
00911 {
00912 ASSERT( m_pDragList == NULL );
00913
00914 m_pDragList = pList;
00915 m_pDragImage = pImage;
00916
00917 CPoint ptStart( ptMouse );
00918 ScreenToClient( &ptStart );
00919
00920 CRect rcClient;
00921 GetClientRect( &rcClient );
00922 ClientToScreen( &rcClient );
00923
00924 ClipCursor( &rcClient );
00925 SetCapture();
00926
00927 SetFocus();
00928 UpdateWindow();
00929
00930 OnSetCursor( NULL, 0, 0 );
00931
00932 m_pDragImage->DragEnter( this, ptStart );
00933 }
00934
00935 void CLibraryFrame::CancelDrag()
00936 {
00937 if ( m_pDragList == NULL ) return;
00938
00939 ClipCursor( NULL );
00940 ReleaseCapture();
00941
00942 m_pDragImage->DragLeave( this );
00943 m_pDragImage->EndDrag();
00944 delete m_pDragImage;
00945 m_pDragImage = NULL;
00946
00947 delete m_pDragList;
00948 m_pDragList = NULL;
00949
00950 m_wndTree.DropObjects( NULL, FALSE, CSingleLock( &Library.m_pSection ) );
00951 }
00952
00953 void CLibraryFrame::OnMouseMove(UINT nFlags, CPoint point)
00954 {
00955 if ( m_pDragList == NULL ) return;
00956
00957 m_pDragImage->DragMove( point );
00958
00959 ClientToScreen( &point );
00960 m_wndTree.DropShowTarget( m_pDragList, point );
00961 }
00962
00963 void CLibraryFrame::OnLButtonUp(UINT nFlags, CPoint point)
00964 {
00965 if ( m_pDragList == NULL ) return;
00966
00967 ClipCursor( NULL );
00968 ReleaseCapture();
00969
00970 m_pDragImage->DragLeave( this );
00971 m_pDragImage->EndDrag();
00972 delete m_pDragImage;
00973 m_pDragImage = NULL;
00974
00975 ClientToScreen( &point );
00976
00977 BOOL bCopy = FALSE;
00978
00979 if ( Settings.Library.ShowVirtual )
00980 {
00981 bCopy = ( nFlags & MK_SHIFT ) == 0;
00982 }
00983 else
00984 {
00985 bCopy = ( nFlags & MK_CONTROL ) != 0;
00986 }
00987
00988 {
00989 CSingleLock oLock( &Library.m_pSection, TRUE );
00990 m_wndTree.DropObjects( m_pDragList, bCopy, oLock );
00991 Library.Update();
00992 }
00993
00994 delete m_pDragList;
00995 m_pDragList = NULL;
00996 }
00997
00998 void CLibraryFrame::OnRButtonDown(UINT nFlags, CPoint point)
00999 {
01000 if ( m_pDragList != NULL )
01001 {
01002 CancelDrag();
01003 return;
01004 }
01005
01006 CWnd::OnRButtonDown( nFlags, point );
01007 }
01008
01009 void CLibraryFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
01010 {
01011 if ( nChar == VK_ESCAPE ) CancelDrag();
01012 if ( m_pDragList ) OnSetCursor( NULL, 0, 0 );
01013 CWnd::OnKeyDown( nChar, nRepCnt, nFlags );
01014 }
01015
01016 void CLibraryFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
01017 {
01018 if ( m_pDragList ) OnSetCursor( NULL, 0, 0 );
01019 CWnd::OnKeyUp( nChar, nRepCnt, nFlags );
01020 }
01021
01023
01024
01025 void CLibraryFrame::OnUpdateLibraryTreePhysical(CCmdUI* pCmdUI)
01026 {
01027 pCmdUI->SetCheck( Settings.Library.ShowVirtual == FALSE );
01028 }
01029
01030 void CLibraryFrame::OnLibraryTreePhysical()
01031 {
01032 if ( Settings.Library.ShowVirtual != FALSE )
01033 {
01034 Settings.Library.ShowVirtual = FALSE;
01035 OnSkinChange();
01036 m_wndTreeBottom.Invalidate();
01037 }
01038 }
01039
01040 void CLibraryFrame::OnUpdateLibraryTreeVirtual(CCmdUI* pCmdUI)
01041 {
01042 pCmdUI->SetCheck( Settings.Library.ShowVirtual == TRUE );
01043 }
01044
01045 void CLibraryFrame::OnLibraryTreeVirtual()
01046 {
01047 if ( Settings.Library.ShowVirtual != TRUE )
01048 {
01049 Settings.Library.ShowVirtual = TRUE;
01050 OnSkinChange();
01051 m_wndTreeBottom.Invalidate();
01052 }
01053 }
01054
01055 void CLibraryFrame::OnLibraryRefresh()
01056 {
01057 CWaitCursor pCursor;
01058 Update( TRUE );
01059 }
01060
01061 void CLibraryFrame::OnUpdateLibraryPanel(CCmdUI* pCmdUI)
01062 {
01063 pCmdUI->SetCheck( m_pPanel != NULL );
01064 }
01065
01066 void CLibraryFrame::OnLibraryPanel()
01067 {
01068 if ( m_pPanel )
01069 {
01070 m_bPanelShow = FALSE;
01071 SetPanel( NULL );
01072 }
01073 else
01074 {
01075 m_bPanelShow = TRUE;
01076 Update( TRUE );
01077 }
01078 }
01079
01080 void CLibraryFrame::OnLibrarySearch()
01081 {
01082 CNewSearchDlg dlg( NULL, NULL, TRUE );
01083
01084 if ( dlg.DoModal() == IDOK )
01085 {
01086 RunLocalSearch( dlg.GetSearch() );
01087 }
01088 }
01089
01090 void CLibraryFrame::OnLibrarySearchQuick()
01091 {
01092 CString str;
01093 m_wndSearch.GetWindowText( str );
01094
01095 if ( str.GetLength() > 0 )
01096 {
01097 CQuerySearch* pSearch = new CQuerySearch();
01098 pSearch->m_sSearch = str;
01099 RunLocalSearch( pSearch );
01100 m_wndSearch.SetWindowText( _T("") );
01101 }
01102 else
01103 {
01104 OnLibrarySearch();
01105 }
01106 }
01107
01108 void CLibraryFrame::OnToolbarReturn()
01109 {
01110 if ( GetFocus() == &m_wndSearch )
01111 {
01112 if ( m_wndSearch.GetWindowTextLength() > 0 )
01113 OnLibrarySearchQuick();
01114 else if ( m_pView != NULL )
01115 m_pView->SetFocus();
01116 }
01117 }
01118
01119 void CLibraryFrame::OnToolbarEscape()
01120 {
01121 if ( GetFocus() == &m_wndSearch )
01122 {
01123 m_wndSearch.SetWindowText( _T("") );
01124 if ( m_pView != NULL ) m_pView->SetFocus();
01125 }
01126 }
01127
01128 void CLibraryFrame::RunLocalSearch(CQuerySearch* pSearch)
01129 {
01130 CWaitCursor pCursor;
01131
01132 pSearch->BuildWordList();
01133
01134 CAlbumFolder* pRoot = Library.GetAlbumRoot();
01135 CAlbumFolder* pFolder = pRoot->GetFolderByURI( CSchema::uriSearchFolder );
01136
01137 if ( pFolder == NULL )
01138 {
01139 pFolder = pRoot->AddFolder( CSchema::uriSearchFolder, _T("Search Results") );
01140 if ( pFolder->m_pSchema != NULL )
01141 {
01142 int nColon = pFolder->m_pSchema->m_sTitle.Find( ':' );
01143 if ( nColon >= 0 ) pFolder->m_sName = pFolder->m_pSchema->m_sTitle.Mid( nColon + 1 );
01144 }
01145 }
01146 else
01147 pFolder->Clear();
01148
01149 if ( pFolder->m_pSchema != NULL )
01150 {
01151 CString strDate, strTime;
01152 SYSTEMTIME pTime;
01153
01154 GetLocalTime( &pTime );
01155 GetDateFormat( LOCALE_USER_DEFAULT, 0, &pTime, _T("yyyy-MM-dd"), strDate.GetBuffer( 64 ), 64 );
01156 GetTimeFormat( LOCALE_USER_DEFAULT, 0, &pTime, _T("hh:mm tt"), strTime.GetBuffer( 64 ), 64 );
01157 strDate.ReleaseBuffer(); strTime.ReleaseBuffer();
01158
01159 CXMLElement* pOuter = pFolder->m_pSchema->Instantiate();
01160 CXMLElement* pInner = pOuter->AddElement( _T("searchFolder") );
01161 pInner->AddAttribute( _T("title"), pFolder->m_sName );
01162 pInner->AddAttribute( _T("content"), pSearch->m_sSearch );
01163 pInner->AddAttribute( _T("date"), strDate );
01164 pInner->AddAttribute( _T("time"), strTime );
01165 pFolder->SetMetadata( pOuter );
01166 delete pOuter;
01167 }
01168
01169 {
01170 CQuickLock oLock( Library.m_pSection );
01171
01172 CPtrList* pFiles = Library.Search( pSearch, 0, TRUE );
01173
01174 if ( pFiles != NULL )
01175 {
01176 for ( POSITION pos = pFiles->GetHeadPosition() ; pos ; )
01177 {
01178 CLibraryFile* pFile = (CLibraryFile*)pFiles->GetNext( pos );
01179
01180 if ( Settings.Search.SchemaTypes && pSearch->m_pSchema != NULL )
01181 {
01182 if ( pSearch->m_pSchema->FilterType( pFile->m_sName, TRUE ) == FALSE )
01183 pFile = NULL;
01184 }
01185
01186 if ( pFile != NULL && pFile->IsAvailable() ) pFolder->AddFile( pFile );
01187 }
01188
01189 delete pFiles;
01190 }
01191 }
01192
01193 delete pSearch;
01194
01195 Update();
01196 Display( pFolder );
01197 }
01198
01199 void CLibraryFrame::OnSetFocus(CWnd* pOldWnd)
01200 {
01201 CWnd::OnSetFocus( pOldWnd );
01202 if ( m_pView != NULL && IsWindow( m_pView->m_hWnd ) && m_pView->IsWindowVisible() )
01203 m_pView->SetFocus();
01204 }