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 "Library.h"
00025 #include "SharedFile.h"
00026 #include "AlbumFolder.h"
00027 #include "CollectionFile.h"
00028 #include "Schema.h"
00029 #include "SchemaChild.h"
00030 #include "SchemaCache.h"
00031 #include "ShellIcons.h"
00032 #include "XML.h"
00033 #include "SHA.h"
00034
00035 #ifdef _DEBUG
00036 #undef THIS_FILE
00037 static char THIS_FILE[]=__FILE__;
00038 #define new DEBUG_NEW
00039 #endif
00040
00041 IMPLEMENT_DYNAMIC(CAlbumFolder, CComObject)
00042
00043
00044
00045
00046
00047 CAlbumFolder::CAlbumFolder(CAlbumFolder* pParent, LPCTSTR pszSchemaURI, LPCTSTR pszName, BOOL bAutoDelete)
00048 {
00049 m_pParent = pParent;
00050
00051 m_sSchemaURI = pszSchemaURI ? pszSchemaURI : NULL;
00052 m_pSchema = pszSchemaURI ? SchemaCache.Get( pszSchemaURI ) : NULL;
00053 m_pXML = NULL;
00054 m_bCollSHA1 = FALSE;
00055
00056 if ( pszName > (LPCTSTR)1 )
00057 {
00058 m_sName = pszName;
00059 }
00060 else if ( pszName != (LPCTSTR)1 )
00061 {
00062 if ( m_pSchema != NULL )
00063 {
00064 int nColon = m_pSchema->m_sTitle.Find( ':' );
00065 if ( nColon >= 0 ) m_sName = m_pSchema->m_sTitle.Mid( nColon + 1 ).Trim();
00066 }
00067
00068 if ( m_sName.IsEmpty() ) m_sName = _T("New Folder");
00069 }
00070
00071 m_bExpanded = pParent == NULL || pParent->m_pParent == NULL;
00072 m_bAutoDelete = bAutoDelete;
00073
00074 m_nUpdateCookie = 0;
00075 m_nSelectCookie = 0;
00076 m_nListCookie = 0;
00077 m_pCollection = NULL;
00078 }
00079
00080 CAlbumFolder::~CAlbumFolder()
00081 {
00082 Clear();
00083 }
00084
00086
00087
00088 CAlbumFolder* CAlbumFolder::AddFolder(LPCTSTR pszSchemaURI, LPCTSTR pszName, BOOL bAutoDelete)
00089 {
00090 if ( pszSchemaURI == NULL && m_pSchema != NULL )
00091 {
00092 pszSchemaURI = m_pSchema->GetContainedURI( CSchema::stFolder );
00093 }
00094
00095 if ( pszSchemaURI == NULL ) pszSchemaURI = CSchema::uriFolder;
00096
00097 CAlbumFolder* pFolder = new CAlbumFolder( this, pszSchemaURI, pszName, bAutoDelete );
00098
00099 m_pFolders.AddTail( pFolder );
00100
00101 return pFolder;
00102 }
00103
00104 POSITION CAlbumFolder::GetFolderIterator() const
00105 {
00106 return m_pFolders.GetHeadPosition();
00107 }
00108
00109 CAlbumFolder* CAlbumFolder::GetNextFolder(POSITION& pos) const
00110 {
00111 return (CAlbumFolder*)m_pFolders.GetNext( pos );
00112 }
00113
00114 CAlbumFolder* CAlbumFolder::GetFolder(LPCTSTR pszName) const
00115 {
00116 for ( POSITION pos = GetFolderIterator() ; pos ; )
00117 {
00118 CAlbumFolder* pCheck = GetNextFolder( pos );
00119 if ( pCheck->m_sName.CompareNoCase( pszName ) == 0 ) return pCheck;
00120 }
00121
00122 return NULL;
00123 }
00124
00125 CAlbumFolder* CAlbumFolder::GetFolderByURI(LPCTSTR pszURI) const
00126 {
00127 for ( POSITION pos = GetFolderIterator() ; pos ; )
00128 {
00129 CAlbumFolder* pCheck = GetNextFolder( pos );
00130 if ( pCheck->m_pSchema != NULL &&
00131 pCheck->m_pSchema->CheckURI( pszURI ) ) return pCheck;
00132 }
00133
00134 return NULL;
00135 }
00136
00137 int CAlbumFolder::GetFolderCount() const
00138 {
00139 return m_pFolders.GetCount();
00140 }
00141
00142 BOOL CAlbumFolder::CheckFolder(CAlbumFolder* pFolder, BOOL bRecursive) const
00143 {
00144 for ( POSITION pos = GetFolderIterator() ; pos ; )
00145 {
00146 CAlbumFolder* pCheck = GetNextFolder( pos );
00147 if ( pCheck == pFolder ) return TRUE;
00148 if ( bRecursive && pCheck->CheckFolder( pFolder, TRUE ) ) return TRUE;
00149 }
00150
00151 return FALSE;
00152 }
00153
00155
00156
00157 CAlbumFolder* CAlbumFolder::GetTarget(CSchemaMember* pMember, LPCTSTR pszValue) const
00158 {
00159 if ( m_pSchema == pMember->m_pSchema )
00160 {
00161 if ( pszValue == NULL )
00162 {
00163 return (CAlbumFolder*)this;
00164 }
00165 else if ( m_pXML != NULL )
00166 {
00167 CString strValue = pMember->GetValueFrom( m_pXML, NULL, TRUE );
00168 CXMLNode::UniformString( strValue );
00169 if ( strValue.CompareNoCase( pszValue ) == 0 ) return (CAlbumFolder*)this;
00170 }
00171 }
00172
00173 for ( POSITION pos = GetFolderIterator() ; pos ; )
00174 {
00175 CAlbumFolder* pCheck = GetNextFolder( pos );
00176 CAlbumFolder* pResult = pCheck->GetTarget( pMember, pszValue );
00177 if ( pResult ) return pResult;
00178 }
00179
00180 return NULL;
00181 }
00182
00183 CAlbumFolder* CAlbumFolder::FindCollection(SHA1* pSHA1)
00184 {
00185 if ( m_bCollSHA1 && *pSHA1 == m_pCollSHA1 ) return this;
00186
00187 for ( POSITION pos = GetFolderIterator() ; pos ; )
00188 {
00189 CAlbumFolder* pFolder = GetNextFolder( pos );
00190 if ( CAlbumFolder* pFind = pFolder->FindCollection( pSHA1 ) ) return pFind;
00191 }
00192
00193 return NULL;
00194 }
00195
00196 void CAlbumFolder::OnFolderDelete(CAlbumFolder* pFolder)
00197 {
00198 POSITION pos = m_pFolders.Find( pFolder );
00199 if ( pos == NULL ) return;
00200 m_pFolders.RemoveAt( pos );
00201
00202 Library.m_nUpdateCookie++;
00203 m_nUpdateCookie++;
00204 Delete( TRUE );
00205 }
00206
00208
00209
00210 void CAlbumFolder::AddFile(CLibraryFile* pFile)
00211 {
00212 if ( pFile == NULL ) return;
00213
00214 POSITION pos = m_pFiles.Find( pFile );
00215 if ( pos != NULL ) return;
00216
00217 m_pFiles.AddTail( pFile );
00218
00219 if ( m_bCollSHA1 )
00220 {
00221 if ( CLibraryFile* pCollection = LibraryMaps.LookupFileBySHA1( &m_pCollSHA1, FALSE, TRUE ) )
00222 {
00223 pFile->m_nCollIndex = pCollection->m_nIndex;
00224 }
00225 else
00226 {
00227 m_bCollSHA1 = FALSE;
00228 }
00229 }
00230
00231 m_nUpdateCookie++;
00232 Library.m_nUpdateCookie++;
00233 }
00234
00235 POSITION CAlbumFolder::GetFileIterator() const
00236 {
00237 return m_pFiles.GetHeadPosition();
00238 }
00239
00240 CLibraryFile* CAlbumFolder::GetNextFile(POSITION& pos) const
00241 {
00242 return (CLibraryFile*)m_pFiles.GetNext( pos );
00243 }
00244
00245 int CAlbumFolder::GetFileCount() const
00246 {
00247 return m_pFiles.GetCount();
00248 }
00249
00250 int CAlbumFolder::GetSharedCount() const
00251 {
00252 int nCount = 0;
00253
00254 for ( POSITION pos = GetFileIterator() ; pos ; )
00255 {
00256 CLibraryFile* pFile = GetNextFile( pos );
00257 if ( pFile->IsShared() ) nCount++;
00258 }
00259
00260 for ( POSITION pos = GetFolderIterator() ; pos ; )
00261 {
00262 nCount += GetNextFolder( pos )->GetSharedCount();
00263 }
00264
00265 return nCount;
00266 }
00267
00268 void CAlbumFolder::RemoveFile(CLibraryFile* pFile)
00269 {
00270 if ( POSITION pos = m_pFiles.Find( pFile ) )
00271 {
00272 m_pFiles.RemoveAt( pos );
00273 m_nUpdateCookie++;
00274 Library.m_nUpdateCookie++;
00275 Delete( TRUE );
00276 }
00277 }
00278
00279 void CAlbumFolder::OnFileDelete(CLibraryFile* pFile)
00280 {
00281 for ( POSITION pos = GetFolderIterator() ; pos ; )
00282 {
00283 GetNextFolder( pos )->OnFileDelete( pFile );
00284 }
00285
00286 if ( POSITION pos = m_pFiles.Find( pFile ) )
00287 {
00288 m_pFiles.RemoveAt( pos );
00289 m_nUpdateCookie++;
00290 Library.m_nUpdateCookie++;
00291 Delete( TRUE );
00292 }
00293 }
00294
00295 CAlbumFolder* CAlbumFolder::FindFile(CLibraryFile* pFile) const
00296 {
00297 if ( m_pFiles.Find( pFile ) != NULL ) return (CAlbumFolder*)this;
00298
00299 POSITION pos = GetFolderIterator();
00300 CAlbumFolder* pFirst = pos ? GetNextFolder( pos ) : NULL;
00301
00302 if ( GetFolderCount() > 1 )
00303 {
00304 while ( pos )
00305 {
00306 CAlbumFolder* pFolder = GetNextFolder( pos )->FindFile( pFile );
00307 if ( pFolder != NULL ) return pFolder;
00308 }
00309
00310 CAlbumFolder* pFolder = pFirst->FindFile( pFile );
00311 if ( pFolder != NULL ) return pFolder;
00312 }
00313 else if ( pFirst != NULL )
00314 {
00315 CAlbumFolder* pFolder = pFirst->FindFile( pFile );
00316 if ( pFolder != NULL ) return pFolder;
00317 }
00318
00319 return NULL;
00320 }
00321
00322 int CAlbumFolder::GetFileList(CLibraryList* pList, BOOL bRecursive) const
00323 {
00324 int nCount = 0;
00325
00326 for ( POSITION pos = GetFileIterator() ; pos ; )
00327 {
00328 pList->CheckAndAdd( GetNextFile( pos )->m_nIndex );
00329 nCount++;
00330 }
00331
00332 if ( bRecursive )
00333 {
00334 for ( POSITION pos = GetFolderIterator() ; pos ; )
00335 {
00336 GetNextFolder( pos )->GetFileList( pList, bRecursive );
00337 }
00338 }
00339
00340 return nCount;
00341 }
00342
00344
00345
00346 void CAlbumFolder::Delete(BOOL bIfEmpty)
00347 {
00348 if ( m_pParent == NULL ) return;
00349
00350 if ( bIfEmpty )
00351 {
00352 if ( ! m_bAutoDelete ) return;
00353 if ( m_bCollSHA1 ) return;
00354 if ( GetFolderCount() ) return;
00355 if ( GetFileCount() ) return;
00356 }
00357
00358 m_pParent->OnFolderDelete( this );
00359 delete this;
00360 }
00361
00363
00364
00365 BOOL CAlbumFolder::SetMetadata(CXMLElement* pXML)
00366 {
00367 m_nUpdateCookie++;
00368 Library.m_nUpdateCookie++;
00369
00370 if ( m_pXML != NULL )
00371 {
00372 delete m_pXML;
00373 m_pXML = NULL;
00374 m_pSchema = NULL;
00375 m_sSchemaURI.Empty();
00376 }
00377
00378 if ( pXML == NULL ) return TRUE;
00379
00380 m_sSchemaURI = pXML->GetAttributeValue( CXMLAttribute::schemaName );
00381 m_pSchema = SchemaCache.Get( m_sSchemaURI );
00382 m_pXML = pXML->GetFirstElement();
00383
00384 if ( m_pSchema == NULL || m_pXML == NULL )
00385 {
00386 m_pXML = NULL;
00387 m_pSchema = NULL;
00388 m_sSchemaURI.Empty();
00389 return FALSE;
00390 }
00391
00392 m_pXML->Detach();
00393
00394 return TRUE;
00395 }
00396
00398
00399
00400 BOOL CAlbumFolder::MetaFromFile(CLibraryFile* pFile)
00401 {
00402 if ( m_pSchema == NULL || pFile->m_pMetadata == NULL ) return FALSE;
00403
00404 CSchemaChild* pChild = m_pSchema->GetContained( pFile->m_pSchema->m_sURI );
00405 if ( pChild == NULL ) return FALSE;
00406
00407 if ( m_pXML == NULL ) m_pXML = new CXMLElement( NULL, m_pSchema->m_sSingular );
00408
00409 pChild->MemberCopy( m_pXML, pFile->m_pMetadata );
00410
00411 m_nUpdateCookie++;
00412 Library.m_nUpdateCookie++;
00413
00414 return TRUE;
00415 }
00416
00417 BOOL CAlbumFolder::MetaToFiles(BOOL bAggressive)
00418 {
00419 if ( m_pSchema == NULL || m_pXML == NULL ) return FALSE;
00420
00421 for ( POSITION pos = GetFileIterator() ; pos ; )
00422 {
00423 CLibraryFile* pFile = GetNextFile( pos );
00424 CSchema* pSchema = pFile->m_pSchema;
00425
00426 if ( pSchema == NULL ) continue;
00427
00428 if ( CSchemaChild* pChild = m_pSchema->GetContained( pSchema->m_sURI ) )
00429 {
00430 CXMLElement* pXML = pFile->m_pMetadata->Clone();
00431
00432 if ( pChild->MemberCopy( m_pXML, pXML, TRUE, bAggressive ) )
00433 {
00434 CXMLElement* pRoot = pSchema->Instantiate( TRUE );
00435 pRoot->AddElement( pXML );
00436 pFile->SetMetadata( pRoot );
00437 delete pRoot;
00438 }
00439 else
00440 {
00441 delete pXML;
00442 }
00443 }
00444 }
00445
00446 return TRUE;
00447 }
00448
00450
00451
00452 CString CAlbumFolder::GetBestView() const
00453 {
00454 if ( m_sBestView.GetLength() > 0 ) return m_sBestView;
00455
00456 if ( m_bCollSHA1 ) return _T("CLibraryCollectionView");
00457
00458 if ( m_pSchema != NULL && m_pSchema->m_sLibraryView.GetLength() > 0 )
00459 return m_pSchema->m_sLibraryView;
00460
00461 return CString();
00462 }
00463
00465
00466
00467 BOOL CAlbumFolder::MountCollection(SHA1* pSHA1, CCollectionFile* pCollection, BOOL bForce)
00468 {
00469 if ( ! bForce )
00470 {
00471 BOOL bResult = FALSE;
00472
00473 for ( POSITION pos = GetFolderIterator() ; pos ; )
00474 {
00475 bResult |= GetNextFolder( pos )->MountCollection( pSHA1, pCollection, bForce );
00476 }
00477
00478 if ( m_pSchema == NULL ) return bResult;
00479
00480 if ( m_pSchema->GetContained( pCollection->GetThisURI() ) == NULL &&
00481 m_sSchemaURI != CSchema::uriCollectionsFolder ) return bResult;
00482 }
00483
00484 CAlbumFolder* pFolder = NULL;
00485
00486 for ( POSITION pos = GetFolderIterator() ; pos ; )
00487 {
00488 pFolder = GetNextFolder( pos );
00489 if ( pFolder->m_bCollSHA1 && *pSHA1 == pFolder->m_pCollSHA1 ) break;
00490 pFolder = NULL;
00491 }
00492
00493 if ( pFolder == NULL )
00494 {
00495 pFolder = AddFolder( pCollection->GetThisURI(), pCollection->GetTitle() );
00496 }
00497
00498 pFolder->SetCollection( pSHA1, pCollection );
00499
00500 m_nUpdateCookie++;
00501 Library.m_nUpdateCookie++;
00502
00503 return TRUE;
00504 }
00505
00506 void CAlbumFolder::SetCollection(SHA1* pSHA1, CCollectionFile* pCollection)
00507 {
00508 m_bCollSHA1 = TRUE;
00509 m_pCollSHA1 = *pSHA1;
00510 m_sBestView.Empty();
00511
00512 if ( m_pCollection != NULL )
00513 {
00514 delete m_pCollection;
00515 m_pCollection = NULL;
00516 }
00517
00518 if ( CXMLElement* pMetadata = pCollection->GetMetadata() )
00519 {
00520 pMetadata = pMetadata->Clone();
00521 SetMetadata( pMetadata );
00522 delete pMetadata;
00523 }
00524
00525 for ( POSITION pos = LibraryMaps.GetFileIterator() ; pos ; )
00526 {
00527 CLibraryFile* pFile = LibraryMaps.GetNextFile( pos );
00528
00529 if ( pFile->IsAvailable() )
00530 {
00531 if ( m_pCollSHA1 == pFile->m_pSHA1 ||
00532 pCollection->FindFile( pFile, TRUE ) ) AddFile( pFile );
00533 }
00534 }
00535
00536 m_nUpdateCookie++;
00537 Library.m_nUpdateCookie++;
00538 }
00539
00541
00542
00543 CCollectionFile* CAlbumFolder::GetCollection()
00544 {
00545 if ( ! m_bCollSHA1 ) return NULL;
00546 if ( m_pCollection != NULL ) return m_pCollection;
00547
00548 if ( CLibraryFile* pFile = LibraryMaps.LookupFileBySHA1( &m_pCollSHA1, FALSE, TRUE ) )
00549 {
00550 m_pCollection = new CCollectionFile();
00551
00552 if ( m_pCollection->Open( pFile->GetPath() ) )
00553 {
00554 return m_pCollection;
00555 }
00556 else
00557 {
00558 delete m_pCollection;
00559 m_pCollection = NULL;
00560 }
00561 }
00562
00563 m_bCollSHA1 = FALSE;
00564 m_nUpdateCookie++;
00565 Library.m_nUpdateCookie++;
00566
00567 return NULL;
00568 }
00569
00571
00572
00573 BOOL CAlbumFolder::OrganiseFile(CLibraryFile* pFile)
00574 {
00575 BOOL bResult = FALSE;
00576
00577 if ( m_sSchemaURI == CSchema::uriAllFiles )
00578 {
00579 AddFile( pFile );
00580 return TRUE;
00581 }
00582
00583 if ( m_bCollSHA1 && ( m_pCollection != NULL || GetCollection() ) )
00584 {
00585 if ( m_pCollSHA1 == pFile->m_pSHA1 ||
00586 m_pCollection->FindFile( pFile, TRUE ) )
00587 {
00588 AddFile( pFile );
00589 return TRUE;
00590 }
00591 else
00592 {
00593 return FALSE;
00594 }
00595 }
00596
00597 if ( pFile->m_pMetadata == NULL && m_pParent != NULL ) return FALSE;
00598
00599 if ( m_sSchemaURI == CSchema::uriMusicRoot )
00600 {
00601 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00602 }
00603 else if ( m_sSchemaURI == CSchema::uriMusicAlbumCollection )
00604 {
00605 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00606
00607 CString strAlbum = pFile->m_pMetadata->GetAttributeValue( _T("album") );
00608 CXMLNode::UniformString( strAlbum );
00609
00610 if ( strAlbum.IsEmpty() ) return FALSE;
00611 if ( _tcsicmp( strAlbum, _T("tba") ) == 0 ) return FALSE;
00612 if ( _tcsicmp( strAlbum, _T("na") ) == 0 ) return FALSE;
00613 if ( _tcsicmp( strAlbum, _T("n/a") ) == 0 ) return FALSE;
00614 if ( _tcsicmp( strAlbum, _T("none") ) == 0 ) return FALSE;
00615 if ( _tcsicmp( strAlbum, _T("empty") ) == 0 ) return FALSE;
00616 if ( _tcsicmp( strAlbum, _T("unknown") ) == 0 ) return FALSE;
00617 if ( _tcsistr( strAlbum, _T("uploaded by") ) ) return FALSE;
00618 if ( _tcsistr( strAlbum, _T("ripped by") ) ) return FALSE;
00619 if ( _tcsistr( strAlbum, _T("downloaded") ) ) return FALSE;
00620 if ( _tcsistr( strAlbum, _T("http") ) ) return FALSE;
00621 if ( _tcsistr( strAlbum, _T("mp3") ) ) return FALSE;
00622 if ( _tcsistr( strAlbum, _T("www.mp3sfinder.com") ) ) return FALSE;
00623 if ( _tcsistr( strAlbum, _T("single") ) ) strAlbum = _T("Singles");
00624
00625 for ( POSITION pos = GetFolderIterator() ; pos ; )
00626 {
00627 CAlbumFolder* pAlbum = GetNextFolder( pos );
00628
00629 if ( pAlbum->m_sName.CompareNoCase( strAlbum ) == 0 )
00630 {
00631 bResult = pAlbum->OrganiseFile( pFile );
00632 }
00633 else if ( pAlbum->m_bAutoDelete )
00634 {
00635 pAlbum->RemoveFile( pFile );
00636 }
00637 }
00638
00639 if ( bResult ) return TRUE;
00640
00641 CAlbumFolder* pAlbum = AddFolder( CSchema::uriMusicAlbum, strAlbum, TRUE );
00642
00643 return pAlbum->OrganiseFile( pFile );
00644 }
00645 else if ( m_sSchemaURI == CSchema::uriMusicAlbum )
00646 {
00647 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00648
00649 CString strAlbum = pFile->m_pMetadata->GetAttributeValue( _T("album") );
00650 CXMLNode::UniformString( strAlbum );
00651 if ( _tcsistr( strAlbum, _T("single") ) ) strAlbum = _T("Singles");
00652 if ( strAlbum.CompareNoCase( m_sName ) ) return FALSE;
00653
00654 AddFile( pFile );
00655
00656 if ( _tcsistr( m_sName, _T("soundtrack") ) != NULL ||
00657 _tcsistr( m_sName, _T("ost") ) != NULL )
00658 {
00659
00660 MetaFromFile( pFile );
00661 }
00662 else
00663 {
00664 MetaFromFile( pFile );
00665 }
00666
00667 return TRUE;
00668 }
00669 else if ( m_sSchemaURI == CSchema::uriMusicArtistCollection )
00670 {
00671 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00672
00673 CString strArtist = pFile->m_pMetadata->GetAttributeValue( _T("artist") );
00674 CXMLNode::UniformString( strArtist );
00675
00676 Replace( strArtist, _T(" (www.mp3sfinder.com)"), _T("") );
00677 if ( strArtist.IsEmpty() ) return FALSE;
00678
00679 for ( POSITION pos = GetFolderIterator() ; pos ; )
00680 {
00681 CAlbumFolder* pAlbum = GetNextFolder( pos );
00682
00683 if ( pAlbum->m_sName.CompareNoCase( strArtist ) == 0 )
00684 {
00685 bResult = pAlbum->OrganiseFile( pFile );
00686 }
00687 else if ( pAlbum->m_bAutoDelete )
00688 {
00689 pAlbum->RemoveFile( pFile );
00690 }
00691 }
00692
00693 if ( bResult ) return TRUE;
00694
00695 CAlbumFolder* pAlbum = AddFolder( CSchema::uriMusicArtist, strArtist, TRUE );
00696
00697 return pAlbum->OrganiseFile( pFile );
00698 }
00699 else if ( m_sSchemaURI == CSchema::uriMusicArtist )
00700 {
00701 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00702
00703 CString strArtist = pFile->m_pMetadata->GetAttributeValue( _T("artist") );
00704 CXMLNode::UniformString( strArtist );
00705 if ( strArtist.CompareNoCase( m_sName ) ) return FALSE;
00706
00707 AddFile( pFile );
00708 MetaFromFile( pFile );
00709
00710 return TRUE;
00711 }
00712 else if ( m_sSchemaURI == CSchema::uriMusicGenreCollection )
00713 {
00714 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00715
00716 CString strGenre = pFile->m_pMetadata->GetAttributeValue( _T("genre") );
00717 if ( strGenre.IsEmpty() ) return FALSE;
00718
00719 for ( POSITION pos = GetFolderIterator() ; pos ; )
00720 {
00721 CAlbumFolder* pAlbum = GetNextFolder( pos );
00722
00723 if ( pAlbum->m_sName.CompareNoCase( strGenre ) == 0 )
00724 {
00725 bResult = pAlbum->OrganiseFile( pFile );
00726 }
00727 else if ( pAlbum->m_bAutoDelete )
00728 {
00729 pAlbum->RemoveFile( pFile );
00730 }
00731 }
00732
00733 if ( bResult ) return TRUE;
00734
00735 CAlbumFolder* pAlbum = AddFolder( CSchema::uriMusicGenre, strGenre, TRUE );
00736
00737 return pAlbum->OrganiseFile( pFile );
00738 }
00739 else if ( m_sSchemaURI == CSchema::uriMusicGenre )
00740 {
00741 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00742
00743 CString strGenre = pFile->m_pMetadata->GetAttributeValue( _T("genre") );
00744 if ( strGenre.CompareNoCase( m_sName ) ) return FALSE;
00745
00746 AddFile( pFile );
00747 MetaFromFile( pFile );
00748
00749 return TRUE;
00750 }
00751 else if ( m_sSchemaURI == CSchema::uriMusicAll )
00752 {
00753 if ( ! pFile->IsSchemaURI( CSchema::uriAudio ) ) return FALSE;
00754 AddFile( pFile );
00755 return TRUE;
00756 }
00757 else if ( m_sSchemaURI == CSchema::uriVideoRoot )
00758 {
00759 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00760 }
00761 else if ( m_sSchemaURI == CSchema::uriVideoSeriesCollection )
00762 {
00763 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00764
00765 CString strSeries = pFile->m_pMetadata->GetAttributeValue( _T("series") );
00766 CXMLNode::UniformString( strSeries );
00767 if ( strSeries.IsEmpty() ) return FALSE;
00768
00769 for ( POSITION pos = GetFolderIterator() ; pos ; )
00770 {
00771 CAlbumFolder* pAlbum = GetNextFolder( pos );
00772
00773 if ( pAlbum->m_sName.CompareNoCase( strSeries ) == 0 )
00774 {
00775 bResult = pAlbum->OrganiseFile( pFile );
00776 }
00777 else if ( pAlbum->m_bAutoDelete )
00778 {
00779 pAlbum->RemoveFile( pFile );
00780 }
00781 }
00782
00783 if ( bResult ) return TRUE;
00784
00785 CAlbumFolder* pAlbum = AddFolder( CSchema::uriVideoSeries, strSeries, TRUE );
00786
00787 return pAlbum->OrganiseFile( pFile );
00788 }
00789 else if ( m_sSchemaURI == CSchema::uriVideoSeries )
00790 {
00791 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00792
00793 CString strSeries = pFile->m_pMetadata->GetAttributeValue( _T("series") );
00794 CXMLNode::UniformString( strSeries );
00795 if ( strSeries.CompareNoCase( m_sName ) ) return FALSE;
00796
00797 AddFile( pFile );
00798 MetaFromFile( pFile );
00799
00800 return TRUE;
00801 }
00802 else if ( m_sSchemaURI == CSchema::uriVideoFilmCollection )
00803 {
00804 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00805
00806 CString strType = pFile->m_pMetadata->GetAttributeValue( _T("type") );
00807 if ( strType.CompareNoCase( _T("film") ) ) return FALSE;
00808
00809 CString strTitle = pFile->m_pMetadata->GetAttributeValue( _T("title") );
00810 CXMLNode::UniformString( strTitle );
00811 if ( strTitle.IsEmpty() ) return FALSE;
00812
00813 for ( POSITION pos = GetFolderIterator() ; pos ; )
00814 {
00815 CAlbumFolder* pAlbum = GetNextFolder( pos );
00816
00817 if ( pAlbum->m_sName.CompareNoCase( strTitle ) == 0 )
00818 {
00819 bResult = pAlbum->OrganiseFile( pFile );
00820 }
00821 else if ( pAlbum->m_bAutoDelete )
00822 {
00823 pAlbum->RemoveFile( pFile );
00824 }
00825 }
00826
00827 if ( bResult ) return TRUE;
00828
00829 CAlbumFolder* pAlbum = AddFolder( CSchema::uriVideoFilm, strTitle, TRUE );
00830
00831 return pAlbum->OrganiseFile( pFile );
00832 }
00833 else if ( m_sSchemaURI == CSchema::uriVideoFilm )
00834 {
00835 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00836
00837 CString strType = pFile->m_pMetadata->GetAttributeValue( _T("type") );
00838 if ( strType.CompareNoCase( _T("film") ) ) return FALSE;
00839
00840 CString strTitle = pFile->m_pMetadata->GetAttributeValue( _T("title") );
00841 CXMLNode::UniformString( strTitle );
00842 if ( strTitle.CompareNoCase( m_sName ) ) return FALSE;
00843
00844 AddFile( pFile );
00845 MetaFromFile( pFile );
00846
00847 return TRUE;
00848 }
00849 else if ( m_sSchemaURI == CSchema::uriVideoMusicCollection )
00850 {
00851 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00852
00853 CString strType = pFile->m_pMetadata->GetAttributeValue( _T("type") );
00854 if ( strType.CompareNoCase( _T("music video") ) ) return FALSE;
00855
00856 AddFile( pFile );
00857
00858 return TRUE;
00859 }
00860 else if ( m_sSchemaURI == CSchema::uriVideoAll )
00861 {
00862 if ( ! pFile->IsSchemaURI( CSchema::uriVideo ) ) return FALSE;
00863 AddFile( pFile );
00864 return TRUE;
00865 }
00866 else if ( m_sSchemaURI == CSchema::uriImageRoot )
00867 {
00868 if ( ! pFile->IsSchemaURI( CSchema::uriImage ) ) return FALSE;
00869 }
00870 else if ( m_sSchemaURI == CSchema::uriImageAll )
00871 {
00872 if ( ! pFile->IsSchemaURI( CSchema::uriImage ) ) return FALSE;
00873 AddFile( pFile );
00874 return TRUE;
00875 }
00876 else if ( m_sSchemaURI == CSchema::uriApplicationRoot )
00877 {
00878 if ( ! pFile->IsSchemaURI( CSchema::uriApplication ) ) return FALSE;
00879 }
00880 else if ( m_sSchemaURI == CSchema::uriApplicationAll )
00881 {
00882 if ( ! pFile->IsSchemaURI( CSchema::uriApplication ) ) return FALSE;
00883 AddFile( pFile );
00884 return TRUE;
00885 }
00886 else if ( m_sSchemaURI == CSchema::uriBookRoot )
00887 {
00888 if ( ! pFile->IsSchemaURI( CSchema::uriBook ) ) return FALSE;
00889 }
00890 else if ( m_sSchemaURI == CSchema::uriBookAll )
00891 {
00892 if ( ! pFile->IsSchemaURI( CSchema::uriBook ) ) return FALSE;
00893 AddFile( pFile );
00894 return TRUE;
00895 }
00896 else if ( m_sSchemaURI == CSchema::uriDocumentRoot )
00897 {
00898 if ( ! pFile->IsSchemaURI( CSchema::uriDocument ) &&
00899 ! pFile->IsSchemaURI( CSchema::uriSpreadsheet ) &&
00900 ! pFile->IsSchemaURI( CSchema::uriPresentation ) ) return FALSE;
00901 }
00902 else if ( m_sSchemaURI == CSchema::uriDocumentAll )
00903 {
00904 if ( ! pFile->IsSchemaURI( CSchema::uriDocument ) &&
00905 ! pFile->IsSchemaURI( CSchema::uriSpreadsheet ) &&
00906 ! pFile->IsSchemaURI( CSchema::uriPresentation ) ) return FALSE;
00907 AddFile( pFile );
00908 return TRUE;
00909 }
00910
00911 for ( POSITION pos = GetFolderIterator() ; pos ; )
00912 {
00913 bResult |= GetNextFolder( pos )->OrganiseFile( pFile );
00914 }
00915
00916 return bResult;
00917 }
00918
00920
00921
00922 void CAlbumFolder::Serialize(CArchive& ar, int nVersion)
00923 {
00924 POSITION pos;
00925
00926 if ( ar.IsStoring() )
00927 {
00928 ar << m_sSchemaURI;
00929
00930 ar.WriteCount( m_pXML != NULL ? 1 : 0 );
00931 if ( m_pXML ) m_pXML->Serialize( ar );
00932
00933 ar << m_bCollSHA1;
00934 if ( m_bCollSHA1 ) ar.Write( &m_pCollSHA1, sizeof(SHA1) );
00935
00936 ar << m_sName;
00937 ar << m_bExpanded;
00938 ar << m_bAutoDelete;
00939 ar << m_sBestView;
00940
00941 ar.WriteCount( GetFolderCount() );
00942
00943 for ( pos = GetFolderIterator() ; pos ; )
00944 {
00945 CAlbumFolder* pFolder = GetNextFolder( pos );
00946 pFolder->Serialize( ar, nVersion );
00947 }
00948
00949 ar.WriteCount( GetFileCount() );
00950
00951 for ( pos = GetFileIterator() ; pos ; )
00952 {
00953 CLibraryFile* pFile = GetNextFile( pos );
00954 ar << pFile->m_nIndex;
00955 }
00956 }
00957 else
00958 {
00959 CLibraryFile* pCollection = NULL;
00960
00961 if ( m_pParent != NULL )
00962 {
00963 ar >> m_sSchemaURI;
00964 m_pSchema = SchemaCache.Get( m_sSchemaURI );
00965 }
00966 else
00967 {
00968 CString str;
00969 ar >> str;
00970 }
00971
00972 if ( ar.ReadCount() )
00973 {
00974 ASSERT( m_pXML == NULL );
00975 m_pXML = new CXMLElement();
00976 m_pXML->Serialize( ar );
00977 }
00978
00979 if ( nVersion >= 19 )
00980 {
00981 ar >> m_bCollSHA1;
00982
00983 if ( m_bCollSHA1 )
00984 {
00985 ar.Read( &m_pCollSHA1, sizeof(SHA1) );
00986 pCollection = LibraryMaps.LookupFileBySHA1( &m_pCollSHA1, FALSE, TRUE );
00987 if ( pCollection == NULL ) m_bCollSHA1 = FALSE;
00988 }
00989 }
00990
00991 ar >> m_sName;
00992 ar >> m_bExpanded;
00993 ar >> m_bAutoDelete;
00994
00995 if ( nVersion >= 9 ) ar >> m_sBestView;
00996
00997 int nCount = ar.ReadCount();
00998
00999 while ( nCount-- > 0 )
01000 {
01001 CAlbumFolder* pFolder = new CAlbumFolder( this, NULL, (LPCTSTR)1 );
01002 pFolder->Serialize( ar, nVersion );
01003 m_pFolders.AddTail( pFolder );
01004 }
01005
01006 nCount = ar.ReadCount();
01007
01008 while ( nCount-- > 0 )
01009 {
01010 DWORD nIndex;
01011 ar >> nIndex;
01012
01013 if ( CLibraryFile* pFile = Library.LookupFile( nIndex ) )
01014 {
01015 m_pFiles.AddTail( pFile );
01016 if ( pCollection != NULL ) pFile->m_nCollIndex = pCollection->m_nIndex;
01017 }
01018 }
01019 }
01020 }
01021
01023
01024
01025 void CAlbumFolder::Clear()
01026 {
01027 for ( POSITION pos = GetFolderIterator() ; pos ; )
01028 {
01029 delete GetNextFolder( pos );
01030 }
01031
01032 m_pFolders.RemoveAll();
01033 m_pFiles.RemoveAll();
01034
01035 if ( m_pXML != NULL ) delete m_pXML;
01036 m_pXML = NULL;
01037
01038 if ( m_pCollection != NULL ) delete m_pCollection;
01039 m_pCollection = NULL;
01040 }