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