⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrllibrarydetailview.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// CtrlLibraryDetailView.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 "SharedFolder.h"
#include "SharedFile.h"
#include "AlbumFolder.h"
#include "LiveList.h"
#include "XML.h"
#include "SHA.h"
#include "Schema.h"
#include "SchemaCache.h"

#include "CoolInterface.h"
#include "ShellIcons.h"
#include "CoolMenu.h"
#include "Skin.h"
#include "CtrlLibraryFrame.h"
#include "CtrlLibraryDetailView.h"
#include "DlgHitColumns.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CLibraryDetailView, CLibraryFileView)
IMPLEMENT_DYNCREATE(CLibraryListView, CLibraryDetailView)
IMPLEMENT_DYNCREATE(CLibraryIconView, CLibraryDetailView)

BEGIN_MESSAGE_MAP(CLibraryDetailView, CLibraryFileView)
	//{{AFX_MSG_MAP(CLibraryDetailView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_CONTEXTMENU()
	ON_WM_MEASUREITEM()
	ON_WM_DRAWITEM()
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_RENAME, OnUpdateLibraryRename)
	ON_COMMAND(ID_LIBRARY_RENAME, OnLibraryRename)
	ON_COMMAND(ID_LIBRARY_COLUMNS, OnLibraryColumns)
	ON_UPDATE_COMMAND_UI(ID_LIBRARY_COLUMNS, OnUpdateLibraryColumns)
	//}}AFX_MSG_MAP
	ON_NOTIFY_REFLECT(LVN_ODCACHEHINT, OnCacheHint)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFOW, OnGetDispInfoW)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFOA, OnGetDispInfoA)
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
	ON_NOTIFY_REFLECT(LVN_BEGINLABELEDITW, OnBeginLabelEdit)
	ON_NOTIFY_REFLECT(LVN_BEGINLABELEDITA, OnBeginLabelEdit)
	ON_NOTIFY_REFLECT(LVN_ENDLABELEDITW, OnEndLabelEditW)
	ON_NOTIFY_REFLECT(LVN_ENDLABELEDITA, OnEndLabelEditA)
	ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
	ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemChanged)
	ON_NOTIFY_REFLECT(LVN_ODSTATECHANGED, OnItemRangeChanged)
	ON_NOTIFY_REFLECT(LVN_ODFINDITEMW, OnFindItemW)
	ON_NOTIFY_REFLECT(LVN_ODFINDITEMA, OnFindItemA)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblClk)
	ON_UPDATE_COMMAND_UI_RANGE(1000, 1100, OnUpdateBlocker)
END_MESSAGE_MAP()

#define GET_LIST()		CListCtrl* pList = (CListCtrl*)this
#define DETAIL_COLUMNS	7


/////////////////////////////////////////////////////////////////////////////
// CLibraryDetailView construction

CLibraryDetailView::CLibraryDetailView(UINT nCommandID)
{
	switch ( m_nCommandID = nCommandID )
	{
	case ID_LIBRARY_VIEW_DETAIL:
		m_nStyle = LVS_REPORT;
		break;
	case ID_LIBRARY_VIEW_LIST:
		m_nStyle = LVS_LIST;
		break;
	case ID_LIBRARY_VIEW_ICON:
		m_nStyle = LVS_ICON;
		break;
	}
	
	m_pCoolMenu	= NULL;
	m_pSchema	= NULL;
}

CLibraryDetailView::~CLibraryDetailView()
{
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryDetailView create and destroy

BOOL CLibraryDetailView::Create(CWnd* pParentWnd) 
{
	CRect rect( 0, 0, 0, 0 );
	SelClear( FALSE );
	DWORD nStyle = m_nStyle;
	return CWnd::Create( WC_LISTVIEW, _T("CLibraryDetailView"),
		WS_CHILD|LVS_ICON|LVS_AUTOARRANGE|LVS_SHOWSELALWAYS|nStyle|
		LVS_SHAREIMAGELISTS|LVS_EDITLABELS|LVS_OWNERDATA, rect, pParentWnd, IDC_LIBRARY_VIEW );
}

int CLibraryDetailView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CLibraryFileView::OnCreate( lpCreateStruct ) == -1 ) return -1;
	
	SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
		LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP,
		LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP );
	
	GET_LIST();
	
	pList->InsertColumn( 0, _T("File"), LVCFMT_LEFT, 200, -1 );
	pList->SetCallbackMask( LVIS_SELECTED );
	
	if ( m_nStyle == LVS_REPORT )
	{
		pList->InsertColumn( 1, _T("Type"), LVCFMT_CENTER, 40, 0 );
		pList->InsertColumn( 2, _T("Size"), LVCFMT_CENTER, 60, 1 );
		pList->InsertColumn( 3, _T("Folder"), LVCFMT_LEFT, 0, 2 );
		pList->InsertColumn( 4, _T("Hits"), LVCFMT_CENTER, 70, 3 );
		pList->InsertColumn( 5, _T("Uploads"), LVCFMT_CENTER, 70, 4 );
		pList->InsertColumn( 6, _T("Modified"), LVCFMT_CENTER, 0, 5 );
		pList->SetImageList( ShellIcons.GetObject( 16 ), LVSIL_SMALL );

		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetWindow( GW_CHILD );
		if ( pHeader ) Skin.Translate( _T("CLibraryWnd"), pHeader );
	}
	else if ( m_nStyle != LVS_ICON )
	{
		pList->SetImageList( ShellIcons.GetObject( 16 ), LVSIL_SMALL );
	}
	else
	{
		pList->SetImageList( ShellIcons.GetObject( 32 ), LVSIL_NORMAL );
	}
	
	pList->SetCallbackMask( LVIS_SELECTED );
	
	m_pList	= NULL;
	m_nList	= m_nBuffer = 0;
	
	CString strSchemaURI = Settings.Library.FilterURI.GetLength() ?
		Settings.Library.FilterURI : Settings.Library.SchemaURI;
	
	if ( CSchema* pSchema = SchemaCache.Get( strSchemaURI ) )
	{
		CPtrList pColumns;
		CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
		SetViewSchema( pSchema, &pColumns, FALSE, FALSE );
	}
	else
	{
		SetViewSchema( NULL, NULL, FALSE, FALSE );
	}
	
	m_bCreateDragImage	= FALSE;
	
	return 0;
}

void CLibraryDetailView::OnDestroy() 
{
	if ( m_pList )
	{
		for ( DWORD nItem = 0 ; nItem < m_nBuffer ; nItem++ )
		{
			if ( m_pList[ nItem ].pText ) delete m_pList[ nItem ].pText;
		}

		delete [] m_pList;
	}
	
	m_pList = NULL;
	m_nList = m_nBuffer = 0;
	
	if ( m_nStyle == LVS_REPORT )
	{
		if ( m_pSchema != NULL )
		{
			Settings.SaveList( _T("CLibraryDetailView.") + m_pSchema->m_sSingular, (CListCtrl*)this );
		}
		else
		{
			Settings.SaveList( _T("CLibraryDetailView"), (CListCtrl*)this );
		}
	}

	CLibraryFileView::OnDestroy();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryDetailView schema setup

void CLibraryDetailView::SetViewSchema(CSchema* pSchema, CPtrList* pColumns, BOOL bSave, BOOL bUpdate)
{
	GET_LIST();
	
	pList->DeleteAllItems();
	
	if ( m_nStyle != LVS_REPORT )
	{
		if ( bUpdate ) PostUpdate();
		return;
	}

	if ( bSave )
	{
		if ( m_pSchema )
		{
			Settings.SaveList( _T("CLibraryDetailView.") + m_pSchema->m_sSingular, pList );
		}
		else
		{
			Settings.SaveList( _T("CLibraryDetailView"), pList );
		}
	}
	
	m_pColumns.RemoveAll();
	if ( m_pSchema = pSchema ) m_pColumns.AddTail( pColumns );
	
	int nColumn = DETAIL_COLUMNS;
	while ( pList->DeleteColumn( nColumn ) );
	
	for ( POSITION pos = m_pColumns.GetHeadPosition() ; pos ; nColumn++ )
	{
		CSchemaMember* pMember = (CSchemaMember*)m_pColumns.GetNext( pos );
		pList->InsertColumn( nColumn, pMember->m_sTitle, pMember->m_nColumnAlign, pMember->m_nColumnWidth, nColumn - 1 );
	}

	if ( m_pSchema )
		Settings.LoadList( _T("CLibraryDetailView.") + m_pSchema->m_sSingular, pList, 1 );
	else
		Settings.LoadList( _T("CLibraryDetailView"), pList, 1 );

	if ( bUpdate ) PostUpdate();
}

/////////////////////////////////////////////////////////////////////////////
// CLibraryDetailView update

void CLibraryDetailView::Update()
{
	GET_LIST();
	
	CSchema* pSchema	= SchemaCache.Get( Settings.Library.FilterURI );
	DWORD nCookie		= GetFolderCookie();
	
	if ( Settings.Library.ShowVirtual ) pSchema = NULL;
	
	if ( m_nStyle == LVS_REPORT )
	{
		CLibraryTreeItem* pTree = GetFolderSelection();
		
		if ( pTree != NULL && pTree->m_pVirtual != NULL && pTree->m_pSelNext == NULL &&
			 pTree->m_pVirtual->m_pSchema != NULL )
		{
			CString strURI = pTree->m_pVirtual->m_pSchema->GetContainedURI( CSchema::stFile );
			
			if ( strURI.GetLength() && ( m_pSchema == NULL || m_pSchema->m_sURI != strURI ) )
			{
				if ( CSchema* pSchema = SchemaCache.Get( strURI ) )
				{
					CPtrList pColumns;
					CSchemaColumnsDlg::LoadColumns( pSchema, &pColumns );
					SetViewSchema( pSchema, &pColumns, TRUE, FALSE );
				}
			}
		}
	}

	LDVITEM* pItem = m_pList + m_nList - 1;

	for ( DWORD nCount = m_nList ; nCount ; nCount--, pItem-- )
	{
		CLibraryFile* pFile = Library.LookupFile( pItem->nIndex );
		
		if ( pFile && pFile->m_nSelectCookie == nCookie && pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			pFile->m_nListCookie = nCookie;
		}
		else
		{
			SelRemove( pItem->nIndex );
			CStringArray* pSaved = pItem->pText;
			CopyMemory( pItem, pItem + 1, sizeof(LDVITEM) * ( m_nList - nCount ) );
			pItem[ m_nList - nCount ].pText = pSaved;
			m_nList--;
		}
	}

	for ( POSITION pos = LibraryMaps.GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = LibraryMaps.GetNextFile( pos );

		if ( pFile->m_nSelectCookie == nCookie &&
 			 pFile->m_nListCookie != nCookie &&
			 pFile->IsAvailable() &&
			 ( ! pSchema || pSchema->Equals( pFile->m_pSchema ) ||
			 ( ! pFile->m_pMetadata && pSchema->FilterType( pFile->m_sName ) ) ) )
		{
			if ( m_nList == m_nBuffer )	// MUST EQUAL
			{
				m_nBuffer += 64;
				LDVITEM* pList = new LDVITEM[ m_nBuffer ];
				if ( m_nList ) CopyMemory( pList, m_pList, m_nList * sizeof(LDVITEM) );
				if ( m_pList ) delete [] m_pList;
				ZeroMemory( pList + m_nList, ( m_nBuffer - m_nList ) * sizeof(LDVITEM) );
				m_pList = pList;
			}
			
			m_pList[ m_nList ].nIndex		= pFile->m_nIndex;
			m_pList[ m_nList ].nState		&= ~LDVI_SELECTED;
			m_nList++;
			
			pFile->m_nListCookie = nCookie;
		}
	}
	
	m_nListCookie++;
	
	SortItems();
}

BOOL CLibraryDetailView::Select(DWORD nObject)
{
	GET_LIST();
	
	for ( int nDeselect = -1 ; ; )
	{
		nDeselect = pList->GetNextItem( nDeselect, LVNI_SELECTED );
		if ( nDeselect < 0 ) break;
		pList->SetItemState( nDeselect, 0, LVIS_SELECTED );
	}
	
	LDVITEM* pItem = m_pList;
	
	for ( DWORD nCount = 0 ; nCount < m_nList ; nCount++, pItem++ )
	{
		if ( pItem->nIndex == nObject )
		{
			LV_ITEM pItem;
			
			pItem.mask = LVIF_STATE; pItem.state = 0xFFFFFFFF; pItem.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
			SendMessage( LVM_SETITEMSTATE, nCount, (LPARAM)&pItem );
			PostMessage( LVM_ENSUREVISIBLE, nCount, FALSE );
			
			return TRUE;
		}
	}
	
	return FALSE;
}

void CLibraryDetailView::CacheItem(int nItem)
{
	CLibraryFile* pFile = Library.LookupFile( m_pList[ nItem ].nIndex );
	if ( ! pFile ) return;
	
	LDVITEM* pItem = &m_pList[ nItem ];
	pItem->nCookie = m_nListCookie;
	
	if ( pItem->pText == NULL ) pItem->pText = new CStringArray();
	
	CStringArray* pText = pItem->pText;
	pText->SetSize( m_nStyle == LVS_REPORT ? DETAIL_COLUMNS + m_pColumns.GetCount() : 1 );
	
	CString strName( pFile->m_sName );
	int nDot = strName.ReverseFind( '.' );
	if ( nDot >= 0 ) strName.SetAt( nDot, 0 );
	pText->SetAt( 0, strName );
	
	if ( m_nStyle == LVS_ICON )
	{
		pItem->nIcon = ShellIcons.Get( pFile->m_sName, 32 );
	}
	else
	{
		if ( pFile->m_nIcon16 >= 0 )
			pItem->nIcon = pFile->m_nIcon16;
		else
			pItem->nIcon = pFile->m_nIcon16 = ShellIcons.Get( pFile->m_sName, 16 );
	}
	
	pItem->nState &= LDVI_SELECTED;
	if ( ! pFile->IsShared() ) pItem->nState |= LDVI_PRIVATE;
	if ( ! pFile->m_bSHA1 ) pItem->nState |= LDVI_UNSCANNED;
	if ( pFile->m_bVerify == TS_FALSE ) pItem->nState |= LDVI_UNSAFE;
	
	if ( m_nStyle != LVS_REPORT ) return;
	
	if ( LPCTSTR pszType = _tcsrchr( pFile->m_sName, '.' ) )
		pText->SetAt( 1, pszType + 1 );
	else
		pText->SetAt( 1, _T("") );
	
	pText->SetAt( 2, Settings.SmartVolume( pFile->GetSize(), FALSE ) );
	if ( pFile->m_pFolder != NULL ) pText->SetAt( 3, pFile->m_pFolder->m_sPath );
	
	CString str;
	str.Format( _T("%lu (%lu)"), pFile->m_nHitsToday, pFile->m_nHitsTotal );
	pText->SetAt( 4, str );
	str.Format( _T("%lu (%lu)"), pFile->m_nUploadsToday, pFile->m_nUploadsTotal );
	pText->SetAt( 5, str );
	
	TCHAR szModified[ 64 ];
	SYSTEMTIME pTime;
	
	FileTimeToSystemTime( &pFile->m_pTime, &pTime );
	SystemTimeToTzSpecificLocalTime( NULL, &pTime, &pTime );
	
	GetDateFormat( LOCALE_USER_DEFAULT, 0, &pTime, _T("yyyy-MM-dd"), szModified, 64 );
	_tcscat( szModified, _T(" ") );
	GetTimeFormat( LOCALE_USER_DEFAULT, 0, &pTime, _T("hh:mm tt"), szModified + _tcslen( szModified ), 64 - _tcslen( szModified ) );
	
	pText->SetAt( 6, szModified );
	
	if ( m_pSchema == NULL ) return;
	
	int nColumn = DETAIL_COLUMNS;
	
	BOOL bSource =	pFile->m_pMetadata && m_pSchema->Equals( pFile->m_pSchema ) &&
					m_pSchema->m_sSingular.CompareNoCase( pFile->m_pMetadata->GetName() ) == 0;
	
	for ( POSITION pos = m_pColumns.GetHeadPosition() ; pos ; nColumn++ )
	{
		CSchemaMember* pMember = (CSchemaMember*)m_pColumns.GetNext( pos );
		
		if ( pMember->m_sName.CompareNoCase( _T("SHA1") ) == 0 )
		{
			if ( pFile->m_bSHA1 )
			{
				pText->SetAt( nColumn, CSHA::HashToString( &pFile->m_pSHA1 ) );
			}
			else pText->SetAt( nColumn, _T("") );
		}
		else if ( bSource )
		{
			pText->SetAt( nColumn, pMember->GetValueFrom( pFile->m_pMetadata, NULL, TRUE ) );
		}
		else
		{
			pText->SetAt( nColumn, _T("") );
		}
	}
}

void CLibraryDetailView::OnCacheHint(NMLVCACHEHINT* pNotify, LRESULT* pResult)
{
	if ( ! Library.Lock( 100 ) ) return;
	
	for ( int nItem = pNotify->iFrom ; nItem <= pNotify->iTo ; nItem++ )
	{
		CacheItem( nItem );
	}
	
	Library.Unlock();
}

void CLibraryDetailView::OnGetDispInfoW(NMLVDISPINFO* pNotify, LRESULT* pResult)
{
	*pResult = 0;
	
	LDVITEM* pItem = &m_pList[ pNotify->item.iItem ];
	
	if ( pNotify->item.mask & LVIF_STATE )
	{
		pNotify->item.state &= ~LVIS_SELECTED;
		if ( pItem->nState & LDVI_SELECTED ) pNotify->item.state |= LVIS_SELECTED;
	}
	
	if ( pItem->nCookie != m_nListCookie )
	{
		if ( ! Library.Lock( 100 ) ) return;
		CacheItem( pNotify->item.iItem );
		Library.Unlock();
		if ( pItem->nCookie != m_nListCookie ) return;
	}
	
	if ( pNotify->item.mask & LVIF_TEXT )
	{
		if ( pNotify->item.iSubItem < pItem->pText->GetSize() )
		{
			wcsncpy( (LPWSTR)pNotify->item.pszText, pItem->pText->GetAt( pNotify->item.iSubItem ), pNotify->item.cchTextMax );
		}
	}
	
	if ( pNotify->item.mask & LVIF_IMAGE )
	{
		pNotify->item.iImage = pItem->nIcon;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -