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

📄 albumfolder.cpp

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

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

IMPLEMENT_DYNAMIC(CAlbumFolder, CComObject)


//////////////////////////////////////////////////////////////////////
// CAlbumFolder construction

CAlbumFolder::CAlbumFolder(CAlbumFolder* pParent, LPCTSTR pszSchemaURI, LPCTSTR pszName, BOOL bAutoDelete)
{
	m_pParent = pParent;
	
	m_sSchemaURI	= pszSchemaURI ? pszSchemaURI : NULL;
	m_pSchema		= pszSchemaURI ? SchemaCache.Get( pszSchemaURI ) : NULL;
	m_pXML			= NULL;
	m_bCollSHA1		= FALSE;
	
	if ( pszName > (LPCTSTR)1 )
	{
		m_sName = pszName;
	}
	else if ( pszName != (LPCTSTR)1 )
	{
		if ( m_pSchema != NULL )
		{
			int nColon = m_pSchema->m_sTitle.Find( ':' );
			if ( nColon >= 0 ) m_sName = m_pSchema->m_sTitle.Mid( nColon + 1 );
		}
		
		if ( m_sName.IsEmpty() ) m_sName = _T("New Folder");
	}
	
	m_bExpanded		= pParent == NULL || pParent->m_pParent == NULL;
	m_bAutoDelete	= bAutoDelete;
	
	m_nUpdateCookie	= 0;
	m_nSelectCookie	= 0;
	m_nListCookie	= 0;
	m_pCollection	= NULL;
}

CAlbumFolder::~CAlbumFolder()
{
	Clear();
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder folder list

CAlbumFolder* CAlbumFolder::AddFolder(LPCTSTR pszSchemaURI, LPCTSTR pszName, BOOL bAutoDelete)
{
	if ( pszSchemaURI == NULL && m_pSchema != NULL )
	{
		pszSchemaURI = m_pSchema->GetContainedURI( CSchema::stFolder );
	}
	
	if ( pszSchemaURI == NULL ) pszSchemaURI = CSchema::uriFolder;
	
	CAlbumFolder* pFolder = new CAlbumFolder( this, pszSchemaURI, pszName, bAutoDelete );
	
	m_pFolders.AddTail( pFolder );
	
	return pFolder;
}

POSITION CAlbumFolder::GetFolderIterator() const
{
	return m_pFolders.GetHeadPosition();
}

CAlbumFolder* CAlbumFolder::GetNextFolder(POSITION& pos) const
{
	return (CAlbumFolder*)m_pFolders.GetNext( pos );
}

CAlbumFolder* CAlbumFolder::GetFolder(LPCTSTR pszName) const
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pCheck = GetNextFolder( pos );
		if ( pCheck->m_sName.CompareNoCase( pszName ) == 0 ) return pCheck;
	}
	
	return NULL;
}

CAlbumFolder* CAlbumFolder::GetFolderByURI(LPCTSTR pszURI) const
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pCheck = GetNextFolder( pos );
		if ( pCheck->m_pSchema != NULL &&
			 pCheck->m_pSchema->CheckURI( pszURI ) ) return pCheck;
	}
	
	return NULL;
}

int CAlbumFolder::GetFolderCount() const
{
	return m_pFolders.GetCount();
}

BOOL CAlbumFolder::CheckFolder(CAlbumFolder* pFolder, BOOL bRecursive) const
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pCheck = GetNextFolder( pos );
		if ( pCheck == pFolder ) return TRUE;
		if ( bRecursive && pCheck->CheckFolder( pFolder, TRUE ) ) return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder search for objects

CAlbumFolder* CAlbumFolder::GetTarget(CSchemaMember* pMember, LPCTSTR pszValue) const
{
	if ( m_pSchema == pMember->m_pSchema )
	{
		if ( pszValue == NULL )
		{
			return (CAlbumFolder*)this;
		}
		else if ( m_pXML != NULL )
		{
			CString strValue = pMember->GetValueFrom( m_pXML, NULL, TRUE );
			CXMLNode::UniformString( strValue );
			if ( strValue.CompareNoCase( pszValue ) == 0 ) return (CAlbumFolder*)this;
		}
	}
	
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pCheck	= GetNextFolder( pos );
		CAlbumFolder* pResult	= pCheck->GetTarget( pMember, pszValue );
		if ( pResult ) return pResult;
	}
	
	return NULL;
}

CAlbumFolder* CAlbumFolder::FindCollection(SHA1* pSHA1)
{
	if ( m_bCollSHA1 && *pSHA1 == m_pCollSHA1 ) return this;
	
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CAlbumFolder* pFolder = GetNextFolder( pos );
		if ( CAlbumFolder* pFind = pFolder->FindCollection( pSHA1 ) ) return pFind;
	}
	
	return NULL;
}

void CAlbumFolder::OnFolderDelete(CAlbumFolder* pFolder)
{
	POSITION pos = m_pFolders.Find( pFolder );
	if ( pos == NULL ) return;
	m_pFolders.RemoveAt( pos );
	
	Library.m_nUpdateCookie++;
	m_nUpdateCookie++;
	Delete( TRUE );
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder file list

void CAlbumFolder::AddFile(CLibraryFile* pFile)
{
	if ( pFile == NULL ) return;
	
	POSITION pos = m_pFiles.Find( pFile );
	if ( pos != NULL ) return;
	
	m_pFiles.AddTail( pFile );
	
	if ( m_bCollSHA1 )
	{
		if ( CLibraryFile* pCollection = LibraryMaps.LookupFileBySHA1( &m_pCollSHA1, FALSE, FALSE, TRUE ) )
		{
			pFile->m_nCollIndex = pCollection->m_nIndex;
		}
		else
		{
			m_bCollSHA1 = FALSE;
		}
	}
	
	m_nUpdateCookie++;
	Library.m_nUpdateCookie++;
}

POSITION CAlbumFolder::GetFileIterator() const
{
	return m_pFiles.GetHeadPosition();
}

CLibraryFile* CAlbumFolder::GetNextFile(POSITION& pos) const
{
	return (CLibraryFile*)m_pFiles.GetNext( pos );
}

int CAlbumFolder::GetFileCount() const
{
	return m_pFiles.GetCount();
}

int CAlbumFolder::GetSharedCount() const
{
	int nCount = 0;
	
	for ( POSITION pos = GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = GetNextFile( pos );
		if ( pFile->IsShared() ) nCount++;
	}
	
	for ( pos = GetFolderIterator() ; pos ; )
	{
		nCount += GetNextFolder( pos )->GetSharedCount();
	}
	
	return nCount;
}

void CAlbumFolder::RemoveFile(CLibraryFile* pFile)
{
	if ( POSITION pos = m_pFiles.Find( pFile ) )
	{
		m_pFiles.RemoveAt( pos );
		m_nUpdateCookie++;
		Library.m_nUpdateCookie++;
		Delete( TRUE );
	}
}

void CAlbumFolder::OnFileDelete(CLibraryFile* pFile)
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		GetNextFolder( pos )->OnFileDelete( pFile );
	}
	
	if ( pos = m_pFiles.Find( pFile ) )
	{
		m_pFiles.RemoveAt( pos );
		m_nUpdateCookie++;
		Library.m_nUpdateCookie++;
		Delete( TRUE );
	}
}

CAlbumFolder* CAlbumFolder::FindFile(CLibraryFile* pFile) const
{
	if ( m_pFiles.Find( pFile ) != NULL ) return (CAlbumFolder*)this;
	
	POSITION pos = GetFolderIterator();
	CAlbumFolder* pFirst = pos ? GetNextFolder( pos ) : NULL;
	
	if ( GetFolderCount() > 1 )
	{
		while ( pos )
		{
			CAlbumFolder* pFolder = GetNextFolder( pos )->FindFile( pFile );
			if ( pFolder != NULL ) return pFolder;
		}
		
		CAlbumFolder* pFolder = pFirst->FindFile( pFile );
		if ( pFolder != NULL ) return pFolder;
	}
	else if ( pFirst != NULL )
	{
		CAlbumFolder* pFolder = pFirst->FindFile( pFile );
		if ( pFolder != NULL ) return pFolder;
	}
	
	return NULL;
}

int CAlbumFolder::GetFileList(CLibraryList* pList, BOOL bRecursive) const
{
	int nCount = 0;
	
	for ( POSITION pos = GetFileIterator() ; pos ; )
	{
		pList->CheckAndAdd( GetNextFile( pos )->m_nIndex );
		nCount++;
	}
	
	if ( bRecursive )
	{
		for ( pos = GetFolderIterator() ; pos ; )
		{
			GetNextFolder( pos )->GetFileList( pList, bRecursive );
		}
	}
	
	return nCount;
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder clear

void CAlbumFolder::Delete(BOOL bIfEmpty)
{
	if ( m_pParent == NULL ) return;
	
	if ( bIfEmpty )
	{
		if ( ! m_bAutoDelete ) return;
		if ( m_bCollSHA1 ) return;
		if ( GetFolderCount() ) return;
		if ( GetFileCount() ) return;
	}
	
	m_pParent->OnFolderDelete( this );
	delete this;
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder metadata

BOOL CAlbumFolder::SetMetadata(CXMLElement* pXML)
{
	m_nUpdateCookie++;
	Library.m_nUpdateCookie++;
	
	if ( m_pXML != NULL )
	{
		delete m_pXML;
		m_pXML		= NULL;
		m_pSchema	= NULL;
		m_sSchemaURI.Empty();
	}
	
	if ( pXML == NULL ) return TRUE;
	
	m_sSchemaURI	= pXML->GetAttributeValue( CXMLAttribute::schemaName );
	m_pSchema		= SchemaCache.Get( m_sSchemaURI );
	m_pXML			= pXML->GetFirstElement();
	
	if ( m_pSchema == NULL || m_pXML == NULL )
	{
		m_pXML		= NULL;
		m_pSchema	= NULL;
		m_sSchemaURI.Empty();
		return FALSE;
	}
	
	m_pXML->Detach();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder metadata synchronisation

BOOL CAlbumFolder::MetaFromFile(CLibraryFile* pFile)
{
	if ( m_pSchema == NULL || pFile->m_pMetadata == NULL ) return FALSE;
	
	CSchemaChild* pChild = m_pSchema->GetContained( pFile->m_pSchema->m_sURI );
	if ( pChild == NULL ) return FALSE;
	
	if ( m_pXML == NULL ) m_pXML = new CXMLElement( NULL, m_pSchema->m_sSingular );
	
	pChild->MemberCopy( m_pXML, pFile->m_pMetadata );
	
	m_nUpdateCookie++;
	Library.m_nUpdateCookie++;
	
	return TRUE;
}

BOOL CAlbumFolder::MetaToFiles(BOOL bAggressive)
{
	if ( m_pSchema == NULL || m_pXML == NULL ) return FALSE;
	
	for ( POSITION pos = GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile	= GetNextFile( pos );
		CSchema* pSchema	= pFile->m_pSchema;
		
		if ( pSchema == NULL ) continue;
		
		if ( CSchemaChild* pChild = m_pSchema->GetContained( pSchema->m_sURI ) )
		{
			CXMLElement* pXML = pFile->m_pMetadata->Clone();
			
			if ( pChild->MemberCopy( m_pXML, pXML, TRUE, bAggressive ) )
			{
				CXMLElement* pRoot = pSchema->Instantiate( TRUE );
				pRoot->AddElement( pXML );
				pFile->SetMetadata( pRoot );
				delete pRoot;
			}
			else
			{
				delete pXML;
			}
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder select the best view

CString CAlbumFolder::GetBestView() const
{
	if ( m_sBestView.GetLength() > 0 ) return m_sBestView;
	
	if ( m_bCollSHA1 ) return _T("CLibraryCollectionView");
	
	if ( m_pSchema != NULL && m_pSchema->m_sLibraryView.GetLength() > 0 )
		return m_pSchema->m_sLibraryView;
	
	return CString();
}

//////////////////////////////////////////////////////////////////////
// CAlbumFolder mount a collection

BOOL CAlbumFolder::MountCollection(SHA1* pSHA1, CCollectionFile* pCollection, BOOL bForce)
{
	if ( ! bForce )
	{
		BOOL bResult = FALSE;
		
		for ( POSITION pos = GetFolderIterator() ; pos ; )
		{
			bResult |= GetNextFolder( pos )->MountCollection( pSHA1, pCollection, bForce );
		}
		
		if ( m_pSchema == NULL ) return bResult;
		
		if ( m_pSchema->GetContained( pCollection->GetThisURI() ) == NULL &&
			 m_sSchemaURI != CSchema::uriCollectionsFolder ) return bResult;
	}
	
	CAlbumFolder* pFolder = NULL;
	
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		pFolder = GetNextFolder( pos );
		if ( pFolder->m_bCollSHA1 && *pSHA1 == pFolder->m_pCollSHA1 ) break;
		pFolder = NULL;
	}
	
	if ( pFolder == NULL )
	{
		pFolder = AddFolder( pCollection->GetThisURI(), pCollection->GetTitle() );
	}
	
	pFolder->SetCollection( pSHA1, pCollection );
	
	m_nUpdateCookie++;
	Library.m_nUpdateCookie++;
	
	return TRUE;
}

void CAlbumFolder::SetCollection(SHA1* pSHA1, CCollectionFile* pCollection)
{
	m_bCollSHA1 = TRUE;
	m_pCollSHA1 = *pSHA1;
	m_sBestView.Empty();
	
	if ( m_pCollection != NULL )
	{
		delete m_pCollection;

⌨️ 快捷键说明

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