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