📄 ctrllibrarytreeview.cpp
字号:
//
// CtrlLibraryTreeView.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Library.h"
#include "LibraryFolders.h"
#include "SharedFile.h"
#include "SharedFolder.h"
#include "AlbumFolder.h"
#include "FileExecutor.h"
#include "CtrlLibraryTreeView.h"
#include "CtrlLibraryFrame.h"
#include "CtrlCoolBar.h"
#include "Schema.h"
#include "Skin.h"
#include "DlgFolderScan.h"
#include "DlgFolderProperties.h"
#include "DlgFilePropertiesSheet.h"
#include "DlgFileCopy.h"
#include "DlgCollectionExport.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(CLibraryTreeView, CLibraryTreeCtrl)
BEGIN_MESSAGE_MAP(CLibraryTreeView, CLibraryTreeCtrl)
//{{AFX_MSG_MAP(CLibraryTreeView)
ON_WM_CONTEXTMENU()
ON_WM_LBUTTONDBLCLK()
ON_UPDATE_COMMAND_UI(ID_LIBRARY_PARENT, OnUpdateLibraryParent)
ON_COMMAND(ID_LIBRARY_PARENT, OnLibraryParent)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_EXPLORE, OnUpdateLibraryExplore)
ON_COMMAND(ID_LIBRARY_EXPLORE, OnLibraryExplore)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_SCAN, OnUpdateLibraryScan)
ON_COMMAND(ID_LIBRARY_SCAN, OnLibraryScan)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_SHARED_FOLDER, OnUpdateLibraryShared)
ON_COMMAND(ID_LIBRARY_SHARED_FOLDER, OnLibraryShared)
ON_COMMAND(ID_LIBRARY_ADD, OnLibraryAdd)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_REMOVE, OnUpdateLibraryRemove)
ON_COMMAND(ID_LIBRARY_REMOVE, OnLibraryRemove)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_PROPERTIES, OnUpdateLibraryFolderProperties)
ON_COMMAND(ID_LIBRARY_FOLDER_PROPERTIES, OnLibraryFolderProperties)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_NEW, OnUpdateLibraryFolderNew)
ON_COMMAND(ID_LIBRARY_FOLDER_NEW, OnLibraryFolderNew)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_DELETE, OnUpdateLibraryFolderDelete)
ON_COMMAND(ID_LIBRARY_FOLDER_DELETE, OnLibraryFolderDelete)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_METADATA, OnUpdateLibraryFolderMetadata)
ON_COMMAND(ID_LIBRARY_FOLDER_METADATA, OnLibraryFolderMetadata)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_ENQUEUE, OnUpdateLibraryFolderEnqueue)
ON_COMMAND(ID_LIBRARY_FOLDER_ENQUEUE, OnLibraryFolderEnqueue)
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(ID_LIBRARY_FOLDER_FILE_PROPERTIES, OnUpdateLibraryFolderFileProperties)
ON_COMMAND(ID_LIBRARY_FOLDER_FILE_PROPERTIES, OnLibraryFolderFileProperties)
ON_UPDATE_COMMAND_UI(ID_LIBRARY_REBUILD, OnUpdateLibraryRebuild)
ON_COMMAND(ID_LIBRARY_REBUILD, OnLibraryRebuild)
//}}AFX_MSG_MAP
ON_UPDATE_COMMAND_UI(ID_LIBRARY_EXPORT_COLLECTION, OnUpdateLibraryExportCollection)
ON_COMMAND(ID_LIBRARY_EXPORT_COLLECTION, OnLibraryExportCollection)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView construction
CLibraryTreeView::CLibraryTreeView()
{
m_bVirtual = -1;
}
CLibraryTreeView::~CLibraryTreeView()
{
}
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView root update
void CLibraryTreeView::SetVirtual(BOOL bVirtual)
{
if ( bVirtual == m_bVirtual ) return;
m_bVirtual = bVirtual;
SetToolTip( m_bVirtual ? (CCoolTipCtrl*)&m_wndAlbumTip : (CCoolTipCtrl*)&m_wndFolderTip );
Clear();
}
void CLibraryTreeView::Update(DWORD nSelectCookie)
{
if ( m_bVirtual )
{
UpdateVirtual( nSelectCookie );
}
else
{
UpdatePhysical( nSelectCookie );
}
}
void CLibraryTreeView::PostUpdate()
{
GetOwner()->PostMessage( WM_COMMAND, ID_LIBRARY_REFRESH );
}
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView update physical
void CLibraryTreeView::UpdatePhysical(DWORD nSelectCookie)
{
DWORD nCleanCookie = m_nCleanCookie++;
BOOL bChanged = FALSE;
for ( POSITION pos = LibraryFolders.GetFolderIterator() ; pos ; )
{
CLibraryFolder* pFolder = LibraryFolders.GetNextFolder( pos );
CLibraryTreeItem** pChild = m_pRoot->m_pList;
for ( int nChild = m_pRoot->m_nCount ; nChild ; nChild--, pChild++ )
{
CLibraryFolder* pOld = (*pChild)->m_pPhysical;
if ( pOld == pFolder )
{
bChanged |= Update( pFolder, *pChild, m_pRoot, TRUE, TRUE,
nCleanCookie, nSelectCookie, FALSE );
break;
}
}
if ( nChild == 0 )
{
bChanged |= Update( pFolder, NULL, m_pRoot, TRUE, TRUE,
nCleanCookie, nSelectCookie, FALSE );
}
}
bChanged |= CleanItems( m_pRoot, nCleanCookie, TRUE );
if ( bChanged )
{
UpdateScroll();
Invalidate();
NotifySelection();
}
}
BOOL CLibraryTreeView::Update(CLibraryFolder* pFolder, CLibraryTreeItem* pItem, CLibraryTreeItem* pParent, BOOL bVisible, BOOL bShared, DWORD nCleanCookie, DWORD nSelectCookie, BOOL bRecurse)
{
BOOL bChanged = FALSE;
if ( pFolder->m_bShared == TS_TRUE ) bShared = TRUE;
else if ( pFolder->m_bShared == TS_FALSE ) bShared = FALSE;
if ( pItem == NULL )
{
pItem = pParent->Add( pFolder->m_sName );
if ( bVisible ) m_nTotal++;
pItem->m_bExpanded = pFolder->m_bExpanded;
pItem->m_pPhysical = pFolder;
pItem->m_sText = pFolder->m_sName;
pItem->m_bShared = bShared;
pItem->m_bBold = ( pFolder->m_sPath.CompareNoCase( Settings.Downloads.CompletePath ) == 0 );
if ( pFolder->m_pParent == NULL )
{
if ( pFolder->m_sPath.Find( _T(":\\") ) == 1 || pFolder->m_sPath.GetLength() == 2 )
{
CString strDrive;
strDrive.Format( _T(" (%c:)"), pFolder->m_sPath[0] );
pItem->m_sText += strDrive;
}
else
{
pItem->m_sText += _T(" (Net)");
}
}
bChanged = bVisible;
}
else
{
if ( pFolder->m_pParent == NULL )
{
BOOL bBold = ( pFolder->m_sPath.CompareNoCase( Settings.Downloads.CompletePath ) == 0 );
if ( bBold != pItem->m_bBold )
{
pItem->m_bBold = bBold;
bChanged |= bVisible;
}
}
if ( pItem->m_bShared != bShared )
{
pItem->m_bShared = bShared;
bChanged |= bVisible;
}
}
pItem->m_nCleanCookie = nCleanCookie;
bVisible = bVisible && pItem->m_bExpanded;
if ( nSelectCookie )
{
if ( bRecurse || pItem->m_bSelected )
{
CLibraryFile* pFile;
CString strTemp;
for ( POSITION pos = pFolder->m_pFiles.GetStartPosition() ; pos ; )
{
pFolder->m_pFiles.GetNextAssoc( pos, strTemp, (CObject*&)pFile );
pFile->m_nSelectCookie = nSelectCookie;
}
pFolder->m_nSelectCookie = nSelectCookie;
bRecurse |= ( ! pItem->m_bExpanded );
}
}
nCleanCookie = m_nCleanCookie++;
for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
{
CLibraryFolder* pSub = pFolder->GetNextFolder( pos );
CLibraryTreeItem** pChild = pItem->m_pList;
for ( int nChild = pItem->m_nCount ; nChild ; nChild--, pChild++ )
{
CLibraryFolder* pOld = (*pChild)->m_pPhysical;
if ( pOld == pSub )
{
bChanged |= Update( pSub, *pChild, pItem, bVisible, bShared,
nCleanCookie, nSelectCookie, bRecurse );
break;
}
}
if ( nChild == 0 )
{
bChanged |= Update( pSub, NULL, pItem, bVisible, bShared,
nCleanCookie, nSelectCookie, bRecurse );
}
}
bChanged |= CleanItems( pItem, nCleanCookie, bVisible );
pItem->m_nCookie = pFolder->m_nUpdateCookie;
return bChanged;
}
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView update virtual
void CLibraryTreeView::UpdateVirtual(DWORD nSelectCookie)
{
BOOL bChanged = Update( Library.GetAlbumRoot(), m_pRoot, NULL, TRUE, 0, nSelectCookie );
if ( bChanged )
{
UpdateScroll();
Invalidate();
NotifySelection();
}
}
BOOL CLibraryTreeView::Update(CAlbumFolder* pFolder, CLibraryTreeItem* pItem, CLibraryTreeItem* pParent, BOOL bVisible, DWORD nCleanCookie, DWORD nSelectCookie)
{
BOOL bChanged = FALSE;
if ( pItem != NULL && pParent != NULL && pItem->m_sText != pFolder->m_sName )
{
// CleanCookie is not updated so it will be dropped later
pItem = NULL;
}
if ( pItem == NULL )
{
pItem = pParent->Add( pFolder->m_sName );
if ( bVisible ) m_nTotal++;
pItem->m_bExpanded = pFolder->m_bExpanded;
pItem->m_pVirtual = pFolder;
pItem->m_sText = pFolder->m_sName;
pItem->m_nIcon16 = pFolder->m_pSchema ? pFolder->m_pSchema->m_nIcon16 : -1;
pItem->m_bBold = pItem->m_bCollection = pFolder->m_bCollSHA1;
bChanged = bVisible;
}
else
{
if ( pFolder->m_pSchema != NULL && pItem->m_nIcon16 != pFolder->m_pSchema->m_nIcon16 )
{
pItem->m_nIcon16 = pFolder->m_pSchema->m_nIcon16;
bChanged = bVisible;
}
if ( pItem->m_bCollection != pFolder->m_bCollSHA1 )
{
pItem->m_bBold = pItem->m_bCollection = pFolder->m_bCollSHA1;
bChanged = bVisible;
}
}
pItem->m_nCleanCookie = nCleanCookie;
bVisible = bVisible && pItem->m_bExpanded;
if ( nSelectCookie && pItem->m_bSelected )
{
for ( POSITION pos = pFolder->m_pFiles.GetHeadPosition() ; pos ; )
{
CLibraryFile* pFile = (CLibraryFile*)pFolder->m_pFiles.GetNext( pos );
pFile->m_nSelectCookie = nSelectCookie;
}
pFolder->m_nSelectCookie = nSelectCookie;
}
nCleanCookie = m_nCleanCookie++;
for ( POSITION pos = pFolder->GetFolderIterator() ; pos ; )
{
CAlbumFolder* pSub = pFolder->GetNextFolder( pos );
CLibraryTreeItem** pChild = pItem->m_pList;
for ( int nChild = pItem->m_nCount ; nChild ; nChild--, pChild++ )
{
CAlbumFolder* pOld = (*pChild)->m_pVirtual;
if ( pOld == pSub )
{
bChanged |= Update( pSub, *pChild, pItem, bVisible,
nCleanCookie, nSelectCookie );
break;
}
}
if ( nChild == 0 )
{
bChanged |= Update( pSub, NULL, pItem, bVisible,
nCleanCookie, nSelectCookie );
}
}
bChanged |= CleanItems( pItem, nCleanCookie, bVisible );
pItem->m_nCookie = pFolder->m_nUpdateCookie;
return bChanged;
}
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView folder selection
BOOL CLibraryTreeView::SelectFolder(LPVOID pSearch)
{
CLibraryTreeItem* pItem = GetFolderItem( pSearch );
if ( pItem == NULL ) return FALSE;
if ( m_nSelected == 1 && pItem->m_bSelected )
{
Highlight( pItem );
return TRUE;
}
DeselectAll( pItem, NULL, FALSE );
Select( pItem, TS_TRUE, FALSE );
Highlight( pItem );
NotifySelection();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CLibraryTreeView drag drop
BOOL CLibraryTreeView::DropShowTarget(CLibraryList* pList, const CPoint& point)
{
CPoint ptLocal( point );
ScreenToClient( &ptLocal );
CRect rcClient, rcItem;
GetClientRect( &rcClient );
CLibraryTreeItem* pHit = HitTest( ptLocal, &rcItem );
if ( pHit && ! rcItem.PtInRect( ptLocal ) ) pHit = NULL;
if ( m_pDropItem != pHit )
{
m_pDropItem = pHit;
CImageList::DragShowNolock( FALSE );
RedrawWindow();
CImageList::DragShowNolock( TRUE );
}
if ( rcClient.PtInRect( ptLocal ) )
{
if ( ptLocal.y < rcClient.top + 8 )
{
CImageList::DragShowNolock( FALSE );
ScrollBy( -16 );
UpdateWindow();
CImageList::DragShowNolock( TRUE );
}
else if ( ptLocal.y >= rcClient.bottom - 8 )
{
CImageList::DragShowNolock( FALSE );
ScrollBy( 16 );
UpdateWindow();
CImageList::DragShowNolock( TRUE );
}
}
return ( m_pDropItem != NULL );
}
BOOL CLibraryTreeView::DropObjects(CLibraryList* pList, BOOL bCopy)
{
if ( m_pDropItem == NULL ) return FALSE;
CWaitCursor pCursor;
if ( pList == NULL )
{
}
else if ( m_pDropItem->m_pPhysical != NULL )
{
CFileCopyDlg dlg( NULL, ! bCopy );
for ( POSITION pos = pList->GetHeadPosition() ; pos ; )
{
DWORD nObject = pList->GetNext( pos );
if ( CLibraryFile* pFile = Library.LookupFile( nObject ) )
{
if ( pFile->m_pFolder != m_pDropItem->m_pPhysical )
dlg.AddFile( pFile );
}
}
dlg.m_sTarget = m_pDropItem->m_pPhysical->m_sPath;
m_pDropItem = NULL;
Library.Unlock();
dlg.DoModal();
Library.Lock();
}
else if ( m_pDropItem->m_pVirtual != NULL )
{
for ( POSITION pos = pList->GetHeadPosition() ; pos ; )
{
DWORD nObject = pList->GetNext( pos );
if ( CLibraryFile* pFile = Library.LookupFile( nObject ) )
{
m_pDropItem->m_pVirtual->AddFile( pFile );
for ( CLibraryTreeItem* pItem = m_pSelFirst ; pItem && ! bCopy ;
pItem = pItem->m_pSelNext )
{
if ( pItem->m_pVirtual != NULL && pItem != m_pDropItem )
{
if ( LibraryFolders.CheckAlbum( pItem->m_pVirtual ) )
{
pItem->m_pVirtual->RemoveFile( pFile );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -