--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpengine/src/mpmpxcollectionframeworkwrapper_p.cpp Tue Aug 31 15:12:29 2010 +0300
@@ -0,0 +1,1563 @@
+/*
+* 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: Wrapper for mpx collection framework utilities - private implementation.
+*
+*/
+
+#include <QStringList>
+#include <QRegExp>
+#include <QFileInfo>
+#include <QDateTime>
+#include <QTime>
+#include <QDate>
+
+#include <s32strm.h>
+#include <s32mem.h>
+#include <apgcli.h>
+#include <apacmdln.h>
+
+#include <mpxplaybackutility.h>
+#include <mpxcollectionutility.h>
+#include <mpxharvesterutility.h>
+#include <mpxcollectionpath.h>
+#include <mpxcollectionmessage.h>
+#include <mpxcollectionplaylist.h>
+#include <mpxmessagecontainerdefs.h>
+#include <mpxmediacollectiondetaildefs.h>
+#include <mpxmediamusicdefs.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediaaudiodefs.h>
+#include <mpxmediadrmdefs.h>
+#include <mpxcollectionplugin.hrh>
+#include <mpxmessagegeneraldefs.h>
+#include <mpxmediacontainerdefs.h>
+#include <mpxcollectionmessagedefs.h>
+#include <mpxparameter.h>
+#include <mpxcollectionhelperfactory.h>
+#include <mpxcollectionuihelper.h>
+#include <mpxcollectionopenutility.h>
+#include <mpxmediaarray.h>
+#include <mpxmedia.h>
+#include <mpxlog.h>
+
+#include "mpmpxcollectionframeworkwrapper_p.h"
+#include "mpmpxcollectionframeworkwrapper.h"
+#include "mpmpxcollectiondata.h"
+#include "mpcommondefs.h"
+#include "mptrace.h"
+#include "mpsettingsmanager.h"
+#include "mpsongdata.h"
+
+const TInt KIncrementalDelay = 0;
+const TInt KIncrementalFetchBlockSize = 1000;
+
+const TInt KMPXChunkSize = 100; // number of songs added in each chunk, IncAddL
+_LIT( KPlaylistPath, "C:\\Data\\Playlists\\" ); // Todo
+
+/*!
+ \class MpMpxCollectionFrameworkWrapperPrivate
+ \brief Wrapper for mpx framework utilities - private implementation.
+
+ This is a private implementation of the mpx framework wrapper utilties interface.
+*/
+
+/*!
+ \internal
+ */
+MpMpxCollectionFrameworkWrapperPrivate::MpMpxCollectionFrameworkWrapperPrivate( MpMpxCollectionFrameworkWrapper *wrapper )
+ : q_ptr( wrapper ),
+ iCollectionUtility( 0 ),
+ iCollectionUiHelper( 0 ),
+ iIncrementalOpenUtil( 0 ),
+ iIsolatedCollectionHelper( 0 ),
+ iPlaybackUtility( 0 ),
+ iCollectionData( 0 ),
+ iIsolatedCollectionData( 0 ),
+ iFirstIncrementalOpen( EFalse ),
+ iUserPlaylists( 0 ),
+ iRepeatFeature( ETrue ),
+ iShuffleFeature( ETrue ),
+ iReopen( EFalse ),
+ iShuffleAll( EFalse ),
+ iRestoreDefaultPath( EFalse ),
+ iRestorePathIndex( 0 ),
+ iSongData( 0 )
+{
+ TX_LOG
+}
+
+/*!
+ \internal
+ */
+MpMpxCollectionFrameworkWrapperPrivate::~MpMpxCollectionFrameworkWrapperPrivate()
+{
+ TX_ENTRY
+ delete iCollectionData;
+ delete iIsolatedCollectionData;
+
+ if ( iCollectionUtility ) {
+ iCollectionUtility->Collection().CancelRequest();
+ iCollectionUtility->Close();
+ }
+
+ if ( iCollectionUiHelper ) {
+ iCollectionUiHelper->Close();
+ }
+
+ if ( iPlaybackUtility ) {
+ iPlaybackUtility->Close();
+ }
+
+ delete iIncrementalOpenUtil;
+ delete iIsolatedCollectionHelper;
+ delete iUserPlaylists;
+
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::init( TUid hostUid, MpSongData *songData )
+{
+ TX_ENTRY
+ iHostUid = hostUid;
+ iSongData = songData;
+ TRAPD( err, DoInitL() );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::openCollection( TCollectionContext context )
+{
+ TRAPD( err, DoOpenCollectionL( context ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::openCollectionItem( int index )
+{
+ TRAPD( err, DoOpenCollectionItemL( index ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::reopenCollection()
+{
+ TRAPD( err, DoReopenCollectionL() );
+ if ( err == KErrNone ) {
+ iReopen = ETrue;
+ }
+ else {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::back()
+{
+ TRAPD( err, DoBackL() );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::findPlaylists( QStringList &playlists )
+{
+ TRAPD( err, DoFindPlaylistsL( playlists ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::createPlaylist( QString &playlistName, QList<int> &selection, MpMpxCollectionData* collectionData )
+{
+ TRAPD( err, DoCreatePlaylistL( playlistName, selection, collectionData ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::saveToPlaylist( int playlistIndex, QList<int> &selection )
+{
+ TRAPD( err, DoSaveToPlaylistL( playlistIndex, selection ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::saveToCurrentPlaylist( QList<int> &selection, MpMpxCollectionData *collectionData )
+{
+ TRAPD( err, DoSaveToCurrentPlaylistL( selection, collectionData ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::deleteSongs( QList<int> &selection )
+{
+ TCollectionContext context = iCollectionData->context();
+ int err;
+ if ( context == ECollectionContextArtistAlbumsTBone
+ || context == ECollectionContextAlbumsTBone ) {
+ TRAP( err, DoDeleteAlbumSongsL( selection ) );
+ }
+ else {
+ TRAP( err, DoDeleteSongsL( selection ) );
+ }
+ if ( err == KErrNone ) {
+ // send signal that deleting has started.
+ emit q_ptr->deleteStarted(iCollectionData->context(), selection.count());
+ }
+ else{
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::renamePlaylist( QString &newName, int index )
+{
+ TRAPD( err, DoRenamePlaylistL( newName, index ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::renamePlaylist( QString &newName )
+{
+ TRAPD( err, DoRenamePlaylistL( newName ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::setShuffle( bool active )
+{
+ TRAPD( err, DoSetShuffleL( active ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::previewItem( int index )
+{
+ TCollectionContext context = iCollectionData->context();
+ int err;
+ if ( context == ECollectionContextArtistAlbumsTBone
+ || context == ECollectionContextAlbumsTBone ) {
+ TRAP( err, DoPreviewAlbumSongL( index ) );
+ }
+ else {
+ TRAP( err, DoPreviewSongL( index ) );
+ }
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+ void MpMpxCollectionFrameworkWrapperPrivate::openIsolatedCollection( TCollectionContext context )
+{
+ TRAPD( err, DoOpenIsolatedCollectionL( context ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::releaseIsolatedCollection()
+{
+ delete iIsolatedCollectionHelper;
+ iIsolatedCollectionHelper = 0;
+ delete iIsolatedCollectionData;
+ iIsolatedCollectionData = 0;
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::reorderPlaylist( int playlistId, int songId, int originalOrdinal, int newOrdinal )
+{
+ TRAPD( err, DoReorderPlaylistL( playlistId, songId, originalOrdinal, newOrdinal ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::cancel()
+{
+ iCollectionUiHelper->Cancel();
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::findAlbumSongs( int index )
+{
+ TRAPD( err, DoFindAlbumSongsL( index ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::playAlbumSongs( int albumIndex, int songIndex, MpMpxCollectionData* collectionData )
+{
+ TRAPD( err, DoPlayAlbumSongsL( albumIndex, songIndex, collectionData ? collectionData : iCollectionData ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+}
+
+/*!
+ \internal
+ */
+MpMpxCollectionData *MpMpxCollectionFrameworkWrapperPrivate::collectionData()
+{
+ return iCollectionData;
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::openShuffleAllSongsPath()
+{
+ TX_ENTRY
+ TRAPD( err, DoOpenCollectionL(ECollectionContextAllSongs) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+ else {
+ iShuffleAll = ETrue;
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::retrieveSongDetails( int index )
+{
+ TX_ENTRY
+ TRAPD( err, DoRetrieveSongDetailsL(index) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::savePath( QByteArray &data )
+{
+ TX_ENTRY
+ TRAPD( err, DoSavePathL( data ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+ TX_EXIT
+
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::restorePath( const QByteArray &data )
+{
+ TX_ENTRY
+ TRAPD( err, DoRestorePathL( data ) );
+ if ( err != KErrNone ) {
+ TX_LOG_ARGS( "Error: " << err << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+
+/*!
+ \internal
+ Result of open or re-open operation to the Collection Framework.
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleOpenL(
+ const CMPXMedia& aEntries,
+ TInt aIndex,
+ TBool aComplete,
+ TInt aError )
+{
+ Q_UNUSED( aIndex );
+ TX_UNUSED( aComplete );
+ TX_ENTRY_ARGS( "aError=" << aError << "aComplete=" << aComplete );
+ if ( aError == KErrNone ) {
+ if ( iFirstIncrementalOpen ) {
+ iFirstIncrementalOpen = EFalse;
+ if( iShuffleAll ) {
+ iShuffleAll = EFalse;
+ TX_LOG_ARGS( "Path is ready" );
+ DoPlayAllSongsPlaylistL();
+ }
+ iCollectionData->setMpxMedia( aEntries, iReopen );
+ iReopen = EFalse;
+ }
+ else {
+ iCollectionData->incrementalOpenUpdate();
+ }
+ }
+ else {
+ TX_LOG_ARGS( "Error: " << aError << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleOpenL(
+ const CMPXCollectionPlaylist& aPlaylist,
+ TInt aError )
+{
+ TX_ENTRY_ARGS( "aError=" << aError );
+
+ if ( aError == KErrNone ) {
+ //TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( aPlaylist, ETrue );
+ emit q_ptr->collectionPlaylistOpened();
+ }
+ else {
+ TX_LOG_ARGS( "Error: " << aError << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleCollectionMessage(
+ CMPXMessage* aMsg,
+ TInt aErr )
+{
+ TX_ENTRY_ARGS( "aErr=" << aErr );
+ if ( aErr == KErrNone && aMsg )
+ {
+ TRAP_IGNORE( DoHandleCollectionMessageL( *aMsg ) );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleCollectionMediaL(
+ const CMPXMedia& aMedia,
+ TInt aError )
+{
+ TX_ENTRY
+ if ( KErrNone != aError ){
+ TX_LOG_ARGS( "Error: " << aError << "; should never get here." );
+ TX_EXIT
+ return;
+ }
+ iSongData->setMpxMedia( aMedia );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ Handles the completion of any collection helper event.
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleOperationCompleteL(
+ TCHelperOperation aOperation,
+ TInt aErr,
+ void* aArgument )
+{
+ TX_ENTRY_ARGS( "aErr=" << aErr );
+ switch( aOperation ) {
+ case EDeleteOp:
+ emit q_ptr->songsDeleted( KErrNone == aErr );
+ break;
+ case EAddOp:
+ emit q_ptr->playlistSaved( KErrNone == aErr );
+ break;
+ case ERenameOp:
+ emit q_ptr->playlistsRenamed( KErrNone == aErr );
+ break;
+ default:
+ break;
+ }
+
+ if ( aArgument ) {
+ delete ( CBase* )aArgument;
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleIsolatedOpenL( const CMPXMedia& aEntries, TInt aError )
+{
+ TX_ENTRY_ARGS( "aError=" << aError );
+ if ( aError == KErrNone ) {
+ if ( iIsolatedCollectionData ) {
+ delete iIsolatedCollectionData;
+ iIsolatedCollectionData = 0;
+ }
+ iIsolatedCollectionData = new MpMpxCollectionData();
+ iIsolatedCollectionData->setMpxMedia( aEntries );
+ emit q_ptr->isolatedCollectionOpened( iIsolatedCollectionData );
+ }
+ else {
+ TX_LOG_ARGS( "Error: " << aError << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleIsolatedOpenRestorePathL( const CMPXCollectionPath& aPath, TInt aError )
+{
+ TX_ENTRY_ARGS( "aError=" << aError );
+ if ( aError == KErrNone ) {
+ CMPXCollectionPath* cpath = CMPXCollectionPath::NewL( aPath );
+ CleanupStack::PushL( cpath );
+ if ( cpath->Count() <= 0 ) {
+ //There are no entries on the path
+ if ( !iRestoreDefaultPath ) {
+ //Try restoring default path if not already tried
+ //This is a special case where a playlist's songs where on the MMC and it was removed
+ iRestoreDefaultPath = ETrue;
+ iRestorePathIndex = 0;
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicAllSongsPathL();
+ CleanupStack::PushL( cpath );
+ iIsolatedCollectionHelper->OpenCollectionL( *cpath, iRestorePathIndex, CMpMpxIsolatedCollectionHelper::RestorePathMode );
+ CleanupStack::PopAndDestroy( cpath );
+ }
+ else {
+ //emit signal to go back to collection view because there is no music
+ emit q_ptr->restorePathFailed();
+ }
+ }
+ else if ( iRestorePathIndex ) {
+ //If RestorePathIndex equals zero there is no need to check with previous index
+ //just go and create playlist below
+ if ( iRestorePathIndex == cpath->IndexOfId( iRestorePathIndexId ) ) {
+ //Song is in path and maintains previous position
+ cpath->Set( iRestorePathIndex );
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( *playList, EFalse );
+ CleanupStack::PopAndDestroy( playList );
+ }
+ else {
+ //Re open path starting at the beginning of the collection
+ iRestorePathIndex = 0;
+ cpath->Back();
+ iIsolatedCollectionHelper->OpenCollectionL( *cpath, iRestorePathIndex, CMpMpxIsolatedCollectionHelper::RestorePathMode );
+ }
+ }
+ else {
+ //We create a playlist right away since there is no need to check the index for the first element
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( *playList, EFalse );
+ CleanupStack::PopAndDestroy( playList );
+ }
+ CleanupStack::PopAndDestroy( cpath );
+ }
+ else if ( aError == KErrNotFound ) {
+ //Path not found (e.g. MMC removed) try restoring default path
+ iRestoreDefaultPath = ETrue;
+ iRestorePathIndex = 0;
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicAllSongsPathL();
+ CleanupStack::PushL( cpath );
+ iIsolatedCollectionHelper->OpenCollectionL( *cpath, iRestorePathIndex, CMpMpxIsolatedCollectionHelper::RestorePathMode );
+ CleanupStack::PopAndDestroy( cpath );
+ }
+ else {
+ //Open path failed
+ TX_LOG_ARGS( "Error: " << aError << "; should never get here." );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::HandleFindAllL( const CMPXMedia& aResults, TBool aComplete, TInt aError )
+{
+ Q_UNUSED( aComplete );
+ TX_ENTRY_ARGS( "aError=" << aError );
+
+ if ( aError == KErrNone ) {
+ iCollectionData->setAlbumContent( aResults );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoInitL()
+{
+ TX_ENTRY
+ iCollectionUtility = MMPXCollectionUtility::NewL( this, iHostUid );
+ iCollectionUiHelper = CMPXCollectionHelperFactory:: NewCollectionUiHelperL( iHostUid );
+ iIncrementalOpenUtil = CMPXCollectionOpenUtility::NewL( this, iHostUid );
+ iCollectionData = new MpMpxCollectionData();
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoOpenCollectionL(
+ TCollectionContext aContext )
+{
+ TX_ENTRY_ARGS( "aContext=" << aContext );
+
+ switch ( aContext ) {
+ case ECollectionContextAllSongs:
+ {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicAllSongsPathL();
+ CleanupStack::PushL( cpath );
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ break;
+ }
+ case ECollectionContextArtists:
+ {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicMenuPathL();
+ CleanupStack::PushL( cpath );
+ cpath->AppendL( BrowseArtist );
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ break;
+ }
+ case ECollectionContextAlbums:
+ {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicMenuPathL();
+ CleanupStack::PushL( cpath );
+ cpath->AppendL( BrowseAlbum );
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ break;
+ }
+ case ECollectionContextPlaylists:
+ {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicPlaylistPathL();
+ CleanupStack::PushL( cpath );
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ break;
+ }
+ case ECollectionContextAlbumsMediaWall:
+ {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicMenuPathL();
+ CleanupStack::PushL( cpath );
+ cpath->AppendL( BrowseAlbumMediaWall );
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ break;
+ }
+ default:
+ TX_LOG_ARGS( "Error: Unexpected context; should never get here." );
+ break;
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoOpenCollectionItemL( TInt aIndex )
+ {
+ TX_ENTRY_ARGS( "aIndex=" << aIndex );
+ iCollectionUtility->Collection().OpenL( aIndex );
+ TX_EXIT
+ }
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoIncrementalOpenL()
+{
+ TX_ENTRY
+ // Cancel any reads
+ iIncrementalOpenUtil->Stop();
+
+ // Start the read
+ iFirstIncrementalOpen = ETrue;
+ RArray<TMPXAttribute> attrs;
+ CleanupClosePushL( attrs );
+ TArray<TMPXAttribute> ary = attrs.Array();
+ iIncrementalOpenUtil->SetDelay( KIncrementalDelay );
+ iIncrementalOpenUtil->StartL( ary, KIncrementalFetchBlockSize,
+ 0, CMPXCollectionOpenUtility::EFetchDown );
+ CleanupStack::PopAndDestroy( &attrs );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoReopenCollectionL()
+{
+ TX_ENTRY
+ CMPXCollectionPath* cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ cpath->Back();
+ iCollectionUtility->Collection().OpenL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoBackL()
+{
+ TX_ENTRY
+ iCollectionUtility->Collection().BackL();
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoFindPlaylistsL( QStringList &playlists )
+{
+ TX_ENTRY
+ delete iUserPlaylists;
+ iUserPlaylists = NULL;
+
+ RArray<TMPXAttribute> attrs;
+ CleanupClosePushL( attrs );
+ attrs.AppendL( KMPXMediaGeneralId );
+ attrs.AppendL( KMPXMediaGeneralTitle );
+
+ CMPXMedia* criteria = CMPXMedia::NewL();
+ CleanupStack::PushL( criteria );
+ criteria->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXGroup );
+ criteria->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+
+ // Look up collection UID and set to criteria
+ RArray<TUid> ary;
+ CleanupClosePushL( ary );
+ ary.AppendL( TUid::Uid( EMPXCollectionPluginMusic ) );
+ TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() );
+ CleanupStack::PopAndDestroy( &ary );
+
+ criteria->SetTObjectValueL<TUid>( KMPXMediaGeneralCollectionId, musicCollection );
+
+ iUserPlaylists = iCollectionUtility->Collection().FindAllL( *criteria, attrs.Array() );
+ CleanupStack::PopAndDestroy( criteria );
+ CleanupStack::PopAndDestroy( &attrs );
+
+ if ( iUserPlaylists ) {
+ const CMPXMediaArray* mediaArray =
+ iUserPlaylists->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ User::LeaveIfNull( const_cast<CMPXMediaArray*>( mediaArray ) );
+ TInt count = mediaArray->Count();
+ for ( TInt i = 0; i < count; i++ ) {
+ CMPXMedia* media( mediaArray->AtL( i ) );
+ const TDesC& titleText = media->ValueText( KMPXMediaGeneralTitle );
+ if ( titleText.Compare( KNullDesC ) != 0 ) {
+ playlists += QString::fromUtf16( titleText.Ptr(), titleText.Length() );
+ }
+ }
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoCreatePlaylistL( QString &playlistName, QList<int> &selection, MpMpxCollectionData* collectionData )
+{
+ TX_ENTRY_ARGS( "playlistName=" << playlistName );
+ CMPXMedia* tracks = CMPXMedia::NewL();
+ CleanupStack::PushL( tracks );
+
+ TPtrC ptr( reinterpret_cast<const TText*>( playlistName.constData() ) );
+ tracks->SetTextValueL( KMPXMediaGeneralTitle, ptr );
+ tracks->SetTextValueL( KMPXMediaGeneralUri, KPlaylistPath );
+ //if collection data is not provided we use the browsing collection.
+ PreparePlaylistMediaL( *tracks, selection, collectionData ? collectionData : iCollectionData );
+
+ iCollectionUiHelper->IncAddL( *tracks, this, KMPXChunkSize );
+ CleanupStack::PopAndDestroy( tracks );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoSaveToPlaylistL( TMPXItemId playlistId, QList<int> &selection, MpMpxCollectionData *collectionData )
+{
+ TX_ENTRY_ARGS( "playlistId=" << int( playlistId ) );
+
+ CMPXMedia* tracks = CMPXMedia::NewL();
+ CleanupStack::PushL( tracks );
+
+ RArray<TUid> ary;
+ CleanupClosePushL( ary );
+ ary.AppendL( TUid::Uid( EMPXCollectionPluginMusic ) );
+ TUid musicCollection = iCollectionUtility->CollectionIDL( ary.Array() );
+ CleanupStack::PopAndDestroy( &ary );
+
+ tracks->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, playlistId );
+ tracks->SetTObjectValueL<TUid>( KMPXMediaGeneralCollectionId, musicCollection );
+ PreparePlaylistMediaL( *tracks, selection, collectionData );
+
+ iCollectionUiHelper->IncAddL( *tracks, this, KMPXChunkSize );
+ CleanupStack::PopAndDestroy( tracks );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoSaveToPlaylistL( int playlistIndex, QList<int> &selection )
+{
+ TX_ENTRY_ARGS( "playlistIndex=" << playlistIndex );
+
+ const CMPXMediaArray* mediaArray = iUserPlaylists->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ User::LeaveIfNull( const_cast<CMPXMediaArray*>( mediaArray ) );
+ CMPXMedia* media( mediaArray->AtL( playlistIndex ) );
+ TMPXItemId playlistId = media->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
+ DoSaveToPlaylistL( playlistId, selection, iCollectionData );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoSaveToCurrentPlaylistL( QList<int> &selection, MpMpxCollectionData *collectionData )
+{
+ TX_ENTRY
+
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ if ( container.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) != EMPXItem &&
+ container.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory) != EMPXPlaylist) {
+ User::Leave( KErrArgument );
+ }
+ TMPXItemId playlistId( container.ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ DoSaveToPlaylistL( playlistId, selection, collectionData );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoDeleteSongsL( QList<int> &selection )
+{
+ int count = selection.count();
+ TX_ENTRY_ARGS( "selection count=" << count );
+
+ CMPXCollectionPath* path( iCollectionUtility->Collection().PathL() );
+ CleanupStack::PushL( path );
+
+ if (count > 1) {
+ for ( TInt i = 0; i < count; i++ ){
+ path->SelectL( selection.at( i ) );
+ }
+ }
+ else {
+ path->Set( selection.at(0) );
+ }
+
+ iCollectionUiHelper->DeleteL( *path, this );
+ CleanupStack::PopAndDestroy( path );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoDeleteAlbumSongsL( QList<int> &selection )
+{
+ int count = selection.count();
+ TX_ENTRY_ARGS( "selection count=" << count );
+
+ CMPXCollectionPath* path( iCollectionUtility->Collection().PathL() );
+ CleanupStack::PushL( path );
+ MPX_DEBUG_PATH( *path );
+
+ CMPXMediaArray *mediaArray;
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ mediaArray = const_cast<CMPXMediaArray*>( container.Value<CMPXMediaArray>( KMPXMediaArrayContents ) );
+ int currentAlbumIndex = iCollectionData->currentAlbumIndex();
+ CMPXMedia* album( mediaArray->AtL( currentAlbumIndex ) );
+ if ( album->IsSupported(KMPXMediaArrayContents) ) {
+ const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(const_cast<CMPXMediaArray*>(songs));
+ int index = selection.at(0);
+ CMPXMedia* song = songs->AtL(index);
+
+ TMPXItemId id( song->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ path->AppendL( id ); // Append the song ID to be deleted
+ path->Set( 0 ); // Select 1st song
+
+ iCollectionUiHelper->DeleteL( *path, this );
+ }
+ CleanupStack::PopAndDestroy( path );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoRenamePlaylistL( QString &newName, int index )
+{
+ TX_ENTRY
+ CMPXMediaArray *mediaArray;
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ mediaArray = const_cast<CMPXMediaArray*>( container.Value<CMPXMediaArray>( KMPXMediaArrayContents ) );
+ CMPXMedia* currentPlaylistMedia( mediaArray->AtL( index ) );
+ TMPXItemId id( currentPlaylistMedia->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ DoRenamePlaylistL( id, newName );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoRenamePlaylistL( QString &newName )
+{
+ TX_ENTRY
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ TMPXItemId id( container.ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ DoRenamePlaylistL( id, newName );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoRenamePlaylistL( TMPXItemId id, QString &newName )
+ {
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL( media );
+ media->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ media->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+ media->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, id );
+ TPtrC ptr( reinterpret_cast<const TText*>( newName.constData() ) );
+ media->SetTextValueL( KMPXMediaGeneralTitle, ptr );
+ iCollectionUiHelper->RenameL( *media, this );
+ CleanupStack::PopAndDestroy( media );
+ }
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoSetShuffleL( bool active )
+{
+ TX_ENTRY
+ if ( iPlaybackUtility ) {
+ iPlaybackUtility->SetL( EPbPropertyRandomMode, active );
+ }
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoPreviewSongL( int index )
+{
+ TX_ENTRY
+
+ // Get the current path
+ CMPXCollectionPath* cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ MPX_DEBUG_PATH( *cpath );
+ cpath->Back();
+
+ TMPXItemId id( iCollectionData->itemId(index) );
+ cpath->AppendL( id ); // Top level items of songs
+ cpath->Set( 0 ); // Select 1st song
+
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+ playList->SetToFirst();
+ //TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( *playList, ETrue );
+ emit q_ptr->collectionPlaylistOpened();
+
+ CleanupStack::PopAndDestroy( playList );
+ CleanupStack::PopAndDestroy( cpath );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoPreviewAlbumSongL( int index )
+{
+ TX_ENTRY
+ //TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ if ( !iPlaybackUtility ) {
+ iPlaybackUtility = MMPXPlaybackUtility::UtilityL( iHostUid );
+ }
+
+ // Get the current path
+ CMPXCollectionPath* cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ MPX_DEBUG_PATH( *cpath );
+
+ CMPXMediaArray *mediaArray;
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ mediaArray = const_cast<CMPXMediaArray*>( container.Value<CMPXMediaArray>( KMPXMediaArrayContents ) );
+ int currentAlbumIndex = iCollectionData->currentAlbumIndex();
+ CMPXMedia* album( mediaArray->AtL( currentAlbumIndex ) );
+ if ( album->IsSupported(KMPXMediaArrayContents) ) {
+ const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(const_cast<CMPXMediaArray*>(songs));
+ CMPXMedia* song = songs->AtL(index);
+
+ TMPXItemId id( song->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ cpath->AppendL( id ); // Top level items of songs
+ cpath->Set( 0 ); // Select 1st song
+
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+ playList->SetToFirst();
+ //TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ iPlaybackUtility->InitL( *playList, ETrue );
+ emit q_ptr->collectionPlaylistOpened();
+
+ CleanupStack::PopAndDestroy( playList );
+ }
+ CleanupStack::PopAndDestroy( cpath );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoOpenIsolatedCollectionL( TCollectionContext context )
+{
+
+ if ( ECollectionContextAllSongs == context ) {
+ CMPXCollectionPath* cpath = iCollectionUiHelper->MusicAllSongsPathL();
+ CleanupStack::PushL( cpath );
+ if ( !iIsolatedCollectionHelper ) {
+ iIsolatedCollectionHelper = CMpMpxIsolatedCollectionHelper::NewL( this );
+ }
+ iIsolatedCollectionHelper->OpenCollectionL( *cpath );
+ CleanupStack::PopAndDestroy( cpath );
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoReorderPlaylistL( int playlistId, int songId, int originalOrdinal, int newOrdinal )
+{
+ iCollectionUiHelper->ReorderPlaylistL( playlistId, songId, originalOrdinal, newOrdinal, this );
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoFindAlbumSongsL( int index )
+{
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ const CMPXMediaArray* mediaArray = container.Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ CMPXMedia* album( mediaArray->AtL( index ) );
+
+ // Obtain the artistId from the container
+ TMPXItemId artistId = container.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
+
+ // Fetch the songs for the selected album and the artist
+ // Specifying artistId is necessary to search for songs in the artist’s unknown album.
+ TMPXItemId albumId = album->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
+ CMPXMedia* findCriteria = CMPXMedia::NewL();
+ CleanupStack::PushL( findCriteria );
+ findCriteria->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, EMPXGroup );
+ findCriteria->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, EMPXSong );
+ findCriteria->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, albumId );
+ findCriteria->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralContainerId, artistId );
+ RArray<TMPXAttribute> attrs;
+ CleanupClosePushL( attrs );
+ attrs.AppendL( TMPXAttribute( KMPXMediaIdGeneral,
+ EMPXMediaGeneralTitle |
+ EMPXMediaGeneralUri |
+ EMPXMediaGeneralId |
+ EMPXMediaGeneralType |
+ EMPXMediaGeneralCategory |
+ EMPXMediaGeneralFlags ) );
+ attrs.AppendL( KMPXMediaMusicAlbumTrack );
+
+ iCollectionUtility->Collection().FindAllL( *findCriteria, attrs.Array(), *this );
+ CleanupStack::PopAndDestroy( &attrs );
+ CleanupStack::PopAndDestroy( findCriteria );
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoPlayAlbumSongsL( int albumIndex, int songIndex, MpMpxCollectionData* collectionData )
+{
+ TX_ENTRY
+
+ RArray<TMPXItemId> ids;
+ CleanupClosePushL(ids);
+
+ CMPXCollectionPath* cpath;
+
+ //Following check is for a use case for media wall, where it is required
+ //to play songs that are browsed by an isolated collection.
+ if ( collectionData->context() == ECollectionContextAlbumsMediaWall ) {
+ //Get the Media Wall path.
+ cpath = iCollectionUiHelper->MusicMenuPathL();
+ CleanupStack::PushL( cpath );
+ //TODO: change to BrowseAlbumMediaWall befor when merging with olveras changes.
+ cpath->AppendL( BrowseAlbum );
+ const TMPXItemId albumId = collectionData->itemId( albumIndex );
+ //Append the selected album.
+ RArray<TMPXItemId> items;
+ CleanupClosePushL(items);
+ items.AppendL(albumId);
+ cpath->AppendL(items.Array());
+ CleanupStack::PopAndDestroy( &items );
+ cpath->Set( 0 ); // Set the album.
+
+ }
+ else {
+ // Get the current path
+ cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ cpath->Set(albumIndex); // Set the selected album
+ }
+ MPX_DEBUG_PATH( *cpath );
+
+ CMPXMediaArray *mediaArray;
+ const CMPXMedia& container = collectionData->containerMedia();
+ mediaArray = const_cast<CMPXMediaArray*>( container.Value<CMPXMediaArray>( KMPXMediaArrayContents ) );
+ CMPXMedia* album( mediaArray->AtL( albumIndex ) );
+ const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(const_cast<CMPXMediaArray*>(songs));
+
+ TInt count = songs->Count();
+ for ( TInt i = 0; i < count; ++i ) {
+ CMPXMedia* song = songs->AtL(i);
+ const TMPXItemId id = song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
+ ids.AppendL(id);
+ }
+
+ cpath->AppendL(ids.Array()); // Top level items of songs
+ cpath->Set(songIndex); // Set the selected song
+ MPX_DEBUG_PATH(*cpath);
+
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+
+ //TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( *playList, ETrue );
+ emit q_ptr->collectionPlaylistOpened();
+
+ CleanupStack::PopAndDestroy( playList );
+ CleanupStack::PopAndDestroy( cpath );
+ CleanupStack::PopAndDestroy( &ids );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::setRepeatFeatureEnabled( bool enable )
+{
+ iRepeatFeature = enable;
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::setShuffleFeatureEnabled( bool enable )
+{
+ iShuffleFeature = enable;
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoHandleCollectionMessageL(
+ const CMPXMessage& aMsg )
+{
+ TX_ENTRY
+ TMPXMessageId id( aMsg.ValueTObjectL<TMPXMessageId>( KMPXMessageGeneralId ) );
+ if ( KMPXMessageGeneral == id ) {
+ TInt event( aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralEvent ) );
+ TInt type( aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralType ) );
+ TInt data( aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralData ) );
+ TX_LOG_ARGS( "event=" << event << ", type=" << type << ", data=" << data );
+
+ if ( event == TMPXCollectionMessage::EPathChanged &&
+ type == EMcPathChangedByOpen &&
+ data == EMcContainerOpened ) {
+ // Incremental Open when browsing to the next level
+ DoIncrementalOpenL();
+ }
+ else if ( event == TMPXCollectionMessage::EPathChanged &&
+ type == EMcPathChangedByOpen &&
+ data == EMcItemOpened ) {
+ // Opened a song
+ // This will result in HandleOpenL with CMPXCollectionPlaylist
+ iCollectionUtility->Collection().OpenL();
+ }
+ }
+ else if( id == KMPXMessageIdItemChanged ) {
+ TInt eventType( aMsg.ValueTObjectL<TMPXChangeEventType>( KMPXMessageChangeEventType ) );
+
+ if ( eventType == EMPXItemDeleted || eventType == EMPXItemInserted ) {
+ emit q_ptr->containerContentsChanged();
+ }
+ }
+ TX_EXIT
+}
+
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::PreparePlaylistMediaL(
+ CMPXMedia& aMedia,
+ QList<int> &selection,
+ MpMpxCollectionData *collectionData )
+{
+ int count = selection.count();
+ TX_ENTRY_ARGS( "selection count=" << count );
+
+ const CMPXMediaArray* mediaArray = 0;
+
+ if ( ( collectionData->context() == ECollectionContextArtistAlbumsTBone ) ||
+ ( collectionData->context() == ECollectionContextAlbumsTBone ) ) {
+ //There is no need to find the track information, for TBone we cash it under the media itself.
+ //Fetching song data from container media.
+ CMPXMedia* album;
+ const CMPXMediaArray* albumsArray;
+ albumsArray = collectionData->containerMedia().Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ int index = collectionData->currentAlbumIndex();
+ if ( index >= 0 ) {
+ album = albumsArray->AtL( collectionData->currentAlbumIndex() );
+ mediaArray = album->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ }
+ }
+ else {
+ const CMPXMedia& container = collectionData->containerMedia();
+ mediaArray = container.Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ }
+
+ User::LeaveIfNull( const_cast<CMPXMediaArray*>( mediaArray ) );
+ CMPXMediaArray* tracksArray( CMPXMediaArray::NewL() );
+ CleanupStack::PushL( tracksArray );
+
+ CMPXCollectionPath* path( iCollectionUtility->Collection().PathL() );
+ CleanupStack::PushL( path );
+ TMPXItemId collectionId( path->Id( 0 ) );
+ CleanupStack::PopAndDestroy( path );
+
+ if ( collectionData->context() == ECollectionContextAlbums ||
+ collectionData->context() == ECollectionContextArtistAlbums ||
+ collectionData->context() == ECollectionContextArtists ) {
+ //Container, it is possible to append multiple containers to a playlist.
+ //Currently we are just using single selection from the ui.
+ for ( TInt i = 0; i < count; i++ ) {
+ CMPXMedia* results;
+ CMPXMedia* container( mediaArray->AtL( selection[i] ) );
+ // Fetch the songs for the selected container
+ TMPXItemId containerId = container->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
+ CMPXMedia* findCriteria = CMPXMedia::NewL();
+ CleanupStack::PushL( findCriteria );
+ findCriteria->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, EMPXGroup );
+ findCriteria->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, EMPXSong );
+ findCriteria->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, containerId );
+ RArray<TMPXAttribute> attrs;
+ CleanupClosePushL( attrs );
+ attrs.AppendL( TMPXAttribute( KMPXMediaIdGeneral,
+ EMPXMediaGeneralTitle |
+ EMPXMediaGeneralId ) );
+ results = iCollectionUtility->Collection().FindAllL( *findCriteria, attrs.Array() );
+ CleanupStack::PopAndDestroy( &attrs );
+ CleanupStack::PopAndDestroy( findCriteria );
+ CleanupStack::PushL( results );
+
+ const CMPXMediaArray* resultsArray = results->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ User::LeaveIfNull( resultsArray );
+ for ( int j = 0 ; j < resultsArray->Count();j++ ) {
+ CMPXMedia* media( resultsArray->AtL( j ) );
+ CMPXMedia* entry = CMPXMedia::NewL();
+ CleanupStack::PushL( entry );
+ entry->SetTextValueL( KMPXMediaGeneralTitle,
+ media->ValueText( KMPXMediaGeneralTitle ) );
+ entry->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem );
+ entry->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXSong );
+ entry->SetTObjectValueL( KMPXMediaGeneralId,
+ media->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ entry->SetTObjectValueL( KMPXMediaGeneralCollectionId, collectionId );
+ CleanupStack::Pop( entry );
+ tracksArray->AppendL( entry );
+ }
+ CleanupStack::PopAndDestroy( results );
+ }
+
+ }
+ else {
+ //Tracks
+ for ( TInt i = 0; i < count; i++ ) {
+ CMPXMedia* media( mediaArray->AtL( selection.at( i ) ) );
+ CMPXMedia* entry = CMPXMedia::NewL();
+ CleanupStack::PushL( entry );
+ entry->SetTextValueL( KMPXMediaGeneralTitle,
+ media->ValueText( KMPXMediaGeneralTitle ) );
+ entry->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem );
+ entry->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXSong );
+ entry->SetTObjectValueL( KMPXMediaGeneralId,
+ media->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ entry->SetTObjectValueL( KMPXMediaGeneralCollectionId, collectionId );
+ CleanupStack::Pop( entry );
+ tracksArray->AppendL( entry );
+ }
+ }
+ aMedia.SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, EMPXItem );
+ aMedia.SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, EMPXPlaylist );
+ aMedia.SetCObjectValueL( KMPXMediaArrayContents, tracksArray );
+ aMedia.SetTObjectValueL( KMPXMediaArrayCount, tracksArray->Count() );
+
+ emit q_ptr->aboutToAddSongs( tracksArray->Count() );
+
+ CleanupStack::PopAndDestroy( tracksArray );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ TODO: all calls to playback utility should be done via the engine and trough the playback FW wrapper.
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::createPlaybackUtilityL()
+{
+ if ( !iPlaybackUtility ) {
+
+ iPlaybackUtility = MMPXPlaybackUtility::UtilityL( iHostUid );
+
+ if ( iShuffleFeature ) {
+ iPlaybackUtility->SetL( EPbPropertyRandomMode, MpSettingsManager::shuffle() ? ETrue : EFalse );
+ }
+ if ( iRepeatFeature ) {
+ iPlaybackUtility->SetL( EPbPropertyRepeatMode, MpSettingsManager::repeat() ? EPbRepeatAll : EPbRepeatOff );
+ }
+ }
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoPlayAllSongsPlaylistL()
+{
+ TX_ENTRY
+ CMPXCollectionPath* cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *cpath );
+ CleanupStack::PushL( playList );
+ playList->SetShuffleL( true, false );
+ MpSettingsManager::setShuffle( true );
+ createPlaybackUtilityL();
+ iPlaybackUtility->InitL( *playList, ETrue );
+ CleanupStack::PopAndDestroy( playList );
+ CleanupStack::PopAndDestroy( cpath );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoRetrieveSongDetailsL( int index )
+{
+ TX_ENTRY
+ RArray<TMPXAttribute> requestedAttr;
+ CleanupClosePushL( requestedAttr );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralTitle ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicArtist ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicAlbum ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralUri ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicAlbumArtFileName ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralMimeType ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicAlbumTrack ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicComposer ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicYear ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicGenre ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralDuration ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaAudioBitrate ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaAudioSamplerate ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaGeneralCopyright ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaMusicURL ) );
+ requestedAttr.AppendL( TMPXAttribute( KMPXMediaDrmProtected ) );
+
+ CMPXCollectionPath* cpath = iCollectionUtility->Collection().PathL();
+ CleanupStack::PushL( cpath );
+ TCollectionContext context = iCollectionData->context();
+ if ( context == ECollectionContextArtistAlbumsTBone
+ || context == ECollectionContextAlbumsTBone ) {
+ CMPXMediaArray *mediaArray;
+ const CMPXMedia& container = iCollectionData->containerMedia();
+ mediaArray = const_cast<CMPXMediaArray*>( container.Value<CMPXMediaArray>( KMPXMediaArrayContents ) );
+ int currentAlbumIndex = iCollectionData->currentAlbumIndex();
+ CMPXMedia* album( mediaArray->AtL( currentAlbumIndex ) );
+ if ( album->IsSupported(KMPXMediaArrayContents) ) {
+ const CMPXMediaArray* songs = album->Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(const_cast<CMPXMediaArray*>(songs));
+ CMPXMedia* song = songs->AtL(index);
+ TMPXItemId id( song->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
+ cpath->AppendL( id ); // Top level items of songs
+ cpath->Set( 0 ); // Select 1st song
+ }
+ }
+ else {
+ cpath->Set( index );
+ }
+ iCollectionUtility->Collection().MediaL( *cpath, requestedAttr.Array() );
+ CleanupStack::PopAndDestroy( cpath );
+ CleanupStack::PopAndDestroy( &requestedAttr );
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoSavePathL( QByteArray &data )
+{
+ TX_ENTRY
+ CBufFlat* buffer = CBufFlat::NewL( 256 );
+ CleanupStack::PushL( buffer );
+ TBufBuf bufBuf;
+ bufBuf.Set( *buffer, 0, TBufBuf::EWrite );
+
+ RWriteStream writeStream( &bufBuf );
+ writeStream.PushL();
+
+ if ( iPlaybackUtility ) {
+ MMPXSource* source = iPlaybackUtility->Source();
+ CMPXCollectionPlaylist* playList( NULL );
+ if( source ) {
+ playList = source->PlaylistL();
+ if ( playList ) {
+ CleanupStack::PushL( playList );
+ const CMPXCollectionPath& cpath = playList->Path();
+ writeStream << cpath;
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy( playList );
+ }
+ }
+ }
+ data.append(reinterpret_cast<const char*>(buffer->Ptr(0).Ptr()) ,buffer->Ptr(0).Length());
+ CleanupStack::PopAndDestroy( 2, buffer ); //writeStream and buffer
+ TX_EXIT
+}
+
+/*!
+ \internal
+ */
+void MpMpxCollectionFrameworkWrapperPrivate::DoRestorePathL( const QByteArray &data )
+{
+ TX_ENTRY
+ int dataSize = data.size();
+ if ( dataSize > 0 ) {
+ TPtrC8 activityDataDescriptor( reinterpret_cast<const unsigned char*> ( data.constData() ), data.size() );
+
+ //Take a copy of the data
+ CBufFlat* buffer = CBufFlat::NewL( dataSize );
+ CleanupStack::PushL( buffer );
+ buffer->InsertL( 0, activityDataDescriptor, dataSize );
+
+ TBufBuf bufBuf;
+ bufBuf.Set( *buffer, 0, TBufBuf::ERead );
+ RReadStream readStream( &bufBuf );
+ readStream.PushL();
+
+ CMPXCollectionPath* cpath( NULL );
+ cpath = CMPXCollectionPath::NewL(readStream);
+ CleanupStack::PushL(cpath);
+ iRestorePathIndex = 0;
+ if( cpath->Levels() ) {
+ iRestorePathIndexId = cpath->Id();
+ iRestorePathIndex = cpath->Index();
+ cpath->Back();
+ }
+ if ( !iIsolatedCollectionHelper ) {
+ iIsolatedCollectionHelper = CMpMpxIsolatedCollectionHelper::NewL( this );
+ }
+ iIsolatedCollectionHelper->OpenCollectionL( *cpath, iRestorePathIndex, CMpMpxIsolatedCollectionHelper::RestorePathMode );
+
+ CleanupStack::PopAndDestroy( cpath );
+ CleanupStack::PopAndDestroy( 2, buffer ); //readStream and buffer
+ }
+ TX_EXIT
+}
+
+//EOF