mpdata/src/mpmpxcollectiondata_p.cpp
changeset 35 fdb31ab341af
parent 22 ecf06a08d4d9
child 32 c163ef0b758d
equal deleted inserted replaced
34:2c5162224003 35:fdb31ab341af
    25 #include <mpxmediamusicdefs.h>
    25 #include <mpxmediamusicdefs.h>
    26 
    26 
    27 #include "mpmpxcollectiondata_p.h"
    27 #include "mpmpxcollectiondata_p.h"
    28 #include "mptrace.h"
    28 #include "mptrace.h"
    29 
    29 
    30 _LIT( KSong, " song" );
       
    31 _LIT( KSongs, " songs" );
       
    32 
       
    33 /*!
    30 /*!
    34     \class MpMpxCollectionDataPrivate
    31     \class MpMpxCollectionDataPrivate
    35     \brief Music Player collection data - private implementation.
    32     \brief Music Player collection data - private implementation.
    36 
    33 
    37     This is a private implementation of the collection data interface.
    34     This is a private implementation of the collection data interface.
    40 /*!
    37 /*!
    41  \internal
    38  \internal
    42  */
    39  */
    43 MpMpxCollectionDataPrivate::MpMpxCollectionDataPrivate( MpMpxCollectionData *wrapper )
    40 MpMpxCollectionDataPrivate::MpMpxCollectionDataPrivate( MpMpxCollectionData *wrapper )
    44     : q_ptr( wrapper ),
    41     : q_ptr( wrapper ),
       
    42       iContext( ECollectionContextUnknown ),
    45       iContainerMedia(0),
    43       iContainerMedia(0),
    46       iMediaArray(0),
    44       iMediaArray(0),
    47       iContext( ECollectionContextUnknown ),
    45       iCachedRemovedItem(0),
    48       iCachedRemovedItem ( 0 )
    46       iCurrentAlbumIndex(-1),
       
    47       iAlbumSongCount(0)
    49 {
    48 {
    50     TX_LOG
    49     TX_LOG
    51 }
    50 }
    52 
    51 
    53 /*!
    52 /*!
   254 }
   253 }
   255 
   254 
   256 /*!
   255 /*!
   257  \internal
   256  \internal
   258  */
   257  */
   259 void MpMpxCollectionDataPrivate::setMpxMedia( const CMPXMedia& entries )
   258 bool MpMpxCollectionDataPrivate::setCurrentAlbum( int index )
   260 {
   259 {
   261     TX_ENTRY
   260     TX_ENTRY_ARGS( "index=" << index);
       
   261     bool available = false;
       
   262     TRAPD( err, available = DoSetCurrentAlbumL( index ) );
       
   263     if ( err != KErrNone ) {
       
   264         TX_LOG_ARGS("Error: " << err << "; should never get here.");
       
   265     }
       
   266     TX_EXIT
       
   267     return available;
       
   268 }
       
   269 
       
   270 /*!
       
   271  \internal
       
   272  */
       
   273 int MpMpxCollectionDataPrivate::currentAlbumIndex() const
       
   274 {
       
   275     return iCurrentAlbumIndex;
       
   276 }
       
   277 
       
   278 /*!
       
   279  \internal
       
   280  */
       
   281 int MpMpxCollectionDataPrivate::albumSongsCount() const
       
   282 {
       
   283     return iAlbumSongCount;
       
   284 }
       
   285 
       
   286 /*!
       
   287  \internal
       
   288  */
       
   289 QString MpMpxCollectionDataPrivate::albumSongData( int index, MpMpxCollectionData::DataType type ) const
       
   290 {
       
   291     TX_ENTRY_ARGS("index=" << index << ", type=" << type);
       
   292     QString data;
       
   293     TRAPD(err, DoGetAlbumSongDataL(index, type, data));
       
   294     if ( err != KErrNone ) {
       
   295         TX_LOG_ARGS("Error: " << err << "; should never get here.");
       
   296     }
       
   297     TX_EXIT
       
   298     return data;
       
   299 }
       
   300 
       
   301 /*!
       
   302  \internal
       
   303  New data from MPX collection. This could be due to Open operation, in which case
       
   304  context would have changed. This could also be due to Re-open after operations
       
   305  such as delete, playlist renaming, playlist rearraging, etc., in which case the
       
   306  context would remain the same, but the internal data may have changed.
       
   307  */
       
   308 void MpMpxCollectionDataPrivate::setMpxMedia( const CMPXMedia& entries, bool reopen )
       
   309 {
       
   310     TX_ENTRY
       
   311     TCollectionContext prevContext = iContext;
       
   312     int prevCount = count();
       
   313 
   262     TRAPD(err, DoSetMpxMediaL(entries));
   314     TRAPD(err, DoSetMpxMediaL(entries));
   263     if ( err == KErrNone ) {
   315     if ( err == KErrNone ) {
   264         TX_LOG_ARGS("Context changed: iContext=" << iContext);
   316         int newCount = count();
   265         emit q_ptr->contextChanged(iContext);
   317         if ( (newCount == 0) || (prevCount == 0) ) {
       
   318             TX_LOG_ARGS("Empty container");
       
   319             // Two cases:
       
   320             //     1) newCount is zero: Last item in the model was deleted.
       
   321             //     2) prevCount is zero: Refresh operation found new data.
       
   322             // In these cases, independent of context change, we must emit the
       
   323             // contextChanged() signal so that the container can properly reload
       
   324             // the layout.
       
   325             emit q_ptr->contextChanged(iContext);
       
   326         }
       
   327         else if ( iContext != prevContext ) {
       
   328             TX_LOG_ARGS("Context changed: iContext=" << iContext);
       
   329             if ( prevContext == ECollectionContextArtistAlbumsTBone
       
   330                  && iContext == ECollectionContextArtistAlbums
       
   331                  && reopen ) {
       
   332                 // Special case 1: This occurs when a song was deleted from TBone list
       
   333                 // within artist container. And the fact that the new context is ArtistAlbums
       
   334                 // indicates that the artist has more than 1 album.
       
   335                 // Restore context to ArtistAlbumsTBone.
       
   336                 iContext = ECollectionContextArtistAlbumsTBone;
       
   337                 if ( newCount != prevCount ) {
       
   338                     // Change in count indicates that the deleted song was the last song
       
   339                     // in the TBone list. As a result, the album was deleted also, therefore
       
   340                     // we must emit dataChanged() indicating changes to the album section
       
   341                     // of the TBone.
       
   342                     emit q_ptr->dataChanged();
       
   343                 }
       
   344                 else {
       
   345                     // Same count indicates that one of the songs in the TBone's list
       
   346                     // section was deleted. We only want to reload the list section of the
       
   347                     // TBone in this case.
       
   348                     emit q_ptr->albumDataChanged();
       
   349                 }
       
   350             }
       
   351             else if ( prevContext == ECollectionContextAlbumsTBone && reopen ) {
       
   352                 // Special case 2: This occurs when a song was deleted from TBone list
       
   353                 // within album container. Restore context to AlbumsTBone.
       
   354                 iContext = ECollectionContextAlbumsTBone;
       
   355                 if ( newCount != prevCount ) {
       
   356                     // Change in count indicates that the deleted song was the last song
       
   357                     // in the TBone list. As a result, the album was deleted also, therefore
       
   358                     // we must emit dataChanged() indicating changes to the album section
       
   359                     // of the TBone.
       
   360                     emit q_ptr->dataChanged();
       
   361                 }
       
   362                 else {
       
   363                     // Same count indicates that one of the songs in the TBone's list
       
   364                     // section was deleted. We only want to reload the list section of the
       
   365                     // TBone in this case.
       
   366                     emit q_ptr->albumDataChanged();
       
   367                 }
       
   368             }
       
   369             else {
       
   370                 // Simple case where the context has really changed and it didn't
       
   371                 // involve TBone.
       
   372                 emit q_ptr->contextChanged(iContext);
       
   373             }
       
   374         }
       
   375         else if ( prevContext == ECollectionContextArtistAlbumsTBone
       
   376                   && iContext == ECollectionContextArtistAlbumsTBone
       
   377                   && reopen ) {
       
   378             // Special case 3: This occurs when a song was deleted from TBone list
       
   379             // within artist container. This is similar to special case 1, however, the
       
   380             // fact that the new context is also ArtistAlbumsTBone indicates that the
       
   381             // artist has only 1 album. We only want to reload the list section of the
       
   382             // TBone in this case.
       
   383             emit q_ptr->albumDataChanged();
       
   384         }
       
   385         else {
       
   386             // Same context, but the data has changed.
       
   387             emit q_ptr->dataChanged();
       
   388         }
   266     }
   389     }
   267     else {
   390     else {
   268         TX_LOG_ARGS("Error: " << err << "; should never get here.");
   391         TX_LOG_ARGS("Error: " << err << "; should never get here.");
   269     }
   392     }
   270     TX_EXIT
   393     TX_EXIT
   271 }
   394 }
   272 
   395 
   273 /*!
   396 /*!
   274  \internal
   397  \internal
   275  */
   398  */
       
   399 const CMPXMedia& MpMpxCollectionDataPrivate::containerMedia()
       
   400 {
       
   401     return *iContainerMedia;
       
   402 }
       
   403 
       
   404 /*!
       
   405  \internal
       
   406  */
       
   407 void MpMpxCollectionDataPrivate::setContext( TCollectionContext context )
       
   408 {
       
   409     iContext = context;
       
   410     TX_LOG_ARGS("Context changed: iContext=" << iContext);
       
   411     
       
   412     //Clearing all the album ids.
       
   413     albumIdIndexMapping.clear();
       
   414     if ( iContext == ECollectionContextAlbumsMediaWall) {
       
   415         //Adding album ids and indixes to the hash, for itemIndex lookup.
       
   416         //This is disabled for other containers to save resources.
       
   417         for ( int i = count() - 1 ; i >= 0 ; i-- ) {
       
   418             albumIdIndexMapping.insert( itemId( i ) , i );
       
   419         }
       
   420     }
       
   421     
       
   422     emit q_ptr->contextChanged(iContext);
       
   423 }
       
   424 
       
   425 /*!
       
   426  \internal
       
   427  */
       
   428 void MpMpxCollectionDataPrivate::setAlbumContent( const CMPXMedia& albumContent )
       
   429 {
       
   430     TX_ENTRY
       
   431     TRAPD(err, DoSetAlbumContentL(albumContent));
       
   432     if ( err == KErrNone ) {
       
   433         TX_LOG_ARGS("Album content is available.");
       
   434         emit q_ptr->refreshAlbumSongs();
       
   435     }
       
   436     else {
       
   437         TX_LOG_ARGS("Error: " << err << "; should never get here.");
       
   438     }
       
   439     TX_EXIT
       
   440 }
       
   441 
       
   442 /*!
       
   443  \internal
       
   444    Currently only used to lookup playing song album id to index of albums on 
       
   445    media wall.
       
   446  */
       
   447 int MpMpxCollectionDataPrivate::itemIndex( int itemUniqueId )
       
   448 {
       
   449     return albumIdIndexMapping.value( itemUniqueId );
       
   450 }
       
   451 
       
   452 /*!
       
   453  \internal
       
   454  */
   276 void MpMpxCollectionDataPrivate::DoGetDataL( int index, MpMpxCollectionData::DataType type, QString& data ) const
   455 void MpMpxCollectionDataPrivate::DoGetDataL( int index, MpMpxCollectionData::DataType type, QString& data ) const
   277 {
   456 {
   278     TX_ENTRY
   457     TX_ENTRY
   279     CMPXMedia* currentMedia( iMediaArray->AtL( index ) );
   458     CMPXMedia* currentMedia( iMediaArray->AtL( index ) );
   280 
   459 
   281     TBuf<256> countBuf;
   460     TBuf<10> countBuf;
   282     TBuf<20> temp;
       
   283     TInt count = 0;
   461     TInt count = 0;
   284     switch ( type ) {
   462     switch ( type ) {
   285         case MpMpxCollectionData::Title:
   463         case MpMpxCollectionData::Title:
   286             if ( currentMedia->IsSupported( KMPXMediaGeneralTitle ) ) {
   464             if ( currentMedia->IsSupported( KMPXMediaGeneralTitle ) ) {
   287                 const TDesC& title = currentMedia->ValueText( KMPXMediaGeneralTitle );
   465                 const TDesC& title = currentMedia->ValueText( KMPXMediaGeneralTitle );
   308             break;
   486             break;
   309         case MpMpxCollectionData::Count:
   487         case MpMpxCollectionData::Count:
   310             if ( currentMedia->IsSupported( KMPXMediaGeneralCount ) ) {
   488             if ( currentMedia->IsSupported( KMPXMediaGeneralCount ) ) {
   311                 count = currentMedia->ValueTObjectL<TInt>( KMPXMediaGeneralCount );
   489                 count = currentMedia->ValueTObjectL<TInt>( KMPXMediaGeneralCount );
   312             }
   490             }
   313             temp.AppendNum( count );
   491             countBuf.AppendNum( count );
   314             //AknTextUtils::LanguageSpecificNumberConversion( temp );
       
   315             countBuf.Append( temp );
       
   316             countBuf.Append( (count > 1 ) ? KSongs() : KSong() );
       
   317             data = QString::fromUtf16( countBuf.Ptr(), countBuf.Length() );
   492             data = QString::fromUtf16( countBuf.Ptr(), countBuf.Length() );
   318             break;
   493             break;
   319         case MpMpxCollectionData::AlbumArtUri:
   494         case MpMpxCollectionData::AlbumArtUri:
   320             if ( currentMedia->IsSupported( KMPXMediaMusicAlbumArtFileName ) ) {
   495             if ( currentMedia->IsSupported( KMPXMediaMusicAlbumArtFileName ) ) {
   321                 const TDesC& album = currentMedia->ValueText( KMPXMediaMusicAlbumArtFileName );
   496                 const TDesC& album = currentMedia->ValueText( KMPXMediaMusicAlbumArtFileName );
   430         User::Leave(KErrNotFound);
   605         User::Leave(KErrNotFound);
   431     }
   606     }
   432     return ( itemId == iCachedRemovedItem->ValueTObjectL<TInt>( KMPXMediaGeneralId ) );
   607     return ( itemId == iCachedRemovedItem->ValueTObjectL<TInt>( KMPXMediaGeneralId ) );
   433 }
   608 }
   434 
   609 
       
   610 /*!
       
   611  \internal
       
   612  */
       
   613 bool MpMpxCollectionDataPrivate::DoSetCurrentAlbumL( int index )
       
   614 {
       
   615     TX_ENTRY_ARGS( "index=" << index);
       
   616     iCurrentAlbumIndex = index;
       
   617 
       
   618     bool songsAvailable = false;
       
   619     CMPXMedia* album( iMediaArray->AtL( index ) );
       
   620     if ( album->IsSupported(KMPXMediaArrayContents) ) {
       
   621         // We've previously fetched the songs for this album so
       
   622         // all we do now is populate the list with the song titles.
       
   623         const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
   624         iAlbumSongCount = songs->Count();
       
   625         songsAvailable = true;
       
   626         TX_LOG_ARGS("Songs available.");
       
   627         emit q_ptr->refreshAlbumSongs();
       
   628     }
       
   629     TX_EXIT
       
   630     return songsAvailable;
       
   631 }
       
   632 
       
   633 /*!
       
   634  \internal
       
   635  */
       
   636 void MpMpxCollectionDataPrivate::DoGetAlbumSongDataL( int index, MpMpxCollectionData::DataType type, QString& data ) const
       
   637 {
       
   638     TX_ENTRY
       
   639     CMPXMedia* album( iMediaArray->AtL( iCurrentAlbumIndex ) );
       
   640     if ( album->IsSupported(KMPXMediaArrayContents) ) {
       
   641         const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
   642         User::LeaveIfNull(const_cast<CMPXMediaArray*>(songs));
       
   643         CMPXMedia* song = songs->AtL(index);
       
   644 
       
   645         switch ( type ) {
       
   646             case MpMpxCollectionData::Title:
       
   647                 if ( song->IsSupported( KMPXMediaGeneralTitle ) ) {
       
   648                     const TDesC& title = song->ValueText( KMPXMediaGeneralTitle );
       
   649                     if ( title.Compare( KNullDesC ) != 0 ) {
       
   650                         data = QString::fromUtf16( title.Ptr(), title.Length() );
       
   651                     }
       
   652                 }
       
   653                 break;
       
   654             case MpMpxCollectionData::Uri:
       
   655                 if ( song->IsSupported( KMPXMediaGeneralUri ) ) {
       
   656                     const TDesC& uri = song->ValueText( KMPXMediaGeneralUri );
       
   657                     if ( uri.Compare( KNullDesC ) != 0 ) {
       
   658                         data = QString::fromUtf16( uri.Ptr(), uri.Length() );
       
   659                     }
       
   660                 }
       
   661                 break;
       
   662             default:
       
   663                 break;
       
   664         }
       
   665     }
       
   666     TX_EXIT
       
   667 }
   435 
   668 
   436 /*!
   669 /*!
   437  \internal
   670  \internal
   438  */
   671  */
   439 void MpMpxCollectionDataPrivate::SetCollectionContextL()
   672 void MpMpxCollectionDataPrivate::SetCollectionContextL()
   463                 iContext = ECollectionContextAlbums;
   696                 iContext = ECollectionContextAlbums;
   464                 break;
   697                 break;
   465             case EMPXPlaylist:
   698             case EMPXPlaylist:
   466                 iContext = ECollectionContextPlaylists;
   699                 iContext = ECollectionContextPlaylists;
   467                 break;
   700                 break;
   468             case EMPXGenre:
       
   469                 iContext = ECollectionContextGenres;
       
   470                 break;
       
   471         }
   701         }
   472     }
   702     }
   473     else if ( containerType == EMPXItem ) {
   703     else if ( containerType == EMPXItem ) {
   474         switch (containerCategory) {
   704         switch (containerCategory) {
   475             case EMPXArtist:
   705             case EMPXArtist:
   476                 iContext = ECollectionContextArtistAlbums;
   706                 if ( iMediaArray->Count() > 1 ) {
   477                 break;
   707                     iContext = ECollectionContextArtistAlbums;
   478             case EMPXAlbum:
   708                 }
   479                 iContext = ECollectionContextAlbumSongs;
   709                 else {
       
   710                     // Single album. Go directly to TBone.
       
   711                     iContext = ECollectionContextArtistAlbumsTBone;
       
   712                 }
   480                 break;
   713                 break;
   481             case EMPXSong:
   714             case EMPXSong:
   482                 iContext = ECollectionContextArtistSongs;
   715                 // All songs for an artist
       
   716                 iContext = ECollectionContextArtistAllSongs;
   483                 break;
   717                 break;
   484             case EMPXPlaylist:
   718             case EMPXPlaylist:
   485                 iContext = ECollectionContextPlaylistSongs;
   719                 iContext = ECollectionContextPlaylistSongs;
   486                 break;
       
   487             case EMPXGenre:
       
   488                 iContext = ECollectionContextGenreSongs;
       
   489                 break;
   720                 break;
   490         }
   721         }
   491     }
   722     }
   492     TX_EXIT
   723     TX_EXIT
   493 }
   724 }
   509 }
   740 }
   510 
   741 
   511 /*!
   742 /*!
   512  \internal
   743  \internal
   513  */
   744  */
   514 const CMPXMedia& MpMpxCollectionDataPrivate::containerMedia()
   745 void MpMpxCollectionDataPrivate::DoSetAlbumContentL( const CMPXMedia& albumContent )
   515 {
   746 {
   516     return *iContainerMedia;
   747     TX_ENTRY
   517 }
   748     CMPXMediaArray* songArray(const_cast<CMPXMediaArray*>( albumContent.Value<CMPXMediaArray>(
   518 
   749                     KMPXMediaArrayContents ) ) );
       
   750     User::LeaveIfNull( songArray );
       
   751 
       
   752     // Save the songs to the album so that we don't need to find them again
       
   753     // if the same album is selected again.
       
   754     iAlbumSongCount = songArray->Count();
       
   755 
       
   756     if ( iAlbumSongCount ) {
       
   757         CMPXMedia* albumMedia( iMediaArray->AtL( iCurrentAlbumIndex ) );
       
   758         albumMedia->SetCObjectValueL(KMPXMediaArrayContents, songArray);
       
   759         albumMedia->SetTObjectValueL<TInt>(KMPXMediaArrayCount, iAlbumSongCount);
       
   760     }
       
   761     TX_EXIT
       
   762 }
       
   763 
       
   764