mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbplugin/src/mpxdbplugin.cpp
changeset 0 ff3acec5bc43
child 15 171e07ac910f
equal deleted inserted replaced
-1:000000000000 0:ff3acec5bc43
       
     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:  Implementation of collection DB Plugin interface
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32cmn.h>
       
    21 #include <StringLoader.h>
       
    22 #include <bautils.h>
       
    23 #include <data_caging_path_literals.hrh>
       
    24 
       
    25 #include <mpxcmn.h>
       
    26 #include <mpxuser.h>
       
    27 #include <mpxcollectionpluginobserver.h>
       
    28 #include <mpxmediacontainerdefs.h>
       
    29 #include <mpxmediamusicdefs.h>
       
    30 #include <mpxmediaaudiodefs.h>
       
    31 #include <mpxmediacollectiondetaildefs.h>
       
    32 #include <mpxcommandgeneraldefs.h>
       
    33 #include <mpxmessagegeneraldefs.h>
       
    34 #include <mpxmessagecontainerdefs.h>
       
    35 #include <mpxcollectioncommanddefs.h>
       
    36 #include <mpxcollectionmessagedefs.h>
       
    37 #include <mpxincrementalopendefs.h>
       
    38 #include <mpxcollectionopenlresultdef.h>
       
    39 #include <mpxmedia.h>
       
    40 #include <mpxmediaarray.h>
       
    41 #include <mpxdrmmediautility.h>
       
    42 #include <mpxmediadrmdefs.h>
       
    43 #include <mpxlog.h>
       
    44 #include <mpxcollectiondbres.rsg>
       
    45 #include <mpxdbplugin.mbg>
       
    46 #include <centralrepository.h>
       
    47 
       
    48 #ifdef RD_MULTIPLE_DRIVE
       
    49 #include <driveinfo.h>
       
    50 #endif //RD_MULTIPLE_DRIVE
       
    51 
       
    52 #include "mpxresource.h"
       
    53 #include "mpxdbcommondef.h"
       
    54 #include "mpxdbcommonutil.h"
       
    55 
       
    56 #include "mpxdbhandler.h"
       
    57 #include "mpxdbutil.h"
       
    58 #include "mpxcollectiondbdef.h"
       
    59 #include "mpxdbplugin.h"
       
    60 
       
    61 // CONSTANTS
       
    62 _LIT(KMPlayerDbPluginMbmFile, "mpxdbplugin.mif");
       
    63 const TInt KFirstFetchCount = 400;
       
    64 
       
    65 const TUid KCRUIDMusicPlayerFeatures = { 0x101FFCD0 };
       
    66 const TInt KMusicPlayerFeatures = 1;
       
    67 const TInt KDisablePodcasting = 0x80;
       
    68 
       
    69 const TInt KIncrementalDeleteCount = 400;
       
    70 
       
    71 const TInt KSQLErrGeneral = -311; // SQL General error. Don't want to include sql header here
       
    72 // ============================ MEMBER FUNCTIONS ==============================
       
    73 
       
    74 // ----------------------------------------------------------------------------
       
    75 // Two-phased constructor.
       
    76 // ----------------------------------------------------------------------------
       
    77 //
       
    78 CMPXDbPlugin* CMPXDbPlugin::NewL(
       
    79     TAny* /*aInitParams*/)
       
    80     {
       
    81     MPX_FUNC("CMPXDbPlugin::NewL");
       
    82 
       
    83     CMPXDbPlugin* self = new (ELeave) CMPXDbPlugin();
       
    84     CleanupStack::PushL (self);
       
    85     self->ConstructL ();
       
    86     CleanupStack::Pop (self);
       
    87     return self;
       
    88     }
       
    89 
       
    90 // ----------------------------------------------------------------------------
       
    91 // Destructor.
       
    92 // ----------------------------------------------------------------------------
       
    93 //
       
    94 CMPXDbPlugin::~CMPXDbPlugin()
       
    95     {
       
    96     MPX_FUNC("CMPXDbPlugin::~CMPXDbPlugin");
       
    97 
       
    98     iSelections.Reset();
       
    99     iSelections.Close();
       
   100     iFs.Close();
       
   101     delete iDbHandler;
       
   102     delete iDrmMediaUtility;
       
   103     if (iResource)
       
   104         {
       
   105         iResource->Release();
       
   106         }
       
   107     iMusicLibraryMenuIds.Close();
       
   108     delete iMusicLibraryMenuTitles;
       
   109     delete iMusicLibraryTitles;
       
   110     delete iAllSongsForArtistTitle;
       
   111     delete iMusicMenuTitle;
       
   112 
       
   113     if (iActiveTask)
       
   114         {
       
   115         iActiveTask->Cancel();
       
   116         delete iActiveTask;
       
   117         }
       
   118     }
       
   119 
       
   120 // ----------------------------------------------------------------------------
       
   121 // Constructor.
       
   122 // ----------------------------------------------------------------------------
       
   123 //
       
   124 CMPXDbPlugin::CMPXDbPlugin()
       
   125     {
       
   126     MPX_FUNC("CMPXDbPlugin::CMPXDbPlugin");
       
   127     }
       
   128 
       
   129 // ----------------------------------------------------------------------------
       
   130 // Symbian 2nd phase constructor can leave.
       
   131 // ----------------------------------------------------------------------------
       
   132 //
       
   133 void CMPXDbPlugin::ConstructL()
       
   134     {
       
   135     MPX_FUNC("CMPXDbPlugin::ConstructL");
       
   136     iFirstDeleteStep = ETrue;
       
   137     User::LeaveIfError(iFs.Connect());
       
   138     iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
       
   139 
       
   140     TParse parse;
       
   141     parse.Set( KMPXCollectionDbResourceFile, &KDC_APP_RESOURCE_DIR, NULL );
       
   142     TFileName resFile(parse.FullName());
       
   143     User::LeaveIfError(MPXUser::CompleteWithDllPath(resFile));
       
   144     BaflUtils::NearestLanguageFile(iFs, resFile);
       
   145     iResource = CMPXResource::NewL(resFile);
       
   146 
       
   147     iDbHandler = CMPXDbHandler::NewL(iFs, *iResource);
       
   148     iMusicLibraryMenuTitles = iResource->ReadMenuArrayL(R_MC_MENU_ITEMS_ARRAY, iMusicLibraryMenuIds);
       
   149     iMusicLibraryTitles = iResource->ReadMenuArrayL(R_MC_TITLE_ITEMS_ARRAY, iMusicLibraryMenuIds );
       
   150     iAllSongsForArtistTitle = iResource->ReadHBufCL(R_MC_ALL_SONGS_FOR_ARTIST);
       
   151 
       
   152 #ifdef __ENABLE_MUSIC_TEXT_ALIGNMENT
       
   153     iMusicMenuTitle = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_MY_MUSIC_MENU_NSERIES);
       
   154 #else
       
   155     iMusicMenuTitle = iResource->ReadHBufCL(R_MPX_QTN_MUS_TITLE_MUSIC_MENU);
       
   156 #endif // __ENABLE_MUSIC_TEXT_ALIGNMENT
       
   157 
       
   158     iActiveTask = CMPXDbActiveTask::NewL(*this);
       
   159 
       
   160     CRepository* cenrep(NULL);
       
   161     TRAPD( err, cenrep = CRepository::NewL( KCRUIDMusicPlayerFeatures ) );
       
   162     if( err == KErrNone )
       
   163         {
       
   164         TInt val(0);
       
   165         cenrep->Get( KMusicPlayerFeatures, val );
       
   166         iDisablePodcasting = val&KDisablePodcasting ? ETrue:EFalse;
       
   167         delete cenrep;
       
   168         }
       
   169     else
       
   170         {
       
   171         iDisablePodcasting = EFalse;
       
   172         }
       
   173     iAllSongsValid = ETrue;
       
   174     }
       
   175 
       
   176 // ----------------------------------------------------------------------------
       
   177 // Navigates to the given path
       
   178 // ----------------------------------------------------------------------------
       
   179 //
       
   180 void CMPXDbPlugin::OpenL(
       
   181     const CMPXCollectionPath& aPath,
       
   182     const TArray<TMPXAttribute>& /*aAttrs*/,
       
   183     CMPXFilter* aFilter)
       
   184     {
       
   185     MPX_FUNC("CMPXDbPlugin::OpenL");
       
   186     MPX_DEBUG_PATH(aPath);
       
   187     //Create a path object to be returned.
       
   188     CMPXCollectionPath* path = CMPXCollectionPath::NewL(aPath);
       
   189     CleanupStack::PushL(path);
       
   190     RArray<TMPXAttribute> openAttrs;
       
   191     CleanupClosePushL(openAttrs);
       
   192 
       
   193     RArray<TInt> supportedIds;
       
   194     CleanupClosePushL(supportedIds);
       
   195 
       
   196     // Replace the attributes requested by the client with the ones below.
       
   197     // This will eventually have to be fixed
       
   198     SetAttributesL(aPath, openAttrs, supportedIds);
       
   199 
       
   200     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
   201     CleanupStack::PopAndDestroy(&supportedIds);
       
   202     CleanupStack::PushL(entries);
       
   203     //Add returned path into media
       
   204     entries->SetTObjectValueL<TInt>(KMPXMediaGeneralValue, (TInt)path);
       
   205 
       
   206     TInt error(KErrNone);
       
   207     TBool isASong(EFalse);
       
   208     CMPXCollectionPath* newPath(NULL);
       
   209 
       
   210     // Make sure we handle open the correct open mode
       
   211     //
       
   212     TMPXOpenMode openmode = aPath.OpenNextMode();
       
   213     switch (openmode)
       
   214         {
       
   215         case EMPXOpenGroupOrPlaylist:
       
   216             {
       
   217             // Open By Path
       
   218             MPX_TRAP(error, isASong = DoOpenL(aPath, openAttrs.Array(), *entries, aFilter));
       
   219             break;
       
   220             }
       
   221 
       
   222         case EMPXOpenPlaylistOnly:
       
   223             {
       
   224             if (aPath.Count() > 0)
       
   225                 {
       
   226                 // Try to open
       
   227                 MPX_TRAP(error, newPath = DoOpenPlaylistL(aPath, openAttrs.Array()));
       
   228                 CleanupStack::PushL(newPath);
       
   229                 isASong = ETrue;
       
   230                 }
       
   231             else // no items
       
   232                 {
       
   233                 MPX_TRAP(error, isASong = DoOpenL(aPath, openAttrs.Array(), *entries, aFilter));
       
   234                 }
       
   235 
       
   236             break;
       
   237             }
       
   238 
       
   239         default:
       
   240             // do nothing
       
   241             break;
       
   242         }
       
   243 
       
   244     // generate the callback
       
   245     if (isASong )
       
   246         {
       
   247         if (openmode == EMPXOpenGroupOrPlaylist)
       
   248             {
       
   249             iObs->HandleOpen(const_cast<CMPXCollectionPath*>(&aPath), error);
       
   250             }
       
   251         else  // openmode == EMPXOpenPlaylistOnly
       
   252             {
       
   253             iObs->HandleOpen(newPath, error);
       
   254             }
       
   255         }
       
   256     else
       
   257         {
       
   258         entries->SetCObjectValueL(KMPXMediaGeneralContainerPath,
       
   259             const_cast<CMPXCollectionPath*>(&aPath));
       
   260         entries->Delete(KMPXMediaGeneralValue);
       
   261         iObs->HandleOpen(entries, path, error);
       
   262         }
       
   263 
       
   264     if (newPath)
       
   265         {
       
   266         CleanupStack::PopAndDestroy(newPath);
       
   267         }
       
   268 
       
   269     CleanupStack::PopAndDestroy(entries);
       
   270     CleanupStack::PopAndDestroy(&openAttrs);
       
   271     CleanupStack::PopAndDestroy(path);
       
   272     }
       
   273 
       
   274 // ----------------------------------------------------------------------------
       
   275 // Get the extended properties of the current file (async)
       
   276 // ----------------------------------------------------------------------------
       
   277 //
       
   278 void CMPXDbPlugin::MediaL(
       
   279     const CMPXCollectionPath& aPath,
       
   280     const TArray<TMPXAttribute>& aAttrs,
       
   281     const TArray<TCapability>& /*aCaps*/,
       
   282     CMPXAttributeSpecs* /*aSpecs*/)
       
   283     {
       
   284     MPX_FUNC("CMPXDbPlugin::MediaL");
       
   285     MPX_DEBUG_PATH(aPath);
       
   286 
       
   287     RArray<TInt> supportedIds;
       
   288     CleanupClosePushL(supportedIds);
       
   289     if (aPath.Selection().Count())
       
   290         {
       
   291         // it's a container if there are multiple selection, else it's not a container
       
   292         supportedIds.AppendL(KMPXMediaIdContainer);
       
   293         }
       
   294     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
   295 
       
   296     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
   297     CleanupStack::PopAndDestroy(&supportedIds);
       
   298     CleanupStack::PushL(entries);
       
   299 
       
   300     DoMediaL(aPath, aAttrs, *entries);
       
   301 
       
   302     // Also fetch collection details and set the path if required
       
   303     DoHandleOtherMediaAttributesL(aAttrs, aPath, *entries);
       
   304 
       
   305     iObs->HandleMedia(entries, KErrNone);
       
   306     CleanupStack::PopAndDestroy(entries);
       
   307     }
       
   308 
       
   309 // ----------------------------------------------------------------------------
       
   310 // Cancel outstanding request
       
   311 // ----------------------------------------------------------------------------
       
   312 //
       
   313 void CMPXDbPlugin::CancelRequest()
       
   314     {
       
   315     MPX_FUNC("CMPXDbPlugin::CancelRequest");
       
   316     iActiveTask->Cancel();
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 // Executes the given command on the collection
       
   321 // ----------------------------------------------------------------------------
       
   322 //
       
   323 void CMPXDbPlugin::CommandL(
       
   324     TMPXCollectionCommand aCmd,
       
   325     TInt aArg /* = 0 */)
       
   326     {
       
   327     MPX_FUNC("CMPXDbPlugin::CommandL");
       
   328     MPX_DEBUG2("CMPXDbPlugin::CommandL %d", aCmd);
       
   329     iAllSongsValid = ETrue;
       
   330     switch (aCmd)
       
   331         {
       
   332         case EMcCmdRemoveAll:
       
   333             {
       
   334             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdRemoveAll");
       
   335             // Remove EVERYthing from the collection
       
   336             iDbHandler->RemoveEntireCollectionL();
       
   337             break;
       
   338             }
       
   339         case EMcCmdClose:
       
   340         case EMcCloseCollection:
       
   341             {
       
   342             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCloseCollection");
       
   343             // Close the specified database
       
   344             TRAP_IGNORE(iDbHandler->PreCloseCollectionL());
       
   345  #ifdef RD_MULTIPLE_DRIVE
       
   346             MPX_DEBUG1("Multiple drives closing databases");
       
   347             if ( aArg <0)
       
   348                 {
       
   349                 DriveInfo::TDriveArray driveArray;
       
   350                 User::LeaveIfError ( DriveInfo::GetUserVisibleDrives( iFs, driveArray));
       
   351                 TInt count( driveArray.Count ());
       
   352                 for (TInt i=0; i<count; ++i)
       
   353                     {
       
   354                     MPX_DEBUG2("At drive %i", driveArray[i]);
       
   355                     if (( driveArray[i] != EDriveC) && (!iDbHandler->IsRemoteDrive(static_cast<TDriveNumber>(driveArray[i])))) 
       
   356                         {
       
   357                         MPX_DEBUG2("Closing database %i", driveArray[i]);
       
   358                         TRAP_IGNORE( iDbHandler->CloseDatabaseL( driveArray[i] ) );
       
   359                         }
       
   360                     }
       
   361                 }
       
   362             else
       
   363                 {
       
   364                 iDbHandler->CloseDatabaseL(aArg);
       
   365                 }
       
   366  #else
       
   367             iDbHandler->CloseDatabaseL(aArg);
       
   368  #endif // RD_MULTIPLE_DRIVE
       
   369             iDbHandler->CollectionClosed();
       
   370             break;
       
   371             }
       
   372         case EMcReOpenCollection:
       
   373             {
       
   374             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcReOpenCollection");
       
   375             // Open the specified database
       
   376 #ifdef RD_MULTIPLE_DRIVE
       
   377             MPX_DEBUG1("Multiple drives opening databases");
       
   378             DriveInfo::TDriveArray driveArray;
       
   379             User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveArray ) );
       
   380             TInt count( driveArray.Count() );
       
   381             for( TInt i=0; i<count; ++i )
       
   382                 {
       
   383                 MPX_DEBUG2("At drive %i", driveArray[i]);
       
   384                 if( (driveArray[i] != EDriveC)  && (!iDbHandler->IsRemoteDrive(static_cast<TDriveNumber>(driveArray[i])))) 
       
   385                     {
       
   386                     TUint driveStatus(0);
       
   387                     User::LeaveIfError( DriveInfo::GetDriveStatus(
       
   388                         iFs, driveArray[i], driveStatus ) );
       
   389                     if( driveStatus & DriveInfo::EDrivePresent )
       
   390                         {
       
   391                         MPX_DEBUG2("Opening database %i", driveArray[i]);
       
   392                         TRAP_IGNORE( iDbHandler->OpenDatabaseL( driveArray[i] ) );
       
   393                         }
       
   394                     }
       
   395                 }
       
   396 #else
       
   397             iDbHandler->OpenDatabaseL(aArg);
       
   398 #endif // RD_MULTIPLE_DRIVE
       
   399             TRAP_IGNORE(iDbHandler->CollectionOpenedL());
       
   400             break;
       
   401             }
       
   402         case EMcRefreshStarted:
       
   403             {
       
   404             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcRefreshStarted");
       
   405             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   406             // ask the handler to start a transaction
       
   407             iDbHandler->RefreshStartL();
       
   408             iRefreshing=ETrue;
       
   409             break;
       
   410             }
       
   411         case EMcRefreshEnded:
       
   412             {
       
   413             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcRefreshEnded");
       
   414             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   415             // ask the handler to finalize the transaction
       
   416             iDbHandler->RefreshEndL();
       
   417             iRefreshing=EFalse;
       
   418             break;
       
   419             }
       
   420          case EMcCmdReCreateDB:
       
   421             {
       
   422             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdReCreateDB");
       
   423             // Recreate all databases
       
   424             iDbHandler->ReCreateDatabasesL();
       
   425             break;
       
   426             }
       
   427          case EMcCmdDbCorrupted:
       
   428             {
       
   429             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdDbCorrupted");
       
   430             iDbHandler->SetDBCorruptedL(ETrue);
       
   431             break;
       
   432             }
       
   433         case EMcCmdRefresh:
       
   434         case EMcCmdCollectionInit:
       
   435         case EMcCmdCollectionResyn:
       
   436             {
       
   437             // deprecated
       
   438             break;
       
   439             }
       
   440         case EMcCmdMtpStart:
       
   441             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   442             iMtpInUse = ETrue;
       
   443             iDbHandler->MtpStartL();            
       
   444             break;
       
   445         case EMcCmdMtpEnd:
       
   446             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   447             iMtpInUse = EFalse;
       
   448             iDbHandler->MtpEndL();            
       
   449             break;
       
   450          default:
       
   451             {
       
   452             User::Leave(KErrNotSupported);
       
   453             }
       
   454         }
       
   455     }
       
   456 
       
   457 // ----------------------------------------------------------------------------
       
   458 // Executes the given command on the collection
       
   459 // ----------------------------------------------------------------------------
       
   460 //
       
   461 void CMPXDbPlugin::CommandL(
       
   462     CMPXCommand& aCmd)
       
   463     {
       
   464     MPX_FUNC("CMPXDbPlugin::CommandL");
       
   465 
       
   466     if (!aCmd.IsSupported(KMPXCommandGeneralId))
       
   467         {
       
   468         User::Leave(KErrArgument);
       
   469         }
       
   470 
       
   471     TMPXCommandId commandId = aCmd.ValueTObjectL<TMPXCommandId>(KMPXCommandGeneralId);
       
   472 
       
   473     TBool syncOp(EFalse);
       
   474     if (aCmd.IsSupported(KMPXCommandGeneralDoSync))
       
   475         {
       
   476         syncOp = aCmd.ValueTObjectL<TBool>(KMPXCommandGeneralDoSync);
       
   477         }
       
   478 
       
   479     // Handle this operation synchronously or asynchronously
       
   480     //
       
   481     if (!syncOp)
       
   482         {
       
   483         iActiveTask->StartL(commandId, aCmd);
       
   484         }
       
   485     else  // Sync operation
       
   486         {
       
   487         switch (commandId)
       
   488             {
       
   489             case KMPXCommandIdCollectionRetrieveUriForDeletion:
       
   490                 {
       
   491                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRetrieveUriForDeletion");
       
   492                 DoRetrieveUriForDeletionL(aCmd);
       
   493                 break;
       
   494                 }
       
   495             case KMPXCommandIdCollectionRemove:
       
   496                 {
       
   497                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRemove");
       
   498                 if ( !iDbHandler->InTransaction() )
       
   499                     {
       
   500                     iDbHandler->BeginTransactionL();
       
   501                     }
       
   502 
       
   503                 if (iFirstDeleteStep )
       
   504                     {
       
   505                     iFirstDeleteStep = EFalse;
       
   506                     }
       
   507                 DoRemovePathL(aCmd);
       
   508                 break;
       
   509                 }
       
   510             case KMPXCommandIdCollectionRemoveMedia:
       
   511                 {
       
   512                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRemoveMedia");
       
   513                 DoRemoveMediaL(aCmd);
       
   514                 break;
       
   515                 }
       
   516             case KMPXCommandIdCollectionCleanupDeletedMedias:
       
   517                 {
       
   518                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionCleanupDeletedMedias");
       
   519                 CleanupDeletedRecordsL(aCmd);
       
   520                 break;
       
   521                 }
       
   522             case KMPXCommandIdCollectionAdd:
       
   523                 {
       
   524                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectioAdd");
       
   525                 CMPXMedia* media = aCmd.Value<CMPXMedia>(KMPXCommandColAddMedia);
       
   526                 User::LeaveIfNull( media );
       
   527                 TUint32 id(DoAddL(*media));
       
   528                 aCmd.SetTObjectValueL<TMPXItemId>(KMPXCommandColAddRtnId, id);
       
   529                 break;
       
   530                 }
       
   531             case KMPXCommandIdCollectionSet:
       
   532                 {
       
   533                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionSet");
       
   534                 CMPXMedia* media = aCmd.Value<CMPXMedia>(KMPXCommandColSetMedia);
       
   535                 User::LeaveIfNull( media );
       
   536                 DoSetL(*media);
       
   537                 break;
       
   538                 }
       
   539             case KMPXCommandIdCollectionCompleteDelete:
       
   540                 {
       
   541                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionCompleteDelete");
       
   542                 DoHandleDeleteCompleteL(aCmd);
       
   543                 break;
       
   544                 }
       
   545             case KMPXCommandIdReorderPlaylist:
       
   546                 {
       
   547                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdReorderPlaylist");
       
   548                 DoReorderPlaylistL(aCmd);
       
   549                 break;
       
   550                 }
       
   551             case KMPXCommandIdUpdateRefreshTime:
       
   552                 {
       
   553                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime");
       
   554                 TTime curTime;
       
   555                 curTime.HomeTime();
       
   556                 iDbHandler->SetLastRefreshedTimeL(curTime);
       
   557                 break;
       
   558                 }
       
   559             case KMPXCommandCollectionGetCount:
       
   560                 {
       
   561                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandCollectionGetCount");
       
   562                 DoGetCollectionCountL(aCmd);
       
   563                 break;
       
   564                 }
       
   565             case KMPXCommandCollectionGetURIs:
       
   566                 {
       
   567                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandCollectionGetURIs");
       
   568                 DoGetCollectionUriL(aCmd);
       
   569                 break;
       
   570                 }
       
   571             default:
       
   572                 {
       
   573                 User::Leave(KErrNotSupported);
       
   574                 }
       
   575             }
       
   576         }
       
   577     }
       
   578 
       
   579 // ----------------------------------------------------------------------------
       
   580 // Adds an item (song or playlist) to the collection
       
   581 // ----------------------------------------------------------------------------
       
   582 //
       
   583 void CMPXDbPlugin::AddL(
       
   584     const CMPXMedia& aMedia)
       
   585     {
       
   586     MPX_FUNC("CMPXDbPlugin::AddL");
       
   587     DoAddL(aMedia);
       
   588     }
       
   589 
       
   590 // ----------------------------------------------------------------------------
       
   591 // Remove an item from the collection database using the given path
       
   592 // ----------------------------------------------------------------------------
       
   593 //
       
   594 void CMPXDbPlugin::RemoveL(
       
   595     const CMPXCollectionPath& aPath)
       
   596     {
       
   597     MPX_FUNC("CMPXDbPlugin::RemoveL(by path)");
       
   598     MPX_DEBUG_PATH(aPath);
       
   599 
       
   600     CMPXMessageArray* msgAry = CMPXMessageArray::NewL();
       
   601     CleanupStack::PushL(msgAry);
       
   602 
       
   603     // Return file path for deleted item(s)
       
   604     CDesCArray* fp = DoRemoveL(aPath, *msgAry);
       
   605 
       
   606     iObs->HandleRemove(*fp, KErrNone);
       
   607     delete fp;
       
   608 
       
   609     // Send Change Messages
       
   610     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
   611     DoHandleChangeL(msgAry);
       
   612     CleanupStack::PopAndDestroy(msgAry);
       
   613     }
       
   614 
       
   615 // ----------------------------------------------------------------------------
       
   616 // Remove an item from the collection database using the given media properties
       
   617 // ----------------------------------------------------------------------------
       
   618 //
       
   619 void CMPXDbPlugin::RemoveL(
       
   620     const CMPXMedia& aMedia)
       
   621     {
       
   622     MPX_FUNC("CMPXDbPlugin::RemoveL(by media)");
       
   623     DoRemoveL(aMedia, EFalse);
       
   624     }
       
   625 
       
   626 // ----------------------------------------------------------------------------
       
   627 // Sets/updates the media for an item in the collection
       
   628 // DEPRECATED for week 18
       
   629 // ----------------------------------------------------------------------------
       
   630 //
       
   631 void CMPXDbPlugin::SetL(
       
   632     const CMPXMedia& aMedia)
       
   633     {
       
   634     MPX_FUNC("CMPXDbPlugin::SetL");
       
   635     DoSetL(aMedia);
       
   636     }
       
   637 
       
   638 // ----------------------------------------------------------------------------
       
   639 // Find the items matching the media specifications
       
   640 // ----------------------------------------------------------------------------
       
   641 //
       
   642 void CMPXDbPlugin::FindAllL(
       
   643     const CMPXMedia& aCriteria,
       
   644     const TArray<TMPXAttribute>& aAttrs)
       
   645     {
       
   646     MPX_FUNC("CMPXDbPlugin::FindAllL");
       
   647 
       
   648     CMPXMedia* entries = FindAllSyncL(aCriteria, aAttrs);
       
   649 
       
   650     // notify client. if FindAllL leaves, framework will notify client of the error
       
   651     iObs->HandleFindAll(entries, KErrNone);
       
   652     delete entries;
       
   653     }
       
   654 
       
   655 // ----------------------------------------------------------------------------
       
   656 // Find the items matching the media specifications
       
   657 // ----------------------------------------------------------------------------
       
   658 //
       
   659 CMPXMedia* CMPXDbPlugin::FindAllSyncL(
       
   660     const CMPXMedia& aCriteria,
       
   661     const TArray<TMPXAttribute>& aAttrs)
       
   662     {
       
   663     MPX_FUNC("CMPXDbPlugin::FindAllSyncL");
       
   664 
       
   665     CMPXMedia* entries = iDbHandler->FindAllLC(aCriteria, aAttrs);
       
   666 
       
   667     if (entries)
       
   668         {
       
   669         CMPXMediaArray* ary = entries->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
   670         User::LeaveIfNull( ary );
       
   671         DoSetDrmForArrayL( *ary, aAttrs );
       
   672         }
       
   673 
       
   674     CleanupStack::Pop(entries);
       
   675     return entries;
       
   676     }
       
   677 
       
   678 // ----------------------------------------------------------------------------
       
   679 // Get the list of supported capabilities
       
   680 // ----------------------------------------------------------------------------
       
   681 //
       
   682 TCollectionCapability CMPXDbPlugin::GetCapabilities()
       
   683     {
       
   684     // This one supports simple search
       
   685     return EMcSearch;
       
   686     }
       
   687 
       
   688 // ----------------------------------------------------------------------------
       
   689 // Get the list of supported capabilities
       
   690 // ----------------------------------------------------------------------------
       
   691 //
       
   692 TBool CMPXDbPlugin::HandleStepL()
       
   693     {
       
   694     MPX_FUNC("CMPXDbPlugin::HandleStepL");
       
   695 
       
   696     TBool done(ETrue);
       
   697 
       
   698     switch (iActiveTask->GetTask())
       
   699         {
       
   700         case KMPXCommandIdCollectionSet:
       
   701             {
       
   702             done = DoSetAsyncL();
       
   703             break;
       
   704             }
       
   705         case KMPXCommandIdCollectionAdd:
       
   706             {
       
   707             done = DoAddAsyncL();
       
   708             break;
       
   709             }
       
   710         case KMPXCommandIdCollectionRemove:
       
   711             {
       
   712             DoRemovePathL(iActiveTask->GetCommand());
       
   713             done = ETrue;
       
   714             break;
       
   715             }
       
   716         case KMPXCommandIdCollectionRemoveMedia:
       
   717             {
       
   718             DoRemoveMediaL(iActiveTask->GetCommand());
       
   719             done = ETrue;
       
   720             break;
       
   721             }
       
   722         case KMPXCommandIdCollectionRetrieveUriForDeletion:
       
   723             {
       
   724             DoRetrieveUriForDeletionL(iActiveTask->GetCommand());
       
   725             done = ETrue;
       
   726             break;
       
   727             }
       
   728         case KMPXCommandIdCollectionCleanupDeletedMedias:
       
   729             {
       
   730             CleanupDeletedRecordsL(iActiveTask->GetCommand());
       
   731             done = ETrue;
       
   732             break;
       
   733             }
       
   734         case KMPXCommandIdCollectionCompleteDelete:
       
   735             {
       
   736             DoHandleDeleteCompleteL( iActiveTask->GetCommand() );
       
   737             break;
       
   738             }
       
   739         case KMPXCommandIdUpdateRefreshTime:
       
   740             {
       
   741             MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime");
       
   742             TTime curTime;
       
   743             curTime.HomeTime();
       
   744             iDbHandler->SetLastRefreshedTimeL(curTime);
       
   745             break;
       
   746             }
       
   747         case KMPXCommandIdIncrementalOpenL:
       
   748             {
       
   749             DoIncrementalOpenL( iActiveTask->GetCommand() );
       
   750             done = ETrue;
       
   751             break;
       
   752             }
       
   753         default:
       
   754             {
       
   755             // Should never happen!
       
   756             ASSERT(0);
       
   757             break;
       
   758             }
       
   759         }
       
   760     return done;
       
   761     }
       
   762 
       
   763 // ----------------------------------------------------------------------------
       
   764 // Handler for async operations completed
       
   765 // ----------------------------------------------------------------------------
       
   766 //
       
   767 void CMPXDbPlugin::HandleOperationCompleted(
       
   768     TInt aErr)
       
   769     {
       
   770     MPX_FUNC("CMPXDbPlugin::HandleOperationCompleted");
       
   771     TRAP_IGNORE(DoHandleOperationCompletedL(aErr));
       
   772     }
       
   773 
       
   774 // ----------------------------------------------------------------------------
       
   775 // Process the OpenL command
       
   776 // ----------------------------------------------------------------------------
       
   777 //
       
   778 TBool CMPXDbPlugin::DoOpenL(
       
   779     const CMPXCollectionPath& aPath,
       
   780     const TArray<TMPXAttribute>& aAttrs,
       
   781     CMPXMedia& aEntries,
       
   782     CMPXFilter* aFilter )
       
   783     {
       
   784     MPX_FUNC("CMPXDbPlugin::DoOpenL");
       
   785 
       
   786     TInt err( KErrNone );
       
   787     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
   788     CleanupStack::PushL(array);
       
   789 
       
   790     TInt count(0);
       
   791     TInt levels(aPath.Levels());
       
   792     TBool isASong(EFalse);
       
   793 
       
   794     aEntries.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPath.Id(levels - 1));
       
   795 
       
   796     if (1 == levels)
       
   797         {
       
   798         // return the "main menu"
       
   799         count = iMusicLibraryMenuTitles->Count();
       
   800         RArray<TMPXItemId> ids;
       
   801         CleanupClosePushL(ids);
       
   802 
       
   803         // due to ui changes, the order of main menu is changed
       
   804         // since multiple clients hardcode indexes to each entry,
       
   805         // the enum cannot be changed, instead we will have to
       
   806         // manually change the display order to minimize the impact to
       
   807         // external clients
       
   808 
       
   809         // change from:
       
   810         // all songs, playlist, artist, album, (podcast), genre, composer
       
   811         // to:
       
   812         // artist, album, playlist, all songs, (podcast), genre, composer
       
   813         for (TInt i = EBrowseArtist; i <= EBrowseAlbum; ++i)
       
   814             {
       
   815             MPXDbCommonUtil::AppendMediaL(*array, iMusicLibraryMenuTitles->MdcaPoint(i), EMPXGroup,
       
   816                 CategoryForBrowseType(static_cast<TMCBrowseType>(i)), iMusicLibraryMenuIds[i]);
       
   817             ids.AppendL(TMPXItemId(iMusicLibraryMenuIds[i]));
       
   818             }
       
   819         MPXDbCommonUtil::AppendMediaL(*array, iMusicLibraryMenuTitles->MdcaPoint(1), EMPXGroup,
       
   820             CategoryForBrowseType(static_cast<TMCBrowseType>(1)), iMusicLibraryMenuIds[1]);
       
   821         ids.AppendL(TMPXItemId(iMusicLibraryMenuIds[1]));
       
   822         MPXDbCommonUtil::AppendMediaL(*array, iMusicLibraryMenuTitles->MdcaPoint(0), EMPXGroup,
       
   823             CategoryForBrowseType(static_cast<TMCBrowseType>(0)), iMusicLibraryMenuIds[0]);
       
   824         ids.AppendL(TMPXItemId(iMusicLibraryMenuIds[0]));
       
   825 
       
   826 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU
       
   827         if( !iDisablePodcasting )
       
   828             {
       
   829             MPXDbCommonUtil::AppendMediaL(*array, iMusicLibraryMenuTitles->MdcaPoint(EBrowsePodcasts), EMPXGroup,
       
   830                 CategoryForBrowseType(static_cast<TMCBrowseType>(EBrowsePodcasts)), iMusicLibraryMenuIds[EBrowsePodcasts]);
       
   831             ids.AppendL(TMPXItemId(iMusicLibraryMenuIds[EBrowsePodcasts]));
       
   832             }
       
   833 #endif // __ENABLE_PODCAST_IN_MUSIC_MENU
       
   834 
       
   835         // Genre and composer
       
   836         for (TInt i = ( EBrowseGenre ); i < count; ++i)
       
   837             {
       
   838             MPXDbCommonUtil::AppendMediaL(*array, iMusicLibraryMenuTitles->MdcaPoint(i), EMPXGroup,
       
   839                 CategoryForBrowseType(static_cast<TMCBrowseType>(i)), iMusicLibraryMenuIds[i]);
       
   840             ids.AppendL(TMPXItemId(iMusicLibraryMenuIds[i]));
       
   841             }
       
   842 
       
   843         TInt pPath = aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
   844         MPX_ASSERT(pPath);
       
   845         ((CMPXCollectionPath*)pPath)->AppendL(ids.Array());
       
   846         CleanupStack::PopAndDestroy(&ids);
       
   847         SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXCollection, *iMusicMenuTitle);
       
   848         aEntries.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
   849             KMPXMediaGeneralNonPermissibleActions, EMPXWrite);
       
   850         }
       
   851     else if (levels >= 2)
       
   852         {
       
   853         // Create a media which hold the pointer to the returned path
       
   854         if (aEntries.IsSupported(KMPXMediaGeneralValue))
       
   855             {
       
   856             CMPXMedia* pMedia = CMPXMedia::NewL();
       
   857             CleanupStack::PushL(pMedia);
       
   858             pMedia->SetTObjectValueL<TInt>(KMPXMediaGeneralValue,
       
   859                                           aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue));
       
   860             array->AppendL(*pMedia);
       
   861             CleanupStack::PopAndDestroy(pMedia);
       
   862             MPX_ASSERT(array->Count()==1);
       
   863             }
       
   864 
       
   865         // check the browse type
       
   866         switch (aPath.Id(1).iId2)
       
   867             {
       
   868             case EBrowseAll:
       
   869                 {
       
   870                 TBool doIncremental(ETrue);
       
   871                 if( aFilter && aFilter->IsSupported( KMPXCollectionOpenLSupportsIncremental ) )
       
   872                     {
       
   873                     doIncremental =
       
   874                          aFilter->ValueTObjectL<TBool>(KMPXCollectionOpenLSupportsIncremental);
       
   875                     }
       
   876 
       
   877                 if( doIncremental )
       
   878                     {
       
   879                     TRAP( err, isASong = DoOpenIncrementalL( aPath, aAttrs, aEntries, array ) );
       
   880                     }
       
   881                 else
       
   882                     {
       
   883                     TRAP( err, isASong = DoOpenBrowseAllL(aPath, aAttrs, aEntries, array) );
       
   884                     }
       
   885                 break;
       
   886                 }
       
   887 
       
   888             case EBrowseArtist:
       
   889                 {
       
   890                 if( iAllSongsValid )
       
   891                     {
       
   892                     isASong = DoOpenBrowseArtistL( aPath, aAttrs, aEntries, array );
       
   893                     }
       
   894                 break;
       
   895                 }
       
   896 
       
   897             case EBrowseAlbum:
       
   898                 {
       
   899                 if( iAllSongsValid )
       
   900                     {
       
   901                     isASong = DoOpenBrowseAlbumL( aPath, aAttrs, aEntries, array );
       
   902                     }
       
   903                 break;
       
   904                 }
       
   905 
       
   906             case EBrowsePlaylist:
       
   907                 {
       
   908                 if( iAllSongsValid )
       
   909                     {
       
   910                     isASong = DoOpenBrowsePlaylistL(aPath, aAttrs, aEntries, array);
       
   911                     }
       
   912 
       
   913                 break;
       
   914                 }
       
   915 
       
   916             case EBrowseGenre:
       
   917                 {
       
   918                 if( iAllSongsValid )
       
   919                     {
       
   920                     isASong = DoOpenBrowseGenreL( aPath, aAttrs, aEntries, array );
       
   921                     }
       
   922                 break;
       
   923                 }
       
   924 
       
   925             case EBrowseComposer:
       
   926                 {
       
   927                 if( iAllSongsValid )
       
   928                     {
       
   929                     isASong = DoOpenBrowseComposerL( aPath, aAttrs, aEntries, array );
       
   930                     }
       
   931                 break;
       
   932                 }
       
   933 
       
   934             default:
       
   935                 {
       
   936                 User::Leave(KErrArgument);
       
   937                 }
       
   938             }
       
   939         //Remove the first media
       
   940         if ( array->Count() &&
       
   941             (*array)[0]->IsSupported(KMPXMediaGeneralValue))
       
   942             {
       
   943             array->Remove(0);
       
   944             }
       
   945         }
       
   946     else
       
   947         {
       
   948         User::Leave(KErrNotSupported);
       
   949         }
       
   950     aEntries.SetCObjectValueL(KMPXMediaArrayContents, array);
       
   951     aEntries.SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
   952 
       
   953     CleanupStack::PopAndDestroy(array);
       
   954 
       
   955     if( err == KSQLErrGeneral )
       
   956         {
       
   957         iAllSongsValid = EFalse;
       
   958         User::Leave( KErrDiskFull );
       
   959         }
       
   960     else if( err != KErrNone )
       
   961         {
       
   962         User::Leave( err );
       
   963         }
       
   964     return isASong;
       
   965     }
       
   966 
       
   967 
       
   968 // ----------------------------------------------------------------------------
       
   969 // CMPXDbPlugin::DoOpenIncrementalL
       
   970 // ----------------------------------------------------------------------------
       
   971 //
       
   972 TBool CMPXDbPlugin::DoOpenIncrementalL( const CMPXCollectionPath& aPath,  const TArray<TMPXAttribute>& aAttrs,
       
   973                                        CMPXMedia& aEntries, CMPXMediaArray* aArray)
       
   974     {
       
   975     TBool isASong(EFalse);
       
   976 
       
   977     TInt levels(aPath.Levels());
       
   978 
       
   979     if( levels == 2 )
       
   980         {
       
   981         // Remove the pPath dummy from the array
       
   982         TInt pPath = aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
   983         aArray->Remove(0);
       
   984         CMPXCollectionPath* p = (CMPXCollectionPath*) pPath;
       
   985 
       
   986         RArray<TMPXItemId> ids;
       
   987         CleanupClosePushL( ids );
       
   988 
       
   989         iDbHandler->GetAllSongsLimitedL( aAttrs, *aArray, KFirstFetchCount );
       
   990 
       
   991         TInt c( aArray->Count() );
       
   992         for( TInt i=0; i<c; ++i )
       
   993             {
       
   994             TMPXItemId id = aArray->AtL(i)->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
   995             ids.Append( id );
       
   996             }
       
   997 
       
   998         // Rest are all blank items
       
   999         CMPXMedia* entry = CMPXMedia::NewL();
       
  1000         CleanupStack::PushL(entry);
       
  1001         entry->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXItem);
       
  1002         entry->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, EMPXSong);
       
  1003         entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, KMPXInvalidItemId );
       
  1004 
       
  1005         TInt count = iDbHandler->NumberOfItemsL(EMPXSong);
       
  1006         count-=c;
       
  1007         for( TInt i=0; i<count; ++i )
       
  1008             {
       
  1009             aArray->AppendL( *entry );
       
  1010             ids.Append( KMPXInvalidItemId );
       
  1011             }
       
  1012         CleanupStack::PopAndDestroy( entry );
       
  1013 
       
  1014         // Set the "Supportes incremental Command" flag
       
  1015         //
       
  1016         aEntries.SetTObjectValueL( KMPXCollectionOpenLSupportsIncremental, ETrue );
       
  1017 
       
  1018         TMPXOpenDataBlock block;
       
  1019         block.iOffset=KErrNotFound;
       
  1020         block.iSize=count;
       
  1021         aEntries.SetTObjectValueL<TMPXOpenDataBlock>( KMPXCollectionOpenLResultRange, block );
       
  1022 
       
  1023         SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXSong,
       
  1024                 iMusicLibraryTitles->MdcaPoint(EBrowseAll));
       
  1025 
       
  1026         p->AppendL(ids.Array());
       
  1027         CleanupStack::PopAndDestroy( &ids );
       
  1028         }
       
  1029     else if( levels == 3 )
       
  1030         {
       
  1031         iDbHandler->GetSongL(aPath.Id(levels - 1).iId2, aAttrs, *aArray);
       
  1032         isASong = ETrue;
       
  1033         }
       
  1034 
       
  1035 
       
  1036     return isASong;
       
  1037     }
       
  1038 
       
  1039 // ----------------------------------------------------------------------------
       
  1040 // Handles OpenL called for EBrowseAll
       
  1041 // ----------------------------------------------------------------------------
       
  1042 //
       
  1043 TBool CMPXDbPlugin::DoOpenBrowseAllL(
       
  1044     const CMPXCollectionPath& aPath,
       
  1045     const TArray<TMPXAttribute>& aAttrs,
       
  1046     CMPXMedia& aEntries,
       
  1047     CMPXMediaArray* aArray)
       
  1048     {
       
  1049     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseAllL");
       
  1050 
       
  1051     TInt levels(aPath.Levels());
       
  1052     switch (levels)
       
  1053        {
       
  1054        // All songs
       
  1055        case 2:
       
  1056             {
       
  1057             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAllL_All);
       
  1058 
       
  1059             iDbHandler->GetAllSongsL(aArray, aAttrs);
       
  1060             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXSong,
       
  1061                 iMusicLibraryTitles->MdcaPoint(EBrowseAll));
       
  1062 
       
  1063             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAllL_All);
       
  1064             break;
       
  1065             }
       
  1066 
       
  1067          // A Song in all songs
       
  1068          case 3:
       
  1069             {
       
  1070             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAllL_Song);
       
  1071 
       
  1072             iDbHandler->GetSongL(aPath.Id(levels - 1).iId2, aAttrs, *aArray);
       
  1073 
       
  1074             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAllL_Song);
       
  1075             break;
       
  1076             }
       
  1077 
       
  1078          default:
       
  1079             {
       
  1080             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseAllL: Invalid levels[%d]", levels);
       
  1081             User::Leave(KErrNotSupported);
       
  1082             }
       
  1083         } // end switch(levels)
       
  1084 
       
  1085     return (levels == 3);
       
  1086     }
       
  1087 
       
  1088 // ----------------------------------------------------------------------------
       
  1089 // Handles OpenL called for EBrowseArtist
       
  1090 // ----------------------------------------------------------------------------
       
  1091 //
       
  1092 TBool CMPXDbPlugin::DoOpenBrowseArtistL(
       
  1093     const CMPXCollectionPath& aPath,
       
  1094     const TArray<TMPXAttribute>& aAttrs,
       
  1095     CMPXMedia& aEntries,
       
  1096     CMPXMediaArray* aArray)
       
  1097     {
       
  1098     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseArtistL");
       
  1099 
       
  1100     TBool isASong(EFalse);
       
  1101     TInt levels(aPath.Levels());
       
  1102     TInt idIndex(levels - 1);
       
  1103 
       
  1104     RArray<TMPXItemId> selections;
       
  1105     CleanupClosePushL(selections);
       
  1106     aPath.SelectionL(selections);
       
  1107 
       
  1108     switch (levels)
       
  1109         {
       
  1110         // All artists
       
  1111         case 2:
       
  1112             {
       
  1113             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_All);
       
  1114 
       
  1115             iDbHandler->GetAllArtistsL(aAttrs, aArray);
       
  1116             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXArtist,
       
  1117                 iMusicLibraryTitles->MdcaPoint(EBrowseArtist));
       
  1118 
       
  1119             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_All);
       
  1120             break;
       
  1121             }
       
  1122 
       
  1123         // All albums of an artist
       
  1124         case 3:
       
  1125             {
       
  1126             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllAlbums);
       
  1127             // get the albums
       
  1128             TInt id(aPath.Id(idIndex).iId2);
       
  1129             MPX_ASSERT(aArray->Count());
       
  1130             MPX_ASSERT((*aArray)[0]->IsSupported(KMPXMediaGeneralValue));
       
  1131             TInt pPath = (*aArray)[0]->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
  1132             MPX_ASSERT(pPath);
       
  1133             iDbHandler->GetAlbumsMatchingArtistL(id, aAttrs, *aArray);
       
  1134             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXArtist, id);
       
  1135 
       
  1136             TInt count = aArray->Count();
       
  1137             if ( count > 2 )
       
  1138                 {
       
  1139                 // Only show "all" item if there is more than 1 album
       
  1140                 // count for "all" item
       
  1141                 TInt total = 0;
       
  1142                 for ( TInt i = 1; i < count; i++ )
       
  1143                 {
       
  1144                 TInt temp = (*aArray)[i]->ValueTObjectL<TInt>(KMPXMediaGeneralCount);
       
  1145                 total += temp;
       
  1146                 }
       
  1147             // Add "all" item under an artist
       
  1148             MPXDbCommonUtil::PrependMediaL(*aArray, *iAllSongsForArtistTitle, EMPXItem, EMPXAlbum,
       
  1149                 aPath.Id(idIndex), 0, 0, 1);
       
  1150     
       
  1151                 (*aArray)[1]->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, total);
       
  1152     
       
  1153             TMPXItemId allId = ((*aArray)[1]->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  1154             if (aArray->Count() > 2)
       
  1155                 { // path media, all id  and at least one media
       
  1156                 ((CMPXCollectionPath*)pPath)->InsertL(allId, 0);
       
  1157                 }
       
  1158             else
       
  1159                 { // only has all item
       
  1160                 ((CMPXCollectionPath*)pPath)->AppendL(allId);
       
  1161                     }
       
  1162                 }
       
  1163 
       
  1164             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllAlbums);
       
  1165             break;
       
  1166             }
       
  1167 
       
  1168         // All songs of an album for an artist or all songs for an artist
       
  1169         case 4:
       
  1170             {
       
  1171             // all songs for an artist
       
  1172             if (aPath.Id(3) == aPath.Id(2))
       
  1173                 {
       
  1174                 MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongs);
       
  1175 
       
  1176                 TInt id(aPath.Id(idIndex - 1).iId2);
       
  1177                 iDbHandler->GetSongsMatchingArtistL(id, aAttrs, aArray);
       
  1178                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXSong, id);
       
  1179 
       
  1180                 MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongs);
       
  1181                 }
       
  1182             // all songs of an album for an artist
       
  1183             else
       
  1184                 {
       
  1185                 MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongsForAlbum);
       
  1186                 TUint32 artistId(aPath.Id(idIndex - 1).iId2);
       
  1187 
       
  1188                 if (selections.Count())
       
  1189                     {
       
  1190                     // Multiple albums
       
  1191                     const TInt count(aPath.Selection().Count());
       
  1192                     for (TInt i = 0; i < count; ++i)
       
  1193                         {
       
  1194                         iDbHandler->GetSongsMatchingArtistAndAlbumL(artistId, selections[i].iId2,
       
  1195                             aAttrs, aArray);
       
  1196                         }
       
  1197                     }
       
  1198                 else
       
  1199                     {
       
  1200                     // One album
       
  1201                     iDbHandler->GetSongsMatchingArtistAndAlbumL(artistId, aPath.Id(idIndex).iId2,
       
  1202                         aAttrs, aArray);
       
  1203                     }
       
  1204 
       
  1205                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXAlbum, aPath.Id(idIndex).iId2);
       
  1206                 MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongsForAlbum);
       
  1207                 }
       
  1208 
       
  1209             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseArtistL: retrieved %d items", aArray->Count());
       
  1210 
       
  1211             break;
       
  1212             }
       
  1213 
       
  1214         // A Song in an album
       
  1215         case 5:
       
  1216             {
       
  1217             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_Song);
       
  1218 
       
  1219             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1220             isASong = ETrue;
       
  1221 
       
  1222             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_Song);
       
  1223             break;
       
  1224             }
       
  1225 
       
  1226         default:
       
  1227             {
       
  1228             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseArtistL: Invalid levels[%d]", levels);
       
  1229             User::Leave(KErrNotSupported);
       
  1230             }
       
  1231         } // end switch(level)
       
  1232 
       
  1233     CleanupStack::PopAndDestroy(&selections);
       
  1234     return isASong;
       
  1235     }
       
  1236 
       
  1237 // ----------------------------------------------------------------------------
       
  1238 // Handles OpenL called for EBrowseAlbum
       
  1239 // ----------------------------------------------------------------------------
       
  1240 //
       
  1241 TBool CMPXDbPlugin::DoOpenBrowseAlbumL(
       
  1242     const CMPXCollectionPath& aPath,
       
  1243     const TArray<TMPXAttribute>& aAttrs,
       
  1244     CMPXMedia& aEntries,
       
  1245     CMPXMediaArray* aArray)
       
  1246     {
       
  1247     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseAlbumL");
       
  1248 
       
  1249     TBool isASong(EFalse);
       
  1250     TInt levels(aPath.Levels());
       
  1251     TInt idIndex(levels - 1);
       
  1252 
       
  1253     RArray<TMPXItemId> selections;
       
  1254     CleanupClosePushL(selections);
       
  1255     aPath.SelectionL(selections);
       
  1256 
       
  1257     switch (levels)
       
  1258         {
       
  1259         // All Albums
       
  1260         case 2:
       
  1261             {
       
  1262             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_All);
       
  1263 
       
  1264             iDbHandler->GetAllAlbumsL(aAttrs, aArray);
       
  1265             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXAlbum,
       
  1266                 iMusicLibraryTitles->MdcaPoint(EBrowseAlbum));
       
  1267 
       
  1268             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_All);
       
  1269             break;
       
  1270             }
       
  1271 
       
  1272         // All songs in one or multiple albums
       
  1273         case 3:
       
  1274             {
       
  1275             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_AllSongs);
       
  1276             if (selections.Count())
       
  1277                 {
       
  1278                 // Multiple albums
       
  1279                 const TInt count(aPath.Selection().Count());
       
  1280                 for (TInt i = 0; i < count; ++i)
       
  1281                     {
       
  1282                     iDbHandler->GetSongsMatchingAlbumL(selections[i].iId2, aAttrs, aArray);
       
  1283                     }
       
  1284                 }
       
  1285             else
       
  1286                 {
       
  1287                 // One album
       
  1288                 iDbHandler->GetSongsMatchingAlbumL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1289                 }
       
  1290 
       
  1291 //            SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXAlbum, aPath.Id(idIndex).iId2);
       
  1292 // added for ganes
       
  1293                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXAlbum, iMusicLibraryTitles->MdcaPoint(EBrowseAlbumSong));
       
  1294 
       
  1295             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_AllSongs);
       
  1296             break;
       
  1297             }
       
  1298 
       
  1299         // A song in an album
       
  1300         case 4:
       
  1301             {
       
  1302             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_Song);
       
  1303 
       
  1304             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1305             isASong = ETrue;
       
  1306 
       
  1307             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_Song);
       
  1308             break;
       
  1309             }
       
  1310 
       
  1311         default:
       
  1312             {
       
  1313             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseAlbumL: Invalid levels[%d]", levels);
       
  1314             User::Leave(KErrNotSupported);
       
  1315             }
       
  1316         }
       
  1317 
       
  1318     CleanupStack::PopAndDestroy(&selections);
       
  1319     return isASong;
       
  1320     }
       
  1321 
       
  1322 // ----------------------------------------------------------------------------
       
  1323 // Handles OpenL called for EBrowsePlaylist
       
  1324 // ----------------------------------------------------------------------------
       
  1325 //
       
  1326 TBool CMPXDbPlugin::DoOpenBrowsePlaylistL(
       
  1327     const CMPXCollectionPath& aPath,
       
  1328     const TArray<TMPXAttribute>& aAttrs,
       
  1329     CMPXMedia& aEntries,
       
  1330     CMPXMediaArray* aArray)
       
  1331     {
       
  1332     MPX_FUNC("CMPXDbPlugin::DoOpenBrowsePlaylistL");
       
  1333 
       
  1334     TBool isASong(EFalse);
       
  1335     TInt levels(aPath.Levels());
       
  1336     TInt idIndex(levels - 1);
       
  1337 
       
  1338     RArray<TMPXItemId> selections;
       
  1339     CleanupClosePushL(selections);
       
  1340     aPath.SelectionL(selections);
       
  1341 
       
  1342     switch (levels)
       
  1343          {
       
  1344          case 2:
       
  1345             {
       
  1346             // All playlists
       
  1347             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_All);
       
  1348 
       
  1349             iDbHandler->GetAllPlaylistsL(aArray, aAttrs);
       
  1350             iDbHandler->GetAllSystemPlaylistNamesL(aArray);
       
  1351 
       
  1352             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPlaylist,
       
  1353                 iMusicLibraryTitles->MdcaPoint(EBrowsePlaylist));
       
  1354 
       
  1355             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_All);
       
  1356             break;
       
  1357             }
       
  1358 
       
  1359          // All songs in a playlist
       
  1360          case 3:
       
  1361             {
       
  1362             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_AllSongs);
       
  1363 
       
  1364             if (selections.Count())
       
  1365                 {
       
  1366                 const TInt count(aPath.Selection().Count());
       
  1367                 for (TInt i = 0; i < count; ++i)
       
  1368                     {
       
  1369                     iDbHandler->GetSongsMatchingPlaylistL(selections[i].iId2, aAttrs, aArray);
       
  1370                     }
       
  1371                 }
       
  1372             else
       
  1373                 {
       
  1374                 iDbHandler->GetSongsMatchingPlaylistL(aPath.Id (idIndex).iId2, aAttrs, aArray);
       
  1375                 }
       
  1376 
       
  1377             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXPlaylist, aPath.Id(idIndex).iId2);
       
  1378 
       
  1379             // populate EMPXMediaGeneralNonPermissibleActions
       
  1380             if (iDbHandler->IsAutoPlaylistL(aPath.Id(idIndex).iId2))
       
  1381                 {
       
  1382                 // set non-permissible actions to not writable and cacheable
       
  1383                 aEntries.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  1384                     KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache));
       
  1385                 }
       
  1386 
       
  1387             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_AllSongs);
       
  1388             break;
       
  1389             }
       
  1390 
       
  1391          // Specific song in a playlist
       
  1392          case 4:
       
  1393             {
       
  1394             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_Song);
       
  1395 
       
  1396             iDbHandler->GetPlaylistSongL(aPath.Id(idIndex).iId2, aPath.Id(idIndex - 1).iId2,
       
  1397                 aAttrs, *aArray);
       
  1398             isASong = ETrue;
       
  1399 
       
  1400             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_Song);
       
  1401             break;
       
  1402             }
       
  1403 
       
  1404          default:
       
  1405             {
       
  1406             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowsePlaylistL: Invalid levels[%d]", levels);
       
  1407             User::Leave(KErrNotSupported);
       
  1408             }
       
  1409        }
       
  1410 
       
  1411     CleanupStack::PopAndDestroy(&selections);
       
  1412     return isASong;
       
  1413     }
       
  1414 
       
  1415 // ----------------------------------------------------------------------------
       
  1416 // Handles OpenL called for EBrowseGenre
       
  1417 // ----------------------------------------------------------------------------
       
  1418 //
       
  1419 TBool CMPXDbPlugin::DoOpenBrowseGenreL(
       
  1420     const CMPXCollectionPath& aPath,
       
  1421     const TArray<TMPXAttribute>& aAttrs,
       
  1422     CMPXMedia& aEntries,
       
  1423     CMPXMediaArray* aArray)
       
  1424     {
       
  1425     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseGenreL");
       
  1426 
       
  1427     TBool isASong(EFalse);
       
  1428     TInt levels(aPath.Levels());
       
  1429     TInt idIndex(levels - 1);
       
  1430 
       
  1431     RArray<TMPXItemId> selections;
       
  1432     CleanupClosePushL(selections);
       
  1433     aPath.SelectionL(selections);
       
  1434 
       
  1435     switch (levels)
       
  1436         {
       
  1437         // All genres
       
  1438          case 2:
       
  1439             {
       
  1440             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_All);
       
  1441 
       
  1442             iDbHandler->GetAllGenresL(aAttrs, aArray);
       
  1443             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXGenre,
       
  1444                 iMusicLibraryTitles->MdcaPoint(EBrowseGenre));
       
  1445 
       
  1446             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_All);
       
  1447             break;
       
  1448             }
       
  1449 
       
  1450         // All songs of a genre
       
  1451         case 3:
       
  1452             {
       
  1453             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_AllSongs);
       
  1454 
       
  1455             if (selections.Count())
       
  1456                 {
       
  1457                 const TInt count(aPath.Selection().Count());
       
  1458                 for (TInt i = 0; i < count; ++i)
       
  1459                     {
       
  1460                     iDbHandler->GetSongsMatchingGenreL(selections[i].iId2, aAttrs, aArray);
       
  1461                     }
       
  1462                 }
       
  1463             else
       
  1464                 {
       
  1465                 iDbHandler->GetSongsMatchingGenreL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1466                 }
       
  1467             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXGenre, aPath.Id(idIndex).iId2);
       
  1468 
       
  1469             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_AllSongs);
       
  1470             break;
       
  1471             }
       
  1472 
       
  1473         // Specific song in a genre
       
  1474         case 4:
       
  1475             {
       
  1476             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_Song);
       
  1477 
       
  1478             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1479             isASong = ETrue;
       
  1480 
       
  1481             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_Song);
       
  1482             break;
       
  1483             }
       
  1484 
       
  1485         default:
       
  1486             {
       
  1487             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseGenreL: Invalid levels[%d]", levels);
       
  1488             User::Leave(KErrNotSupported);
       
  1489             }
       
  1490         }
       
  1491 
       
  1492     CleanupStack::PopAndDestroy(&selections);
       
  1493     return isASong;
       
  1494     }
       
  1495 
       
  1496 // ----------------------------------------------------------------------------
       
  1497 // Handles OpenL called for EBrowseComposer
       
  1498 // ----------------------------------------------------------------------------
       
  1499 //
       
  1500 TBool CMPXDbPlugin::DoOpenBrowseComposerL(
       
  1501     const CMPXCollectionPath& aPath,
       
  1502     const TArray<TMPXAttribute>& aAttrs,
       
  1503     CMPXMedia& aEntries,
       
  1504     CMPXMediaArray* aArray)
       
  1505     {
       
  1506     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseComposerL");
       
  1507 
       
  1508     TBool isASong(EFalse);
       
  1509     TInt levels(aPath.Levels());
       
  1510     TInt idIndex(levels - 1);
       
  1511 
       
  1512     RArray<TMPXItemId> selections;
       
  1513     CleanupClosePushL(selections);
       
  1514     aPath.SelectionL(selections);
       
  1515 
       
  1516     switch (levels)
       
  1517         {
       
  1518         // All composers
       
  1519         case 2:
       
  1520             {
       
  1521             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_All);
       
  1522 
       
  1523             iDbHandler->GetAllComposersL(aAttrs, aArray);
       
  1524             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXComposer,
       
  1525                 iMusicLibraryTitles->MdcaPoint(EBrowseComposer));
       
  1526 
       
  1527             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_All);
       
  1528             break;
       
  1529             }
       
  1530 
       
  1531         // All songs of a composer
       
  1532         case 3:
       
  1533             {
       
  1534             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_AllSongs);
       
  1535             if (selections.Count())
       
  1536                 {
       
  1537                 const TInt count(aPath.Selection().Count());
       
  1538                 for (TInt i = 0; i < count; ++i)
       
  1539                     {
       
  1540                     iDbHandler->GetSongsMatchingComposerL(selections[i].iId2, aAttrs, aArray);
       
  1541                     }
       
  1542                 }
       
  1543             else
       
  1544                 {
       
  1545                 iDbHandler->GetSongsMatchingComposerL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1546                 }
       
  1547             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXComposer, aPath.Id(idIndex).iId2);
       
  1548 
       
  1549             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_AllSongs);
       
  1550             break;
       
  1551             }
       
  1552 
       
  1553         // Specific song of a composer
       
  1554         case 4:
       
  1555             {
       
  1556             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_Song);
       
  1557 
       
  1558             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1559             isASong = ETrue;
       
  1560 
       
  1561             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_Song);
       
  1562             break;
       
  1563             }
       
  1564 
       
  1565         default:
       
  1566             {
       
  1567             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseComposerL: Invalid levels[%d]", levels);
       
  1568             User::Leave(KErrNotSupported);
       
  1569             }
       
  1570         }
       
  1571 
       
  1572     CleanupStack::PopAndDestroy(&selections);
       
  1573     return isASong;
       
  1574     }
       
  1575 
       
  1576 // ----------------------------------------------------------------------------
       
  1577 // Process the OpenL method with open mode EMPXOpenPlaylistOnly
       
  1578 // ----------------------------------------------------------------------------
       
  1579 //
       
  1580 CMPXCollectionPath* CMPXDbPlugin::DoOpenPlaylistL(
       
  1581     const CMPXCollectionPath& aPath,
       
  1582     const TArray<TMPXAttribute>& aAttrs )
       
  1583     {
       
  1584     MPX_FUNC("CMPXDbPlugin::DoOpenPlaylistL");
       
  1585 
       
  1586     RArray<TMPXItemId> ids;
       
  1587     CleanupClosePushL(ids);
       
  1588 
       
  1589     CMPXMedia* entries = CMPXMedia::NewL();
       
  1590     CleanupStack::PushL(entries);
       
  1591 
       
  1592     CMPXCollectionPath* path = CMPXCollectionPath::NewL(aPath);
       
  1593     CleanupStack::PushL(path);
       
  1594 
       
  1595     // Go through the browse path
       
  1596     TInt levels(aPath.Levels());
       
  1597     if (levels == 2)
       
  1598         {
       
  1599         // Create a new collection path
       
  1600         CleanupStack::PopAndDestroy( path );
       
  1601         path = CMPXCollectionPath::NewL();
       
  1602         CleanupStack::PushL( path );
       
  1603 
       
  1604         // Always return all songs here
       
  1605         ids.Reset();
       
  1606         ids.AppendL( KDBPluginUid );
       
  1607         path->AppendL(ids.Array());
       
  1608         path->SelectL((TMPXItemId) KDBPluginUid);
       
  1609 
       
  1610         ids.Reset();
       
  1611         ids.AppendL(EBrowseAll);
       
  1612         path->AppendL(ids.Array());
       
  1613         path->SelectL((TMPXItemId) EBrowseAll);
       
  1614         path->Set(EMPXOpenPlaylistOnly);
       
  1615 
       
  1616         // Get all item IDs
       
  1617         CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1618         CleanupStack::PushL(array);
       
  1619 
       
  1620         DoOpenBrowseAllL(*path, aAttrs, *entries, array);
       
  1621 
       
  1622         entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1623         entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1624 
       
  1625         CleanupStack::PopAndDestroy(array);
       
  1626 
       
  1627         DoAppendLevelL(*path, *entries);
       
  1628         }
       
  1629     else if (levels > 2)
       
  1630         {
       
  1631         switch (aPath.Id(1).iId2)
       
  1632             {
       
  1633             case EBrowseAll:
       
  1634                 {
       
  1635                 path->Set(EMPXOpenPlaylistOnly);
       
  1636                 // Returns the same path that we copied
       
  1637                 break;
       
  1638                 }
       
  1639             case EBrowseArtist:
       
  1640                 {
       
  1641                 if (levels == 3)
       
  1642                     {
       
  1643                     // return all songs of a particular artist (currently highlighted)
       
  1644                     path->Set(EMPXOpenGroupOrPlaylist);
       
  1645                     ids.Reset();
       
  1646                     ids.Append(aPath.Id(2));
       
  1647                     path->AppendL(ids.Array());
       
  1648                     path->SelectL(aPath.Id(2));
       
  1649                     path->Set(EMPXOpenPlaylistOnly);
       
  1650 
       
  1651                     // Opens all songs of an artist and create the corresponding
       
  1652                     // Collection playlist by appending all songs of an artist to
       
  1653                     // the collection path
       
  1654                     //
       
  1655                     DoOpenL(*path, aAttrs, *entries, NULL);
       
  1656                     DoAppendLevelL(*path, *entries);
       
  1657                     }
       
  1658                 else if (levels == 4)
       
  1659                     {
       
  1660                     // Open the album of an artist and create the corresponding
       
  1661                     // Collection playlist by appending all songs of an artist to
       
  1662                     // the collection path
       
  1663                     //
       
  1664                     path->Set(EMPXOpenPlaylistOnly);
       
  1665                     DoOpenL(*path, aAttrs, *entries, NULL);
       
  1666                     DoAppendLevelL(*path, *entries);
       
  1667                     }
       
  1668                 else
       
  1669                     {
       
  1670                     // case is a song no need to open again!
       
  1671                     }
       
  1672 
       
  1673                 break;
       
  1674                 }
       
  1675             // Playlist, album, genre and composer easier, only 2 levels deep
       
  1676             // plugin | category | category contents | songs of category
       
  1677             //
       
  1678             case EBrowsePlaylist:
       
  1679             case EBrowseAlbum:
       
  1680             case EBrowseGenre:
       
  1681             case EBrowseComposer:
       
  1682                 {
       
  1683                 if (!DoOpenL(aPath, aAttrs, *entries, NULL))
       
  1684                     {
       
  1685                     // If it is not at a song level
       
  1686                     // Append all entries to create collection path
       
  1687                     //
       
  1688                     path->Set(EMPXOpenPlaylistOnly);
       
  1689                     DoAppendLevelL( *path, *entries );
       
  1690                     }
       
  1691                 break;
       
  1692                 }
       
  1693             default:
       
  1694                 {
       
  1695                 User::Leave(KErrNotSupported);
       
  1696                 }
       
  1697             }
       
  1698         }
       
  1699     else  // levels < 2
       
  1700         {
       
  1701         User::Leave(KErrNotSupported);
       
  1702         }
       
  1703 
       
  1704     // Cleanup
       
  1705     CleanupStack::Pop(path);
       
  1706     CleanupStack::PopAndDestroy(entries);
       
  1707     CleanupStack::PopAndDestroy(&ids);
       
  1708 
       
  1709     return path;
       
  1710     }
       
  1711 
       
  1712 // ----------------------------------------------------------------------------
       
  1713 // Process the MediaL command
       
  1714 // ----------------------------------------------------------------------------
       
  1715 //
       
  1716 void CMPXDbPlugin::DoMediaL(
       
  1717     const CMPXCollectionPath& aPath,
       
  1718     const TArray<TMPXAttribute>& aAttrs,
       
  1719     CMPXMedia& aEntries)
       
  1720     {
       
  1721     MPX_FUNC("CMPXDbPlugin::DoMediaL");
       
  1722 
       
  1723     // Fetch Media for root level
       
  1724     //
       
  1725     if (aPath.Levels() == 1) //root
       
  1726         {
       
  1727         DoRootMediaL( aAttrs, aEntries );
       
  1728         }
       
  1729     // Ensure the database has been merged before attempting MediaL()
       
  1730     //
       
  1731     else
       
  1732         {
       
  1733         CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1734         CleanupStack::PushL(array);
       
  1735 
       
  1736         switch (aPath.Id(1).iId2)
       
  1737             {
       
  1738             case EBrowseAll:
       
  1739                 {
       
  1740                 DoAllSongsMediaL(aPath, aAttrs, aEntries, *array);
       
  1741                 break;
       
  1742                 } // end case EBrowseAll
       
  1743 
       
  1744             case EBrowseArtist:
       
  1745                 {
       
  1746                 DoArtistMediaL(aPath, aAttrs, aEntries, *array);
       
  1747                 break;
       
  1748                 } // end case EBrowseArtist
       
  1749 
       
  1750             case EBrowseAlbum:
       
  1751                 {
       
  1752                 DoCategoryMediaL(aPath, aAttrs, EMPXAlbum, aEntries, *array);
       
  1753                 break;
       
  1754                 } // end case EBrowseAlbum
       
  1755 
       
  1756             case EBrowsePlaylist:
       
  1757                 {
       
  1758                 DoCategoryMediaL(aPath, aAttrs, EMPXPlaylist, aEntries, *array);
       
  1759                 break;
       
  1760                 } // end case EBrowsePlaylist
       
  1761 
       
  1762             case EBrowseGenre:
       
  1763                 {
       
  1764                 DoCategoryMediaL(aPath, aAttrs, EMPXGenre, aEntries, *array);
       
  1765                 break;
       
  1766                 } // end case EBrowseGenre
       
  1767 
       
  1768             case EBrowseComposer:
       
  1769                 {
       
  1770                 DoCategoryMediaL(aPath, aAttrs, EMPXComposer, aEntries, *array);
       
  1771                 break;
       
  1772                 } // end case EBrowseComposer
       
  1773 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1774             case EBrowsePodcasts:
       
  1775                 {
       
  1776                 break;
       
  1777                 }
       
  1778 #endif
       
  1779             default:
       
  1780                 {
       
  1781                 User::Leave(KErrArgument);
       
  1782                 }
       
  1783             } // end switch(aPath.id(1)
       
  1784 
       
  1785         if (array->Count() > 0)
       
  1786             {
       
  1787             aEntries.SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1788             aEntries.SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1789             }
       
  1790         CleanupStack::PopAndDestroy(array);
       
  1791         }
       
  1792     // Else case cannot leave, because this will happen when we have no disk space to
       
  1793     // perform the merging. It should NOT leave.
       
  1794     //
       
  1795     }
       
  1796 
       
  1797 // ----------------------------------------------------------------------------
       
  1798 // Find the collection media for root level
       
  1799 // ----------------------------------------------------------------------------
       
  1800 //
       
  1801 void CMPXDbPlugin::DoRootMediaL(
       
  1802     const TArray<TMPXAttribute>& aAttrs,
       
  1803     CMPXMedia& aMedia )
       
  1804     {
       
  1805     MPX_FUNC("CMPXDbPlugin::DoRootMediaL");
       
  1806 
       
  1807     TInt count(aAttrs.Count());
       
  1808 #ifndef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1809     aMedia.SetTObjectValueL<TMPXGeneralNonPermissibleActions> (
       
  1810             KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache) );
       
  1811 #endif // __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1812     for (TInt i = 0; i < count; ++i)
       
  1813         {
       
  1814         if (aAttrs[i].ContentId() == KMPXMediaIdGeneral)
       
  1815             {
       
  1816             TUint att(aAttrs[i].AttributeId());
       
  1817             if (att & EMPXMediaGeneralTitle)
       
  1818                 {
       
  1819                 HBufC* title(iResource->ReadHBufCL(R_MPX_QTN_MUS_MUSIC));
       
  1820                 CleanupStack::PushL(title);
       
  1821                 aMedia.SetTextValueL(KMPXMediaGeneralTitle, *title);
       
  1822                 CleanupStack::PopAndDestroy(title);
       
  1823                 }
       
  1824             if (att & EMPXMediaGeneralSubTitle)
       
  1825                 {
       
  1826                 TInt numSongs(iDbHandler->NumberOfItemsL(EMPXSong));
       
  1827                 aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralCount, numSongs);
       
  1828 
       
  1829                 HBufC* text(iResource->ReadHBufCL((1 == numSongs) ?
       
  1830                     R_MPX_QTN_MUS_MUSIC_ONE_SONG : R_MPX_QTN_MUS_MUSIC_NUM_SONGS));
       
  1831 
       
  1832                 CleanupStack::PushL(text);
       
  1833                 aMedia.SetTextValueL(KMPXMediaGeneralSubTitle, *text);
       
  1834                 CleanupStack::PopAndDestroy(text);
       
  1835                 }
       
  1836             if (att & EMPXMediaGeneralIcon)
       
  1837                 {
       
  1838                 TIconInfo icon;
       
  1839                 icon.bmpfile = KMPlayerDbPluginMbmFile;
       
  1840                 icon.bitmapId = EMbmMpxdbpluginQgn_graf_mup_dlst_music;
       
  1841                 icon.maskId = EMbmMpxdbpluginQgn_graf_mup_dlst_music_mask;
       
  1842                 aMedia.SetTObjectValueL<TIconInfo>(KMPXMediaGeneralIcon, icon);
       
  1843                 }
       
  1844             } // if
       
  1845         } // for
       
  1846     }
       
  1847 
       
  1848 // ----------------------------------------------------------------------------
       
  1849 // Find the collection media for all songs category
       
  1850 // ----------------------------------------------------------------------------
       
  1851 //
       
  1852 void CMPXDbPlugin::DoAllSongsMediaL(
       
  1853     const CMPXCollectionPath& aPath,
       
  1854     const TArray<TMPXAttribute>& aAttrs,
       
  1855     CMPXMedia& aEntries,
       
  1856     CMPXMediaArray& aMediaArray)
       
  1857     {
       
  1858     MPX_FUNC("CMPXDbPlugin::DoAllSongsMediaL");
       
  1859 
       
  1860     TInt levels(aPath.Levels());
       
  1861 
       
  1862     switch (levels)
       
  1863        {
       
  1864        // All songs
       
  1865        case 2:
       
  1866             {
       
  1867             MPX_PERF_START(CMPXDbPlugin_DoAllSongsMediaL_All);
       
  1868             DoRootCategoryMediaL(aAttrs, EBrowseAll, EMPXSong, aEntries);
       
  1869             MPX_PERF_END(CMPXDbPlugin_DoAllSongsMediaL_All);
       
  1870             break;
       
  1871             }
       
  1872 
       
  1873          // A Song in all songs
       
  1874          case 3:
       
  1875             {
       
  1876             MPX_PERF_START(CMPXDbPlugin_DoAllSongsMediaL_Song);
       
  1877             GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  1878             MPX_PERF_END(CMPXDbPlugin_DoAllSongsMediaL_Song);
       
  1879             break;
       
  1880             }
       
  1881 
       
  1882          default:
       
  1883             {
       
  1884             MPX_DEBUG2("CMPXDbPlugin_DoAllSongsMediaL: Invalid levels[%d]", levels);
       
  1885             User::Leave(KErrNotSupported);
       
  1886             }
       
  1887         } // end switch(levels)
       
  1888     }
       
  1889 
       
  1890 // ----------------------------------------------------------------------------
       
  1891 // Find the collection media for artists category
       
  1892 // ----------------------------------------------------------------------------
       
  1893 //
       
  1894 void CMPXDbPlugin::DoArtistMediaL (
       
  1895     const CMPXCollectionPath& aPath,
       
  1896     const TArray<TMPXAttribute>& aAttrs,
       
  1897     CMPXMedia& aEntries,
       
  1898     CMPXMediaArray& aMediaArray)
       
  1899     {
       
  1900     MPX_FUNC("CMPXDbPlugin::DoArtistMediaL");
       
  1901 
       
  1902     TInt levels(aPath.Levels());
       
  1903     TInt count(aPath.Selection().Count());
       
  1904 
       
  1905      // All artists
       
  1906     if (levels == 2)
       
  1907         {
       
  1908         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_All);
       
  1909         DoRootCategoryMediaL(aAttrs, EBrowseArtist, EMPXArtist, aEntries);
       
  1910         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_All);
       
  1911         }
       
  1912     else if ((levels == 3) && count) // multiple artists selected
       
  1913         {
       
  1914         RArray<TMPXItemId> selections;
       
  1915         CleanupClosePushL(selections);
       
  1916         aPath.SelectionL(selections);
       
  1917 
       
  1918         for (TInt i = 0; i < count; ++i)
       
  1919             {
       
  1920             CMPXMedia* artist = CMPXMedia::NewL();
       
  1921             CleanupStack::PushL(artist);
       
  1922             iDbHandler->GetCategoryL(selections[i].iId2, EMPXArtist, aAttrs, artist);
       
  1923             aMediaArray.AppendL(*artist);
       
  1924             CleanupStack::PopAndDestroy(artist);
       
  1925             }
       
  1926 
       
  1927         CleanupStack::PopAndDestroy(&selections);
       
  1928         }
       
  1929     else if (levels == 3) // single artist selected
       
  1930         {
       
  1931         iDbHandler->GetCategoryL(aPath.Id(2).iId2, EMPXArtist, aAttrs, &aEntries);
       
  1932         }
       
  1933     else if (levels == 4 && (aPath.Id(3) == aPath.Id(2))) // all songs for an artist
       
  1934         {
       
  1935         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_AllSongs);
       
  1936         // Calculate duration directly with SQL
       
  1937         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  1938             {
       
  1939             DoDurationL(aEntries, EMPXArtist, aPath.Id(2));
       
  1940             }
       
  1941 
       
  1942         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_AllSongs);
       
  1943         }
       
  1944     else if ((levels == 4) && count) // multiple albums of an artist
       
  1945         {
       
  1946         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_AllAlbums);
       
  1947 
       
  1948         RArray<TMPXItemId> selections;
       
  1949         CleanupClosePushL(selections);
       
  1950         aPath.SelectionL(selections);
       
  1951 
       
  1952         for (TInt i = 0; i < count; ++i)
       
  1953             {
       
  1954             CMPXMedia* media = CMPXMedia::NewL();
       
  1955             CleanupStack::PushL(media);
       
  1956             iDbHandler->GetCategoryL(selections[i].iId2, EMPXAlbum, aAttrs, media);
       
  1957             aMediaArray.AppendL(*media);
       
  1958             CleanupStack::PopAndDestroy(media);
       
  1959             }
       
  1960 
       
  1961         CleanupStack::PopAndDestroy(&selections);
       
  1962 
       
  1963         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_AllAlbums);
       
  1964         }
       
  1965     else if (levels == 4) // one album of an artist
       
  1966         {
       
  1967         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_OneAlbum);
       
  1968         iDbHandler->GetCategoryL(aPath.Id(3).iId2, EMPXAlbum, aAttrs, &aEntries);
       
  1969 
       
  1970         // Calculate duration
       
  1971         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  1972             {
       
  1973             DoDurationL(aEntries, EMPXArtist, aPath.Id(2), EMPXAlbum, aPath.Id(3));
       
  1974             }
       
  1975 
       
  1976         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_OneAlbum);
       
  1977         }
       
  1978      else if (levels == 5) // a song/songs in an album
       
  1979         {
       
  1980         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_Song);
       
  1981         GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  1982         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_Song);
       
  1983         }
       
  1984     else
       
  1985         {
       
  1986         MPX_DEBUG2("CMPXDbPlugin_DoArtistMediaL: Invalid levels[%d]", levels);
       
  1987         User::Leave(KErrNotSupported);
       
  1988         }
       
  1989     }
       
  1990 
       
  1991 // ----------------------------------------------------------------------------
       
  1992 // Find the collection media for all songs category
       
  1993 // ----------------------------------------------------------------------------
       
  1994 //
       
  1995 void CMPXDbPlugin::DoRootCategoryMediaL (
       
  1996     const TArray<TMPXAttribute>& aAttrs,
       
  1997     TMPXItemId aRootCategoryId,
       
  1998     TMPXGeneralCategory aCategory,
       
  1999     CMPXMedia& aEntries)
       
  2000     {
       
  2001     MPX_FUNC("CMPXDbPlugin::DoRootCategoryMediaL");
       
  2002 
       
  2003     TInt count(aAttrs.Count());
       
  2004     for (TInt i = 0; i < count; ++i)
       
  2005         {
       
  2006         if (aAttrs[i].ContentId() == KMPXMediaIdGeneral)
       
  2007             {
       
  2008             TUint att(aAttrs[i].AttributeId());
       
  2009             switch (att)
       
  2010                 {
       
  2011                 case EMPXMediaGeneralId:
       
  2012                     {
       
  2013                     aEntries.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aRootCategoryId);
       
  2014                     break;
       
  2015                     }
       
  2016                 case EMPXMediaGeneralTitle:
       
  2017                     {
       
  2018                     aEntries.SetTextValueL(KMPXMediaGeneralTitle,
       
  2019                         iMusicLibraryMenuTitles->MdcaPoint(BrowseTypeForCategory(aCategory)));
       
  2020                     break;
       
  2021                     }
       
  2022                 case EMPXMediaGeneralCount:
       
  2023                     {
       
  2024                     // count number of category
       
  2025                     aEntries.SetTObjectValueL<TInt>(KMPXMediaGeneralCount,
       
  2026                         iDbHandler->NumberOfItemsL(aCategory));
       
  2027                     break;
       
  2028                     }
       
  2029                 case EMPXMediaGeneralDuration:
       
  2030                     {
       
  2031                     if (aCategory == EMPXSong)
       
  2032                         {
       
  2033                         DoDurationL(aEntries, EMPXSong);
       
  2034                         }
       
  2035                     break;
       
  2036                     }
       
  2037                 default:
       
  2038                     // not supported
       
  2039                     break;
       
  2040                 } // end switch
       
  2041             } // end if
       
  2042         } // end for
       
  2043 
       
  2044     aEntries.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
       
  2045     aEntries.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, aCategory);
       
  2046     }
       
  2047 
       
  2048 // ----------------------------------------------------------------------------
       
  2049 // Find the collection media for albums/playlists/genres/composers category
       
  2050 // ----------------------------------------------------------------------------
       
  2051 //
       
  2052 void CMPXDbPlugin::DoCategoryMediaL(
       
  2053     const CMPXCollectionPath& aPath,
       
  2054     const TArray<TMPXAttribute>& aAttrs,
       
  2055     TMPXGeneralCategory aCategory,
       
  2056     CMPXMedia& aEntries,
       
  2057     CMPXMediaArray& aMediaArray)
       
  2058     {
       
  2059     MPX_FUNC("CMPXDbPlugin::DoCategoryMediaL");
       
  2060 
       
  2061     TInt levels(aPath.Levels());
       
  2062     TInt count(aPath.Selection().Count());
       
  2063 
       
  2064     if (levels == 2) // all albums/playlists/genres/composers
       
  2065         {
       
  2066         MPX_PERF_START (CMPXDbPlugin_DoCategoryMediaL_All);
       
  2067         DoRootCategoryMediaL(aAttrs, aPath.Id(1).iId2, aCategory, aEntries);
       
  2068         MPX_PERF_END (CMPXDbPlugin_DoCategoryMediaL_All);
       
  2069         }
       
  2070     else if (levels == 3 && count) // multiple albums/playlists/genres/composers selected
       
  2071         {
       
  2072         RArray<TMPXItemId> selections;
       
  2073         CleanupClosePushL(selections);
       
  2074         aPath.SelectionL(selections);
       
  2075 
       
  2076         for (TInt i = 0; i < count; ++i)
       
  2077             {
       
  2078             CMPXMedia* media = CMPXMedia::NewL();
       
  2079             CleanupStack::PushL(media);
       
  2080             iDbHandler->GetCategoryL(selections[i].iId2, aCategory, aAttrs, media);
       
  2081             aMediaArray.AppendL(*media);
       
  2082             CleanupStack::PopAndDestroy(media);
       
  2083             }
       
  2084 
       
  2085         CleanupStack::PopAndDestroy(&selections);
       
  2086         }
       
  2087     else if (levels == 3) // all songs in an album/playlist/genre/composer
       
  2088         {
       
  2089         MPX_PERF_START(CMPXDbPlugin_DoCategoryMediaL_Category);
       
  2090         TMPXItemId id = aPath.Id(2);
       
  2091         iDbHandler->GetCategoryL(id.iId2, aCategory, aAttrs, &aEntries);
       
  2092 
       
  2093         // Calculate duration directly with SQL
       
  2094         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  2095             {
       
  2096             DoDurationL(aEntries, aCategory, id);
       
  2097             }
       
  2098 
       
  2099         TInt nonPermisAction( aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralNonPermissibleActions));
       
  2100         nonPermisAction |= EMPXCache;
       
  2101 
       
  2102         aEntries.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  2103                     KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions) nonPermisAction );
       
  2104 
       
  2105         MPX_PERF_END(CMPXDbPlugin_DoCategoryMediaL_Category);
       
  2106         }
       
  2107     else if (levels == 4) // a song/songs in an album/playlist/genre/composer
       
  2108         {
       
  2109         MPX_PERF_START(CMPXDbPlugin_DoCategoryMediaL_Song);
       
  2110         GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  2111         MPX_PERF_END(CMPXDbPlugin_DoCategoryMediaL_Song);
       
  2112         }
       
  2113     else
       
  2114         {
       
  2115         MPX_DEBUG2("CMPXDbPlugin__DoMediaL__EBrowseAlbum: Invalid levels[%d]", levels);
       
  2116         User::Leave(KErrNotSupported);
       
  2117         }
       
  2118     }
       
  2119 
       
  2120 // ----------------------------------------------------------------------------
       
  2121 // Set all the attributes in CMPXMedia corresponding to KMPXMediaIdDrm
       
  2122 // ----------------------------------------------------------------------------
       
  2123 //
       
  2124 void CMPXDbPlugin::DoSetMediaDrmL(
       
  2125     CMPXMedia& aMedia,
       
  2126     TUint aDrmAttributes,
       
  2127     const TDesC& aLocation)
       
  2128     {
       
  2129     MPX_FUNC("CMPXDbPlugin::DoSetMediaDrmL");
       
  2130 
       
  2131     iDrmMediaUtility->InitL(aLocation);
       
  2132     CleanupClosePushL(*iDrmMediaUtility);
       
  2133     const CMPXMedia* drmMedia(iDrmMediaUtility->GetMediaL(aDrmAttributes));
       
  2134 
       
  2135     // Only get attributes if it's a DRM file
       
  2136     if (drmMedia)
       
  2137         {
       
  2138         if ((aDrmAttributes & EMPXMediaDrmType) &&
       
  2139             drmMedia->IsSupported(KMPXMediaDrmType))
       
  2140             {
       
  2141             aMedia.SetTObjectValueL(KMPXMediaDrmType,
       
  2142                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmType));
       
  2143             }
       
  2144         if ((aDrmAttributes & EMPXMediaDrmRightsStatus) &&
       
  2145             drmMedia->IsSupported(KMPXMediaDrmRightsStatus))
       
  2146             {
       
  2147             aMedia.SetTObjectValueL(KMPXMediaDrmRightsStatus,
       
  2148                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmRightsStatus));
       
  2149             }
       
  2150         if ((aDrmAttributes & EMPXMediaDrmRightsType) &&
       
  2151             drmMedia->IsSupported(KMPXMediaDrmRightsType))
       
  2152             {
       
  2153             aMedia.SetTObjectValueL(KMPXMediaDrmRightsType,
       
  2154                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmRightsType));
       
  2155             }
       
  2156         if ((aDrmAttributes & EMPXMediaDrmCount) &&
       
  2157             drmMedia->IsSupported(KMPXMediaDrmCount))
       
  2158             {
       
  2159             aMedia.SetTObjectValueL(KMPXMediaDrmCount,
       
  2160                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmCount));
       
  2161             }
       
  2162         if ((aDrmAttributes & EMPXMediaDrmProtected) &&
       
  2163             drmMedia->IsSupported(KMPXMediaDrmProtected))
       
  2164             {
       
  2165             aMedia.SetTObjectValueL(KMPXMediaDrmProtected,
       
  2166                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmProtected));
       
  2167             }
       
  2168         if ((aDrmAttributes & EMPXMediaDrmSendingAllowed) &&
       
  2169             drmMedia->IsSupported(KMPXMediaDrmSendingAllowed))
       
  2170             {
       
  2171             aMedia.SetTObjectValueL(KMPXMediaDrmSendingAllowed,
       
  2172                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmSendingAllowed));
       
  2173             }
       
  2174         if ((aDrmAttributes & EMPXMediaDrmCanSetAutomated) &&
       
  2175             drmMedia->IsSupported(KMPXMediaDrmCanSetAutomated))
       
  2176             {
       
  2177             aMedia.SetTObjectValueL(KMPXMediaDrmCanSetAutomated,
       
  2178                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmCanSetAutomated));
       
  2179             }
       
  2180         if ((aDrmAttributes & EMPXMediaDrmHasInfoUrl) &&
       
  2181             drmMedia->IsSupported(KMPXMediaDrmHasInfoUrl))
       
  2182             {
       
  2183             aMedia.SetTObjectValueL(KMPXMediaDrmHasInfoUrl,
       
  2184                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmHasInfoUrl));
       
  2185             }
       
  2186         if ((aDrmAttributes & EMPXMediaDrmHasPreviewUrl) &&
       
  2187             drmMedia->IsSupported(KMPXMediaDrmHasPreviewUrl))
       
  2188             {
       
  2189             aMedia.SetTObjectValueL(KMPXMediaDrmHasPreviewUrl,
       
  2190                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmHasPreviewUrl));
       
  2191             }
       
  2192         if ((aDrmAttributes & EMPXMediaDrmAboutToExpire) &&
       
  2193             drmMedia->IsSupported(KMPXMediaDrmAboutToExpire))
       
  2194             {
       
  2195             aMedia.SetTObjectValueL( KMPXMediaDrmAboutToExpire,
       
  2196                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmAboutToExpire));
       
  2197             }
       
  2198         if ((aDrmAttributes & EMPXMediaDrmStartTime) &&
       
  2199             drmMedia->IsSupported(KMPXMediaDrmStartTime))
       
  2200             {
       
  2201             aMedia.SetTObjectValueL(KMPXMediaDrmStartTime,
       
  2202                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmStartTime));
       
  2203             }
       
  2204         if ((aDrmAttributes & EMPXMediaDrmEndTime) &&
       
  2205             drmMedia->IsSupported(KMPXMediaDrmEndTime))
       
  2206             {
       
  2207             aMedia.SetTObjectValueL( KMPXMediaDrmEndTime,
       
  2208                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmEndTime));
       
  2209             }
       
  2210         if ((aDrmAttributes & EMPXMediaDrmIntervalStartTime) &&
       
  2211             drmMedia->IsSupported(KMPXMediaDrmIntervalStartTime))
       
  2212             {
       
  2213             aMedia.SetTObjectValueL( KMPXMediaDrmIntervalStartTime,
       
  2214                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmIntervalStartTime));
       
  2215             }
       
  2216         if ((aDrmAttributes & EMPXMediaDrmAccumulatedTime) &&
       
  2217             drmMedia->IsSupported(KMPXMediaDrmAccumulatedTime))
       
  2218             {
       
  2219             aMedia.SetTObjectValueL(KMPXMediaDrmAccumulatedTime,
       
  2220                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmAccumulatedTime));
       
  2221             }
       
  2222         if ((aDrmAttributes & EMPXMediaDrmInterval) &&
       
  2223             drmMedia->IsSupported(KMPXMediaDrmInterval))
       
  2224             {
       
  2225             aMedia.SetTObjectValueL( KMPXMediaDrmInterval,
       
  2226                 drmMedia->ValueTObjectL<TTimeIntervalSeconds>(KMPXMediaDrmInterval));
       
  2227             }
       
  2228         }
       
  2229 
       
  2230     CleanupStack::PopAndDestroy(iDrmMediaUtility);
       
  2231     }
       
  2232 
       
  2233 // ----------------------------------------------------------------------------
       
  2234 // Add media objects to the array with attributes from song details
       
  2235 // ----------------------------------------------------------------------------
       
  2236 //
       
  2237 void CMPXDbPlugin::GetSongInfoL(
       
  2238     const CMPXCollectionPath& aPath,
       
  2239     const TArray<TMPXAttribute>& aAttrs,
       
  2240     CMPXMedia& aEntry,
       
  2241     CMPXMediaArray& aMediaArray)
       
  2242     {
       
  2243     MPX_FUNC("CMPXDbPlugin::GetSongInfoL");
       
  2244 
       
  2245     RArray<TInt> supportedIds;
       
  2246     CleanupClosePushL(supportedIds);
       
  2247     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
  2248 
       
  2249     RArray<TMPXItemId> selections;
       
  2250     CleanupClosePushL(selections);
       
  2251     aPath.SelectionL(selections);
       
  2252 
       
  2253     //
       
  2254     // If we are trying to locate a song from a playlist, we should read available song
       
  2255     // info from Playlist table first in case the song is located on a removable
       
  2256     // drive and the drive is not currently present. This is achieved by supplying
       
  2257     // playlist Id to GetSongMatchingSongIdL. When playlistId is 0, we are reading song
       
  2258     // info directly from Songs table. If playlistId is specified, GetSongMatchingSongIdL
       
  2259     // will populate song media from Playlist table and if Songs table for the drive
       
  2260     // exists, song media will be overwritten with info from Songs table.
       
  2261     //
       
  2262     TMPXItemId playlistId(0);
       
  2263     if (aPath.Id(1) == EBrowsePlaylist)
       
  2264         {
       
  2265         if (aPath.Levels() < 2)
       
  2266             {
       
  2267             User::Leave(KErrArgument);
       
  2268             }
       
  2269 
       
  2270         playlistId = aPath.Id(aPath.Levels() - 2);
       
  2271         }
       
  2272 
       
  2273     TInt countSelection(aPath.Selection().Count());
       
  2274     if (countSelection)
       
  2275         {
       
  2276         // We have a selection, iterate it
       
  2277         for (TInt selectionIndex = 0; selectionIndex < countSelection; ++selectionIndex)
       
  2278             {
       
  2279             CMPXMedia* newEntry = CMPXMedia::NewL(supportedIds.Array());
       
  2280             CleanupStack::PushL(newEntry);
       
  2281 
       
  2282             DoGetSongInfoL(aAttrs, selections[selectionIndex].iId2, playlistId.iId2, *newEntry);
       
  2283 
       
  2284             aMediaArray.AppendL(*newEntry);
       
  2285             CleanupStack::PopAndDestroy(newEntry);
       
  2286             }
       
  2287         }
       
  2288     else
       
  2289         {
       
  2290         // No selection, get the attributes for the one song
       
  2291         DoGetSongInfoL(aAttrs, aPath.Id(aPath.Levels() - 1).iId2, playlistId.iId2, aEntry);
       
  2292         }
       
  2293 
       
  2294     CleanupStack::PopAndDestroy(&selections);
       
  2295     CleanupStack::PopAndDestroy(&supportedIds);
       
  2296     }
       
  2297 
       
  2298 // ----------------------------------------------------------------------------
       
  2299 // Retrieves the attributes for a media object.
       
  2300 // ----------------------------------------------------------------------------
       
  2301 //
       
  2302 void CMPXDbPlugin::DoGetSongInfoL(
       
  2303     const TArray<TMPXAttribute>& aAttrs,
       
  2304     TInt aEntryId,
       
  2305     TInt aPlaylistId,
       
  2306     CMPXMedia& aEntry)
       
  2307     {
       
  2308     MPX_FUNC("CMPXDbPlugin::DoGetSongInfoL");
       
  2309 
       
  2310     if (aPlaylistId)
       
  2311         {
       
  2312         iDbHandler->GetPlaylistSongL(aEntryId, aPlaylistId, aAttrs, aEntry);
       
  2313         }
       
  2314     else
       
  2315         {
       
  2316         iDbHandler->GetSongL(aEntryId, aAttrs, aEntry);
       
  2317         }
       
  2318 
       
  2319     const TDesC& location(aEntry.ValueText(KMPXMediaGeneralUri));
       
  2320 
       
  2321     // Check DRM Only if we have a location
       
  2322     if (location != KNullDesC)
       
  2323         {
       
  2324         TUint drmAttributes(0);
       
  2325 
       
  2326         // Compact the attribute set
       
  2327         TInt count(aAttrs.Count());
       
  2328         for (TInt i = 0; i < count; ++i)
       
  2329             {
       
  2330             if (aAttrs[i].ContentId() == KMPXMediaIdDrm)
       
  2331                 {
       
  2332                 drmAttributes |= aAttrs[i].AttributeId();
       
  2333                 }
       
  2334             }
       
  2335 
       
  2336         // Set the correct attributes to media, only if requested
       
  2337         if (drmAttributes)
       
  2338             {
       
  2339             DoSetMediaDrmL(aEntry, drmAttributes, location);
       
  2340             }
       
  2341         }
       
  2342 
       
  2343     // Disable caching for any MediaL() returning song info.
       
  2344     TInt nonPermisAction( aEntry.ValueTObjectL<TInt>(KMPXMediaGeneralNonPermissibleActions));
       
  2345     nonPermisAction |= EMPXCache;
       
  2346 
       
  2347     aEntry.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  2348                 KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions) nonPermisAction );
       
  2349     }
       
  2350 
       
  2351 // ----------------------------------------------------------------------------
       
  2352 // Find the collection details
       
  2353 // ----------------------------------------------------------------------------
       
  2354 //
       
  2355 void CMPXDbPlugin::DoHandleOtherMediaAttributesL(
       
  2356     const TArray<TMPXAttribute>& aAttrs,
       
  2357     const CMPXCollectionPath& aPath,
       
  2358     CMPXMedia& aMedia)
       
  2359     {
       
  2360     MPX_FUNC("CMPXDbPlugin::DoHandleOtherMediaAttributesL");
       
  2361 
       
  2362     TInt count(aAttrs.Count());
       
  2363     for (TInt i = 0; i < count; ++i)
       
  2364         {
       
  2365         if (aAttrs[i].ContentId() == KMPXMediaIdCollectionDetails)
       
  2366             {
       
  2367             TUint att(aAttrs[i].AttributeId());
       
  2368 
       
  2369             if (att & EMPXMediaColDetailNumberOfItems)
       
  2370                 {
       
  2371                 aMedia.SetTObjectValueL(KMPXMediaColDetailNumberOfItems,
       
  2372                     iDbHandler->NumberOfItemsL(EMPXSong));
       
  2373                 }
       
  2374             if (att & EMPXMediaColDetailDuration)
       
  2375                 {
       
  2376                 aMedia.SetTObjectValueL(KMPXMediaColDetailDuration,
       
  2377                     DoDurationL(aMedia, EMPXSong));
       
  2378                 }
       
  2379             if (att & EMPXMediaColTotalSize)
       
  2380                 {
       
  2381                 // todo
       
  2382                 TInt totalSize(0);
       
  2383                 aMedia.SetTObjectValueL(KMPXMediaColDetailTotalSize, totalSize);
       
  2384                 }
       
  2385             if (att & EMPXMediaLastRefreshed)
       
  2386                 {
       
  2387                 TTime lastRefreshed(iDbHandler->GetLastRefreshedTimeL());
       
  2388                 aMedia.SetTObjectValueL(KMPXMediaColDetailLastRefreshed,
       
  2389                     lastRefreshed.Int64());
       
  2390                 }
       
  2391             if (att & EMPXMediaColDetailDBCreated)
       
  2392                 {
       
  2393                 aMedia.SetTObjectValueL(KMPXMediaColDetailDBCreated,
       
  2394                     iDbHandler->DatabaseCreated());
       
  2395                 }
       
  2396             if (att & EMPXMediaColDetailDBCorrupted)
       
  2397                 {
       
  2398                 aMedia.SetTObjectValueL(KMPXMediaColDetailDBCorrupted,
       
  2399                     iDbHandler->IsDBCorruptedL());
       
  2400                 }
       
  2401             }
       
  2402         else if (aAttrs[i] == KMPXMediaGeneralPath)
       
  2403             {
       
  2404             aMedia.SetCObjectValueL(KMPXMediaGeneralPath,
       
  2405                 const_cast<CMPXCollectionPath*>(&aPath));
       
  2406             }
       
  2407         }
       
  2408     }
       
  2409 
       
  2410 // ----------------------------------------------------------------------------
       
  2411 // Remove an item from the collection database using the given path
       
  2412 // ----------------------------------------------------------------------------
       
  2413 //
       
  2414 CDesCArray* CMPXDbPlugin::DoRemoveL(
       
  2415     const CMPXCollectionPath& aPath,
       
  2416     CMPXMessageArray& aChangeMsgArray)
       
  2417     {
       
  2418     MPX_FUNC("CMPXDbPlugin::DoRemoveL");
       
  2419 
       
  2420     if (aPath.Levels() <= 1)
       
  2421         {
       
  2422         User::Leave(KErrNotSupported);
       
  2423         }
       
  2424 
       
  2425     // Return file path for deleted item(s)
       
  2426     //
       
  2427     CDesCArray* fp = new(ELeave) CDesCArrayFlat(1);
       
  2428     CleanupStack::PushL(fp);
       
  2429 
       
  2430     // Ids of the selected items
       
  2431     RArray<TMPXItemId> selections;
       
  2432     CleanupClosePushL(selections);
       
  2433     aPath.SelectionL(selections);
       
  2434 
       
  2435     switch (aPath.Id(1).iId2)
       
  2436         {
       
  2437         case EBrowseAll:
       
  2438             {
       
  2439             DoRemoveFromAllSongsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2440             }
       
  2441             break;
       
  2442 
       
  2443         case EBrowseArtist:
       
  2444             {
       
  2445             DoRemoveFromArtistsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2446             }
       
  2447             break;
       
  2448 
       
  2449         case EBrowseAlbum: // deliberate fall through
       
  2450         case EBrowseGenre: // deliberate fall through
       
  2451         case EBrowseComposer: // deliberate fall through
       
  2452             {
       
  2453             DoRemoveFromCategoriesL(aPath, selections.Array(),
       
  2454                 CategoryForBrowseType(static_cast<TMCBrowseType>(aPath.Id(1).iId2)), *fp, aChangeMsgArray);
       
  2455             }
       
  2456             break;
       
  2457 
       
  2458         case EBrowsePlaylist:
       
  2459             {
       
  2460             DoRemoveFromPlaylistsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2461             }
       
  2462             break;
       
  2463 
       
  2464         default:
       
  2465             {
       
  2466             User::Leave(KErrArgument);
       
  2467             }
       
  2468         } // end switch (aPath.Id(1))
       
  2469 
       
  2470     MPX_DEBUG2("CMPXDbPlugin::RemoveL itemId[%d]", aPath.Id(aPath.Levels() - 1).iId2);
       
  2471 
       
  2472     CleanupStack::PopAndDestroy( &selections );
       
  2473     CleanupStack::Pop(fp);
       
  2474 
       
  2475     return fp;
       
  2476     }
       
  2477 
       
  2478 // ----------------------------------------------------------------------------
       
  2479 // Remove an item from the collection database using the given media properties
       
  2480 // ----------------------------------------------------------------------------
       
  2481 //
       
  2482 void CMPXDbPlugin::DoRemoveL(
       
  2483     const CMPXMedia& aMedia,
       
  2484     TBool aDeleteRecord)
       
  2485     {
       
  2486     MPX_FUNC("CMPXDbPlugin::DoRemoveL(by media)");
       
  2487 
       
  2488     // Return deleted file paths to caller
       
  2489     CDesCArray* fp = new(ELeave) CDesCArrayFlat(1);
       
  2490     CleanupStack::PushL(fp);
       
  2491 
       
  2492     // a list of change event messages a result of the item being removed
       
  2493     CMPXMessageArray* itemChangedMessages = CMPXMediaArray::NewL();
       
  2494     CleanupStack::PushL(itemChangedMessages);
       
  2495 
       
  2496     TUint32 mediaId(0);
       
  2497 
       
  2498     // Removing a container of items
       
  2499     //
       
  2500     if (aMedia.IsSupported(KMPXMediaArrayContents))
       
  2501         {
       
  2502         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing a container of items");
       
  2503         const CMPXMediaArray* media = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2504         if( !media )
       
  2505             {
       
  2506             User::Leave(KErrNoMemory);
       
  2507             }
       
  2508         const TInt mediaCount(media->Count());
       
  2509         for (TInt i = 0; i < mediaCount; ++i)
       
  2510             {
       
  2511             CMPXMedia* entry = media->AtL(i);
       
  2512             if (entry->IsSupported(KMPXMediaGeneralId))
       
  2513                 {
       
  2514                 mediaId = entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2515                 }
       
  2516             else if (entry->IsSupported(KMPXMediaGeneralUri))
       
  2517                 {
       
  2518                 const TDesC& uri = entry->ValueText(KMPXMediaGeneralUri);
       
  2519                 mediaId = iDbHandler->GetSongIdMatchingUriL(uri);
       
  2520                 }
       
  2521             else
       
  2522                 {
       
  2523                 // Unable to process this item
       
  2524                 continue;
       
  2525                 }
       
  2526 
       
  2527             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2528             }
       
  2529         }
       
  2530     // Removing an item with known item id
       
  2531     //
       
  2532     else if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  2533         {
       
  2534         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing an item by item id");
       
  2535         mediaId =  aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2536 
       
  2537         if (MPX_ITEM_CATEGORY(mediaId) != EMPXPlaylist)
       
  2538             {
       
  2539             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2540             }
       
  2541         else
       
  2542             {
       
  2543             iDbHandler->RemovePlaylistL(mediaId, *fp, *itemChangedMessages);
       
  2544             }
       
  2545         }
       
  2546     // Removing an item with known uri
       
  2547     //
       
  2548     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2549         {
       
  2550         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing an item by uri");
       
  2551         TPtrC uri = aMedia.ValueText( KMPXMediaGeneralUri );
       
  2552 
       
  2553         TMPXGeneralCategory category =
       
  2554             aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  2555 
       
  2556         if (category == EMPXSong)
       
  2557             {
       
  2558             mediaId = iDbHandler->GetSongIdMatchingUriL(uri);
       
  2559             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2560             }
       
  2561         else if (category == EMPXPlaylist)
       
  2562             {
       
  2563             mediaId = iDbHandler->GetPlaylistIdMatchingUriL(uri);
       
  2564             iDbHandler->RemovePlaylistL(mediaId, *fp, *itemChangedMessages);
       
  2565             }
       
  2566         else
       
  2567             {
       
  2568             // otherwise unable to process this item
       
  2569             }
       
  2570         }
       
  2571     else
       
  2572         {
       
  2573         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Unknown item for removal");
       
  2574         User::Leave(KErrNotSupported);
       
  2575         }
       
  2576 
       
  2577     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  2578 
       
  2579     // Removing an item always invalidates all songs.
       
  2580     //
       
  2581     MPXDbCommonUtil::AddItemChangedMessageL(*itemChangedMessages, EBrowseAll,
       
  2582                                             EMPXItemModified, EMPXCollection, KDBPluginUid);
       
  2583 
       
  2584     DoHandleChangeL(itemChangedMessages);
       
  2585 
       
  2586     CleanupStack::PopAndDestroy(itemChangedMessages);
       
  2587     CleanupStack::PopAndDestroy(fp);
       
  2588     }
       
  2589 
       
  2590 // ----------------------------------------------------------------------------
       
  2591 // Remove media by path through a command
       
  2592 // ----------------------------------------------------------------------------
       
  2593 //
       
  2594 void CMPXDbPlugin::DoRemovePathL(
       
  2595     CMPXCommand& aCmd)
       
  2596     {
       
  2597     MPX_FUNC("CMPXDbPlugin::DoRemovePathL(by command)");
       
  2598 
       
  2599     TInt removeError(KErrNone);
       
  2600     TBool removeCompleted(ETrue);
       
  2601 
       
  2602     if (!aCmd.IsSupported(KMPXCommandCollectionRemovePath) ||
       
  2603         !aCmd.IsSupported(KMPXCommandCollectionRemoveMediaCount))
       
  2604         {
       
  2605         removeError = KErrArgument;
       
  2606         }
       
  2607     else
       
  2608         {
       
  2609         CMPXCollectionPath* path =
       
  2610             aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCommandCollectionRemovePath);
       
  2611         CleanupStack::PushL(path);
       
  2612 
       
  2613         // in order to support cancel delete for a category, we need to adjust path. If
       
  2614         // the path ends in a category, retrieve all songs under the selected category
       
  2615         // and append a new level with all songs under the selected category
       
  2616         DoAppendLevelL(*path);
       
  2617 
       
  2618         CMPXCollectionPath* iterationPath = CMPXCollectionPath::NewL(*path);
       
  2619         CleanupStack::PushL(iterationPath);
       
  2620         iterationPath->ClearSelection();
       
  2621 
       
  2622         // indices of the selected items
       
  2623         TArray<TInt> selectionIndices = path->Selection();
       
  2624         TInt count(selectionIndices.Count());
       
  2625 
       
  2626         // number of media items to remove in this iteration
       
  2627         TInt removeCount = (aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionRemoveMediaCount));
       
  2628 
       
  2629         // remove all in one shot if removeCount is 0 or negative
       
  2630         if (removeCount <= 0)
       
  2631             {
       
  2632             removeCount = count;
       
  2633             }
       
  2634 
       
  2635         // If the given path contains multiple selections, remove the first n selected media
       
  2636         // and update the path so that client can use this path to call remove iteratively
       
  2637         // until all selections are processed
       
  2638         //
       
  2639         if (count)
       
  2640             {
       
  2641             for (TInt i = 0; i < removeCount; ++i)
       
  2642                 {
       
  2643                 TInt index(selectionIndices[i]);
       
  2644 
       
  2645                 MPX_DEBUG4(" path: selected item [index %d] [selectioncount %d] [remove count %d]", index, count, removeCount);
       
  2646 
       
  2647                 iterationPath->SelectL(index);
       
  2648                 path->Remove(index);
       
  2649                 }
       
  2650 
       
  2651             aCmd.SetCObjectValueL(KMPXCommandCollectionRemovePath, path);
       
  2652 
       
  2653             // indicate to the client that subsequent remove command is required
       
  2654             if ((count - removeCount) > 0)
       
  2655                 {
       
  2656                 removeCompleted = EFalse;
       
  2657                 }
       
  2658             }
       
  2659 
       
  2660         // Remove the media specified by the path
       
  2661         CDesCArray* fp(NULL);
       
  2662         TBool supressMsgs(EFalse);
       
  2663         CMPXMessageArray* msgAry(NULL);
       
  2664 
       
  2665         if (aCmd.IsSupported(KMPXCommandCollectionRemoveSuppressMsgs) &&
       
  2666             aCmd.ValueTObjectL<TBool>(KMPXCommandCollectionRemoveSuppressMsgs))
       
  2667             {
       
  2668             // Msgs are stored in the command
       
  2669             supressMsgs = ETrue;
       
  2670 
       
  2671             CMPXMessageArray* msgs( aCmd.Value<CMPXMessageArray>(KMPXCommandCollectionChangeMsgs) );
       
  2672             User::LeaveIfNull( msgs );
       
  2673             fp = DoRemoveL(*iterationPath, *msgs);
       
  2674             }
       
  2675         else
       
  2676             {
       
  2677             // Msgs will be sent after delete
       
  2678             msgAry = CMPXMessageArray::NewL();
       
  2679             CleanupStack::PushL(msgAry);
       
  2680             fp = DoRemoveL(*iterationPath, *msgAry);
       
  2681             }
       
  2682 
       
  2683         CleanupStack::PushL(fp);
       
  2684         if (fp->MdcaCount() > removeCount)
       
  2685             {
       
  2686             removeError = KErrCorrupt;
       
  2687             }
       
  2688         CleanupStack::PopAndDestroy(fp);
       
  2689 
       
  2690         if (!supressMsgs)
       
  2691             {
       
  2692             // Send Change Messages
       
  2693             iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  2694             DoHandleChangeL(msgAry);
       
  2695             CleanupStack::PopAndDestroy(msgAry);
       
  2696             }
       
  2697 
       
  2698         // Cleanup
       
  2699         CleanupStack::PopAndDestroy(iterationPath);
       
  2700         CleanupStack::PopAndDestroy(path);
       
  2701         }
       
  2702 
       
  2703     // mandatory return parameters
       
  2704     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRemoveError, removeError);
       
  2705     aCmd.SetTObjectValueL<TBool>(KMPXCommandCollectionRemoveCompleted, removeCompleted);
       
  2706     }
       
  2707 
       
  2708 // ----------------------------------------------------------------------------
       
  2709 // Remove media by CMPXMedia through a command
       
  2710 // ----------------------------------------------------------------------------
       
  2711 //
       
  2712 void CMPXDbPlugin::DoRemoveMediaL(
       
  2713     CMPXCommand& aCmd)
       
  2714     {
       
  2715     MPX_FUNC("CMPXDbPlugin::DoRemoveMediaL(by command)");
       
  2716 
       
  2717     TInt error(KErrArgument);
       
  2718 
       
  2719     if (aCmd.IsSupported(KMPXCommandCollectionRemoveMedia))
       
  2720         {
       
  2721         CMPXMedia* media = aCmd.ValueCObjectL<CMPXMedia>(KMPXCommandCollectionRemoveMedia);
       
  2722         CleanupStack::PushL(media);
       
  2723 
       
  2724         MPX_TRAP(error, DoRemoveL(*media,
       
  2725             aCmd.ValueTObjectL<TBool>(KMPXCommandCollectionRemoveMediaDeleteRecord)));
       
  2726 
       
  2727         CleanupStack::PopAndDestroy(media);
       
  2728         }
       
  2729 
       
  2730     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRemoveMediaError, error);
       
  2731     }
       
  2732 
       
  2733 // ----------------------------------------------------------------------------
       
  2734 // Remove a media/media items from All Songs view
       
  2735 // ----------------------------------------------------------------------------
       
  2736 //
       
  2737 void CMPXDbPlugin::DoRemoveFromAllSongsL(
       
  2738     const CMPXCollectionPath& aPath,
       
  2739     const TArray<TMPXItemId>& aSelections,
       
  2740     CDesCArray& aUriArray,
       
  2741     CMPXMessageArray& aItemChangedMessages)
       
  2742     {
       
  2743     MPX_FUNC("CMPXDbPlugin::DoRemoveFromAllSongsL");
       
  2744 
       
  2745     switch (aPath.Levels())
       
  2746         {
       
  2747         case 2:
       
  2748             {
       
  2749             // when the collection is removed, it's intended not to delete the files
       
  2750             iDbHandler->RemoveEntireCollectionL();
       
  2751             }
       
  2752             break;
       
  2753 
       
  2754         case 3:
       
  2755             {
       
  2756             TInt count(aSelections.Count());
       
  2757             if (count)
       
  2758                 {
       
  2759                 for (TInt i = 0; i < count; ++i)
       
  2760                     {
       
  2761                     iDbHandler->RemoveSongL(aSelections[i].iId2, aUriArray, aItemChangedMessages);
       
  2762                     } // end for
       
  2763                 }
       
  2764             else
       
  2765                 {
       
  2766                 iDbHandler->RemoveSongL(aPath.Id(aPath.Levels() - 1).iId2, aUriArray,
       
  2767                      aItemChangedMessages);
       
  2768                 }
       
  2769             }
       
  2770             break;
       
  2771 
       
  2772         default:
       
  2773             {
       
  2774             MPX_DEBUG2("CMPXDbPlugin_DoRemoveFromAllSongsL: Invalid levels[%d]", aPath.Levels());
       
  2775             User::Leave(KErrNotSupported);
       
  2776             }
       
  2777         }
       
  2778     }
       
  2779 
       
  2780 // ----------------------------------------------------------------------------
       
  2781 // Remove a media/media items from Artists view
       
  2782 // ----------------------------------------------------------------------------
       
  2783 //
       
  2784 void CMPXDbPlugin::DoRemoveFromArtistsL(
       
  2785     const CMPXCollectionPath& aPath,
       
  2786     const TArray<TMPXItemId>& aSelections,
       
  2787     CDesCArray& aUriArray,
       
  2788     CMPXMessageArray& aItemChangedMessages)
       
  2789     {
       
  2790     MPX_FUNC("CMPXDbPlugin::DoRemoveFromArtistsL");
       
  2791 
       
  2792     TInt levels(aPath.Levels());
       
  2793     if (levels == 2)
       
  2794         {
       
  2795         // when the collection is removed, it's intended not to delete the files
       
  2796         iDbHandler->RemoveEntireCollectionL();
       
  2797         }
       
  2798     else
       
  2799         {
       
  2800         TInt count(aSelections.Count());
       
  2801         if (count)
       
  2802             {
       
  2803             for (TInt i = 0; i < count; ++i)
       
  2804                 {
       
  2805                 RemoveFromArtistsL(aPath, aSelections[i].iId2, aUriArray, aItemChangedMessages);
       
  2806                 }
       
  2807             }
       
  2808         else
       
  2809             {
       
  2810             RemoveFromArtistsL(aPath, aPath.Id(levels - 1).iId2, aUriArray, aItemChangedMessages);
       
  2811             }
       
  2812         }
       
  2813 
       
  2814     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowseArtist: levels[%d]", levels);
       
  2815     }
       
  2816 
       
  2817 // ----------------------------------------------------------------------------
       
  2818 // Remove a media item from Artists view
       
  2819 // ----------------------------------------------------------------------------
       
  2820 //
       
  2821 void CMPXDbPlugin::RemoveFromArtistsL(
       
  2822     const CMPXCollectionPath& aPath,
       
  2823     TUint32 aItemId,
       
  2824     CDesCArray& aUriArray,
       
  2825     CMPXMessageArray& aItemChangedMessages)
       
  2826     {
       
  2827     MPX_FUNC("CMPXDbPlugin::RemoveFromArtistsL");
       
  2828 
       
  2829     switch (aPath.Levels())
       
  2830         {
       
  2831         case 3:
       
  2832             {
       
  2833             iDbHandler->RemoveSongsMatchingCategoryL(EMPXArtist, aItemId, aUriArray, aItemChangedMessages);
       
  2834             break;
       
  2835             }
       
  2836         case 4:
       
  2837             {
       
  2838             // remove the songs for the artist and album
       
  2839             iDbHandler->RemoveSongsMatchingArtistAndAlbumL(aPath.Id(aPath.Levels() - 2), aItemId,
       
  2840                 aUriArray, aItemChangedMessages);
       
  2841             break;
       
  2842             }
       
  2843         case 5:
       
  2844             {
       
  2845             iDbHandler->RemoveSongL(aItemId, aUriArray, aItemChangedMessages);
       
  2846             break;
       
  2847             }
       
  2848         default:
       
  2849             {
       
  2850             User::Leave(KErrArgument);
       
  2851             }
       
  2852         }
       
  2853     }
       
  2854 
       
  2855 // ----------------------------------------------------------------------------
       
  2856 // Remove a media/media items from Albums/Genres/Composers view
       
  2857 // ----------------------------------------------------------------------------
       
  2858 //
       
  2859 void CMPXDbPlugin::DoRemoveFromCategoriesL(
       
  2860     const CMPXCollectionPath& aPath,
       
  2861     const TArray<TMPXItemId>& aSelections,
       
  2862     TMPXGeneralCategory aCategory,
       
  2863     CDesCArray& aUriArray,
       
  2864     CMPXMessageArray& aItemChangedMessages)
       
  2865     {
       
  2866     MPX_FUNC("CMPXDbPlugin::DoRemoveFromCategoriesL");
       
  2867 
       
  2868     TInt levels(aPath.Levels());
       
  2869     if (levels == 2)
       
  2870         {
       
  2871         // when the collection is removed, it's intended not to delete the files
       
  2872         iDbHandler->RemoveEntireCollectionL();
       
  2873         }
       
  2874     else
       
  2875         {
       
  2876         TInt count(aSelections.Count());
       
  2877         if (count)
       
  2878             {
       
  2879             for (TInt i = 0; i < count; ++i)
       
  2880                 {
       
  2881                 RemoveFromCategoriesL(aPath, aSelections[i].iId2, aCategory,
       
  2882                     aUriArray, aItemChangedMessages);
       
  2883                 }
       
  2884             }
       
  2885         else
       
  2886             {
       
  2887             RemoveFromCategoriesL(aPath, aPath.Id(levels - 1).iId2, aCategory,
       
  2888                 aUriArray, aItemChangedMessages);
       
  2889             }
       
  2890         }
       
  2891 
       
  2892     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowseAlbum: levels[%d]", levels);
       
  2893     }
       
  2894 
       
  2895 // ----------------------------------------------------------------------------
       
  2896 // Remove a media item from Albums/Genres/Composers view
       
  2897 // ----------------------------------------------------------------------------
       
  2898 //
       
  2899 void CMPXDbPlugin::RemoveFromCategoriesL(
       
  2900     const CMPXCollectionPath& aPath,
       
  2901     TUint32 aItemId,
       
  2902     TMPXGeneralCategory aCategory,
       
  2903     CDesCArray& aUriArray,
       
  2904     CMPXMessageArray& aItemChangedMessages)
       
  2905     {
       
  2906     MPX_FUNC("CMPXDbPlugin::RemoveFromCategoriesL");
       
  2907 
       
  2908     switch (aPath.Levels())
       
  2909         {
       
  2910         case 3:
       
  2911             {
       
  2912             iDbHandler->RemoveSongsMatchingCategoryL(aCategory, aItemId, aUriArray,
       
  2913                 aItemChangedMessages);
       
  2914             break;
       
  2915             }
       
  2916         case 4:
       
  2917             {
       
  2918             iDbHandler->RemoveSongL(aItemId, aUriArray, aItemChangedMessages);
       
  2919             break;
       
  2920             }
       
  2921         default:
       
  2922             {
       
  2923             User::Leave(KErrArgument);
       
  2924             }
       
  2925         }
       
  2926     }
       
  2927 
       
  2928 // ----------------------------------------------------------------------------
       
  2929 // Remove one or multiple media items from Playlists view
       
  2930 // ----------------------------------------------------------------------------
       
  2931 //
       
  2932 void CMPXDbPlugin::DoRemoveFromPlaylistsL(
       
  2933     const CMPXCollectionPath& aPath,
       
  2934     const TArray<TMPXItemId>& aSelections,
       
  2935     CDesCArray& aUriArray,
       
  2936     CMPXMessageArray& aItemChangedMessages)
       
  2937     {
       
  2938     MPX_FUNC("CMPXDbPlugin::DoRemoveFromPlaylistsL");
       
  2939 
       
  2940     TInt levels(aPath.Levels());
       
  2941 
       
  2942     // all playlists
       
  2943     if (levels == 2)
       
  2944         {
       
  2945         // when the collection is removed, it's intended not to delete the files
       
  2946         iDbHandler->RemoveAllPlaylistsL();
       
  2947         }
       
  2948     else
       
  2949         {
       
  2950         TArray<TInt> selectionIndices = aPath.Selection();
       
  2951         TInt count(selectionIndices.Count());
       
  2952 
       
  2953         // multiple selections
       
  2954         if (count)
       
  2955             {
       
  2956             for (TInt i = (count - 1); i >= 0; --i)
       
  2957                 {
       
  2958                 RemoveFromPlaylistsL(aPath, aSelections[i], selectionIndices[i],
       
  2959                     aUriArray, aItemChangedMessages);
       
  2960                 }
       
  2961             }
       
  2962         // else no selection
       
  2963         else
       
  2964             {
       
  2965             RemoveFromPlaylistsL(aPath, aPath.IdOfIndex(aPath.Index()), aPath.Index(),
       
  2966                 aUriArray, aItemChangedMessages);
       
  2967             }
       
  2968         }
       
  2969 
       
  2970     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowsePlaylist: levels[%d]", levels);
       
  2971     }
       
  2972 
       
  2973 // ----------------------------------------------------------------------------
       
  2974 // Remove a media item from Playlists view
       
  2975 // ----------------------------------------------------------------------------
       
  2976 //
       
  2977 void CMPXDbPlugin::RemoveFromPlaylistsL(
       
  2978     const CMPXCollectionPath& aPath,
       
  2979     const TMPXItemId& aItemId,
       
  2980     TInt aIndex,
       
  2981     CDesCArray& aUriArray,
       
  2982     CMPXMessageArray& aItemChangedMessages)
       
  2983     {
       
  2984     MPX_FUNC("CMPXDbPlugin::RemoveFromPlaylistsL");
       
  2985 
       
  2986     switch (aPath.Levels())
       
  2987         {
       
  2988         case 3:
       
  2989             {
       
  2990             iDbHandler->RemovePlaylistL(aItemId.iId2, aUriArray, aItemChangedMessages);
       
  2991             break;
       
  2992             }
       
  2993         case 4:
       
  2994             {
       
  2995             if ( !iDbHandler->InTransaction() )
       
  2996                 {
       
  2997                 iDbHandler->BeginTransactionL();
       
  2998                 }
       
  2999             iDbHandler->RemoveSongFromPlaylistL(aPath.Id(aPath.Levels() - 2).iId2, aItemId,
       
  3000                 aIndex, aItemChangedMessages);
       
  3001             break;
       
  3002             }
       
  3003         default:
       
  3004             {
       
  3005             User::Leave(KErrArgument);
       
  3006             }
       
  3007         }
       
  3008     }
       
  3009 
       
  3010 // ----------------------------------------------------------------------------
       
  3011 // Retrieve URIs associated with this file path for file deletion
       
  3012 // ----------------------------------------------------------------------------
       
  3013 //
       
  3014 void CMPXDbPlugin::DoRetrieveUriForDeletionL(
       
  3015     CMPXCommand& aCmd)
       
  3016     {
       
  3017     MPX_FUNC("CMPXDbPlugin::DoRetrieveUriForDeletionL");
       
  3018 
       
  3019     // initialize mandatory return parameters
       
  3020     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRetrieveUriError, KErrNone);
       
  3021 
       
  3022     if (!aCmd.IsSupported(KMPXCommandCollectionRetrievePath))
       
  3023         {
       
  3024         aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRetrieveUriError, KErrArgument);
       
  3025         }
       
  3026     else
       
  3027         {
       
  3028         CMPXCollectionPath* path = aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCommandCollectionRetrievePath);
       
  3029         CleanupStack::PushL(path);
       
  3030         if (iFirstDeleteStep )
       
  3031             {
       
  3032             iSelections.Reset( );
       
  3033         // in order to support cancel delete for a category, we need to adjust path. If
       
  3034         // the path ends in a category, retrieve all songs under the selected category
       
  3035         // and append a new level with all songs under the selected category
       
  3036         DoAppendLevelL(*path);
       
  3037 
       
  3038         // Ids of the selected items
       
  3039             path->SelectionL(iSelections );
       
  3040 
       
  3041         // single selection
       
  3042             if (iSelections.Count()== 0 )
       
  3043                 {
       
  3044                 iSelections.AppendL(path->Id (path->Levels()- 1 ) );
       
  3045                 }
       
  3046             }
       
  3047 
       
  3048         CDesCArray* fp = new(ELeave) CDesCArrayFlat(4);
       
  3049         CleanupStack::PushL(fp);
       
  3050 
       
  3051         TInt count(iSelections.Count());
       
  3052         TInt itemCount = count > KIncrementalDeleteCount ? KIncrementalDeleteCount : count;
       
  3053         for (TInt i = 0; i < itemCount; ++i )
       
  3054             {
       
  3055             // do not report song URIs if collection path is for songs within a playlist, i.e.
       
  3056             // EBrowsePlaylist and level 4, because client should not be deleting those song
       
  3057             // files
       
  3058             if (path->Id(1) != EBrowsePlaylist || path->Levels() !=4)
       
  3059                 {
       
  3060                 HBufC * uri = iDbHandler->GetUriMatchingIdL (iSelections[0].iId2 );
       
  3061                 CleanupStack::PushL(uri);
       
  3062                 fp->AppendL(*uri);
       
  3063                 CleanupStack::PopAndDestroy(uri);
       
  3064                 }
       
  3065             iSelections.Remove(0);
       
  3066             }
       
  3067 
       
  3068         aCmd.SetNoNewLCObjectL(KMPXCommandCollectionRetrieveMediaUriArray, fp);
       
  3069         if (iFirstDeleteStep)
       
  3070             {
       
  3071         aCmd.SetCObjectValueL(KMPXCommandCollectionRetrievePath, path);
       
  3072             }
       
  3073 
       
  3074         CleanupStack::PopAndDestroy(fp);
       
  3075         CleanupStack::PopAndDestroy(path);
       
  3076         }
       
  3077     }
       
  3078 
       
  3079 // ----------------------------------------------------------------------------
       
  3080 // Cleanup deleted records
       
  3081 // ----------------------------------------------------------------------------
       
  3082 //
       
  3083 void CMPXDbPlugin::CleanupDeletedRecordsL(
       
  3084     CMPXCommand& aCmd)
       
  3085     {
       
  3086     MPX_FUNC("CMPXDbPlugin::CleanupDeletedRecordsL");
       
  3087 
       
  3088     MPX_TRAPD(error, iDbHandler->CleanupDeletedRecordsL());
       
  3089     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionCleanupError, error);
       
  3090     }
       
  3091 
       
  3092 // ----------------------------------------------------------------------------
       
  3093 // Find the duration
       
  3094 // ----------------------------------------------------------------------------
       
  3095 //
       
  3096 TInt CMPXDbPlugin::DoDurationL(
       
  3097     CMPXMedia& aMedia,
       
  3098     TMPXGeneralCategory aFirstCat,
       
  3099     TMPXItemId aId,
       
  3100     TMPXGeneralCategory aSecondCat,
       
  3101     TMPXItemId aSubId)
       
  3102     {
       
  3103     MPX_FUNC("CMPXDbPlugin::DoDurationL");
       
  3104 
       
  3105     TInt duration(0);
       
  3106 
       
  3107     switch (aFirstCat)
       
  3108         {
       
  3109         case EMPXSong:
       
  3110             {
       
  3111             duration = iDbHandler->GetAllSongsDurationL();
       
  3112             break;
       
  3113             }
       
  3114         case EMPXAlbum:
       
  3115             {
       
  3116             duration = iDbHandler->GetAlbumDurationL(aId.iId2);
       
  3117             break;
       
  3118             }
       
  3119         case EMPXComposer:
       
  3120             {
       
  3121             duration = iDbHandler->GetComposerDurationL(aId.iId2);
       
  3122             break;
       
  3123             }
       
  3124         case EMPXGenre:
       
  3125             {
       
  3126             duration = iDbHandler->GetGenreDurationL(aId.iId2);
       
  3127             break;
       
  3128             }
       
  3129         case EMPXArtist:
       
  3130             {
       
  3131             if (aSecondCat == EMPXAlbum)
       
  3132                 {
       
  3133                 duration = iDbHandler->GetArtistAlbumDurationL(aId.iId2, aSubId.iId2);
       
  3134                 }
       
  3135             else
       
  3136                 {
       
  3137                 duration = iDbHandler->GetArtistDurationL(aId.iId2);
       
  3138                 }
       
  3139             break;
       
  3140             }
       
  3141         case EMPXPlaylist:
       
  3142             {
       
  3143             duration = iDbHandler->GetPlaylistDurationL(aId.iId2);
       
  3144             break;
       
  3145             }
       
  3146         default:
       
  3147             {
       
  3148             User::Leave(KErrNotSupported);
       
  3149             }
       
  3150         }
       
  3151 
       
  3152     aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralDuration, duration);
       
  3153     return duration;
       
  3154     }
       
  3155 
       
  3156 // ----------------------------------------------------------------------------
       
  3157 // Append a level to a collection path and set selection to the first item
       
  3158 // ----------------------------------------------------------------------------
       
  3159 //
       
  3160 TInt CMPXDbPlugin::DoAppendLevelL(
       
  3161     CMPXCollectionPath& aPath,
       
  3162     CMPXMedia& aMedia )
       
  3163     {
       
  3164     MPX_FUNC("CMPXDbPlugin::DoAppendLevelL");
       
  3165 
       
  3166     RArray<TMPXItemId> ids;
       
  3167     CleanupClosePushL(ids);
       
  3168 
       
  3169     // Extract media array, and get all item ids
       
  3170     //
       
  3171     const CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3172     if( !mediaArray )
       
  3173         {
       
  3174         User::Leave( KErrNoMemory );
       
  3175         }
       
  3176 
       
  3177     TInt count(mediaArray->Count());
       
  3178     if (count >= 0)
       
  3179         {
       
  3180         for (TInt i = 0; i < count; ++i)
       
  3181             {
       
  3182             TMPXItemId id = mediaArray->AtL(i)->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  3183             ids.AppendL(id);
       
  3184             }
       
  3185 
       
  3186         // Put item id array into the path and select the first one
       
  3187         aPath.AppendL(ids.Array());
       
  3188         if (count > 0)
       
  3189             {
       
  3190             aPath.Set(0);
       
  3191             }
       
  3192         }
       
  3193 
       
  3194     CleanupStack::PopAndDestroy(&ids);
       
  3195     return count;
       
  3196     }
       
  3197 
       
  3198 // ----------------------------------------------------------------------------
       
  3199 // Append a level to a collection path and set selection to all songs under the
       
  3200 // selected category/categories
       
  3201 // ----------------------------------------------------------------------------
       
  3202 //
       
  3203 void CMPXDbPlugin::DoAppendLevelL(
       
  3204     CMPXCollectionPath& aPath)
       
  3205     {
       
  3206     MPX_FUNC("CMPXDbPlugin::DoAppendLevelL");
       
  3207 
       
  3208     TMPXItemId contextId(aPath.Id(1));
       
  3209     TInt levels(aPath.Levels());
       
  3210 
       
  3211     if ((contextId == EBrowseAll) ||
       
  3212         (contextId == EBrowsePlaylist))
       
  3213         {
       
  3214         return;
       
  3215         }
       
  3216     else if (levels == 3 || (levels == 4 && contextId == EBrowseArtist))
       
  3217         {
       
  3218         // retrieve songs in the selected category
       
  3219         //
       
  3220         CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  3221         CleanupStack::PushL(songs);
       
  3222 
       
  3223         RArray<TMPXAttribute> attributes;
       
  3224         CleanupClosePushL(attributes);
       
  3225         attributes.AppendL(KMPXMediaGeneralId);
       
  3226 
       
  3227         // Ids of the selected items
       
  3228         RArray<TMPXItemId> selections;
       
  3229         CleanupClosePushL(selections);
       
  3230         aPath.SelectionL(selections);
       
  3231 
       
  3232         // single selection
       
  3233         if (selections.Count() == 0)
       
  3234             {
       
  3235             selections.AppendL(aPath.Id(aPath.Levels() - 1));
       
  3236             }
       
  3237 
       
  3238         TInt count(selections.Count());
       
  3239 
       
  3240         // all songs for the selected artist
       
  3241         if (contextId == EBrowseArtist && levels == 3)
       
  3242             {
       
  3243             for (TInt i = 0; i < count; ++i)
       
  3244                 {
       
  3245                 iDbHandler->GetSongsMatchingArtistL(selections[i].iId2, attributes.Array(), songs);
       
  3246                 }
       
  3247             if (songs->Count())
       
  3248                 {
       
  3249                 aPath.AppendL(selections.Array());
       
  3250                 }
       
  3251             }
       
  3252 
       
  3253         // all songs for the selected artist in the specified album
       
  3254         else if ((contextId == EBrowseArtist) && (levels == 4))
       
  3255             {
       
  3256             for (TInt i = 0; i < count; ++i)
       
  3257                 {
       
  3258                 if (aPath.Id(2) == aPath.Id(3))
       
  3259                     {
       
  3260                     iDbHandler->GetSongsMatchingArtistL(aPath.Id(3).iId2,
       
  3261                         attributes.Array(), songs);
       
  3262                     }
       
  3263                 else
       
  3264                     {
       
  3265                     iDbHandler->GetSongsMatchingArtistAndAlbumL(aPath.Id(aPath.Levels() - 2),
       
  3266                         selections[i].iId2, attributes.Array(), songs);
       
  3267                     }
       
  3268                 }
       
  3269             }
       
  3270 
       
  3271          // all songs for the selected album
       
  3272         else if (contextId == EBrowseAlbum && levels == 3)
       
  3273             {
       
  3274             for (TInt i = 0; i < count; ++i)
       
  3275                 {
       
  3276                 iDbHandler->GetSongsMatchingAlbumL(selections[i], attributes.Array(), songs);
       
  3277                 }
       
  3278             }
       
  3279 
       
  3280         // all songs for the selected genre
       
  3281         else if (contextId == EBrowseGenre && levels == 3)
       
  3282             {
       
  3283             for (TInt i = 0; i < count; ++i)
       
  3284                 {
       
  3285                 iDbHandler->GetSongsMatchingGenreL(selections[i], attributes.Array(), songs);
       
  3286                 }
       
  3287             }
       
  3288 
       
  3289         // all songs for the selected composer
       
  3290         else if (contextId == EBrowseComposer && levels == 3)
       
  3291             {
       
  3292             for (TInt i = 0; i < count; ++i)
       
  3293                 {
       
  3294                 iDbHandler->GetSongsMatchingComposerL(selections[i], attributes.Array(), songs);
       
  3295                 }
       
  3296             }
       
  3297         else
       
  3298             {
       
  3299             // else do nothing
       
  3300             }
       
  3301 
       
  3302         CleanupStack::PopAndDestroy(&selections);
       
  3303         CleanupStack::PopAndDestroy(&attributes);
       
  3304 
       
  3305         // transform from CMPXMediaArray to RArray
       
  3306         RArray<TMPXItemId> songIds;
       
  3307         CleanupClosePushL(songIds);
       
  3308 
       
  3309         TInt songCount(songs->Count());
       
  3310         for (TInt i = 0; i < songCount; ++i)
       
  3311             {
       
  3312             CMPXMedia* song = (*songs)[i];
       
  3313 
       
  3314             if (song->IsSupported(KMPXMediaGeneralId))
       
  3315                 {
       
  3316                 songIds.AppendL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  3317                 }
       
  3318             }
       
  3319 
       
  3320         // modify the collection path. append another level with all songs under the selected
       
  3321         // category/categories selected
       
  3322         songCount = songIds.Count();
       
  3323 
       
  3324         if (songCount)
       
  3325             {
       
  3326             aPath.ClearSelection();
       
  3327             aPath.AppendL(songIds.Array());
       
  3328 
       
  3329             // select all
       
  3330             for (TInt i = 0; i < songCount; ++i)
       
  3331                 {
       
  3332                 aPath.SelectL(songIds[i]);
       
  3333                 }
       
  3334             }
       
  3335 
       
  3336         CleanupStack::PopAndDestroy(&songIds);
       
  3337         CleanupStack::PopAndDestroy(songs);
       
  3338         }
       
  3339     else
       
  3340         {
       
  3341         // do nothing
       
  3342         }
       
  3343     }
       
  3344 
       
  3345 // ----------------------------------------------------------------------------
       
  3346 // Execute an Add task step
       
  3347 // ----------------------------------------------------------------------------
       
  3348 //
       
  3349 TBool CMPXDbPlugin::DoAddAsyncL()
       
  3350     {
       
  3351     MPX_FUNC("CMPXDbPlugin::DoAddAsyncL");
       
  3352 
       
  3353     TBool done(EFalse);
       
  3354     const CMPXMedia* task = (iActiveTask->GetCommand().Value<CMPXMedia>(KMPXCommandColAddMedia));
       
  3355     if( !task )
       
  3356         {
       
  3357         User::Leave(KErrNoMemory);
       
  3358         }
       
  3359 
       
  3360     CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages();
       
  3361 
       
  3362     if (!task->IsSupported(KMPXMediaGeneralType))
       
  3363         {
       
  3364         User::Leave(KErrArgument);
       
  3365         }
       
  3366 
       
  3367     // Group of items or a single item
       
  3368     //
       
  3369     if (task->ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3370         {
       
  3371         if (!task->IsSupported(KMPXMediaArrayContents))
       
  3372             {
       
  3373             User::Leave(KErrArgument);
       
  3374             }
       
  3375 
       
  3376         CMPXMediaArray* ary = task->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3377         User::LeaveIfNull(ary);
       
  3378         TInt step( iActiveTask->GetStep() );
       
  3379         DoAddItemL( *ary->AtL(step), msgArray );
       
  3380 
       
  3381         if (++step == ary->Count())
       
  3382             {
       
  3383             done = ETrue;
       
  3384             }
       
  3385         }
       
  3386     else // type == EMPXItem
       
  3387         {
       
  3388         TUint32 item = DoAddItemL( *task, msgArray );
       
  3389         iActiveTask->GetCommand().SetTObjectValueL<TMPXItemId>( KMPXCommandColAddRtnId, item);
       
  3390         done = ETrue;
       
  3391         }
       
  3392 
       
  3393     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3394     return done;
       
  3395     }
       
  3396 
       
  3397 // ----------------------------------------------------------------------------
       
  3398 // Add an item to the collection
       
  3399 // ----------------------------------------------------------------------------
       
  3400 //
       
  3401 TUint32 CMPXDbPlugin::DoAddL(
       
  3402     const CMPXMedia& aMedia)
       
  3403     {
       
  3404     MPX_FUNC("CMPXDbPlugin::DoAddL");
       
  3405 
       
  3406     if (!aMedia.IsSupported(KMPXMediaGeneralType))
       
  3407         {
       
  3408         User::Leave(KErrArgument);
       
  3409         }
       
  3410 
       
  3411     TUint32 itemId(0);
       
  3412     CMPXMessageArray* changeMsgAry = CMPXMessageArray::NewL();
       
  3413     CleanupStack::PushL(changeMsgAry);
       
  3414 
       
  3415 	// start a transaction here
       
  3416 	if (!iDbHandler->InTransaction())
       
  3417 		{
       
  3418 		iDbHandler->BeginTransactionL();
       
  3419 		}
       
  3420 
       
  3421     // Group of items
       
  3422     if (aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3423         {
       
  3424         CMPXMediaArray* array = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3425         User::LeaveIfNull( array );
       
  3426 
       
  3427         TInt count(array->Count());
       
  3428         for (TInt i = 0; i < count; ++i)
       
  3429             {
       
  3430             // ETrue indicates we are batch committing the songs.
       
  3431             // This parameter is only used for the use case of adding
       
  3432             // thousands of songs at a time.
       
  3433             DoAddItemL(*array->AtL(i), *changeMsgAry, ETrue);
       
  3434             }
       
  3435         }
       
  3436     else // single item
       
  3437         {
       
  3438         itemId = DoAddItemL(aMedia, *changeMsgAry);
       
  3439         }
       
  3440 
       
  3441 	// end transaction here.
       
  3442 	iDbHandler->EndTransactionL(KErrNone);
       
  3443 
       
  3444     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3445     DoHandleChangeL(changeMsgAry);
       
  3446     CleanupStack::PopAndDestroy(changeMsgAry);
       
  3447 
       
  3448     return itemId;
       
  3449     }
       
  3450 
       
  3451 // ----------------------------------------------------------------------------------------------------------
       
  3452 // Add an item to the collection
       
  3453 // ----------------------------------------------------------------------------------------------------------
       
  3454 //
       
  3455 TUint32 CMPXDbPlugin::DoAddItemL(
       
  3456     const CMPXMedia& aMedia,
       
  3457     CMPXMessageArray& aMessageArray,
       
  3458     TBool aBatchCommit)
       
  3459     {
       
  3460     MPX_FUNC("CMPXDbPlugin::DoAddItemL");
       
  3461 
       
  3462     TUint32 itemId(0);
       
  3463     if (!aMedia.IsSupported(KMPXMediaGeneralCategory))
       
  3464         {
       
  3465         User::Leave(KErrArgument);
       
  3466         }
       
  3467 
       
  3468     switch (aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory))
       
  3469         {
       
  3470         case EMPXPlaylist:
       
  3471             {
       
  3472             if (!aMedia.IsSupported(KMPXMediaArrayContents))
       
  3473                 {
       
  3474                 User::Leave(KErrArgument);
       
  3475                 }
       
  3476 
       
  3477             if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  3478                 {
       
  3479                 itemId = iDbHandler->AddSongToPlaylistL(aMedia);
       
  3480                 MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, itemId, EMPXItemModified,
       
  3481                     EMPXPlaylist, KDBPluginUid);
       
  3482                 }
       
  3483             else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  3484                 {
       
  3485                 itemId = iDbHandler->AddPlaylistL(aMedia);
       
  3486                 MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, EBrowsePlaylist, EMPXItemInserted,
       
  3487                     EMPXPlaylist, KDBPluginUid);
       
  3488                 }
       
  3489             else
       
  3490                 {
       
  3491                 User::Leave(KErrArgument);
       
  3492                 }
       
  3493             }
       
  3494             break;
       
  3495 
       
  3496         case EMPXSong:
       
  3497             {
       
  3498             // For the use case of adding thousands of songs at once,
       
  3499             // we do not create a new database transaction for each song; 
       
  3500             // Instead DoAddL() will batch 100 songs under a single transaction.
       
  3501             // This enhancement improves performance with MMC-based databases.
       
  3502             if (aBatchCommit)
       
  3503                 {
       
  3504                 itemId = iDbHandler->AddSongWithNoTransactionL(aMedia, &aMessageArray);
       
  3505                 }
       
  3506             else
       
  3507                 {
       
  3508                 itemId = iDbHandler->AddSongL(aMedia, &aMessageArray);
       
  3509                 }
       
  3510             
       
  3511             MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, itemId, EMPXItemInserted,
       
  3512                 EMPXSong, KDBPluginUid);
       
  3513             }
       
  3514             break;
       
  3515 
       
  3516         default:
       
  3517             {
       
  3518             User::Leave(KErrNotSupported);
       
  3519             }
       
  3520         }
       
  3521 
       
  3522     return itemId;
       
  3523     }
       
  3524 
       
  3525 // ----------------------------------------------------------------------------
       
  3526 // Update the collection from a media
       
  3527 // ----------------------------------------------------------------------------
       
  3528 //
       
  3529 void CMPXDbPlugin::DoSetL(
       
  3530     const CMPXMedia& aMedia )
       
  3531     {
       
  3532     MPX_FUNC("CMPXDbPlugin::DoSetL");
       
  3533 
       
  3534     if (!aMedia.IsSupported(KMPXMediaGeneralType))
       
  3535         {
       
  3536         User::Leave(KErrArgument);
       
  3537         }
       
  3538 
       
  3539     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  3540 
       
  3541     CMPXMessageArray* changeMsgArray = CMPXMessageArray::NewL();
       
  3542     CleanupStack::PushL(changeMsgArray);
       
  3543 
       
  3544     if (aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3545         {
       
  3546         if (!aMedia.IsSupported(KMPXMediaArrayContents))
       
  3547             {
       
  3548             User::Leave(KErrArgument);
       
  3549             }
       
  3550 
       
  3551         CMPXMediaArray* array = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3552         User::LeaveIfNull( array );
       
  3553         TInt count( array->Count() );
       
  3554         for (TInt i = 0; i < count; ++i)
       
  3555             {
       
  3556             visibleChange = (CMPXDbActiveTask::TChangeVisibility)(visibleChange | DoSetItemL(*array->AtL(i), *changeMsgArray));
       
  3557             }
       
  3558         }
       
  3559     else
       
  3560         {
       
  3561         visibleChange = DoSetItemL(aMedia, *changeMsgArray);
       
  3562         }
       
  3563 
       
  3564     // Handle Change Events
       
  3565     if (visibleChange)
       
  3566         {
       
  3567         iActiveTask->SetVisibleChange(visibleChange);
       
  3568         DoHandleChangeL(changeMsgArray);
       
  3569         }
       
  3570     CleanupStack::PopAndDestroy(changeMsgArray);
       
  3571     }
       
  3572 
       
  3573 // ----------------------------------------------------------------------------
       
  3574 // Execute a task step for async set
       
  3575 // ----------------------------------------------------------------------------
       
  3576 //
       
  3577 TBool CMPXDbPlugin::DoSetAsyncL()
       
  3578     {
       
  3579     MPX_FUNC("CMPXDbPlugin::DoSetAsyncL");
       
  3580 
       
  3581     TBool done(EFalse);
       
  3582     CMPXMedia* task = iActiveTask->GetCommand().Value<CMPXMedia>(KMPXCommandColSetMedia);
       
  3583     User::LeaveIfNull( task );
       
  3584 
       
  3585     CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages();
       
  3586     CMPXDbActiveTask::TChangeVisibility visibleChange(iActiveTask->GetVisibleChange());
       
  3587 
       
  3588     // Multiple steps can be in a transaction for faster response
       
  3589     if( !iDbHandler->InTransaction() )
       
  3590         {
       
  3591         iDbHandler->BeginTransactionL();
       
  3592         }
       
  3593 
       
  3594     if (!task->IsSupported(KMPXMediaGeneralType))
       
  3595         {
       
  3596         User::Leave(KErrArgument);
       
  3597         }
       
  3598 
       
  3599     if (task->ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3600         {
       
  3601         if (!task->IsSupported(KMPXMediaArrayContents))
       
  3602             {
       
  3603             User::Leave(KErrArgument);
       
  3604             }
       
  3605 
       
  3606         // Multiple items
       
  3607         CMPXMediaArray* array = task->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3608         User::LeaveIfNull( array );
       
  3609         TInt step = iActiveTask->GetStep();
       
  3610         visibleChange = (CMPXDbActiveTask::TChangeVisibility)(visibleChange | DoSetItemL(*array->AtL(step), msgArray));
       
  3611 
       
  3612         if (++step == array->Count())
       
  3613             {
       
  3614             done = ETrue;
       
  3615             }
       
  3616         }
       
  3617     else // Single item
       
  3618         {
       
  3619         visibleChange = DoSetItemL(*task, msgArray);
       
  3620         done = ETrue;
       
  3621         }
       
  3622     iActiveTask->SetVisibleChange(visibleChange);
       
  3623     return done;
       
  3624     }
       
  3625 
       
  3626 // ----------------------------------------------------------------------------
       
  3627 // Update the collection from a media
       
  3628 // ----------------------------------------------------------------------------
       
  3629 //
       
  3630 CMPXDbActiveTask::TChangeVisibility CMPXDbPlugin::DoSetItemL(
       
  3631     const CMPXMedia& aMedia,
       
  3632     CMPXMessageArray& aMessageArray )
       
  3633     {
       
  3634     MPX_FUNC("CMPXDbPlugin::DoSetItemL");
       
  3635 
       
  3636     TMPXGeneralCategory category = aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  3637 
       
  3638     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  3639     switch (category)
       
  3640         {
       
  3641         case EMPXPlaylist:
       
  3642             {
       
  3643             if (aMedia.IsSupported(KMPXMediaArrayContents))
       
  3644                 {
       
  3645                 CMPXMessage* message = CMPXMedia::NewL();
       
  3646                 CleanupStack::PushL(message);
       
  3647 
       
  3648                 iDbHandler->UpdatePlaylistSongsL(aMedia, *message);
       
  3649 
       
  3650                 aMessageArray.AppendL(message); // ownership xfer
       
  3651                 CleanupStack::Pop(message);
       
  3652                 }
       
  3653             else
       
  3654                 {
       
  3655                 iDbHandler->UpdatePlaylistL(aMedia, aMessageArray);
       
  3656                 }
       
  3657 
       
  3658             visibleChange = CMPXDbActiveTask::ESingleVisible;
       
  3659             }
       
  3660             break;
       
  3661 
       
  3662         case EMPXSong:
       
  3663             {
       
  3664             // a list of changed messages as a result of the song being updated
       
  3665             visibleChange = iDbHandler->UpdateSongL(aMedia, aMessageArray);
       
  3666             }
       
  3667             break;
       
  3668 
       
  3669         default:
       
  3670             {
       
  3671             User::Leave(KErrNotSupported);
       
  3672             }
       
  3673             break;
       
  3674         }
       
  3675     return visibleChange; // ownership xfer
       
  3676     }
       
  3677 
       
  3678 // ----------------------------------------------------------------------------
       
  3679 // Sets the drm properties for a list of medias
       
  3680 // ----------------------------------------------------------------------------
       
  3681 //
       
  3682 void CMPXDbPlugin::DoSetDrmForArrayL(
       
  3683     const CMPXMediaArray& mediaArray,
       
  3684     const TArray<TMPXAttribute>& aAttrs)
       
  3685     {
       
  3686     MPX_FUNC("CMPXDbPlugin::DoSetDrmForArrayL");
       
  3687 
       
  3688     TUint drmAttributes(0);
       
  3689 
       
  3690     // Compact the attribute set
       
  3691     //
       
  3692     TInt attrCount(aAttrs.Count());
       
  3693     for (TInt i = 0; i < attrCount; ++i)
       
  3694         {
       
  3695         if (aAttrs[i].ContentId() == KMPXMediaIdDrm)
       
  3696             {
       
  3697             drmAttributes |= aAttrs[i].AttributeId();
       
  3698             }
       
  3699         }
       
  3700 
       
  3701     // Fetch drm attributes for every item
       
  3702     //
       
  3703     if (drmAttributes)
       
  3704         {
       
  3705         TInt count(mediaArray.Count());
       
  3706         for (TInt i = 0; i < count; ++i)
       
  3707             {
       
  3708             if (mediaArray[i]->IsSupported(KMPXMediaGeneralUri))
       
  3709                 {
       
  3710                 DoSetMediaDrmL(*mediaArray[i], drmAttributes,
       
  3711                     mediaArray[i]->ValueText(KMPXMediaGeneralUri));
       
  3712                 }
       
  3713             }
       
  3714         }
       
  3715     }
       
  3716 
       
  3717 // ----------------------------------------------------------------------------
       
  3718 // Handle change events
       
  3719 // ----------------------------------------------------------------------------
       
  3720 //
       
  3721 void CMPXDbPlugin::HandleChangeL(
       
  3722     const CMPXMessage& aMessage)
       
  3723     {
       
  3724     MPX_FUNC("CMPXDbPlugin::HandleChange");
       
  3725 
       
  3726     // check if message is filled
       
  3727     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  3728         {
       
  3729 #if _DEBUG
       
  3730         PrintMessagesL(aMessage);
       
  3731 #endif // _DEBUG
       
  3732         if(iRefreshing)
       
  3733             {
       
  3734             if (aMessage.IsSupported(KMPXMessageArrayContents))
       
  3735                 {
       
  3736                 const CMPXMessageArray* messageArray = aMessage.Value<CMPXMessageArray>(KMPXMessageArrayContents);
       
  3737                 if(messageArray)
       
  3738                     {
       
  3739                     CMPXMessage& message = *((*messageArray)[0]);
       
  3740                     TMPXChangeEventType changeType( message.ValueTObjectL<TMPXChangeEventType>( KMPXMessageChangeEventType ) );
       
  3741                     TMPXGeneralCategory cat(message.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  3742                     if(changeType == EMPXItemInserted && (cat == EMPXSong || cat == EMPXPlaylist || cat == EMPXPodcast))
       
  3743                         {
       
  3744                         iObs->HandleMessage(aMessage);
       
  3745                         }
       
  3746                     }
       
  3747                 }
       
  3748             else
       
  3749                 {
       
  3750                 TMPXChangeEventType changeType( aMessage.ValueTObjectL<TMPXChangeEventType>( KMPXMessageChangeEventType ) );
       
  3751                 TMPXGeneralCategory cat(aMessage.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  3752                 if(changeType == EMPXItemInserted && (cat == EMPXSong || cat == EMPXPlaylist || cat == EMPXPodcast))
       
  3753                     {
       
  3754                     iObs->HandleMessage(aMessage);
       
  3755                     }
       
  3756                 }
       
  3757             }
       
  3758         else
       
  3759             {
       
  3760             if(!iMtpInUse)
       
  3761                 {
       
  3762                 iObs->HandleMessage(aMessage);
       
  3763                 }
       
  3764             }
       
  3765         }
       
  3766     }
       
  3767 
       
  3768 // ----------------------------------------------------------------------------
       
  3769 // Construct a CMPXMedia and call HandleChange
       
  3770 // ----------------------------------------------------------------------------
       
  3771 //
       
  3772 void CMPXDbPlugin::DoHandleChangeL(
       
  3773     CMPXMessageArray* aItemChangedMessages,
       
  3774     TMPXCommandId aCommandId )
       
  3775     {
       
  3776     MPX_FUNC("CMPXDbPlugin::DoHandleChangeL");
       
  3777 
       
  3778     if( (iActiveTask->GetVisibleChange() & CMPXDbActiveTask::EAllVisible)
       
  3779         && (aCommandId == KMPXCommandIdCollectionSet ||
       
  3780             aCommandId == KMPXCommandIdCollectionAdd ||
       
  3781             aCommandId == KMPXCommandIdCollectionRemove ||
       
  3782             aCommandId == KMPXCommandIdCollectionCompleteDelete ))
       
  3783         {
       
  3784         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, EBrowseAll,
       
  3785                                                  EMPXItemModified, EMPXCollection, KDBPluginUid);
       
  3786         }
       
  3787     // group change messages and send to collection client context
       
  3788     //
       
  3789     CMPXMessage* message = CMPXMessage::NewL();
       
  3790     CleanupStack::PushL(message);
       
  3791 
       
  3792     message->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, KMPXMessageIdItemChanged);
       
  3793     message->SetCObjectValueL(KMPXMessageArrayContents, aItemChangedMessages);
       
  3794     message->SetTObjectValueL<TInt>(KMPXMessageArrayCount, aItemChangedMessages->Count());
       
  3795 
       
  3796     HandleChangeL(*message);
       
  3797 
       
  3798     CleanupStack::PopAndDestroy(message);
       
  3799     }
       
  3800 
       
  3801 // ----------------------------------------------------------------------------
       
  3802 // Handle completion of operation
       
  3803 // ----------------------------------------------------------------------------
       
  3804 //
       
  3805 void CMPXDbPlugin::DoHandleOperationCompletedL(
       
  3806     TInt aErr)
       
  3807     {
       
  3808     MPX_FUNC("CMPXDbPlugin::DoHandleOperationCompletedL");
       
  3809 
       
  3810     // Broadcase change messages
       
  3811     //
       
  3812     if (iActiveTask->GetVisibleChange())
       
  3813         {
       
  3814         DoHandleChangeL(&iActiveTask->GetChangeMessages(), iActiveTask->GetTask() );
       
  3815         }
       
  3816 
       
  3817     // Callback to engine to signal completion
       
  3818     // NOTE: Collection server immediately completes the async message when
       
  3819     // Cancel is called, no need to callback to observer
       
  3820     if (aErr != KErrCancel)
       
  3821         {
       
  3822         iObs->HandleCommandComplete(NULL, aErr);
       
  3823         }
       
  3824 
       
  3825     if( iDbHandler->InTransaction() )
       
  3826         {
       
  3827         // Commit if cancelled
       
  3828         TInt err(aErr);
       
  3829         if( err == KErrCancel )
       
  3830             {
       
  3831             err = KErrNone;
       
  3832             }
       
  3833         iDbHandler->EndTransactionL( err );
       
  3834         }
       
  3835     }
       
  3836 
       
  3837 // ----------------------------------------------------------------------------------------------------------
       
  3838 // Complete a delete operation
       
  3839 // ----------------------------------------------------------------------------------------------------------
       
  3840 //
       
  3841 void CMPXDbPlugin::DoHandleDeleteCompleteL(
       
  3842     CMPXCommand& aCmd)
       
  3843     {
       
  3844     MPX_FUNC("CMPXDbPlugin::DoHandleDeleteCompleteL");
       
  3845     iFirstDeleteStep = ETrue;
       
  3846     iSelections.Reset();
       
  3847     if ( iDbHandler->InTransaction() )
       
  3848         {
       
  3849         // if it can reach this point in a transaction, there's no error
       
  3850         iDbHandler->EndTransactionL( KErrNone );
       
  3851         }
       
  3852 
       
  3853     // Change messages
       
  3854     if (aCmd.IsSupported(KMPXCommandCollectionDeleteMsgArray))
       
  3855         {
       
  3856         CMPXMessageArray* msgs = aCmd.Value<CMPXMessageArray>(KMPXCommandCollectionDeleteMsgArray);
       
  3857         User::LeaveIfNull( msgs );
       
  3858         iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3859         DoHandleChangeL(msgs, KMPXCommandIdCollectionCompleteDelete);
       
  3860         }
       
  3861     }
       
  3862 
       
  3863 // ----------------------------------------------------------------------------------------------------------
       
  3864 // Reorder a song in a playlist
       
  3865 // ----------------------------------------------------------------------------------------------------------
       
  3866 //
       
  3867 void CMPXDbPlugin::DoReorderPlaylistL(
       
  3868     const CMPXCommand& aCmd)
       
  3869     {
       
  3870     MPX_FUNC("CMPXDbPlugin::DoReorderPlaylistL");
       
  3871 
       
  3872     if (!aCmd.IsSupported(KMPXCommandReorderPlaylistId) ||
       
  3873         !aCmd.IsSupported(KMPXCommandReorderSongId) ||
       
  3874         !aCmd.IsSupported(KMPXCommandReorderOriginalOrdinal) ||
       
  3875         !aCmd.IsSupported(KMPXCommandReorderNewOrdinal))
       
  3876         {
       
  3877         User::Leave(KErrArgument);
       
  3878         }
       
  3879 
       
  3880     CMPXMessage* message = CMPXMedia::NewL();
       
  3881     CleanupStack::PushL(message);
       
  3882 
       
  3883     iDbHandler->ReorderPlaylistL(
       
  3884         aCmd.ValueTObjectL<TMPXItemId>(KMPXCommandReorderPlaylistId),
       
  3885         aCmd.ValueTObjectL<TMPXItemId>(KMPXCommandReorderSongId),
       
  3886         aCmd.ValueTObjectL<TUint>(KMPXCommandReorderOriginalOrdinal),
       
  3887         aCmd.ValueTObjectL<TUint>(KMPXCommandReorderNewOrdinal),
       
  3888         *message);
       
  3889 
       
  3890     HandleChangeL(*message);
       
  3891 
       
  3892     CleanupStack::PopAndDestroy(message);
       
  3893     }
       
  3894 
       
  3895 // ----------------------------------------------------------------------------------------------------------
       
  3896 // Get total songs and playlists count for a database
       
  3897 // ----------------------------------------------------------------------------------------------------------
       
  3898 //
       
  3899 void CMPXDbPlugin::DoGetCollectionCountL( const CMPXCommand& aCmd )
       
  3900     {
       
  3901     MPX_FUNC("CMPXDbPlugin::DoGetCollectionCountL");
       
  3902     if (!aCmd.IsSupported(KMPXCommandCollectionCountDrive) ||
       
  3903         !aCmd.IsSupported(KMPXCommandCollectionCountTable) )
       
  3904         {
       
  3905         User::Leave(KErrArgument);
       
  3906         }
       
  3907 
       
  3908     TInt count = 0;
       
  3909     TInt drive = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionCountDrive);
       
  3910     TInt table = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionCountTable);
       
  3911     switch(table)
       
  3912         {
       
  3913         case EMPXCollectionCountTrack:
       
  3914             count = (TInt)iDbHandler->GetMusicCountL(drive);
       
  3915             break;
       
  3916         case EMPXCollectionCountPlaylist:
       
  3917             count = (TInt)iDbHandler->GetPlaylistCountL(drive);
       
  3918             break;
       
  3919         case EMPXCollectionCountTotal:
       
  3920             count = (TInt)iDbHandler->GetTotalCountL(drive);
       
  3921             break;
       
  3922         default:
       
  3923             User::Leave(KErrArgument);
       
  3924         }
       
  3925     ((CMPXMedia&)aCmd).SetTObjectValueL<TInt>(KMPXCommandCollectionCountValue, count);
       
  3926     }
       
  3927 
       
  3928 // ----------------------------------------------------------------------------------------------------------
       
  3929 // Get URIs for all songs and file playlists in a database
       
  3930 // ----------------------------------------------------------------------------------------------------------
       
  3931 //
       
  3932 void CMPXDbPlugin::DoGetCollectionUriL( const CMPXCommand& aCmd )
       
  3933     {
       
  3934     MPX_FUNC("CMPXDbPlugin::DoGetCollectionCountL");
       
  3935     if (!aCmd.IsSupported(KMPXCommandCollectionURIDrive) ||
       
  3936         !aCmd.IsSupported(KMPXCommandCollectionURITable) ||
       
  3937         !aCmd.IsSupported(KMPXCommandCollectionURIFromID) ||
       
  3938         !aCmd.IsSupported(KMPXCommandCollectionURIRecords) )
       
  3939         {
       
  3940         User::Leave(KErrArgument);
       
  3941         }
       
  3942 
       
  3943     TInt drive = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIDrive);
       
  3944     TInt table = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURITable);
       
  3945     TInt fromID = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIFromID);
       
  3946     TInt recnum = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIRecords);
       
  3947 
       
  3948     CDesCArray* uris = new(ELeave) CDesCArrayFlat(4);
       
  3949     CleanupStack::PushL(uris);
       
  3950     TInt lastID = 0;
       
  3951 
       
  3952     switch(table)
       
  3953         {
       
  3954         case EMPXCollectionURITrack:
       
  3955             iDbHandler->GetMusicUriArrayL(drive, fromID, recnum, *uris, lastID);
       
  3956             break;
       
  3957         case EMPXCollectionURIPlaylist:
       
  3958             iDbHandler->GetPlaylistUriArrayL(drive, fromID, recnum, *uris, lastID);
       
  3959             break;
       
  3960         default:
       
  3961             User::Leave(KErrArgument);
       
  3962         }
       
  3963 
       
  3964     ((CMPXMedia&)aCmd).SetNoNewLCObjectL(KMPXCommandCollectionURIList, uris);
       
  3965     ((CMPXMedia&)aCmd).SetTObjectValueL(KMPXCommandCollectionURILastID, lastID);
       
  3966     CleanupStack::PopAndDestroy(uris);
       
  3967     }
       
  3968 
       
  3969 
       
  3970 // ----------------------------------------------------------------------------------------------------------
       
  3971 // Perform one step of the incremental operation
       
  3972 // ----------------------------------------------------------------------------------------------------------
       
  3973 //
       
  3974 void CMPXDbPlugin::DoIncrementalOpenL( const CMPXCommand& aCmd )
       
  3975     {
       
  3976     MPX_DEBUG1("CMPXDbPlugin::DoIncrementalOpenL <--");
       
  3977 
       
  3978     TInt offset = aCmd.ValueTObjectL<TInt>( KMPXCollectionCommandIdIncOpenLOffset );
       
  3979     TInt numItems = aCmd.ValueTObjectL<TInt>( KMPXCollectionCommandIdIncOpenLNumItems );
       
  3980 
       
  3981     TReadDirection direction(EReadUnknown);
       
  3982     if( aCmd.IsSupported(KMPXCollectionCommandIdIncOpenLAscDsc) &&
       
  3983         aCmd.IsSupported(KMPXCollectionCommandIdIncOpenLKeyItem) )
       
  3984         {
       
  3985         direction = aCmd.ValueTObjectL<TReadDirection>(KMPXCollectionCommandIdIncOpenLAscDsc);
       
  3986         }
       
  3987 
       
  3988     CMPXCollectionPath* path =  aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCollectionCommandIdIncOpenLPath);
       
  3989     CleanupStack::PushL( path );
       
  3990     MPX_DEBUG_PATH( *path );
       
  3991 
       
  3992     // Switch on level and item selected
       
  3993     //
       
  3994     TInt levels( path->Levels() );
       
  3995     switch( levels )
       
  3996         {
       
  3997         case 3:  // levels of 3 top level is not stripped
       
  3998             {
       
  3999             switch( path->Id(1).iId2 )
       
  4000                 {
       
  4001                 case EBrowseAll:
       
  4002                     {
       
  4003                     CMPXMedia* results = CMPXMedia::NewL();
       
  4004                     CleanupStack::PushL( results );
       
  4005 
       
  4006                     TMPXOpenDataBlock block;
       
  4007                     block.iOffset = offset;
       
  4008                     block.iSize = numItems;
       
  4009 
       
  4010                     // Todo: this should come from the UI
       
  4011                     RArray<TMPXAttribute> attrs;
       
  4012                     CleanupClosePushL( attrs );
       
  4013                     attrs.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
       
  4014                                    EMPXMediaGeneralId | EMPXMediaGeneralType | EMPXMediaGeneralCategory |
       
  4015                                    EMPXMediaGeneralTitle | EMPXMediaGeneralFlags));
       
  4016                     attrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4017                                         EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );
       
  4018 
       
  4019                     // Array to read data from
       
  4020                     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  4021                     CleanupStack::PushL( array );
       
  4022 
       
  4023                     // Do we have to use offset or can we use asc/dsc
       
  4024                     //
       
  4025                     if( direction == EReadUnknown )
       
  4026                         {
       
  4027                         iDbHandler->GetSongsAtOffsetL( array, attrs.Array(), offset, numItems );
       
  4028                         }
       
  4029                     else
       
  4030                         {
       
  4031                         iDbHandler->GetSongsInBlockL( array, attrs.Array(),
       
  4032                                                       aCmd.ValueText( KMPXCollectionCommandIdIncOpenLKeyItem ),
       
  4033                                                       numItems,
       
  4034                                                       direction );
       
  4035                         }
       
  4036 
       
  4037                     TInt max( path->Count() );
       
  4038                     TInt count(0);
       
  4039                     TInt aryCount( array->Count() );
       
  4040                     // Update the collection path
       
  4041                     while( count<numItems && offset<max &&
       
  4042                            count<aryCount )
       
  4043                         {
       
  4044                         TMPXItemId id = array->AtL(count)->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
  4045                         path->Update( offset, id );
       
  4046 
       
  4047                         // Next items
       
  4048                         offset++;
       
  4049                         count++;
       
  4050                         }
       
  4051 
       
  4052                     // Setup the results
       
  4053                     //
       
  4054                     results->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  4055                     results->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  4056                     CleanupStack::PopAndDestroy( array );
       
  4057                     CleanupStack::PopAndDestroy( &attrs );
       
  4058 
       
  4059                     // Callback with results
       
  4060                     //
       
  4061                     results->SetTObjectValueL<TMPXOpenDataBlock>( KMPXCollectionOpenLResultRange, block );
       
  4062                     iObs->HandleOpen( results, path, KErrNone );
       
  4063                     CleanupStack::PopAndDestroy( results );
       
  4064                     break;
       
  4065                     }
       
  4066                 default:
       
  4067                     User::Leave(KErrNotSupported);
       
  4068                     break;
       
  4069                 }
       
  4070             break;
       
  4071             }
       
  4072         default:
       
  4073             {
       
  4074             User::Leave(KErrNotSupported);
       
  4075             break;
       
  4076             }
       
  4077 
       
  4078         }
       
  4079     CleanupStack::PopAndDestroy( path );
       
  4080 
       
  4081     MPX_DEBUG1("CMPXDbPlugin::DoIncrementalOpenL -->");
       
  4082     }
       
  4083 
       
  4084 // ----------------------------------------------------------------------------
       
  4085 // Maps a given browse type to a category ID.
       
  4086 // ----------------------------------------------------------------------------
       
  4087 //
       
  4088 TMPXGeneralCategory CMPXDbPlugin::CategoryForBrowseType(
       
  4089     TMCBrowseType aBrowseType)
       
  4090     {
       
  4091     MPX_FUNC("CMPXDbPlugin::CategoryForBrowseType");
       
  4092 
       
  4093     TMPXGeneralCategory cat(EMPXNoCategory);
       
  4094 
       
  4095     switch (aBrowseType)
       
  4096         {
       
  4097         case EBrowseAll:
       
  4098             {
       
  4099             cat = EMPXSong;
       
  4100             break;
       
  4101             }
       
  4102         case EBrowseArtist:
       
  4103             {
       
  4104             cat = EMPXArtist;
       
  4105             break;
       
  4106             }
       
  4107         case EBrowseAlbum:
       
  4108             {
       
  4109             cat = EMPXAlbum;
       
  4110             break;
       
  4111             }
       
  4112         case EBrowsePlaylist:
       
  4113             {
       
  4114             cat = EMPXPlaylist;
       
  4115             break;
       
  4116             }
       
  4117         case EBrowseGenre:
       
  4118             {
       
  4119             cat = EMPXGenre;
       
  4120             break;
       
  4121             }
       
  4122         case EBrowseComposer:
       
  4123             {
       
  4124             cat = EMPXComposer;
       
  4125             break;
       
  4126             }
       
  4127 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  4128         case EBrowsePodcasts:
       
  4129             {
       
  4130             cat = EMPXPodcast;
       
  4131             break;
       
  4132             }
       
  4133 #endif
       
  4134         default:
       
  4135             {
       
  4136             // do nothing
       
  4137             break;
       
  4138             }
       
  4139         }
       
  4140 
       
  4141     return cat;
       
  4142     }
       
  4143 
       
  4144 // ----------------------------------------------------------------------------
       
  4145 // Maps a given category ID to a browse type.
       
  4146 // ----------------------------------------------------------------------------
       
  4147 //
       
  4148 TMCBrowseType CMPXDbPlugin::BrowseTypeForCategory(
       
  4149     TMPXGeneralCategory aCategory)
       
  4150     {
       
  4151     MPX_FUNC("CMPXDbPlugin::BrowseTypeForCategory");
       
  4152 
       
  4153     TMCBrowseType browseType(EBrowseComposer);
       
  4154 
       
  4155     switch (aCategory)
       
  4156         {
       
  4157         case EMPXSong:
       
  4158             {
       
  4159             browseType = EBrowseAll;
       
  4160             break;
       
  4161             }
       
  4162         case EMPXArtist:
       
  4163             {
       
  4164             browseType = EBrowseArtist;
       
  4165             break;
       
  4166             }
       
  4167         case EMPXAlbum:
       
  4168             {
       
  4169             browseType = EBrowseAlbum;
       
  4170             break;
       
  4171             }
       
  4172         case EMPXPlaylist:
       
  4173             {
       
  4174             browseType = EBrowsePlaylist;
       
  4175             break;
       
  4176             }
       
  4177         case EMPXGenre:
       
  4178             {
       
  4179             browseType = EBrowseGenre;
       
  4180             break;
       
  4181             }
       
  4182         default:
       
  4183             {
       
  4184             // do nothing
       
  4185             break;
       
  4186             }
       
  4187         }
       
  4188 
       
  4189     return browseType;
       
  4190     }
       
  4191 
       
  4192 // ----------------------------------------------------------------------------
       
  4193 // Sets the type, category and title attributes in the specified media instance
       
  4194 // ----------------------------------------------------------------------------
       
  4195 //
       
  4196 void CMPXDbPlugin::SetMediaGeneralAttributesL(
       
  4197     CMPXMedia& aMedia,
       
  4198     TMPXGeneralType aType,
       
  4199     TMPXGeneralCategory aCategory,
       
  4200     const TDesC& aTitle)
       
  4201     {
       
  4202     aMedia.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, aType);
       
  4203     aMedia.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, aCategory);
       
  4204     aMedia.SetTextValueL(KMPXMediaGeneralTitle, aTitle);
       
  4205     }
       
  4206 
       
  4207 // ----------------------------------------------------------------------------
       
  4208 // Sets the type, category and title attributes in the specified media instance
       
  4209 // ----------------------------------------------------------------------------
       
  4210 //
       
  4211 void CMPXDbPlugin::SetMediaGeneralAttributesL(
       
  4212     CMPXMedia& aMedia,
       
  4213     TMPXGeneralType aType,
       
  4214     TMPXGeneralCategory aCategory,
       
  4215     TInt aId)
       
  4216     {
       
  4217     MPX_FUNC("CMPXDbPlugin::SetMediaGeneralAttributesL");
       
  4218 
       
  4219     HBufC* title = iDbHandler->GetNameMatchingIdL(aId);
       
  4220     CleanupStack::PushL(title);
       
  4221     SetMediaGeneralAttributesL(aMedia, aType, aCategory, *title);
       
  4222     CleanupStack::PopAndDestroy(title);
       
  4223     }
       
  4224 
       
  4225 // ----------------------------------------------------------------------------
       
  4226 // Set the attribute list according to current path
       
  4227 // ----------------------------------------------------------------------------
       
  4228 //
       
  4229 void CMPXDbPlugin::SetAttributesL(
       
  4230     const CMPXCollectionPath& aPath,
       
  4231     RArray<TMPXAttribute>& aAttrs,
       
  4232     RArray<TInt>& aSupportedIds )
       
  4233     {
       
  4234     aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral,
       
  4235         EMPXMediaGeneralId | EMPXMediaGeneralType | EMPXMediaGeneralCategory |
       
  4236         EMPXMediaGeneralTitle | EMPXMediaGeneralFlags) );
       
  4237 
       
  4238     aSupportedIds.AppendL(KMPXMediaIdContainer);
       
  4239     aSupportedIds.AppendL(KMPXMediaIdGeneral);
       
  4240 
       
  4241     TInt levels(aPath.Levels());
       
  4242     if ( 2 == levels )
       
  4243         {
       
  4244         // check the browse type
       
  4245         switch ( aPath.Id(1).iId2 )
       
  4246             {
       
  4247             case EBrowseAll:
       
  4248                 {
       
  4249                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4250                     EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );
       
  4251                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4252                 break;
       
  4253                 }
       
  4254             case EBrowseArtist:
       
  4255                 {
       
  4256                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4257                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4258                                     EMPXMediaMusicAlbumArtFileName ) );
       
  4259                 break;
       
  4260                 }
       
  4261             case EBrowseAlbum:
       
  4262                 {
       
  4263                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4264                     EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );
       
  4265                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4266                 break;
       
  4267                 }
       
  4268             case EBrowsePlaylist:
       
  4269                 {
       
  4270                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral,
       
  4271                     EMPXMediaGeneralCount | EMPXMediaGeneralDuration ) );
       
  4272                 break;
       
  4273                 }
       
  4274             case EBrowseGenre:
       
  4275                 {
       
  4276                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4277                 break;
       
  4278                 }
       
  4279             case EBrowseComposer:
       
  4280                 {
       
  4281                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4282                 break;
       
  4283                 }
       
  4284             default:
       
  4285                 {
       
  4286                 User::Leave(KErrArgument);
       
  4287                 }
       
  4288             }
       
  4289         }
       
  4290     else if ( 3 == levels )
       
  4291         {
       
  4292         // check the browse type
       
  4293         switch ( aPath.Id(1).iId2 )
       
  4294             {
       
  4295             case EBrowseArtist:
       
  4296                 {
       
  4297                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4298                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic, EMPXMediaMusicAlbumArtFileName ) );
       
  4299                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4300                 break;
       
  4301                 }
       
  4302             case EBrowseAlbum:
       
  4303             case EBrowsePlaylist:
       
  4304             case EBrowseGenre:
       
  4305             case EBrowseComposer:
       
  4306                 {
       
  4307                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4308 //                    EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );                    
       
  4309                 //added ganes
       
  4310                     EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName | EMPXMediaMusicAlbum) );                    
       
  4311                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4312                 break;
       
  4313                 }
       
  4314             }
       
  4315         }
       
  4316     else if ( (4 == levels) && (aPath.Id(1).iId2 == EBrowseArtist) )
       
  4317         {
       
  4318         aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4319             EMPXMediaMusicArtist | EMPXMediaMusicAlbum | EMPXMediaMusicAlbumArtFileName ) );
       
  4320         aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4321         }
       
  4322     }
       
  4323 
       
  4324 #ifdef _DEBUG
       
  4325 // ----------------------------------------------------------------------------
       
  4326 // Print change events
       
  4327 // ----------------------------------------------------------------------------
       
  4328 //
       
  4329 void CMPXDbPlugin::PrintMessagesL(
       
  4330     const CMPXMessage& aMessage)
       
  4331     {
       
  4332     MPX_FUNC("CMPXDbPlugin::PrintMessages");
       
  4333 
       
  4334     if (aMessage.IsSupported(KMPXMessageArrayContents))
       
  4335         {
       
  4336         const CMPXMessageArray* messageArray =
       
  4337             aMessage.Value<CMPXMessageArray>(KMPXMessageArrayContents);
       
  4338         if( !messageArray )
       
  4339             {
       
  4340             User::Leave( KErrNoMemory );
       
  4341             }
       
  4342 
       
  4343         TInt count(messageArray->Count());
       
  4344         MPX_DEBUG2("%d messages:", count);
       
  4345 
       
  4346         for (TInt i = 0; i < count; ++i)
       
  4347             {
       
  4348             PrintMessage(*((*messageArray)[i]));
       
  4349             }
       
  4350         }
       
  4351     else
       
  4352         {
       
  4353         PrintMessage(aMessage);
       
  4354         }
       
  4355     }
       
  4356 
       
  4357 // ----------------------------------------------------------------------------
       
  4358 // Print one change event
       
  4359 // ----------------------------------------------------------------------------
       
  4360 //
       
  4361 void CMPXDbPlugin::PrintMessage(
       
  4362     const CMPXMessage& aMessage)
       
  4363     {
       
  4364     MPX_FUNC("CMPXDbPlugin::PrintMessage");
       
  4365 
       
  4366     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  4367         {
       
  4368         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageGeneralId);
       
  4369         MPX_DEBUG3("    message id[0x%x, 0x%x]", id.iId1, id.iId2);
       
  4370         }
       
  4371 
       
  4372     if (aMessage.IsSupported(KMPXMessageCollectionId))
       
  4373         {
       
  4374         TUid uid = aMessage.ValueTObjectL<TUid>(KMPXMessageCollectionId);
       
  4375         MPX_DEBUG2("    uid [0x%x]", uid.iUid);
       
  4376         }
       
  4377 
       
  4378     if (aMessage.IsSupported(KMPXMessageChangeEventType))
       
  4379         {
       
  4380         MPX_DEBUG2("    change event type [%d]",
       
  4381             aMessage.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType));
       
  4382         }
       
  4383 
       
  4384     if (aMessage.IsSupported(KMPXMessageMediaGeneralCategory))
       
  4385         {
       
  4386         MPX_DEBUG2("    category [%d]",
       
  4387             aMessage.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  4388         }
       
  4389 
       
  4390     if (aMessage.IsSupported(KMPXMessageMediaGeneralId))
       
  4391         {
       
  4392         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId);
       
  4393         MPX_DEBUG3("    media id[0x%x, 0x%x]", id.iId1, id.iId2);
       
  4394         }
       
  4395 
       
  4396     if (aMessage.IsSupported(KMPXMessageMediaDeprecatedId))
       
  4397         {
       
  4398         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaDeprecatedId);
       
  4399         MPX_DEBUG3("    deprecated id [0x%x, 0x%x]", id.iId1, id.iId2);
       
  4400         }
       
  4401     }
       
  4402 
       
  4403 #endif// _DEBUG
       
  4404 
       
  4405 // End of file