diff -r 26a1709b9fec -r 14979e23cb5e mpdata/src/mpmpxcollectiondata_p.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpdata/src/mpmpxcollectiondata_p.cpp Tue Aug 31 15:12:29 2010 +0300 @@ -0,0 +1,1071 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Music Player collection data - private implementation. +* +*/ + +#include +#include + +#include +#include +#include +#include +#include + +#include "mpmpxcollectiondata_p.h" +#include "mptrace.h" + +/*! + \class MpMpxCollectionDataPrivate + \brief Music Player collection data - private implementation. + + This is a private implementation of the collection data interface. +*/ + +/*! + \internal + */ +MpMpxCollectionDataPrivate::MpMpxCollectionDataPrivate( MpMpxCollectionData *wrapper ) + : q_ptr(wrapper), + iContext(ECollectionContextUnknown), + iContainerMedia(0), + iMediaArray(0), + iCachedRemovedItem(0), + iCurrentAlbumIndex(-1), + iAlbumSongCount(0), + iReloadAlbumContent(false), + iNeedReload(false) +{ + TX_LOG +} + +/*! + \internal + */ +MpMpxCollectionDataPrivate::~MpMpxCollectionDataPrivate() +{ + TX_ENTRY + delete iContainerMedia; + delete iCachedRemovedItem; + TX_EXIT +} + +/*! + \internal + */ +TCollectionContext MpMpxCollectionDataPrivate::context() const +{ + return iContext; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::count() const +{ + if ( iMediaArray ) { + return iMediaArray->Count(); + } + return 0; +} + +/*! + \internal + */ +QString MpMpxCollectionDataPrivate::collectionTitle() const +{ + TX_ENTRY + QString title; + if ( iContainerMedia && iContainerMedia->IsSupported( KMPXMediaGeneralTitle ) ) { + const TDesC& titleText = iContainerMedia->ValueText( KMPXMediaGeneralTitle ); + if ( titleText.Compare( KNullDesC ) != 0 ) { + title = QString::fromUtf16( titleText.Ptr(), titleText.Length() ); + } + } + TX_EXIT_ARGS("title =" << title); + return title; +} + +/*! + \internal + */ +QString MpMpxCollectionDataPrivate::itemData( int index, MpMpxCollectionData::DataType type ) +{ + TX_ENTRY_ARGS("index=" << index << ", type=" << type); + QString data; + TRAPD(err, DoGetDataL(index, type, data)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return data; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::isAutoPlaylist() +{ + TX_ENTRY + if ( iContext != ECollectionContextPlaylistSongs ) { + TX_EXIT + return false; + } + + bool isAuto = false; + TRAPD(err, isAuto = DoIsAutoPlaylistL()); + if ( err == KErrNone ) { + TX_LOG_ARGS("isAuto=" << isAuto); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return isAuto; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::isAutoPlaylist( int index ) +{ + TX_ENTRY_ARGS("index=" << index); + if ( iContext != ECollectionContextPlaylists ) { + TX_EXIT + return false; + } + + bool isAuto = false; + TRAPD(err, isAuto = DoIsAutoPlaylistL(index)); + if ( err == KErrNone ) { + TX_LOG_ARGS("isAuto=" << isAuto); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return isAuto; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::itemCount( int index ) +{ + TX_ENTRY_ARGS("index=" << index); + int count = 0; + TRAPD(err, count = DoGetItemCountL(index)); + if ( err == KErrNone ) { + TX_LOG_ARGS("count=" << count); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return count; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::containerId() +{ + int id = -1; + TRAPD( err, id = DoGetContainerIdL() ); + if ( err == KErrNone ) { + TX_LOG_ARGS("id=" << id); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return id; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::itemId( int index ) +{ + TX_ENTRY_ARGS( "index=" << index ); + int id = -1; + TRAPD( err, id = DoGetItemIdL( index ) ); + if ( err == KErrNone ) { + TX_LOG_ARGS( "id=" << id ); + } + else { + TX_LOG_ARGS( "Error: " << err << "; should never get here." ); + } + TX_EXIT + return id; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::albumSongId( int index ) +{ + TX_ENTRY_ARGS( "index=" << index ); + int id = -1; + TRAPD( err, id = DoGetAlbumSongIdL( index ) ); + if ( err == KErrNone ) { + TX_LOG_ARGS( "id=" << id ); + } + else { + TX_LOG_ARGS( "Error: " << err << "; should never get here." ); + } + TX_EXIT + return id; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::removeItem(int index) +{ + TX_ENTRY_ARGS("index=" << index); + TRAPD(err, DoRemoveItemL(index)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::testCachedItem( int itemId ) +{ + TX_ENTRY_ARGS( "itemId=" << itemId); + bool match = false; + TRAPD( err, match = DoTestCachedItemL( itemId ) ); + if ( err == KErrNone ) { + TX_LOG_ARGS("match=" << match); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return match; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::insertCachedItem(int index) +{ + TX_ENTRY_ARGS("index=" << index); + iMediaArray->Insert( iCachedRemovedItem, index ); + iCachedRemovedItem = 0; //ownership tranferred above. + TX_EXIT +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::setCurrentAlbum( int index ) +{ + TX_ENTRY_ARGS( "index=" << index); + bool available = false; + TRAPD( err, available = DoSetCurrentAlbumL( index ) ); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return available; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::currentAlbumIndex() const +{ + return iCurrentAlbumIndex; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::albumSongsCount() const +{ + return iAlbumSongCount; +} + +/*! + \internal + */ +QString MpMpxCollectionDataPrivate::albumSongData( int index, MpMpxCollectionData::DataType type ) const +{ + TX_ENTRY_ARGS("index=" << index << ", type=" << type); + QString data; + TRAPD(err, DoGetAlbumSongDataL(index, type, data)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return data; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::hasItemProperty( int index, MpMpxCollectionData:: DataProperty type ) const +{ + TX_ENTRY_ARGS("index=" << index << ", type=" << type); + bool available = false; + TRAPD(err, available = DoHasItemPropertyL(index, type)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return available; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::hasAlbumSongProperty( int index, MpMpxCollectionData:: DataProperty type ) const +{ + TX_ENTRY_ARGS("index=" << index << ", type=" << type); + bool available = false; + TRAPD(err, available = DoHasAlbumSongPropertyL(index, type)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT + return available; +} + +/*! + \internal + New data from MPX collection. This could be due to Open operation, in which case + context would have changed. This could also be due to Re-open after operations + such as delete, playlist renaming, playlist rearraging, etc., in which case the + context would remain the same, but the internal data may have changed. + */ +void MpMpxCollectionDataPrivate::setMpxMedia( const CMPXMedia& entries, bool reopen ) +{ + TX_ENTRY + TCollectionContext prevContext = iContext; + int prevCount = count(); + + TRAPD(err, DoSetMpxMediaL(entries)); + if ( err == KErrNone ) { + int newCount = count(); + if ( (newCount == 0) || (prevCount == 0) ) { + TX_LOG_ARGS("Empty container"); + // Two cases: + // 1) newCount is zero: Last item in the model was deleted. + // 2) prevCount is zero: Refresh operation found new data. + // In these cases, independent of context change, we must emit the + // contextChanged() signal so that the container can properly reload + // the layout. + emit q_ptr->contextChanged(iContext); + } + else if ( iContext != prevContext ) { + TX_LOG_ARGS("Context changed: iContext=" << iContext); + if ( prevContext == ECollectionContextArtistAlbumsTBone + && iContext == ECollectionContextArtistAlbums + && reopen ) { + // Special case 1: This occurs when a song was deleted from TBone list + // within artist container. And the fact that the new context is ArtistAlbums + // indicates that the artist has more than 1 album. + // Restore context to ArtistAlbumsTBone. + iContext = ECollectionContextArtistAlbumsTBone; + if ( newCount != prevCount ) { + // Change in count indicates that the deleted song was the last song + // in the TBone list. As a result, the album was deleted also, therefore + // we must emit dataChanged() indicating changes to the album section + // of the TBone. + emit q_ptr->dataChanged(); + } + else { + // Same count indicates that one of the songs in the TBone's list + // section was deleted. We only want to reload the list section of the + // TBone in this case. + emit q_ptr->albumDataChanged(); + } + } + else if ( prevContext == ECollectionContextAlbumsTBone && reopen ) { + // Special case 2: This occurs when a song was deleted from TBone list + // within album container. Restore context to AlbumsTBone. + iContext = ECollectionContextAlbumsTBone; + if ( newCount != prevCount ) { + // Change in count indicates that the deleted song was the last song + // in the TBone list. As a result, the album was deleted also, therefore + // we must emit dataChanged() indicating changes to the album section + // of the TBone. + emit q_ptr->dataChanged(); + } + else { + // Same count indicates that one of the songs in the TBone's list + // section was deleted. We only want to reload the list section of the + // TBone in this case. + emit q_ptr->albumDataChanged(); + } + } + else { + // Simple case where the context has really changed and it didn't + // involve TBone. + emit q_ptr->contextChanged(iContext); + } + } + else if ( prevContext == ECollectionContextArtistAlbumsTBone + && iContext == ECollectionContextArtistAlbumsTBone + && reopen ) { + // Special case 3: This occurs when a song was deleted from TBone list + // within artist container. This is similar to special case 1, however, the + // fact that the new context is also ArtistAlbumsTBone indicates that the + // artist has only 1 album. We only want to reload the list section of the + // TBone in this case. + emit q_ptr->albumDataChanged(); + } + else { + // Same context, but the data has changed. + emit q_ptr->dataChanged(); + } + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT +} + +/*! + \internal + This indicates data update during incremental open operation. This indicates + that media received in setMpxMedia() has updates. + */ +void MpMpxCollectionDataPrivate::incrementalOpenUpdate() +{ + TX_ENTRY_ARGS( "iNeedReload=" << iNeedReload); + if ( iNeedReload ) { + if ( itemId(iReloadRange.second) != -1 ) { + iNeedReload = false; + emit q_ptr->dataChanged(iReloadRange.first, iReloadRange.second); + } + } + TX_EXIT +} + +/*! + \internal + */ +const CMPXMedia& MpMpxCollectionDataPrivate::containerMedia() +{ + return *iContainerMedia; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::setContext( TCollectionContext context ) +{ + iContext = context; + TX_LOG_ARGS("Context changed: iContext=" << iContext); + loadAlbumsLookup(); + emit q_ptr->contextChanged(iContext); +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::setAlbumContent( const CMPXMedia& albumContent ) +{ + TX_ENTRY + TRAPD(err, DoSetAlbumContentL(albumContent)); + if ( err == KErrNone ) { + TX_LOG_ARGS("Album content is available."); + loadAlbumSongsLookup(); + emit q_ptr->refreshAlbumSongs(); + } + else { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT +} + +/*! + \internal + Currently only used to lookup playing song album id to index of albums on + media wall. + */ +int MpMpxCollectionDataPrivate::itemIndex( int itemUniqueId ) +{ + return iAlbumIdIndexMapping.value( itemUniqueId, -1 ); +} + +/*! + \internal + Currently only used to lookup playing song id to index of song in the + current album on media wall. + */ +int MpMpxCollectionDataPrivate::albumSongIndex( int songUniqueId ) +{ + return iAlbumSongIdIndexMapping.value( songUniqueId, -1 ); +} + +/*! + \internal + Use to lookup playing song id to index of song in collection and playlist + view + */ +QList MpMpxCollectionDataPrivate::songIndex( int songUniqueId ) +{ + TX_ENTRY + if(iSongIdIndexMapping.empty()){ + for ( int i = count() - 1 ; i >= 0 ; i-- ) { + iSongIdIndexMapping.insertMulti( itemId2( i ) , i ); + } + } + TX_EXIT + return iSongIdIndexMapping.values( songUniqueId ); +} + +/*! + \internal + Set item at index to corrupted depends on if viewing TBone + */ +void MpMpxCollectionDataPrivate::setCorruptValue( QModelIndex index, bool tBone) +{ + TX_ENTRY + TRAPD(err, DoSetCorruptValueL(index, tBone)); + if ( err != KErrNone ) { + TX_LOG_ARGS("Error: " << err << "; should never get here."); + } + TX_EXIT +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::setReloadAlbumContent( bool reloadAlbum ) +{ + iReloadAlbumContent = reloadAlbum; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::loadAlbumsLookup() +{ + //Clearing all the album ids. + iAlbumIdIndexMapping.clear(); + if ( iContext == ECollectionContextAlbumsMediaWall) { + //Adding album ids and indixes to the hash, for itemIndex lookup. + //This is disabled for other containers to save resources. + for ( int i = count() - 1 ; i >= 0 ; i-- ) { + iAlbumIdIndexMapping.insert( itemId( i ) , i ); + } + } +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::loadAlbumSongsLookup() +{ + //Clearing all the song ids. + iAlbumSongIdIndexMapping.clear(); + //Adding album song ids and indixes to the hash, for albumSongIndex lookup. + //This is disabled for other containers to save resources. + for ( int i = albumSongsCount() - 1 ; i >= 0 ; i-- ) { + iAlbumSongIdIndexMapping.insert( albumSongId( i ) , i ); + } +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::setReloadRange( int index ) +{ + TX_ENTRY_ARGS( "index=" << index); + if ( !iNeedReload ) { + iNeedReload = true; + iReloadRange.first = index; + iReloadRange.second = index; + } + else if ( index < iReloadRange.first ) { + iReloadRange.first = index; + } + else if ( index > iReloadRange.second ) { + iReloadRange.second = index; + } + TX_EXIT +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::itemId2( int index ) +{ + TX_ENTRY_ARGS( "index=" << index ); + int id = -1; + TRAPD( err, id = DoGetItemId2L( index ) ); + if ( err == KErrNone ) { + TX_LOG_ARGS( "id=" << id ); + } + else { + TX_LOG_ARGS( "Error: " << err << "; should never get here." ); + } + TX_EXIT + return id; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoGetDataL( int index, MpMpxCollectionData::DataType type, QString& data ) +{ + TX_ENTRY + CMPXMedia* currentMedia( iMediaArray->AtL( index ) ); + + if ( currentMedia->ValueTObjectL(KMPXMediaGeneralId) == KMPXInvalidItemId ) { + // Accessing a data that hasn't been fully fetched from the collection. + // This can happen during incremental open. Set the index as reload candidate. + setReloadRange(index); + } + + TBuf<10> countBuf; + TInt count = 0; + switch ( type ) { + case MpMpxCollectionData::Title: + if ( currentMedia->IsSupported( KMPXMediaGeneralTitle ) ) { + const TDesC& title = currentMedia->ValueText( KMPXMediaGeneralTitle ); + if ( title.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( title.Ptr(), title.Length() ); + } + } + break; + case MpMpxCollectionData::Artist: + if ( currentMedia->IsSupported( KMPXMediaMusicArtist ) ) { + const TDesC& artist = currentMedia->ValueText( KMPXMediaMusicArtist ); + if ( artist.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( artist.Ptr(), artist.Length() ); + } + } + break; + case MpMpxCollectionData::Album: + if ( currentMedia->IsSupported( KMPXMediaMusicAlbum ) ) { + const TDesC& album = currentMedia->ValueText( KMPXMediaMusicAlbum ); + if ( album.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( album.Ptr(), album.Length() ); + } + } + break; + case MpMpxCollectionData::Count: + if ( currentMedia->IsSupported( KMPXMediaGeneralCount ) ) { + count = currentMedia->ValueTObjectL( KMPXMediaGeneralCount ); + } + countBuf.AppendNum( count ); + data = QString::fromUtf16( countBuf.Ptr(), countBuf.Length() ); + break; + case MpMpxCollectionData::AlbumArtUri: + if ( currentMedia->IsSupported( KMPXMediaMusicAlbumArtFileName ) ) { + const TDesC& album = currentMedia->ValueText( KMPXMediaMusicAlbumArtFileName ); + if ( album.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( album.Ptr(), album.Length() ); + } + } + break; + case MpMpxCollectionData::Uri: + if ( currentMedia->IsSupported( KMPXMediaGeneralUri ) ) { + const TDesC& uri = currentMedia->ValueText( KMPXMediaGeneralUri ); + if ( uri.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( uri.Ptr(), uri.Length() ); + } + } + break; + default: + break; + } + TX_EXIT +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoIsAutoPlaylistL() +{ + if ( iContainerMedia->IsSupported(KMPXMediaGeneralNonPermissibleActions) ) { + TMPXGeneralNonPermissibleActions attr( + iContainerMedia->ValueTObjectL( + KMPXMediaGeneralNonPermissibleActions ) ); + if ( attr & EMPXWrite ) { + return true; + } + } + return false; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoIsAutoPlaylistL( int index ) +{ + const CMPXMediaArray* containerArray = iContainerMedia->Value( KMPXMediaArrayContents ); + User::LeaveIfNull( const_cast( containerArray )); + CMPXMedia* media( containerArray->AtL(index) ); + + if ( media->IsSupported(KMPXMediaGeneralNonPermissibleActions) ) { + TMPXGeneralNonPermissibleActions attr( + media->ValueTObjectL( + KMPXMediaGeneralNonPermissibleActions ) ); + if ( attr & EMPXWrite ) { + return true; + } + } + return false; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::DoGetItemCountL( int index ) +{ + CMPXMedia* currentMedia( iMediaArray->AtL( index ) ); + int count = 0; + if ( currentMedia->IsSupported( KMPXMediaGeneralCount ) ) { + count = currentMedia->ValueTObjectL( KMPXMediaGeneralCount ); + } + return count; +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::DoGetContainerIdL() +{ + if ( !iContainerMedia->IsSupported( KMPXMediaGeneralId ) ) { + User::Leave(KErrNotFound); + } + return iContainerMedia->ValueTObjectL( KMPXMediaGeneralId ); +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::DoGetItemIdL( int index ) +{ + CMPXMedia* currentMedia( iMediaArray->AtL( index ) ); + if ( currentMedia->ValueTObjectL(KMPXMediaGeneralId) == KMPXInvalidItemId ) { + return -1; + } + else { + int id1 = (currentMedia->ValueTObjectL( KMPXMediaGeneralId )).iId1; + int id2 = (currentMedia->ValueTObjectL( KMPXMediaGeneralId )).iId2; + TX_LOG_ARGS( "id1=" << id1 << ", id2=" << id2 ); + return (currentMedia->ValueTObjectL( KMPXMediaGeneralId )).iId1; + } +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::DoGetItemId2L( int index ) +{ + CMPXMedia* currentMedia( iMediaArray->AtL( index ) ); + if ( currentMedia->ValueTObjectL(KMPXMediaGeneralId) == KMPXInvalidItemId ) { + return -1; + } + else { + return (currentMedia->ValueTObjectL( KMPXMediaGeneralId )).iId2; + } +} + +/*! + \internal + */ +int MpMpxCollectionDataPrivate::DoGetAlbumSongIdL( int index ) +{ + CMPXMedia* album( iMediaArray->AtL( iCurrentAlbumIndex ) ); + const CMPXMediaArray* songs = album->Value(KMPXMediaArrayContents); + User::LeaveIfNull(const_cast(songs)); + CMPXMedia* song = songs->AtL(index); + if ( song->ValueTObjectL(KMPXMediaGeneralId) == KMPXInvalidItemId ) { + return -1; + } + else { + return song->ValueTObjectL( KMPXMediaGeneralId ); + } +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoRemoveItemL( int index ) +{ + delete iCachedRemovedItem; + iCachedRemovedItem = 0; + iCachedRemovedItem = CMPXMedia::NewL( *iMediaArray->AtL( index ) ); + iMediaArray->Remove( index ); +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoTestCachedItemL( int itemId ) +{ + if ( !iCachedRemovedItem || !iCachedRemovedItem->IsSupported( KMPXMediaGeneralId ) ) { + User::Leave(KErrNotFound); + } + return ( itemId == TInt( iCachedRemovedItem->ValueTObjectL( KMPXMediaGeneralId ) ) ); +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoSetCurrentAlbumL( int index ) +{ + TX_ENTRY_ARGS( "index=" << index); + iCurrentAlbumIndex = index; + + bool songsAvailable = false; + if (!iReloadAlbumContent){ + CMPXMedia* album( iMediaArray->AtL( index ) ); + if ( album->IsSupported(KMPXMediaArrayContents) ) { + // We've previously fetched the songs for this album so + // all we do now is populate the list with the song titles. + const CMPXMediaArray* songs = album->Value(KMPXMediaArrayContents); + iAlbumSongCount = songs->Count(); + songsAvailable = true; + TX_LOG_ARGS("Songs available."); + loadAlbumSongsLookup(); + emit q_ptr->refreshAlbumSongs(); + } + } + TX_EXIT + return songsAvailable; +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoGetAlbumSongDataL( int index, MpMpxCollectionData::DataType type, QString& data ) const +{ + TX_ENTRY + CMPXMedia* album( iMediaArray->AtL( iCurrentAlbumIndex ) ); + if ( album->IsSupported(KMPXMediaArrayContents) ) { + const CMPXMediaArray* songs = album->Value(KMPXMediaArrayContents); + User::LeaveIfNull(const_cast(songs)); + CMPXMedia* song = songs->AtL(index); + + switch ( type ) { + case MpMpxCollectionData::Title: + if ( song->IsSupported( KMPXMediaGeneralTitle ) ) { + const TDesC& title = song->ValueText( KMPXMediaGeneralTitle ); + if ( title.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( title.Ptr(), title.Length() ); + } + } + break; + case MpMpxCollectionData::Uri: + if ( song->IsSupported( KMPXMediaGeneralUri ) ) { + const TDesC& uri = song->ValueText( KMPXMediaGeneralUri ); + if ( uri.Compare( KNullDesC ) != 0 ) { + data = QString::fromUtf16( uri.Ptr(), uri.Length() ); + } + } + break; + default: + break; + } + } + TX_EXIT +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoHasItemPropertyL( int index, MpMpxCollectionData:: DataProperty type ) const +{ + TX_ENTRY + CMPXMedia* currentMedia( iMediaArray->AtL( index ) ); + + TInt flags(0); + if ( currentMedia->IsSupported( KMPXMediaGeneralFlags ) ) { + flags = currentMedia->ValueTObjectL( KMPXMediaGeneralFlags ); + } + switch ( type ) { + case MpMpxCollectionData::Corrupted: + if ( ( flags ) & ( KMPXMediaGeneralFlagsIsCorrupted ) ){ + return true; + } + break; + case MpMpxCollectionData::DrmExpired: + if ( ( flags ) & ( KMPXMediaGeneralFlagsIsDrmLicenceInvalid ) ){ + return true; + } + break; + default: + break; + } + TX_EXIT + return false; +} + +/*! + \internal + */ +bool MpMpxCollectionDataPrivate::DoHasAlbumSongPropertyL( int index, MpMpxCollectionData:: DataProperty type ) const +{ + TX_ENTRY + CMPXMedia* album( iMediaArray->AtL( iCurrentAlbumIndex ) ); + if ( album->IsSupported(KMPXMediaArrayContents) ) { + const CMPXMediaArray* songs = album->Value(KMPXMediaArrayContents); + User::LeaveIfNull(const_cast(songs)); + CMPXMedia* song = songs->AtL(index); + TInt flags(0); + if ( song->IsSupported( KMPXMediaGeneralFlags ) ) { + flags = song->ValueTObjectL( KMPXMediaGeneralFlags ); + } + switch ( type ) { + case MpMpxCollectionData::Corrupted: + if ( ( flags ) & ( KMPXMediaGeneralFlagsIsCorrupted ) ){ + return true; + } + break; + case MpMpxCollectionData::DrmExpired: + if ( ( flags ) & ( KMPXMediaGeneralFlagsIsDrmLicenceInvalid ) ){ + return true; + } + break; + default: + break; + } + + } + TX_EXIT + return false; +} +/*! + \internal + */ +void MpMpxCollectionDataPrivate::SetCollectionContextL() +{ + TX_ENTRY + // Clear Song Index Hash when context switched + iSongIdIndexMapping.clear(); + TMPXGeneralType containerType( EMPXNoType ); + if ( iContainerMedia->IsSupported( KMPXMediaGeneralType ) ) { + containerType = iContainerMedia->ValueTObjectL( KMPXMediaGeneralType ); + } + + TMPXGeneralCategory containerCategory( EMPXNoCategory ); + if( iContainerMedia->IsSupported( KMPXMediaGeneralCategory ) ) { + containerCategory = iContainerMedia->ValueTObjectL( KMPXMediaGeneralCategory ); + } + TX_LOG_ARGS("type=" << containerType << ", category=" << containerCategory ); + + iContext = ECollectionContextUnknown; + if ( containerType == EMPXGroup ) { + switch (containerCategory) { + case EMPXSong: + iContext = ECollectionContextAllSongs; + break; + case EMPXArtist: + iContext = ECollectionContextArtists; + break; + case EMPXAlbum: + iContext = ECollectionContextAlbums; + break; + case EMPXPlaylist: + iContext = ECollectionContextPlaylists; + break; + } + } + else if ( containerType == EMPXItem ) { + switch (containerCategory) { + case EMPXArtist: + if ( iMediaArray->Count() > 1 ) { + iContext = ECollectionContextArtistAlbums; + } + else { + // Single album. Go directly to TBone. + iContext = ECollectionContextArtistAlbumsTBone; + } + break; + case EMPXSong: + // All songs for an artist + iContext = ECollectionContextArtistAllSongs; + break; + case EMPXPlaylist: + iContext = ECollectionContextPlaylistSongs; + break; + } + } + TX_EXIT +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoSetMpxMediaL( const CMPXMedia& entries ) +{ + TX_ENTRY + delete iContainerMedia; + iContainerMedia = 0; + iContainerMedia = CMPXMedia::NewL(entries); + iMediaArray = const_cast(iContainerMedia->Value( KMPXMediaArrayContents ) ); + TX_LOG_ARGS("media count=" << iMediaArray->Count() ); + iReloadAlbumContent = false; + SetCollectionContextL(); + TX_EXIT +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoSetAlbumContentL( const CMPXMedia& albumContent ) +{ + TX_ENTRY + CMPXMediaArray* songArray(const_cast( albumContent.Value( + KMPXMediaArrayContents ) ) ); + User::LeaveIfNull( songArray ); + + // Save the songs to the album so that we don't need to find them again + // if the same album is selected again. + iAlbumSongCount = songArray->Count(); + + if ( iAlbumSongCount ) { + CMPXMedia* albumMedia( iMediaArray->AtL( iCurrentAlbumIndex ) ); + albumMedia->SetCObjectValueL(KMPXMediaArrayContents, songArray); + albumMedia->SetTObjectValueL(KMPXMediaArrayCount, iAlbumSongCount); + } + TX_EXIT +} + +/*! + \internal + */ +void MpMpxCollectionDataPrivate::DoSetCorruptValueL(QModelIndex index, bool tBone) +{ + TX_ENTRY + if (tBone){ + CMPXMedia* album( iMediaArray->AtL( iCurrentAlbumIndex ) ); + if ( album->IsSupported(KMPXMediaArrayContents) ) { + const CMPXMediaArray* songs = album->Value(KMPXMediaArrayContents); + User::LeaveIfNull(const_cast(songs)); + CMPXMedia* song = songs->AtL( index.row() ); + song->SetTObjectValueL( KMPXMediaGeneralFlags,KMPXMediaGeneralFlagsIsCorrupted ); + } + } + else { + CMPXMedia* song( iMediaArray->AtL( index.row() ) ); + song->SetTObjectValueL( KMPXMediaGeneralFlags,KMPXMediaGeneralFlagsIsCorrupted ); + } + TX_EXIT +} +