mpengine/src/mpmpxcollectionframeworkwrapper_p.cpp
author hgs
Fri, 06 Aug 2010 16:51:36 -0500
changeset 47 4cc1412daed0
parent 45 612c4815aebe
child 51 560ce2306a17
permissions -rw-r--r--
201031

/*
* 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 KIncrementalDelayNone = 0;
const TInt KIncrementalDelayHalfSecond = 500000;
const TInt KIncrementalFetchBlockSize = 400;

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_ENTRY_ARGS( "Path is ready" );
                DoPlayAllSongsPlaylistL();
                
            }
            iCollectionData->setMpxMedia( aEntries, iReopen );
            iReopen = EFalse;
        }
    }
    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( KIncrementalDelayNone );
    iIncrementalOpenUtil->StartL( ary, KIncrementalFetchBlockSize,
                                  KErrNotFound, CMPXCollectionOpenUtility::EFetchDown );
    iIncrementalOpenUtil->SetDelay( KIncrementalDelayHalfSecond );
    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