mmappcomponents/collectionhelper/src/mpxcollectionuihelperimp.cpp
changeset 0 a2952bb97e68
child 2 7a9a8e73f54b
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Collection Ui Helper implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <s32file.h>
       
    21 #include <mpxmedia.h>
       
    22 #include <mpxcollectionplaylist.h>
       
    23 #include <mpxmediaarray.h>
       
    24 #include <mpxmediageneraldefs.h>
       
    25 #include <mpxmediacontainerdefs.h>
       
    26 #include <mpxuser.h>
       
    27 #include <mpxcmn.h>
       
    28 #include <mpxcollectionutility.h>
       
    29 #include <mpxcollectiontype.h>
       
    30 #include <mpxcollectionmediator.h>
       
    31 #include <mpxplaylistenginedefs.h>
       
    32 #include <mpxlog.h>
       
    33 #include <mpxcollectionmessage.h>
       
    34 #include <mpxtaskqueue.h>
       
    35 #include <mpxcollectionplugin.hrh>
       
    36 #include <mpxharvesterutility.h>
       
    37 #include <mpxcommandgeneraldefs.h>
       
    38 #include <mpxcollectioncommanddefs.h>
       
    39 #include <UsbWatcherInternalPSKeys.h>
       
    40 #include <usbpersonalityids.h>
       
    41 
       
    42 #include "mpxcollectionuihelperobserver.h"
       
    43 #include "mpxcollectionuihelperimp.h"
       
    44 #include "mpxcollectionhelpercommon.h"
       
    45 #include "mpxdeletehelper.h"
       
    46 
       
    47 // CONSTANTS
       
    48 const TInt KMPXAllSongsViewIndex = 0;
       
    49 const TInt KMPXPlaylistViewIndex = 1;
       
    50 const TInt KMPXRecentlyPlayedIndex = 0x20000000;
       
    51 const TInt KMPXMostPlayedIndex = 0x20000001;
       
    52 const TInt KMPXRecentlyAddedIndex = 0x20000002;
       
    53 
       
    54 _LIT( KPathVirtualPlaylistHandling, "openpath.dat");
       
    55 
       
    56 // ======== MEMBER FUNCTIONS ========
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // Private Constructor
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CMPXCollectionUiHelperImp::CMPXCollectionUiHelperImp()
       
    63     {
       
    64     }
       
    65 
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // 2nd Phase Constructor
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 void CMPXCollectionUiHelperImp::ConstructL(const TUid& aModeId)
       
    72     {
       
    73     iCollection = MMPXCollectionUtility::NewL(this,aModeId);
       
    74     iMediator = CMPXCollectionMediator::NewL( iCollection->Collection(),
       
    75                                               this );
       
    76     iHarvester = CMPXHarvesterFactory::NewL();
       
    77     iTaskQueue = CMPXActiveTaskQueue::NewL();
       
    78     iDeleteHelper = CMPXDeleteHelper::NewL(*iCollection, *iHarvester, *this);
       
    79     
       
    80     iRemainder = 0;
       
    81     iTotalChunkNumber = 0;
       
    82     iChunkNumber = 0;
       
    83     iChunkSize = 0;
       
    84     iArrayIndex = 0;
       
    85     }
       
    86 
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 // Two-Phased Constructor
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 CMPXCollectionUiHelperImp* CMPXCollectionUiHelperImp::NewL(const TUid& aModeId)
       
    93     {
       
    94     CMPXCollectionUiHelperImp* self = CMPXCollectionUiHelperImp::NewLC(aModeId);
       
    95     CleanupStack::Pop( self );
       
    96     return self;
       
    97     }
       
    98 
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Two-Phased Constructor
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 CMPXCollectionUiHelperImp* CMPXCollectionUiHelperImp::NewLC(const TUid& aModeId)
       
   105     {
       
   106     CMPXCollectionUiHelperImp* self = new( ELeave ) CMPXCollectionUiHelperImp();
       
   107     CleanupStack::PushL( self );
       
   108     self->ConstructL(aModeId);
       
   109     return self;
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // Virtual Destructor
       
   114 // ---------------------------------------------------------------------------
       
   115 //
       
   116 CMPXCollectionUiHelperImp::~CMPXCollectionUiHelperImp()
       
   117     {
       
   118     delete iMediator;
       
   119     if( iCollection )
       
   120         {
       
   121         iCollection->Close();
       
   122         }
       
   123     if( iHarvester )
       
   124         {
       
   125         iHarvester->Close();
       
   126         }
       
   127     delete iTaskQueue;
       
   128     delete iMedia;
       
   129     delete iDeleteHelper;
       
   130     
       
   131     delete iInputMedia;
       
   132     }
       
   133 
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // Issue collection initialization command to collection framework.
       
   137 // This is necessary when collection helper serves as an intermediator
       
   138 // between collection framework and Podcast App or MTP, etc.
       
   139 // There is, currently, no way to check the merge status of the collections
       
   140 // through the collection utility API.  Therefore, collectionhelper issue
       
   141 // an EMcCmdCollectionInit(or merge) command before any collectionhelper
       
   142 // functionality, which expects collection is in valid state, is excuted.
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // Add a Media to the collection
       
   148 // ---------------------------------------------------------------------------
       
   149 //
       
   150 void CMPXCollectionUiHelperImp::AddL( const CMPXMedia& aMedia,
       
   151                                 MMPXCHelperObserver* aObserver )
       
   152     {
       
   153     if (!aObserver)
       
   154         {
       
   155         User::Leave( KErrArgument );
       
   156         }
       
   157 
       
   158     //
       
   159     // leave if the given media doesn't contain the following attributes
       
   160     //
       
   161     if (!aMedia.IsSupported(KMPXMediaGeneralType) ||
       
   162         !aMedia.IsSupported(KMPXMediaGeneralCategory))
       
   163         {
       
   164         User::Leave( KErrArgument );
       
   165         }
       
   166 
       
   167     //
       
   168     // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category
       
   169     // must be EMPXPlaylist
       
   170     //
       
   171     TMPXGeneralType mediaType =
       
   172          aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
   173 
       
   174     TMPXGeneralCategory mediaCategory =
       
   175          aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
   176 
       
   177     //
       
   178     // currently only supporting playlists
       
   179     //
       
   180     if ( mediaType != EMPXItem ||
       
   181          mediaCategory != EMPXPlaylist )
       
   182         {
       
   183         User::Leave( KErrNotSupported );
       
   184         }
       
   185 
       
   186     //
       
   187     // leave if the media doesn't contain mandatory attributes for adding a playlist
       
   188     // or adding (appending) tracks to an existing playlist.
       
   189     // Required attributes for adding a new playlist are:
       
   190     //  type, category, array contents, array counts, title, and path for playlist
       
   191     // Required attributes for adding tracks to an existing playlist are:
       
   192     //  type, category, array contents, array counts, and playlist Id
       
   193     //
       
   194     if (!aMedia.IsSupported(KMPXMediaArrayContents) ||
       
   195         !aMedia.IsSupported(KMPXMediaArrayCount))
       
   196         {
       
   197         User::Leave( KErrArgument );
       
   198         }
       
   199 
       
   200     TInt task(ETaskNone);
       
   201     if (!aMedia.IsSupported(KMPXMediaGeneralId))
       
   202         {
       
   203         if (!aMedia.IsSupported(KMPXMediaGeneralTitle) ||
       
   204             !aMedia.IsSupported(KMPXMediaGeneralUri))
       
   205             {
       
   206             User::Leave( KErrArgument );
       
   207             }
       
   208         else
       
   209             {
       
   210             task = ETaskAddMedia;
       
   211             }
       
   212         }
       
   213     else
       
   214         {
       
   215         task = ETaskAppendMedia;
       
   216         }
       
   217 
       
   218     //
       
   219     // externalize parameters
       
   220     //
       
   221     CBufBase* taskParam(NULL);
       
   222     ::CreateBufferL<CMPXMedia>( aMedia, taskParam );
       
   223     CleanupStack::PushL(taskParam);
       
   224 
       
   225     // Increase reference count for task queue
       
   226     CMPXMedia* ref = CMPXMedia::NewL( aMedia );
       
   227     CleanupStack::PushL(ref);
       
   228 
       
   229     //
       
   230     // add request to the task queue
       
   231     //
       
   232     iTaskQueue->AddTaskL( task,
       
   233                           aObserver,   // callback when task completed
       
   234                           this,        // task queue observer
       
   235                           0,           // Integer paramter, not used
       
   236                           taskParam,   // task queue assumes ownership of taskParam
       
   237                           NULL,        // Ptr data
       
   238                           ref );       // ownership transferred
       
   239 
       
   240     CleanupStack::Pop(2, taskParam);   // ref & task Param
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // Increment Addition
       
   245 // ---------------------------------------------------------------------------
       
   246 //
       
   247 void CMPXCollectionUiHelperImp::IncAddL( const CMPXMedia& aMedia,
       
   248                                          MMPXCHelperObserver* aObserver,
       
   249                                          const TInt aSize )
       
   250     {
       
   251     if (!aObserver)
       
   252         {
       
   253         User::Leave( KErrArgument );
       
   254         }
       
   255     
       
   256     //
       
   257     // leave if the given media doesn't contain the following attributes
       
   258     //
       
   259     if (!aMedia.IsSupported(KMPXMediaGeneralType) ||
       
   260         !aMedia.IsSupported(KMPXMediaGeneralCategory))
       
   261         {
       
   262         User::Leave( KErrArgument );
       
   263         }
       
   264         
       
   265     //
       
   266     // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category
       
   267     // must be EMPXPlaylist
       
   268     //
       
   269     TMPXGeneralType mediaType =
       
   270          aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
   271 
       
   272     TMPXGeneralCategory mediaCategory =
       
   273          aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
   274 
       
   275     //
       
   276     // currently only supporting playlists
       
   277     //
       
   278     if ( mediaType != EMPXItem ||
       
   279          mediaCategory != EMPXPlaylist )
       
   280         {
       
   281         User::Leave( KErrNotSupported );
       
   282         }
       
   283 
       
   284     //
       
   285     // leave if the media doesn't contain mandatory attributes for adding a playlist
       
   286     // or adding (appending) tracks to an existing playlist.
       
   287     // Required attributes for adding a new playlist are:
       
   288     //  type, category, array contents, array counts, title, and path for playlist
       
   289     // Required attributes for adding tracks to an existing playlist are:
       
   290     //  type, category, array contents, array counts, and playlist Id
       
   291     //
       
   292     if (!aMedia.IsSupported(KMPXMediaArrayContents) ||
       
   293         !aMedia.IsSupported(KMPXMediaArrayCount))
       
   294         {
       
   295         User::Leave( KErrArgument );
       
   296         }
       
   297 
       
   298     TInt task(ETaskNone);
       
   299     if (!aMedia.IsSupported(KMPXMediaGeneralId))
       
   300         {
       
   301         if (!aMedia.IsSupported(KMPXMediaGeneralTitle) ||
       
   302             !aMedia.IsSupported(KMPXMediaGeneralUri))
       
   303             {
       
   304             User::Leave( KErrArgument );
       
   305             }
       
   306         else
       
   307             {
       
   308             task = ETaskAddMedia;
       
   309             }
       
   310         }
       
   311     else
       
   312         {
       
   313         task = ETaskAppendMedia;
       
   314         }
       
   315 
       
   316     // get tracks from input media
       
   317     // since using Value instead of ValueCObject, no Push/Pop
       
   318     CMPXMediaArray* tracksArray = 
       
   319         aMedia.Value<CMPXMediaArray>( KMPXMediaArrayContents );
       
   320     
       
   321     // use incremental add only if number of songs > aSize
       
   322     // this is needed as IncAdd does not deal w/ the case when tracksArray->Count() == aSize
       
   323     if( tracksArray->Count() <= aSize || aSize <= 0 )
       
   324         {
       
   325         //
       
   326         // externalize parameters
       
   327         //
       
   328         CBufBase* taskParam(NULL);
       
   329         ::CreateBufferL<CMPXMedia>( aMedia, taskParam );
       
   330         CleanupStack::PushL(taskParam);
       
   331     
       
   332         // Increase reference count for task queue
       
   333         CMPXMedia* ref = CMPXMedia::NewL( aMedia );
       
   334         CleanupStack::PushL(ref);
       
   335         
       
   336         //
       
   337         // add request to the task queue
       
   338         //
       
   339         iTaskQueue->AddTaskL( task,
       
   340                               aObserver,   // callback when task completed
       
   341                               this,        // task queue observer
       
   342                               0,           // Integer paramter, not used
       
   343                               taskParam,   // task queue assumes ownership of taskParam
       
   344                               NULL,        // Ptr data 
       
   345                               ref );       // ownership transferred
       
   346                               
       
   347         CleanupStack::Pop(2, taskParam);   // ref & task Param
       
   348         }
       
   349     else // Inc Add
       
   350         { 
       
   351         // calculate number of songs in the last chunk   
       
   352         iRemainder = tracksArray->Count() % aSize;
       
   353         
       
   354         // calculate the number of iterations/chunks needed to divide the songs
       
   355         // each chunk contians aSize number of songs
       
   356         if( iRemainder == 0 )
       
   357             {
       
   358             iTotalChunkNumber = tracksArray->Count() / aSize;
       
   359             }
       
   360         else
       
   361             {
       
   362             iTotalChunkNumber = tracksArray->Count() / aSize + 1;
       
   363             }
       
   364         
       
   365         iChunkNumber = 0;  // initialize chunk number
       
   366         iChunkSize = aSize;
       
   367         
       
   368         // need this in the case multiple Inc Add is called (if something leaves and
       
   369         // iInputMedia was not cleaned up properly)
       
   370         if( iInputMedia )
       
   371             {
       
   372             delete iInputMedia;
       
   373             iInputMedia = NULL;
       
   374             }
       
   375         
       
   376         // save needed info for subsequent processing
       
   377         iInputMedia = CMPXMedia::CopyL(aMedia);
       
   378         iArrayIndex = 0;  // index on tracksArray of the input media
       
   379         
       
   380         for( int i = 0; i < iTotalChunkNumber; i++ )
       
   381             {
       
   382             if( task ==  ETaskAddMedia )
       
   383                 {
       
   384                 // schedule the adding requests to the task queue
       
   385                 iTaskQueue->AddTaskL( ETaskIncAddMedia,
       
   386                                       aObserver,   // callback when task completed
       
   387                                       this );        // task queue observer
       
   388                 }
       
   389             else  // ETaskAppendMedia
       
   390                 {
       
   391                 // schedule the appending requests to the task queue
       
   392                 iTaskQueue->AddTaskL( ETaskIncAppendMedia,
       
   393                                       aObserver,   // callback when task completed
       
   394                                       this );        // task queue observer
       
   395                 }
       
   396             }
       
   397         }
       
   398     
       
   399     }
       
   400 
       
   401 
       
   402 
       
   403 
       
   404 // ---------------------------------------------------------------------------
       
   405 // Update a single media property
       
   406 // Checks for podcast changes in gendre
       
   407 // Checks for "PodCast" gendre
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 void CMPXCollectionUiHelperImp::SetL( CMPXMedia*& aMedia,
       
   411                                       MMPXCHelperObserver* aObserver )
       
   412     {
       
   413     MPX_FUNC("CMPXCollectionUiHelperImp::SetL");
       
   414 
       
   415     if (!aObserver)
       
   416         {
       
   417         User::Leave( KErrArgument );
       
   418         }
       
   419 
       
   420     //
       
   421     // leave if the given media doesn't contain the following attributes
       
   422     //
       
   423     if (!aMedia->IsSupported(KMPXMediaGeneralType) ||
       
   424         !aMedia->IsSupported(KMPXMediaGeneralCategory))
       
   425         {
       
   426         User::Leave( KErrArgument );
       
   427         }
       
   428 
       
   429     //
       
   430     // externalize parameters
       
   431     //
       
   432     CBufBase* taskParam(NULL);
       
   433     ::CreateBufferL<CMPXMedia>( *aMedia, taskParam );
       
   434     CleanupStack::PushL(taskParam);
       
   435 
       
   436     //
       
   437     // add request to the task queue
       
   438     //
       
   439     CMPXMedia* ref = CMPXMedia::NewL( *aMedia );  // ownership transferred
       
   440     CleanupStack::PushL(ref);
       
   441 
       
   442     iTaskQueue->AddTaskL( ETaskSetMedia,
       
   443                           aObserver,   // callback when task completed
       
   444                           this,        // task queue observer
       
   445                           0,           // Integer paramter, not used
       
   446                           taskParam,   // task queue assumes ownership of taskParam
       
   447                           NULL,        // ptr data
       
   448                           ref );       // keep reference count alive
       
   449 
       
   450     CleanupStack::Pop(2, taskParam);   // ref & taskParam
       
   451     }
       
   452 
       
   453 // ---------------------------------------------------------------------------
       
   454 // Update a list of medias, checks for podcast changes in genre
       
   455 // ---------------------------------------------------------------------------
       
   456 //
       
   457 void CMPXCollectionUiHelperImp::SetL( TArray<CMPXMedia*>& aMediaArray,
       
   458                                 CMPXCollectionPath& aPath,
       
   459                                 RArray<TInt>& aIndices )
       
   460     {
       
   461     iMediator->SetItemL( aMediaArray, aPath, aIndices );
       
   462     }
       
   463 
       
   464 // ---------------------------------------------------------------------------
       
   465 // rename a media
       
   466 // ---------------------------------------------------------------------------
       
   467 //
       
   468 void CMPXCollectionUiHelperImp::RenameL( const CMPXMedia& aMedia,
       
   469                                          MMPXCHelperObserver* aObserver )
       
   470     {
       
   471     if (!aObserver)
       
   472         {
       
   473         User::Leave( KErrArgument );
       
   474         }
       
   475 
       
   476     //
       
   477     // leave if the given media doesn't contain the following attributes
       
   478     //
       
   479     if (!aMedia.IsSupported(KMPXMediaGeneralType) ||
       
   480         !aMedia.IsSupported(KMPXMediaGeneralCategory))
       
   481         {
       
   482         User::Leave( KErrArgument );
       
   483         }
       
   484 
       
   485     //
       
   486     // leave if the given media isn't a playlist
       
   487     //
       
   488     TMPXGeneralType mediaType =
       
   489          aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
   490 
       
   491     TMPXGeneralCategory mediaCategory =
       
   492          aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
   493 
       
   494     //
       
   495     // currently only supporting playlists
       
   496     //
       
   497     if ( mediaType != EMPXItem ||
       
   498          mediaCategory != EMPXPlaylist )
       
   499         {
       
   500         User::Leave( KErrNotSupported );
       
   501         }
       
   502 
       
   503     //
       
   504     // leave if the media doesn't contain mandatory attributes for renaming a playlist
       
   505     //
       
   506     if (!aMedia.IsSupported(KMPXMediaGeneralTitle) ||
       
   507         !aMedia.IsSupported(KMPXMediaGeneralId))
       
   508         {
       
   509         User::Leave( KErrArgument );
       
   510         }
       
   511 
       
   512     //
       
   513     // externalize parameters
       
   514     //
       
   515     CBufBase* taskParam(NULL);
       
   516     ::CreateBufferL<CMPXMedia>( aMedia, taskParam );
       
   517     CleanupStack::PushL(taskParam);
       
   518 
       
   519     // Keep media alive
       
   520     CMPXMedia* ref = CMPXMedia::NewL( aMedia );
       
   521     CleanupStack::PushL(ref);
       
   522 
       
   523     //
       
   524     // add request to the task queue
       
   525     //
       
   526     iTaskQueue->AddTaskL( ETaskRenameMedia,
       
   527                           aObserver,   // callback when task completed
       
   528                           this,        // task queue observer
       
   529                           0,           // Integer paramter, not used
       
   530                           taskParam,   // task queue assumes ownership of taskParam
       
   531                           NULL,        // ptr data
       
   532                           ref );       // ownership transferred
       
   533 
       
   534     CleanupStack::Pop(2, taskParam);   // ref & taskParam
       
   535     }
       
   536 
       
   537 // ---------------------------------------------------------------------------
       
   538 // Delete a collection path and the files
       
   539 // associated with each leaf node in the path
       
   540 // 1: Removes the file from Collection db
       
   541 // 2: Deletes the file from FS
       
   542 // 3: Removes the file from Harvester db
       
   543 // ---------------------------------------------------------------------------
       
   544 //
       
   545 void CMPXCollectionUiHelperImp::DeleteL( CMPXCollectionPath& aPath,
       
   546                                          MMPXCHelperObserver* aObs )
       
   547     {
       
   548     if (!aObs)
       
   549         {
       
   550         User::Leave(KErrArgument);
       
   551         }
       
   552 
       
   553     MPX_DEBUG_PATH(aPath);
       
   554 
       
   555     //
       
   556     // externalize parameters
       
   557     //
       
   558     CBufBase* taskParam(NULL);
       
   559     ::CreateBufferL<CMPXCollectionPath>( aPath, taskParam );
       
   560     CleanupStack::PushL(taskParam);
       
   561 
       
   562     //
       
   563     // add request to the task queue
       
   564     //
       
   565     iTaskQueue->AddTaskL( ETaskRemoveMedia,
       
   566                           aObs,        // callback when task completed
       
   567                           this,        // task queue observer
       
   568                           0,           // Integer paramter, not used
       
   569                           taskParam);  // task queue assumes ownership of taskParam
       
   570 
       
   571     CleanupStack::Pop(taskParam);
       
   572     }
       
   573 
       
   574 // ---------------------------------------------------------------------------
       
   575 // Move an item from one collection to another
       
   576 // 0: Convert enum to collection lookup UID
       
   577 // 1: Removes the item from the old collection
       
   578 // 2: Adds the item to the new collection using mediator
       
   579 //    (Mediator sets genre "Podcast" to "Unknown" if we move from Music -> Podcast
       
   580 // ---------------------------------------------------------------------------
       
   581 //
       
   582 void CMPXCollectionUiHelperImp::MoveL( CMPXMedia*& aMedia,
       
   583                                        TUid aNewCollection,
       
   584                                        MMPXCHelperObserver* aObs )
       
   585     {
       
   586     if (!aMedia->IsSupported(KMPXMediaGeneralCollectionId))
       
   587         {
       
   588         User::Leave(KErrArgument);
       
   589         }
       
   590 
       
   591     // Lookup the collection
       
   592     //
       
   593     RArray<TUid> ary;
       
   594     CleanupClosePushL( ary );
       
   595     ary.AppendL( aNewCollection );
       
   596     TUid newuid = iCollection->CollectionIDL( ary.Array() );
       
   597     CleanupStack::PopAndDestroy( &ary );
       
   598 
       
   599     // Move with mediator
       
   600     //
       
   601     const TUid& olduid = aMedia->ValueTObjectL<TUid>( KMPXMediaGeneralCollectionId );
       
   602 
       
   603     iHelperObserver = aObs;
       
   604     if( !aObs )
       
   605         {
       
   606         iMediator->MoveItemL( aMedia, olduid, newuid );
       
   607         }
       
   608     else
       
   609         {
       
   610         // Should i add this to the task queue? need to think about it
       
   611         iMediator->MoveItemL( aMedia, olduid, newuid, this );
       
   612         }
       
   613 
       
   614     // Notify harvester of the explicit move in collection
       
   615     //
       
   616     aMedia->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, newuid);
       
   617     iHarvester->UpdateFileL( aMedia );
       
   618     }
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // Open the collection in embedded mode for a media
       
   622 // Cannot cleanup aObs because UPnP is using this.
       
   623 // ---------------------------------------------------------------------------
       
   624 //
       
   625 void CMPXCollectionUiHelperImp::OpenL( const TUid& aHostId, CMPXMedia& aMedia,
       
   626                                        MMPXCHelperEmbeddedOpenObserver* /*aObs*/,
       
   627                                        TInt aPluginInfo )
       
   628     {
       
   629     // Grab the in memory collection plugin UID
       
   630     // aPluginInfo provides additional resolution to find the plugin
       
   631     //
       
   632     RArray<TUid> ary;
       
   633     CleanupClosePushL( ary );
       
   634     ary.AppendL( TUid::Uid(EMPXCollectionPluginHidden) );
       
   635     ary.AppendL( TUid::Uid(EMPXCollectionPluginTemporary) );
       
   636     if( aPluginInfo )
       
   637         {
       
   638         ary.AppendL( TUid::Uid(aPluginInfo) );
       
   639         }
       
   640 
       
   641     TUid inMemCollection = iCollection->CollectionIDL( ary.Array() );
       
   642     CleanupStack::PopAndDestroy( &ary );
       
   643 
       
   644     // First step is to add this media to the in memory plugin
       
   645     // Set the item id to be the host ID
       
   646     //
       
   647     aMedia.SetTObjectValueL( KMPXMediaGeneralCollectionId, inMemCollection );
       
   648     aMedia.SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId, aHostId.iUid );
       
   649 
       
   650     // Add the media via CMPXCommand
       
   651     CMPXCommand* cmd = CMPXCommand::NewL();
       
   652     CleanupStack::PushL( cmd );
       
   653     cmd->SetTObjectValueL( KMPXCommandGeneralId,
       
   654                            KMPXCommandIdCollectionAdd );
       
   655     cmd->SetTObjectValueL( KMPXCommandGeneralDoSync,
       
   656                            ETrue );
       
   657     cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId,
       
   658                            inMemCollection.iUid );
       
   659     cmd->SetCObjectValueL( KMPXCommandColAddMedia,
       
   660                            &aMedia );
       
   661     iCollection->Collection().CommandL( *cmd );
       
   662     CleanupStack::PopAndDestroy( cmd );
       
   663 
       
   664     // Second Step is to construct collection path
       
   665     // | collection id | host id |
       
   666     //
       
   667     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   668     CleanupStack::PushL( path );
       
   669     path->AppendL( inMemCollection.iUid );
       
   670     path->AppendL( aHostId.iUid );
       
   671 
       
   672     // Last step is to open this path
       
   673     //
       
   674     iCollection->Collection().OpenL( *path );
       
   675     CleanupStack::PopAndDestroy( path );
       
   676     }
       
   677 
       
   678 // ---------------------------------------------------------------------------
       
   679 // Open the collection in embedded mode for a file handle
       
   680 // ---------------------------------------------------------------------------
       
   681 //
       
   682 void CMPXCollectionUiHelperImp::OpenL( const TUid& aHostId, const TDesC& aFile,
       
   683                                        MMPXCHelperEmbeddedOpenObserver* aObs,
       
   684                                        TInt aPluginInfo )
       
   685     {
       
   686 
       
   687     // Open in embedded mode, no database merge necessary
       
   688     if( !aObs )
       
   689         {
       
   690         User::LeaveIfError( KErrArgument );
       
   691         }
       
   692 
       
   693     iEmbeddedModeID = aHostId;
       
   694     iEmbeddedPluginInfo = aPluginInfo;
       
   695     iOpenObserver = aObs;
       
   696 
       
   697     iHarvester->ImportFileL( aFile, this );
       
   698     }
       
   699 
       
   700 // ---------------------------------------------------------------------------
       
   701 // Open the collection in embedded mode for a file handle
       
   702 // ---------------------------------------------------------------------------
       
   703 //
       
   704 void CMPXCollectionUiHelperImp::OpenL( RFile& aFile,
       
   705                                        MMPXCHelperEmbeddedOpenObserver* aObs )
       
   706     {
       
   707     MPX_FUNC( "CMPXCollectionUiHelperImp::OpenL (file handle, observer)" );
       
   708     // Open in embedded mode, no database merge necessary
       
   709     if( !aObs )
       
   710         {
       
   711         User::Leave( KErrArgument );
       
   712         }
       
   713 
       
   714     iOpenObserver = aObs;
       
   715     TMPXGeneralCategory category( EMPXNoCategory );
       
   716 
       
   717     CFileStore* store( NULL );
       
   718     MPX_TRAPD( error, store = CDirectFileStore::FromL( aFile ); );
       
   719 
       
   720     if ( error == KErrNone )
       
   721         {
       
   722         CleanupStack::PushL( store );
       
   723 
       
   724         RStoreReadStream stream;
       
   725         stream.OpenLC( *store, store->Root() );
       
   726 
       
   727         // Recreate the collection path that we were browsing
       
   728         CMPXCollectionPath* collectionPath = CMPXCollectionPath::NewL( stream );
       
   729         CleanupStack::PopAndDestroy( 2, store ); // stream, store
       
   730         CleanupStack::PushL( collectionPath );
       
   731 
       
   732         MPX_DEBUG_PATH( *collectionPath );
       
   733 
       
   734         if ( collectionPath->Levels() != 3 ||
       
   735             ( collectionPath->Id(1) != KMPXAllSongsViewIndex &&
       
   736              collectionPath->Id(1) != KMPXPlaylistViewIndex ) )
       
   737             {
       
   738             error = KErrNotSupported;
       
   739             }
       
   740         else
       
   741             {
       
   742             category = collectionPath->Id( 1 ) ==
       
   743                 KMPXAllSongsViewIndex ? EMPXSong : EMPXPlaylist;
       
   744             TRAP( error, iCollection->Collection().OpenL( *collectionPath ) );
       
   745             }
       
   746         CleanupStack::PopAndDestroy( collectionPath );
       
   747         }
       
   748 
       
   749     // Callback to observer for err handling
       
   750     ( ( MMPXCHelperEmbeddedOpenObserver* )iOpenObserver )->HandleEmbeddedOpenL( error, category );
       
   751     }
       
   752 
       
   753 // ---------------------------------------------------------------------------
       
   754 // Queries about the playlist file extension of the currently selected playlist
       
   755 // plugin
       
   756 // ---------------------------------------------------------------------------
       
   757 HBufC* CMPXCollectionUiHelperImp::PlaylistFileExtensionLC()
       
   758     {
       
   759     // default to M3U playlist type for now
       
   760     return iHarvester->PlaylistFileExtensionLC(EMPXPlaylistTypeM3U);
       
   761     }
       
   762 
       
   763 // ---------------------------------------------------------------------------
       
   764 // Export a playlist
       
   765 // ---------------------------------------------------------------------------
       
   766 //
       
   767 void CMPXCollectionUiHelperImp::ExportPlaylistL(TMPXItemId aPlaylistId,
       
   768                                                 const TDesC& aDestinationDriveAndPath,
       
   769                                                 MMPXCHelperObserver* aObs)
       
   770     {
       
   771     if (!aObs)
       
   772         {
       
   773         User::Leave(KErrArgument);
       
   774         }
       
   775 
       
   776     CMPXMedia* media = CMPXMedia::NewL();
       
   777     CleanupStack::PushL(media);
       
   778 
       
   779     media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
       
   780     media->SetTextValueL(KMPXMediaGeneralUri, aDestinationDriveAndPath);
       
   781 
       
   782     //
       
   783     // externalize parameters
       
   784     //
       
   785     CBufBase* taskParam(NULL);
       
   786     ::CreateBufferL<CMPXMedia>( *media, taskParam );
       
   787     CleanupStack::PushL(taskParam);
       
   788 
       
   789     //
       
   790     // add request to the task queue
       
   791     //
       
   792     iTaskQueue->AddTaskL( ETaskExportPlaylist,
       
   793                           aObs,        // callback when task completed
       
   794                           this,        // task queue observer
       
   795                           0,           // Integer paramter, not used
       
   796                           taskParam,   // task queue assumes ownership of taskParam
       
   797                           NULL,
       
   798                           media );     // keep media alive, ownership transferred
       
   799 
       
   800     CleanupStack::Pop(2, media);       // taskParam & media
       
   801     }
       
   802 
       
   803 // ---------------------------------------------------------------------------
       
   804 // Reorder a song in a playlist
       
   805 // ---------------------------------------------------------------------------
       
   806 //
       
   807 void CMPXCollectionUiHelperImp::ReorderPlaylistL(const TMPXItemId& aPlaylistId,
       
   808                                                  const TMPXItemId& aSongId,
       
   809                                                  TUint aOriginalOrdinal,
       
   810                                                  TUint aNewOrdinal,
       
   811                                                  MMPXCHelperObserver* aObs)
       
   812     {
       
   813     if (!aObs)
       
   814         {
       
   815         User::Leave(KErrArgument);
       
   816         }
       
   817 
       
   818     CMPXMedia* command = CMPXMedia::NewL();
       
   819     CleanupStack::PushL(command);
       
   820 
       
   821     command->SetTObjectValueL<TMPXItemId>(KMPXCommandReorderPlaylistId, aPlaylistId);
       
   822     command->SetTObjectValueL<TMPXItemId>(KMPXCommandReorderSongId, aSongId);
       
   823     command->SetTObjectValueL<TUint>(KMPXCommandReorderOriginalOrdinal, aOriginalOrdinal);
       
   824     command->SetTObjectValueL<TUint>(KMPXCommandReorderNewOrdinal, aNewOrdinal);
       
   825 
       
   826     //
       
   827     // externalize parameters
       
   828     //
       
   829     CBufBase* taskParam(NULL);
       
   830     ::CreateBufferL<CMPXMedia>( *command, taskParam );
       
   831     CleanupStack::PushL(taskParam);
       
   832 
       
   833     //
       
   834     // add request to the task queue
       
   835     //
       
   836     iTaskQueue->AddTaskL( ETaskReorderPlaylist,
       
   837                           aObs,        // callback when task completed
       
   838                           this,        // task queue observer
       
   839                           0,           // Integer paramter, not used
       
   840                           taskParam,   // task queue assumes ownership of taskParam
       
   841                           NULL,
       
   842                           command );   // keep media alive, ownership transferred
       
   843 
       
   844     CleanupStack::Pop(2, command);       // taskParam & media
       
   845     }
       
   846 
       
   847 // ---------------------------------------------------------------------------
       
   848 // Creates a default collection path to the music menu
       
   849 // ---------------------------------------------------------------------------
       
   850 //
       
   851 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicMenuPathL()
       
   852     {
       
   853     // Get top level path only, no database merge necessary
       
   854 
       
   855     // Convert the Virtual UID to the real UID
       
   856     RArray<TUid> ary;
       
   857     CleanupClosePushL( ary );
       
   858     ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
       
   859     TUid musicCollection = iCollection->CollectionIDL( ary.Array() );
       
   860     CleanupStack::PopAndDestroy( &ary );
       
   861 
       
   862     // Second Step is to construct collection path
       
   863     // | collection id |
       
   864     //
       
   865     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   866     CleanupStack::PushL( path );
       
   867     path->AppendL( musicCollection.iUid );
       
   868     CleanupStack::Pop( path );
       
   869 
       
   870     return path;
       
   871     }
       
   872 
       
   873 // ---------------------------------------------------------------------------
       
   874 // Creates a default collection path to the podcast menu
       
   875 // ---------------------------------------------------------------------------
       
   876 //
       
   877 CMPXCollectionPath* CMPXCollectionUiHelperImp::PodCastMenuPathL()
       
   878     {
       
   879     // Get top level path only, no database merge necessary
       
   880 
       
   881     // Convert the Virtual UID to the real UID
       
   882     RArray<TUid> ary;
       
   883     CleanupClosePushL( ary );
       
   884     ary.AppendL( TUid::Uid(EMPXCollectionPluginPodCast) );
       
   885     TUid pcCollection = iCollection->CollectionIDL( ary.Array() );
       
   886     CleanupStack::PopAndDestroy( &ary );
       
   887 
       
   888     // Second Step is to construct collection path
       
   889     // | collection id |
       
   890     //
       
   891     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   892     CleanupStack::PushL( path );
       
   893     path->AppendL( pcCollection.iUid );
       
   894     CleanupStack::Pop( path );
       
   895 
       
   896     return path;
       
   897     }
       
   898 
       
   899 // ---------------------------------------------------------------------------
       
   900 // Creates a default collection path to the music all songs
       
   901 // ---------------------------------------------------------------------------
       
   902 //
       
   903 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicAllSongsPathL()
       
   904     {
       
   905     CMPXCollectionPath* path = MusicMenuPathL();
       
   906     CleanupStack::PushL( path );
       
   907     path->AppendL( KMPXAllSongsViewIndex );
       
   908     CleanupStack::Pop( path );
       
   909 
       
   910     return path;
       
   911     }
       
   912 
       
   913 // ---------------------------------------------------------------------------
       
   914 // Creates a default collection path to the music playlist
       
   915 // ---------------------------------------------------------------------------
       
   916 //
       
   917 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicPlaylistPathL()
       
   918     {
       
   919     CMPXCollectionPath* path = MusicMenuPathL();
       
   920     CleanupStack::PushL( path );
       
   921     path->AppendL( KMPXPlaylistViewIndex );
       
   922     CleanupStack::Pop( path );
       
   923 
       
   924     return path;
       
   925     }
       
   926 
       
   927 // ---------------------------------------------------------------------------
       
   928 // Creates a default collection path to the music auto playlist
       
   929 // ---------------------------------------------------------------------------
       
   930 //
       
   931 CMPXCollectionPath* CMPXCollectionUiHelperImp::MusicPlaylistPathL(TMPXAutoPlaylistType aPlaylistType)
       
   932     {
       
   933     CMPXCollectionPath* path = MusicPlaylistPathL();
       
   934     CleanupStack::PushL( path );
       
   935     if ( aPlaylistType == EMPXRecentlyPlayedPlaylist )
       
   936         {
       
   937         path->AppendL( KMPXRecentlyPlayedIndex );
       
   938         }
       
   939     else if ( aPlaylistType == EMPXMostPlayedPlaylist )
       
   940         {
       
   941         path->AppendL( KMPXMostPlayedIndex );
       
   942         }
       
   943     else if ( aPlaylistType == EMPXRecentlyAddedPlaylist)
       
   944         {
       
   945         path->AppendL( KMPXRecentlyAddedIndex );
       
   946         }
       
   947     CleanupStack::Pop( path );
       
   948 
       
   949     return path;
       
   950 	}
       
   951 
       
   952 // ---------------------------------------------------------------------------
       
   953 // Creates a default collection playlist hard coded to all songs of
       
   954 // music database
       
   955 // ---------------------------------------------------------------------------
       
   956 //
       
   957 CMPXCollectionPath* CMPXCollectionUiHelperImp::CreateDefaultPlaylistPathLC()
       
   958     {
       
   959     // Get top level path only, no database merge necessary
       
   960 
       
   961     // Convert the Virtual UID to the real UID
       
   962     RArray<TUid> ary;
       
   963     CleanupClosePushL( ary );
       
   964     ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
       
   965     TUid musicCollection = iCollection->CollectionIDL( ary.Array() );
       
   966     CleanupStack::PopAndDestroy( &ary );
       
   967 
       
   968     // Second Step is to construct collection path
       
   969     // | collection id | all songs id |
       
   970     //
       
   971     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   972     CleanupStack::PushL( path );
       
   973     path->AppendL( musicCollection.iUid );
       
   974     path->AppendL( 0 );  // MAGIC, all songs, cannot have dependency to plugin in MPXMusicPlayer
       
   975 
       
   976     return path;
       
   977     }
       
   978 
       
   979 // ---------------------------------------------------------------------------
       
   980 // Returns the file name used for virtual playlist handling
       
   981 // ---------------------------------------------------------------------------
       
   982 //
       
   983 HBufC* CMPXCollectionUiHelperImp::ExternalCollectionPathHandlingFileNameLC()
       
   984     {
       
   985     MPX_FUNC( "CMPXCollectionUiHelperImp::ExternalCollectionPathHandlingFileNameLC" );
       
   986     return KPathVirtualPlaylistHandling().AllocLC();
       
   987     }
       
   988 
       
   989 // ---------------------------------------------------------------------------
       
   990 // Cancel current op
       
   991 // ---------------------------------------------------------------------------
       
   992 //
       
   993 void CMPXCollectionUiHelperImp::Cancel()
       
   994     {
       
   995     if( iTask == ETaskRemoveMedia )
       
   996         {
       
   997         iDeleteHelper->Cancel();
       
   998         }
       
   999     else
       
  1000         {
       
  1001         // currently only used by incremental add
       
  1002         iTaskQueue->CancelRequests();
       
  1003         
       
  1004         // clean up iInputMedia
       
  1005         if( iInputMedia )
       
  1006             {
       
  1007             delete iInputMedia;
       
  1008             iInputMedia = NULL;
       
  1009             }
       
  1010         }
       
  1011     }
       
  1012     
       
  1013 // ---------------------------------------------------------------------------
       
  1014 // Frees this object
       
  1015 // ---------------------------------------------------------------------------
       
  1016 //
       
  1017 void CMPXCollectionUiHelperImp::Close()
       
  1018     {
       
  1019     delete this;
       
  1020     }
       
  1021 
       
  1022 // ---------------------------------------------------------------------------
       
  1023 // Test if the specified title already exists for the category
       
  1024 // ---------------------------------------------------------------------------
       
  1025 //
       
  1026 TBool CMPXCollectionUiHelperImp::TitleExistsL(TMPXGeneralCategory aCategory, 
       
  1027                                               const TDesC& aTitle,
       
  1028                                               TMPXGeneralType aType)
       
  1029     {
       
  1030     CMPXMedia* query = CMPXMedia::NewL();
       
  1031     CleanupStack::PushL(query);
       
  1032     query->SetTObjectValueL(KMPXMediaGeneralType, aType);
       
  1033     query->SetTObjectValueL(KMPXMediaGeneralCategory, aCategory);
       
  1034     query->SetTextValueL(KMPXMediaGeneralTitle, aTitle);
       
  1035 
       
  1036     // Look up collection UID and set to criteria
       
  1037     //
       
  1038     RArray<TUid> ary;
       
  1039     CleanupClosePushL( ary );
       
  1040     ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
       
  1041     TUid musicCollection = iCollection->CollectionIDL( ary.Array() );
       
  1042     CleanupStack::PopAndDestroy( &ary );
       
  1043 
       
  1044     query->SetTObjectValueL<TUid>( KMPXMediaGeneralCollectionId, musicCollection );
       
  1045 
       
  1046     RArray<TMPXAttribute> attributes;
       
  1047     CleanupClosePushL(attributes);
       
  1048     attributes.AppendL(KMPXMediaGeneralId);
       
  1049 
       
  1050     CMPXMedia* result =
       
  1051         iCollection->Collection().FindAllL(*query, attributes.Array());
       
  1052     CleanupStack::PopAndDestroy(&attributes);
       
  1053     CleanupStack::PopAndDestroy(query);
       
  1054     CleanupStack::PushL(result);
       
  1055 
       
  1056     TInt count = result->ValueTObjectL<TInt>(KMPXMediaArrayCount);
       
  1057     CleanupStack::PopAndDestroy(result);
       
  1058 
       
  1059     return count;
       
  1060     }
       
  1061 
       
  1062 // ---------------------------------------------------------------------------
       
  1063 // Updates the harvester with the up to date collection <-> file mapping
       
  1064 // ---------------------------------------------------------------------------
       
  1065 //
       
  1066 void CMPXCollectionUiHelperImp::HandleMediatorPathUpdatedL( CMPXMedia*& aProperty,
       
  1067                                                       TUid  /*aOldPath*/ )
       
  1068     {
       
  1069     iHarvester->UpdateFileL( aProperty );
       
  1070     }
       
  1071 
       
  1072 // ---------------------------------------------------------------------------
       
  1073 // Handles completion of playlist export
       
  1074 // to-do: this should be changed to HandlePlaylistExportCompleted
       
  1075 // ---------------------------------------------------------------------------
       
  1076 //
       
  1077 void CMPXCollectionUiHelperImp::HandlePlaylistExportCompletedL( CMPXMedia* aMedia, TInt aErr )
       
  1078     {
       
  1079     TRAPD(error, DoHandlePlaylistExportCompletedL(aMedia, aErr));
       
  1080 
       
  1081     CompleteTask(iTask, aErr==KErrNone?error:aErr);
       
  1082     }
       
  1083 
       
  1084 // ---------------------------------------------------------------------------
       
  1085 // Handles completion of playlist export
       
  1086 // ---------------------------------------------------------------------------
       
  1087 //
       
  1088 void CMPXCollectionUiHelperImp::DoHandlePlaylistExportCompletedL( CMPXMedia* aMedia, TInt aErr )
       
  1089     {
       
  1090     if (aErr == KErrNone)
       
  1091         {
       
  1092         CleanupStack::PushL(aMedia);
       
  1093         iMedia->SetTextValueL(
       
  1094             KMPXMediaGeneralUri, aMedia->ValueText(KMPXMediaGeneralUri));
       
  1095         CleanupStack::PopAndDestroy(aMedia);
       
  1096         }
       
  1097     }
       
  1098 
       
  1099 // ---------------------------------------------------------------------------
       
  1100 // Handles completion of playlist import
       
  1101 // ---------------------------------------------------------------------------
       
  1102 //
       
  1103 void CMPXCollectionUiHelperImp::HandlePlaylistImportCompletedL( CMPXMedia* aMedia, TInt aErr )
       
  1104     {
       
  1105     if (aErr == KErrNone)
       
  1106         {
       
  1107         delete aMedia;
       
  1108         }
       
  1109     // Should never come here
       
  1110     ASSERT(0);
       
  1111     }
       
  1112 
       
  1113 // ---------------------------------------------------------------------------
       
  1114 // Handle asynchronous file addition by file name
       
  1115 // ---------------------------------------------------------------------------
       
  1116 //
       
  1117 void CMPXCollectionUiHelperImp::HandleFileAddCompletedL( CMPXMedia* aMedia, TInt aErr )
       
  1118     {
       
  1119     // to-do
       
  1120     if (aErr == KErrNone)
       
  1121         {
       
  1122         delete aMedia;
       
  1123         }
       
  1124     // Should never come here
       
  1125     ASSERT(0);
       
  1126     }
       
  1127 
       
  1128 // ---------------------------------------------------------------------------
       
  1129 // Handle file delete completion
       
  1130 // ---------------------------------------------------------------------------
       
  1131 //
       
  1132 void CMPXCollectionUiHelperImp::HandleDeleteCompletedL( TInt /*aErr*/ )
       
  1133     {
       
  1134     }
       
  1135 
       
  1136 // ---------------------------------------------------------------------------
       
  1137 // From MMPXHarvesterUtilityObserver
       
  1138 // ---------------------------------------------------------------------------
       
  1139 //
       
  1140 void CMPXCollectionUiHelperImp::HandleFileImportCompletedL( CMPXMedia* aMedia,
       
  1141                                                            TInt aErr  )
       
  1142     {
       
  1143     // Only do this if we are embedded mode
       
  1144     //
       
  1145     CleanupStack::PushL( aMedia );
       
  1146     if( iEmbeddedModeID.iUid )
       
  1147         {
       
  1148         TInt err( aErr );
       
  1149         TMPXGeneralCategory cat( EMPXNoCategory );
       
  1150         if( aErr == KErrNone )
       
  1151             {
       
  1152             TRAP( err, OpenL( iEmbeddedModeID,
       
  1153                               *aMedia,
       
  1154                               (MMPXCHelperEmbeddedOpenObserver*)iOpenObserver ,
       
  1155                               iEmbeddedPluginInfo ) );
       
  1156             cat = aMedia->ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  1157             }
       
  1158 
       
  1159         // Callback to observer for err handling
       
  1160         ((MMPXCHelperEmbeddedOpenObserver*)iOpenObserver)->HandleEmbeddedOpenL( err, cat );
       
  1161         }
       
  1162     CleanupStack::PopAndDestroy( aMedia );
       
  1163     }
       
  1164 
       
  1165 // ---------------------------------------------------------------------------
       
  1166 // From MMPXHarvesterUtilityObserver
       
  1167 // ---------------------------------------------------------------------------
       
  1168 //
       
  1169 void CMPXCollectionUiHelperImp::HandleFileGetMediaCompletedL( CMPXMedia* /*aMedia*/,
       
  1170                                                               TInt /*aErr*/ )
       
  1171     {
       
  1172     // Not used
       
  1173     ASSERT(0);
       
  1174     }
       
  1175 
       
  1176 // ---------------------------------------------------------------------------
       
  1177 // From MMPXCollectionMediaObserver
       
  1178 // ---------------------------------------------------------------------------
       
  1179 //
       
  1180 void CMPXCollectionUiHelperImp::HandleCollectionMediaL(const CMPXMedia& /*aMedia*/,
       
  1181                                                        TInt /*aError*/)
       
  1182     {
       
  1183     // Not used
       
  1184     ASSERT(0);
       
  1185     }
       
  1186 
       
  1187 // ---------------------------------------------------------------------------
       
  1188 // From MMPXCollectionObserver
       
  1189 // ---------------------------------------------------------------------------
       
  1190 //
       
  1191 void CMPXCollectionUiHelperImp::HandleCollectionMessage(CMPXMessage* aMsg, TInt aErr)
       
  1192     {
       
  1193     iDeleteHelper->HandleCollectionMessage( aMsg, aErr );
       
  1194     }
       
  1195 
       
  1196 // ---------------------------------------------------------------------------
       
  1197 // From MMPXCollectionObserver
       
  1198 // ---------------------------------------------------------------------------
       
  1199 //
       
  1200 void CMPXCollectionUiHelperImp::HandleOpenL(const CMPXMedia& /*aEntries*/, TInt /*aIndex*/, TBool /*aComplete*/, TInt /*aError*/)
       
  1201     {
       
  1202     // Not used
       
  1203     ASSERT(0);
       
  1204     }
       
  1205 
       
  1206 // ---------------------------------------------------------------------------
       
  1207 // From MMPXCollectionObserver
       
  1208 // ---------------------------------------------------------------------------
       
  1209 //
       
  1210 void CMPXCollectionUiHelperImp::HandleOpenL(const CMPXCollectionPlaylist& /*aPlaylist*/, TInt /*aError*/)
       
  1211     {
       
  1212     // Not used
       
  1213     ASSERT(0);
       
  1214     }
       
  1215 
       
  1216 // ----------------------------------------------------------------------------
       
  1217 // Handles completion of moving an object, just a proxy
       
  1218 // ----------------------------------------------------------------------------
       
  1219 //
       
  1220 void CMPXCollectionUiHelperImp::HandleMoveCompleteL( TInt aErr )
       
  1221     {
       
  1222     if( iHelperObserver )
       
  1223         {
       
  1224         iHelperObserver->HandleOperationCompleteL( EMoveOp, aErr, NULL );
       
  1225         }
       
  1226     }
       
  1227 
       
  1228 // ----------------------------------------------------------------------------
       
  1229 // Handles completion of removing a collection path
       
  1230 // ----------------------------------------------------------------------------
       
  1231 //
       
  1232 void CMPXCollectionUiHelperImp::HandleOperationCompleteL( TCHelperOperation aOperation,
       
  1233                                                           TInt aErr,
       
  1234                                                           void* aArgument )
       
  1235     {
       
  1236     if (aOperation == EDeleteOp && iTask == ETaskRemoveMedia)
       
  1237         {
       
  1238         CompleteTask(iTask, aErr);
       
  1239         }
       
  1240     else if ( aOperation == EDeleteStatusOp )
       
  1241         {
       
  1242         iHelperObserver->HandleOperationCompleteL( aOperation, aErr, aArgument );
       
  1243         }
       
  1244     }
       
  1245 
       
  1246 // ----------------------------------------------------------------------------
       
  1247 // Execute an async task
       
  1248 // ----------------------------------------------------------------------------
       
  1249 //
       
  1250 void CMPXCollectionUiHelperImp::ExecuteTask(
       
  1251     TInt      aTask,
       
  1252     TInt      /*aParamData*/,
       
  1253     TAny*     /*aPtrData*/,
       
  1254     const     CBufBase& aBuf,
       
  1255     TAny*     aCallback,
       
  1256     CBase*    /*aCObject1*/,
       
  1257     CBase*    /*aCObject2*/)
       
  1258     {
       
  1259     TRAPD(err, ExecuteTaskL(aTask, aBuf, aCallback));
       
  1260     if (err != KErrNone)
       
  1261         {
       
  1262         CompleteTask(aTask, err);
       
  1263         }
       
  1264     }
       
  1265 
       
  1266 // ----------------------------------------------------------------------------
       
  1267 // Indicates that a task was terminated with an error
       
  1268 // ----------------------------------------------------------------------------
       
  1269 //
       
  1270 void CMPXCollectionUiHelperImp::HandleTaskError(
       
  1271     TInt /* aTask */,
       
  1272     TAny* /*aPtrData*/,
       
  1273     TAny* /*aCallback*/,
       
  1274     TInt /* aError */)
       
  1275     {
       
  1276     // Do nothing
       
  1277     }
       
  1278 
       
  1279 // ----------------------------------------------------------------------------
       
  1280 // Execute an async task. Leaves when an error is encountered.
       
  1281 // ----------------------------------------------------------------------------
       
  1282 //
       
  1283 void CMPXCollectionUiHelperImp::ExecuteTaskL(TInt aTask, const CBufBase& aBuf, TAny* aCallback)
       
  1284     {
       
  1285     iTask = aTask;
       
  1286     MPX_DEBUG2("CMPXCollectionUiHelperImp::ExecuteTaskL, aTask = %d", aTask);
       
  1287     
       
  1288     // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode
       
  1289     // prevent any general add, general delete, and any moficiation of playlist
       
  1290     if ((iTask == ETaskAddMedia)
       
  1291             || (iTask == ETaskAppendMedia)
       
  1292             || (iTask == ETaskIncAddMedia)
       
  1293             || (iTask == ETaskIncAppendMedia)
       
  1294             || (iTask == ETaskRemoveMedia)
       
  1295             || (iTask == ETaskReorderPlaylist)
       
  1296             || (iTask == ETaskRenameMedia))
       
  1297         {
       
  1298         TInt usbStatus;
       
  1299         RProperty::Get(KPSUidUsbWatcher, KUsbWatcherSelectedPersonality, usbStatus);
       
  1300             
       
  1301         if ((usbStatus == KUsbPersonalityIdMTP) || (usbStatus == KUsbPersonalityIdPCSuiteMTP)
       
  1302                          || (usbStatus == KUsbPersonalityIdMS) )
       
  1303             {
       
  1304             MPX_DEBUG1("USB is active, Leave with KErrLocked");
       
  1305             // need to call back even if it leaves here
       
  1306             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1307             CompleteTask( aTask, KErrLocked );
       
  1308             //User::Leave(KErrLocked);
       
  1309             if ((iTaskQueue->Task() != ETaskIncAddMedia)&&(iTaskQueue->Task() != ETaskIncAppendMedia))
       
  1310                 {
       
  1311                 iIncAdding = EFalse;
       
  1312                 }
       
  1313             return;
       
  1314             }
       
  1315         }
       
  1316     
       
  1317     switch( aTask )
       
  1318         {
       
  1319         case ETaskAddMedia:  // fall through
       
  1320         case ETaskAppendMedia:
       
  1321             {
       
  1322             delete iMedia;
       
  1323             iMedia = NULL;
       
  1324             ::NewFromBufferL<CMPXMedia>( aBuf, iMedia );
       
  1325             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1326             DoAddL();
       
  1327             }
       
  1328             break;
       
  1329             
       
  1330         case ETaskIncAddMedia:
       
  1331             {
       
  1332             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1333             DoIncAddMediaL();
       
  1334             }
       
  1335             break;
       
  1336             
       
  1337         case ETaskIncAppendMedia:
       
  1338             {
       
  1339             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1340             DoIncAppendMediaL();
       
  1341             }
       
  1342             break;
       
  1343                 
       
  1344         case ETaskSetMedia:
       
  1345             {
       
  1346             delete iMedia;
       
  1347             iMedia = NULL;
       
  1348             ::NewFromBufferL<CMPXMedia>( aBuf, iMedia );
       
  1349             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1350             DoSetL();
       
  1351             }
       
  1352             break;
       
  1353 
       
  1354         case ETaskRenameMedia:
       
  1355             {
       
  1356             delete iMedia;
       
  1357             iMedia = NULL;
       
  1358             ::NewFromBufferL<CMPXMedia>( aBuf, iMedia );
       
  1359             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1360             DoRenameL();
       
  1361             }
       
  1362             break;
       
  1363 
       
  1364         case ETaskRemoveMedia:
       
  1365             {
       
  1366             CMPXCollectionPath* path(NULL);
       
  1367             ::NewFromBufferL<CMPXCollectionPath>( aBuf, path );
       
  1368             CleanupStack::PushL(path);
       
  1369             MPX_DEBUG_PATH(*path);
       
  1370 
       
  1371             iHelperObserver = (MMPXCHelperObserver*) aCallback;
       
  1372             iDeleteHelper->DeleteL(*path);
       
  1373             CleanupStack::PopAndDestroy(path);
       
  1374             }
       
  1375             break;
       
  1376 
       
  1377         case ETaskExportPlaylist:
       
  1378             {
       
  1379             delete iMedia;
       
  1380             iMedia = NULL;
       
  1381 
       
  1382             CMPXMedia* params(NULL);
       
  1383             ::NewFromBufferL<CMPXMedia>( aBuf, params );
       
  1384             CleanupStack::PushL(params);
       
  1385 
       
  1386             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1387 
       
  1388             DoExportPlaylistL(
       
  1389                 params->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),
       
  1390                 params->ValueText(KMPXMediaGeneralUri));
       
  1391 
       
  1392             CleanupStack::PopAndDestroy(params);
       
  1393             }
       
  1394             break;
       
  1395 
       
  1396         case ETaskReorderPlaylist:
       
  1397             {
       
  1398             delete iMedia;
       
  1399             iMedia = NULL;
       
  1400 
       
  1401             CMPXCommand* params(NULL);
       
  1402             ::NewFromBufferL<CMPXCommand>( aBuf, params );
       
  1403             CleanupStack::PushL(params);
       
  1404 
       
  1405             iHelperObserver = (MMPXCHelperObserver*)aCallback;
       
  1406 
       
  1407             DoReorderPlaylistL(*params);
       
  1408 
       
  1409             CleanupStack::PopAndDestroy(params);
       
  1410             }
       
  1411             break;
       
  1412 
       
  1413         //
       
  1414         // command not supported
       
  1415         //
       
  1416         default:
       
  1417             {
       
  1418             User::Leave( KErrNotSupported );
       
  1419             }
       
  1420         }
       
  1421     }
       
  1422 
       
  1423 // ----------------------------------------------------------------------------
       
  1424 // Completes the currently executing task
       
  1425 // ----------------------------------------------------------------------------
       
  1426 //
       
  1427 void CMPXCollectionUiHelperImp::CompleteTask(TInt aTask, TInt aError)
       
  1428     {
       
  1429     MPX_FUNC("CMPXCollectionUiHelperImp::CompleteTask");
       
  1430 
       
  1431     MPX_DEBUG3("task %d, error %d", aTask, aError);
       
  1432 
       
  1433     TRAP_IGNORE(NotifyClientL(aTask, aError));
       
  1434 
       
  1435     if ( iTask != ETaskNone )
       
  1436         {
       
  1437         // clean up data set during processing of the current task
       
  1438         Cleanup();
       
  1439 
       
  1440         // Complete current task and move on to the next
       
  1441         iTaskQueue->CompleteTask();
       
  1442         }
       
  1443     }
       
  1444 
       
  1445 // ----------------------------------------------------------------------------
       
  1446 // Notifies the client of the completion of a collection helper request
       
  1447 // ----------------------------------------------------------------------------
       
  1448 //
       
  1449 void CMPXCollectionUiHelperImp::NotifyClientL(TInt aTask, TInt aError)
       
  1450     {
       
  1451     MPX_DEBUG3("CMPXCollectionUiHelperImp::NotifyClientL(task %d, error %d)", aTask, aError);
       
  1452 
       
  1453     switch (aTask)
       
  1454         {
       
  1455         case ETaskAddMedia:  // fall through
       
  1456         case ETaskAppendMedia:
       
  1457             {
       
  1458             if ( aError >= KErrNone )
       
  1459                 {
       
  1460                 // make a copy of iMedia to hand over to the client which takes ownership
       
  1461                 // of the copied media. if we failed to make a copy, client is not notified.
       
  1462                 iHelperObserver->HandleOperationCompleteL(EAddOp,
       
  1463                                                           KErrNone,
       
  1464                                                           CMPXMedia::NewL(*iMedia) );
       
  1465                 }
       
  1466             else
       
  1467                 {
       
  1468                 iHelperObserver->HandleOperationCompleteL( EAddOp,
       
  1469                                                            aError,
       
  1470                                                            NULL );
       
  1471                 }
       
  1472             }
       
  1473             break;
       
  1474         case ETaskIncAddMedia:
       
  1475         case ETaskIncAppendMedia: 
       
  1476             {
       
  1477             if ( KErrLocked == aError )
       
  1478                 {
       
  1479                 if( EFalse == iIncAdding )
       
  1480                     {
       
  1481                     iIncAdding = ETrue;
       
  1482                     iHelperObserver->HandleOperationCompleteL( EAddOp, aError, NULL );
       
  1483                     }
       
  1484                 }
       
  1485             }
       
  1486             break;
       
  1487         case ETaskIncFinish:
       
  1488             {
       
  1489             if ( aError >= KErrNone )
       
  1490                 {
       
  1491                 // input media is handed over to observer
       
  1492                 iHelperObserver->HandleOperationCompleteL(EAddOp, 
       
  1493                                                           KErrNone, 
       
  1494                                                           CMPXMedia::NewL(*iInputMedia) );                            
       
  1495                 }
       
  1496             else
       
  1497                 {
       
  1498                 iHelperObserver->HandleOperationCompleteL( EAddOp,
       
  1499                                                            aError,
       
  1500                                                            NULL );
       
  1501                 }
       
  1502             // clean up input media
       
  1503             delete iInputMedia;
       
  1504             iInputMedia = NULL;
       
  1505             }
       
  1506             break;
       
  1507             
       
  1508         case ETaskSetMedia:
       
  1509             {
       
  1510             if ( aError >= KErrNone )
       
  1511                 {
       
  1512                 // make a copy of iMedia to hand over to the client which takes ownership
       
  1513                 // of the copied media. if we failed to make a copy, client is not notified.
       
  1514                 iHelperObserver->HandleOperationCompleteL( ESetOp,
       
  1515                                                            KErrNone,
       
  1516                                                            CMPXMedia::NewL(*iMedia) );
       
  1517                 }
       
  1518             else
       
  1519                 {
       
  1520                 iHelperObserver->HandleOperationCompleteL( ESetOp,
       
  1521                                                            aError,
       
  1522                                                            NULL );
       
  1523                 }
       
  1524             }
       
  1525             break;
       
  1526 
       
  1527         case ETaskRenameMedia:
       
  1528             {
       
  1529             if ( aError >= KErrNone )
       
  1530                 {
       
  1531                 // make a copy of iMedia to hand over to the client which takes ownership
       
  1532                 // of the copied media. if we failed to make a copy, client is not notified.
       
  1533                 iHelperObserver->HandleOperationCompleteL( ERenameOp,
       
  1534                                                            KErrNone,
       
  1535                                                            CMPXMedia::NewL(*iMedia) );
       
  1536                 }
       
  1537             else
       
  1538                 {
       
  1539                 iHelperObserver->HandleOperationCompleteL( ERenameOp,
       
  1540                                                            aError,
       
  1541                                                            NULL );
       
  1542                 }
       
  1543             }
       
  1544             break;
       
  1545 
       
  1546         case ETaskRemoveMedia:
       
  1547             {
       
  1548             iHelperObserver->HandleOperationCompleteL( EDeleteOp,
       
  1549                                                        aError >= KErrNone? KErrNone : aError,
       
  1550                                                        NULL );
       
  1551             }
       
  1552             break;
       
  1553 
       
  1554         case ETaskExportPlaylist:
       
  1555             {
       
  1556             HBufC* buf( NULL );
       
  1557             if( aError == KErrNone )
       
  1558                 {
       
  1559                 const TDesC& uri =
       
  1560                     iMedia->ValueText(KMPXMediaGeneralUri);
       
  1561                 buf = uri.AllocL();
       
  1562                 }
       
  1563 
       
  1564             // client assumes ownership of HBufC copied from title
       
  1565             iHelperObserver->HandleOperationCompleteL(EExportPlaylistOp, aError, buf);
       
  1566             }
       
  1567             break;
       
  1568 
       
  1569         case ETaskReorderPlaylist:
       
  1570             {
       
  1571             iHelperObserver->HandleOperationCompleteL( EReorderPlaylistOp,
       
  1572                                                        aError >= KErrNone? KErrNone : aError,
       
  1573                                                        NULL );
       
  1574             }
       
  1575             break;
       
  1576 
       
  1577         default:
       
  1578             break;
       
  1579         }
       
  1580     }
       
  1581 
       
  1582 // ----------------------------------------------------------------------------
       
  1583 // Cleanup async task variables
       
  1584 // ----------------------------------------------------------------------------
       
  1585 //
       
  1586 void CMPXCollectionUiHelperImp::Cleanup()
       
  1587     {
       
  1588     MPX_DEBUG1("-->CMPXCollectionUiHelperImp::Cleanup");
       
  1589     iTask = ETaskNone;
       
  1590     iHelperObserver = NULL;
       
  1591     delete iMedia;
       
  1592     iMedia = NULL;
       
  1593     MPX_DEBUG1("<--CMPXCollectionUiHelperImp::Cleanup");
       
  1594     }
       
  1595 
       
  1596 // ---------------------------------------------------------------------------
       
  1597 // Add a Media to the collection
       
  1598 //
       
  1599 // For playlists:
       
  1600 // 1) add to collection
       
  1601 // 2) when successfully added to collection, AddItemL returns; otherwise,
       
  1602 //    AddItemL leaves.
       
  1603 // 3) complete task upon successfully addition to the collection. If a leave
       
  1604 //    occurs, it's trapped by ExecuteTask and task is completed by ExecuteTask
       
  1605 // ---------------------------------------------------------------------------
       
  1606 //
       
  1607 void CMPXCollectionUiHelperImp::DoAddL()
       
  1608     {
       
  1609     // creating a new playlist
       
  1610     if (iTask == ETaskAddMedia)
       
  1611         {
       
  1612         // find the collection Id
       
  1613         HBufC* playlistExtension = PlaylistFileExtensionLC();
       
  1614 
       
  1615         TInt collectionId = FindCollectionIdL(*playlistExtension);
       
  1616 
       
  1617         // Add to collection, make sure we set the collection ID.
       
  1618         iMedia->SetTObjectValueL<TUid>(
       
  1619             KMPXMediaGeneralCollectionId, TUid::Uid( collectionId ));
       
  1620 
       
  1621         CleanupStack::PopAndDestroy(playlistExtension);
       
  1622         }
       
  1623 
       
  1624     // adding/appending tracks to a saved playlist
       
  1625     else
       
  1626         {
       
  1627         FillInPlaylistDetailsL(*iMedia);
       
  1628         }
       
  1629 
       
  1630     // when playlist is successfully added to the collection, its
       
  1631     // KMPXMediaGeneralId is automatically updated by mediator
       
  1632     iMediator->AddItemL( iMedia );
       
  1633     
       
  1634     CompleteTask(iTask, KErrNone);
       
  1635     }
       
  1636 
       
  1637 // ---------------------------------------------------------------------------
       
  1638 // Add media to the collection incrementally
       
  1639 // ---------------------------------------------------------------------------
       
  1640 //
       
  1641 void CMPXCollectionUiHelperImp::DoIncAddMediaL()
       
  1642     {
       
  1643     /***** include only aSize/iChunkSize number of songs *****/
       
  1644     
       
  1645     // copy media
       
  1646     CMPXMedia* media = CMPXMedia::CopyL(*iInputMedia);
       
  1647     CleanupStack::PushL(media);
       
  1648     
       
  1649     CMPXMediaArray* tracksArray = iInputMedia->Value<CMPXMediaArray>( KMPXMediaArrayContents );  
       
  1650     
       
  1651     CMPXMediaArray* cArray = CMPXMediaArray::NewL();
       
  1652     CleanupStack::PushL(cArray);
       
  1653        
       
  1654     // last interation/chunk
       
  1655     // for the case when aSize/iChunkSize evenly devides number of songs, the else clause takes care of it
       
  1656     if( (iChunkNumber == iTotalChunkNumber-1) && iRemainder != 0 )
       
  1657         {
       
  1658         // add remaining songs to the array
       
  1659         for(int j = 0; j < iRemainder; j++ )
       
  1660             {
       
  1661             cArray->AppendL(*tracksArray->AtL(iArrayIndex));
       
  1662             iArrayIndex++;
       
  1663             }                   
       
  1664         }
       
  1665     else
       
  1666         {
       
  1667         // adding next aSize/iChunkSize elements
       
  1668         for(int j = 0; j < iChunkSize; j++)
       
  1669             {
       
  1670             cArray->AppendL(*tracksArray->AtL(iArrayIndex));
       
  1671             iArrayIndex++;
       
  1672             }
       
  1673         }
       
  1674     
       
  1675     // update media w/ new array
       
  1676     media->SetCObjectValueL(KMPXMediaArrayContents, cArray);
       
  1677     media->SetTObjectValueL(KMPXMediaArrayCount, cArray->Count() );
       
  1678 
       
  1679     
       
  1680     /***** logic to see which chunk this code is in *****/
       
  1681     
       
  1682     // first chunk
       
  1683     // for the case that there is only one chunk (first & last chunk at the same 
       
  1684     // time), Inc Add is not used
       
  1685     if ( iChunkNumber == 0 )
       
  1686         {
       
  1687         // find the collection Id
       
  1688         HBufC* playlistExtension = PlaylistFileExtensionLC();
       
  1689         
       
  1690         TInt collectionId = FindCollectionIdL(*playlistExtension);                
       
  1691     
       
  1692         // Add to collection, make sure we set the collection ID.
       
  1693         media->SetTObjectValueL<TUid>(
       
  1694             KMPXMediaGeneralCollectionId, TUid::Uid( collectionId ));
       
  1695         
       
  1696         // save collectionId for adding subsequent chunks
       
  1697         iInputMedia->SetTObjectValueL<TUid>(
       
  1698                 KMPXMediaGeneralCollectionId, TUid::Uid( collectionId ));
       
  1699         
       
  1700         CleanupStack::PopAndDestroy(playlistExtension); 
       
  1701 
       
  1702         iMediator->AddItemL( media );  // this creates the new playlist
       
  1703         
       
  1704         // save playlistId in input media & use it for subsequent appending operations
       
  1705         TMPXItemId playlistId = media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1706         iInputMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId);
       
  1707         
       
  1708         iChunkNumber++;  // move on to next chunk
       
  1709         
       
  1710         CompleteTask(iTask, KErrNone);
       
  1711         }
       
  1712     else if ( iChunkNumber == iTotalChunkNumber-1 )  // last chunk
       
  1713         {
       
  1714         // get saved collection id from input media & set it in current media
       
  1715         TUid id = iInputMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId);
       
  1716         media->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, id);
       
  1717  
       
  1718         // get playlistId from input media & set it in current media
       
  1719         TMPXItemId playlistId = iInputMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1720         media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId);
       
  1721         
       
  1722         iMediator->AddItemL( media );
       
  1723         
       
  1724         CompleteTask(ETaskIncFinish, KErrNone);  // finish inc task
       
  1725         }
       
  1726     else // intermedia chunks
       
  1727         {
       
  1728         // get saved collection id from input media & set it in current media
       
  1729         TUid id = iInputMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId);
       
  1730         media->SetTObjectValueL<TUid>(KMPXMediaGeneralCollectionId, id);
       
  1731         
       
  1732         // get playlistId from original media & set it in current media
       
  1733         TMPXItemId playlistId = iInputMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  1734         media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, playlistId);
       
  1735 
       
  1736         iMediator->AddItemL( media );
       
  1737         
       
  1738         iChunkNumber++;  // move on to next chunk
       
  1739         
       
  1740         CompleteTask(iTask, KErrNone);
       
  1741         }
       
  1742     
       
  1743     CleanupStack::PopAndDestroy(cArray);
       
  1744     CleanupStack::PopAndDestroy(media);
       
  1745     }
       
  1746 
       
  1747 // ---------------------------------------------------------------------------
       
  1748 // Append media to the collection incrementally
       
  1749 // ---------------------------------------------------------------------------
       
  1750 //
       
  1751 void CMPXCollectionUiHelperImp::DoIncAppendMediaL()
       
  1752     {
       
  1753     /***** include only aSize/iChunkSize number of songs *****/
       
  1754 
       
  1755     // copy media
       
  1756     CMPXMedia* media = CMPXMedia::CopyL(*iInputMedia);
       
  1757     CleanupStack::PushL(media);
       
  1758     
       
  1759     CMPXMediaArray* tracksArray = iInputMedia->Value<CMPXMediaArray>( KMPXMediaArrayContents );  
       
  1760     
       
  1761     CMPXMediaArray* cArray = CMPXMediaArray::NewL();
       
  1762     CleanupStack::PushL(cArray);
       
  1763        
       
  1764     // last interation/chunk
       
  1765     // for the case when aSize/iChunkSize evenly devides number of tracks, the else clause takes care of it
       
  1766     if( (iChunkNumber == iTotalChunkNumber-1) && iRemainder != 0 )
       
  1767         {
       
  1768         for(int j = 0; j < iRemainder; j++ )
       
  1769             {
       
  1770             cArray->AppendL(*tracksArray->AtL(iArrayIndex));
       
  1771             iArrayIndex++;
       
  1772             }                   
       
  1773         }
       
  1774     else
       
  1775         {
       
  1776         // adding next aSize/iChunkSize elements
       
  1777         for(int j = 0; j < iChunkSize; j++)
       
  1778             {
       
  1779             cArray->AppendL(*tracksArray->AtL(iArrayIndex));
       
  1780             iArrayIndex++;
       
  1781             }
       
  1782         }
       
  1783     
       
  1784     // update media w/ new array
       
  1785     media->SetCObjectValueL(KMPXMediaArrayContents, cArray);
       
  1786     media->SetTObjectValueL(KMPXMediaArrayCount, cArray->Count() );
       
  1787    
       
  1788     
       
  1789     /***** logic to see which chunk this code is in *****/
       
  1790 
       
  1791     // update media then append to playlist
       
  1792     FillInPlaylistDetailsL(*media);
       
  1793     iMediator->AddItemL( media );
       
  1794 
       
  1795     // last chunk
       
  1796     // for the case that there is only one chunk (first & last chunk at the same 
       
  1797     // time), Inc Add is not used
       
  1798     if( iChunkNumber == iTotalChunkNumber-1 )
       
  1799         {
       
  1800         // update input media as well
       
  1801         FillInPlaylistDetailsL(*iInputMedia);
       
  1802         CompleteTask(ETaskIncFinish, KErrNone);        
       
  1803         }
       
  1804     else // intermediate chunks, including first chunk
       
  1805         {       
       
  1806         iChunkNumber++;
       
  1807         CompleteTask(iTask, KErrNone);
       
  1808         }
       
  1809    
       
  1810     CleanupStack::PopAndDestroy(cArray);
       
  1811     CleanupStack::PopAndDestroy(media);
       
  1812     }
       
  1813 
       
  1814 // ---------------------------------------------------------------------------
       
  1815 // Update a media in the collection
       
  1816 //
       
  1817 // For updating (overwriting) a playlist, or updating a song/artist/album/genre/
       
  1818 // composer:
       
  1819 // 1) update collection
       
  1820 // 2) when successfully updated the collection, SetItemL is returned; otherwise
       
  1821 //    a leave occurs.
       
  1822 // 3) complete task upon successfully updating the collection. If a leave
       
  1823 //    occurs, it's trapped by ExecuteTask and task is completed by ExecuteTask
       
  1824 // ---------------------------------------------------------------------------
       
  1825 //
       
  1826 void CMPXCollectionUiHelperImp::DoSetL()
       
  1827     {
       
  1828     MPX_FUNC("CMPXCollectionUiHelperImp::DoSetL");
       
  1829 
       
  1830     // fill in playlist details
       
  1831     TMPXGeneralCategory category =
       
  1832         iMedia->ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  1833     if ( category == EMPXPlaylist )
       
  1834         {
       
  1835         FillInPlaylistDetailsL(*iMedia);
       
  1836         }
       
  1837 
       
  1838     // find the collection Id
       
  1839     if (!iMedia->IsSupported(KMPXMediaGeneralCollectionId) &&
       
  1840         iMedia->IsSupported(KMPXMediaGeneralUri))
       
  1841         {
       
  1842         TInt collectionId =
       
  1843             FindCollectionIdL(iMedia->ValueText(KMPXMediaGeneralUri));
       
  1844 
       
  1845         if (collectionId)
       
  1846             {
       
  1847             iMedia->SetTObjectValueL<TUid>(
       
  1848                 KMPXMediaGeneralCollectionId , TUid::Uid(collectionId));
       
  1849             }
       
  1850         }
       
  1851 
       
  1852     // update collection.
       
  1853     iMediator->SetItemL( iMedia );
       
  1854 
       
  1855     CompleteTask(iTask, KErrNone);
       
  1856     }
       
  1857 
       
  1858 // ---------------------------------------------------------------------------
       
  1859 // Rename a media in the collection
       
  1860 // ---------------------------------------------------------------------------
       
  1861 //
       
  1862 void CMPXCollectionUiHelperImp::DoRenameL()
       
  1863     {
       
  1864     // find the collection Id of the playlist from playlist Id
       
  1865     // iMedia isn't used as the search criteria because it
       
  1866     // contains the new title of the playlist; calling
       
  1867     // FillInPlaylistDetailsL(*iMedia) will result in playlist
       
  1868     // not found.
       
  1869     if (!iMedia->IsSupported(KMPXMediaGeneralCollectionId))
       
  1870         {
       
  1871         CMPXMedia* media = CMPXMedia::NewL();
       
  1872         CleanupStack::PushL(media);
       
  1873 
       
  1874         media->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem);
       
  1875         media->SetTObjectValueL(KMPXMediaGeneralCategory,EMPXPlaylist);
       
  1876         media->SetTObjectValueL(KMPXMediaGeneralId, iMedia->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  1877 
       
  1878         FillInPlaylistDetailsL(*media);
       
  1879 
       
  1880         if (media->IsSupported(KMPXMediaGeneralCollectionId))
       
  1881             {
       
  1882             iMedia->SetTObjectValueL<TUid>(
       
  1883                 KMPXMediaGeneralCollectionId, media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId));
       
  1884             }
       
  1885         else
       
  1886             {
       
  1887             User::Leave(KErrNotFound);
       
  1888             }
       
  1889         CleanupStack::PopAndDestroy(media);
       
  1890         }
       
  1891 
       
  1892     // Update collection via command
       
  1893     //
       
  1894     CMPXCommand* cmd = CMPXCommand::NewL();
       
  1895     CleanupStack::PushL( cmd );
       
  1896     cmd->SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdCollectionSet );
       
  1897     cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue );
       
  1898     TUid colId = iMedia->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId);
       
  1899     cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, colId.iUid );
       
  1900     cmd->SetCObjectValueL<CMPXMedia>( KMPXCommandColSetMedia, iMedia );
       
  1901 
       
  1902     iCollection->Collection().CommandL( *cmd );
       
  1903     CleanupStack::PopAndDestroy( cmd );
       
  1904 
       
  1905     CompleteTask(iTask, KErrNone);
       
  1906     }
       
  1907 
       
  1908 // ---------------------------------------------------------------------------
       
  1909 // Export a playlist
       
  1910 // ---------------------------------------------------------------------------
       
  1911 //
       
  1912 void CMPXCollectionUiHelperImp::DoExportPlaylistL(TMPXItemId aPlaylistId,
       
  1913                                                   const TDesC& aDestinationDriveAndPath)
       
  1914     {
       
  1915     //
       
  1916     // fill in playlist info
       
  1917     //
       
  1918     iMedia = CMPXMedia::NewL();
       
  1919 
       
  1920     iMedia->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem);
       
  1921     iMedia->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist);
       
  1922     iMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
       
  1923 
       
  1924     FillInPlaylistDetailsL(*iMedia);
       
  1925 
       
  1926     //
       
  1927     // find songs that are in the specified playlist
       
  1928     //
       
  1929     CMPXMedia* songQuery = CMPXMedia::NewL();
       
  1930     CleanupStack::PushL(songQuery);
       
  1931     songQuery->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup);
       
  1932     songQuery->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXSong);
       
  1933     songQuery->SetTObjectValueL(KMPXMediaGeneralId, aPlaylistId);
       
  1934 
       
  1935     RArray<TMPXAttribute> songAttributes;
       
  1936     CleanupClosePushL(songAttributes);
       
  1937     iHarvester->RequiredAttributesL( EMPXPlaylistTypeM3U, songAttributes );
       
  1938     songAttributes.AppendL(KMPXMediaGeneralTitle);
       
  1939 
       
  1940     CMPXMedia* songQueryResult =
       
  1941         iCollection->Collection().FindAllL(*songQuery, songAttributes.Array());
       
  1942     CleanupStack::PopAndDestroy(&songAttributes);
       
  1943     CleanupStack::PopAndDestroy(songQuery);
       
  1944     CleanupStack::PushL(songQueryResult);
       
  1945 
       
  1946     // medias contains tracks currently in the playlist
       
  1947     const CMPXMediaArray* medias =
       
  1948         songQueryResult->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  1949     if( !medias )
       
  1950         {
       
  1951         User::Leave( KErrNoMemory );
       
  1952         }
       
  1953 
       
  1954     // add media array to iMedia
       
  1955     iMedia->SetCObjectValueL(
       
  1956         KMPXMediaArrayContents, const_cast<CMPXMediaArray*>(medias));
       
  1957     iMedia->SetTObjectValueL(
       
  1958         KMPXMediaArrayCount, medias->Count());
       
  1959 
       
  1960     CleanupStack::PopAndDestroy(songQueryResult);
       
  1961 
       
  1962     // export playlist, default to M3U file type. When ExportPlaylistL completes,
       
  1963     // HandlePlaylistExportCompletedL will be called
       
  1964     iHarvester->ExportPlaylistL( *iMedia, aDestinationDriveAndPath, EMPXPlaylistTypeM3U, this );
       
  1965     }
       
  1966 
       
  1967 // ---------------------------------------------------------------------------
       
  1968 // Reorder a song in a playlist
       
  1969 // ---------------------------------------------------------------------------
       
  1970 //
       
  1971 void CMPXCollectionUiHelperImp::DoReorderPlaylistL(CMPXCommand& aCommand)
       
  1972     {
       
  1973     // Update collection via command
       
  1974     //
       
  1975     aCommand.SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdReorderPlaylist );
       
  1976     aCommand.SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue );
       
  1977 
       
  1978     iCollection->Collection().CommandL( aCommand );
       
  1979 
       
  1980     CompleteTask(iTask, KErrNone);
       
  1981     }
       
  1982 
       
  1983 // ---------------------------------------------------------------------------
       
  1984 // retrieve information for the required attributes
       
  1985 // ---------------------------------------------------------------------------
       
  1986 //
       
  1987 void CMPXCollectionUiHelperImp::FillInPlaylistDetailsL(CMPXMedia& aMedia)
       
  1988     {
       
  1989     MPX_FUNC("CMPXCollectionUiHelperImp::FillInPlaylistDetailsL");
       
  1990 
       
  1991     //
       
  1992     // retrieve info about the playlist itself
       
  1993     //
       
  1994     RArray<TMPXAttribute> playlistAttributes;
       
  1995     CleanupClosePushL(playlistAttributes);
       
  1996     playlistAttributes.AppendL(KMPXMediaGeneralId);
       
  1997     playlistAttributes.AppendL(KMPXMediaGeneralTitle);
       
  1998     playlistAttributes.AppendL(KMPXMediaGeneralUri);
       
  1999     playlistAttributes.AppendL(KMPXMediaGeneralCollectionId);
       
  2000 
       
  2001     CMPXMedia* playlistSearchResult =
       
  2002         iCollection->Collection().FindAllL(aMedia, playlistAttributes.Array());
       
  2003     CleanupStack::PopAndDestroy(&playlistAttributes);
       
  2004     CleanupStack::PushL(playlistSearchResult);
       
  2005 
       
  2006     const CMPXMediaArray* results =
       
  2007         playlistSearchResult->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2008     if( !results )
       
  2009         {
       
  2010         User::Leave( KErrNoMemory );
       
  2011         }
       
  2012 
       
  2013     if ( results->Count() != 1 )
       
  2014         {
       
  2015         User::Leave(KErrArgument);
       
  2016         }
       
  2017 
       
  2018     MPX_DEBUG1("playlist found");
       
  2019 
       
  2020     aMedia.SetTObjectValueL(
       
  2021         KMPXMediaGeneralId, results->AtL(0)->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  2022     aMedia.SetTextValueL(
       
  2023         KMPXMediaGeneralTitle, results->AtL(0)->ValueText(KMPXMediaGeneralTitle));
       
  2024     aMedia.SetTextValueL(
       
  2025         KMPXMediaGeneralUri, results->AtL(0)->ValueText(KMPXMediaGeneralUri));
       
  2026     aMedia.SetTObjectValueL(
       
  2027         KMPXMediaGeneralCollectionId, results->AtL(0)->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId));
       
  2028 
       
  2029     CleanupStack::PopAndDestroy(playlistSearchResult);
       
  2030     }
       
  2031 
       
  2032 // ---------------------------------------------------------------------------
       
  2033 // retrieve collection from URI
       
  2034 // ResolvePlugin should be able to resolve the plugin without
       
  2035 // the client looking for the collection Id
       
  2036 // ---------------------------------------------------------------------------
       
  2037 //
       
  2038 TInt CMPXCollectionUiHelperImp::FindCollectionIdL(const TDesC& aUri)
       
  2039     {
       
  2040     MPX_FUNC("CMPXCollectionUiHelperImp::FindCollectionIdL");
       
  2041 
       
  2042     TInt collectionId(KErrNotFound);
       
  2043 
       
  2044     TParsePtrC parser( aUri );
       
  2045 
       
  2046     RPointerArray<CMPXCollectionType> collectionType;
       
  2047     iCollection->Collection().GetSupportedTypesL(collectionType);
       
  2048 
       
  2049     TInt index(KErrNotFound);
       
  2050     TInt count( collectionType.Count() );
       
  2051 
       
  2052     for (TInt i = 0; i < count; i++)
       
  2053         {
       
  2054         const CDesCArray& extensions = collectionType[i]->Extensions();
       
  2055 
       
  2056         if (extensions.FindIsq(parser.Ext(), index) == 0)
       
  2057             {
       
  2058             collectionId = collectionType[i]->Uid().iUid;
       
  2059             break;
       
  2060             }
       
  2061         }
       
  2062 
       
  2063     collectionType.ResetAndDestroy();
       
  2064 
       
  2065     MPX_DEBUG3("Uid 0x%x for %S", collectionId, &aUri);
       
  2066 
       
  2067     return collectionId;
       
  2068     }
       
  2069 
       
  2070 // End of file