mmappcomponents/collectionhelper/src/mpxdeletehelper.cpp
changeset 0 a2952bb97e68
child 17 6f9f6e99a23e
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  MPX delete helper
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <f32file.h>
       
    21 #include <mpxmedia.h>
       
    22 #include <mpxmediageneraldefs.h>
       
    23 #include <mpxcommandgeneraldefs.h>
       
    24 #include <mpxcollectioncommanddefs.h>
       
    25 #include <mpxcollectionpath.h>
       
    26 #include <mpxcollectionplaylist.h>
       
    27 #include <mpxplaybackutility.h>
       
    28 #include <mpxcollectionutility.h>
       
    29 #include <mpxharvesterutility.h>
       
    30 #include <mpxplaybackutility.h>
       
    31 #include <mpxlog.h>
       
    32 #include <mpxmessagegeneraldefs.h>
       
    33 #include <mpxcollectionmessage.h>
       
    34 #include <mpxcollectionmessagedefs.h>
       
    35 #include <mpxsubscription.h>
       
    36 #include <mpxharvestercommon.h>
       
    37 
       
    38 #ifdef RD_MPX_TNM_INTEGRATION
       
    39 #include <hash.h>
       
    40 #include <eikenv.h>
       
    41 #include <f32file.h>
       
    42 #include <sysutil.h>
       
    43 #include <thumbnailmanager.h>
       
    44 #endif //RD_MPX_TNM_INTEGRATION
       
    45 // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode
       
    46 #include <UsbWatcherInternalPSKeys.h>
       
    47 #include <usbpersonalityids.h>
       
    48 #include <mpxcollectionuihelper.h>
       
    49 #include "mpxcollectionuihelperobserver.h"
       
    50 #include "mpxcollectionhelpercommon.h"
       
    51 
       
    52 #include "mpxdeletehelper.h"
       
    53 
       
    54 // Constants
       
    55 const TInt KSQLErrGeneral = -311; // SQL General error. Don't want to include sql header here
       
    56 const TInt KDeleteUpdateCount = 50;  // Max # of times to update delete status during a group delete. Value (1-100)
       
    57 #ifdef RD_MPX_TNM_INTEGRATION
       
    58 _LIT( KImageFileType, "image/jpeg" );
       
    59 #endif //RD_MPX_TNM_INTEGRATION
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // Constructor
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CMPXDeleteHelper::CMPXDeleteHelper(MMPXCollectionUtility& aCollectionUtility,
       
    66                                    MMPXHarvesterUtility& aHarvesterUtility,
       
    67                                    MMPXCHelperObserver& aObserver)
       
    68 :   CActive(CActive::EPriorityLow),
       
    69     iCollectionUtil(aCollectionUtility),
       
    70     iHarvester(aHarvesterUtility),
       
    71     iObserver(aObserver),
       
    72     iMoreToDo(ETrue),
       
    73     iHadInUse(EFalse),
       
    74     iState(EMPXIdle),
       
    75     iDeletePercent(0),
       
    76     iDeleteIncFactor(1),
       
    77     iDeleteCount(0),
       
    78     iUsbManConnected( EFalse )
       
    79     {
       
    80     CActiveScheduler::Add(this);
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // 2nd Phase Constructor
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 void CMPXDeleteHelper::ConstructL()
       
    88     {
       
    89     iFiles = new(ELeave)CDesCArrayFlat(4);
       
    90     iMessageArray = CMPXMessageArray::NewL();
       
    91     // Connect to usbman
       
    92     ConnectUsbMan();
       
    93 
       
    94 #ifdef __USE_MESSAGE_SUBSCRIPTION
       
    95     // Subscribe to only a few messages from collection utility
       
    96     CMPXSubscription* subscription( CMPXSubscription::NewL() );
       
    97     CleanupStack::PushL( subscription );
       
    98     CMPXSubscriptionItem* subItem1( CMPXSubscriptionItem::NewL() );
       
    99     CleanupStack::PushL( subItem1 );
       
   100     subItem1->SetTObjectValueL( KMPXMessageGeneralId, KMPXMessageGeneral );
       
   101     subItem1->SetTObjectValueL( KMPXMessageGeneralEvent, TMPXCollectionMessage::EBroadcastEvent );
       
   102     subItem1->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgFormatStart );
       
   103     subscription->AddItemL( *subItem1 );
       
   104     CMPXSubscriptionItem* subItem2( CMPXSubscriptionItem::CopyL( *subItem1 ));
       
   105     CleanupStack::PushL( subItem2 );
       
   106     subItem2->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgDiskRemoved );
       
   107     subscription->AddItemL( *subItem2 );
       
   108     CMPXSubscriptionItem* subItem3( CMPXSubscriptionItem::CopyL( *subItem1 ));
       
   109     CleanupStack::PushL( subItem3 );
       
   110     subItem3->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgUSBMassStorageStart );
       
   111     subscription->AddItemL( *subItem3 );
       
   112     CMPXSubscriptionItem* subItem4( CMPXSubscriptionItem::CopyL( *subItem1 ));
       
   113     CleanupStack::PushL( subItem4 );
       
   114     subItem4->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgUSBMTPStart );
       
   115     subscription->AddItemL( *subItem4 );
       
   116     CMPXSubscriptionItem* subItem5( CMPXSubscriptionItem::CopyL( *subItem1 ));
       
   117     CleanupStack::PushL( subItem5 );
       
   118     iCollectionUtil.Collection().AddSubscriptionL( *subscription );
       
   119     CleanupStack::PopAndDestroy( subItem5 );
       
   120     CleanupStack::PopAndDestroy( subItem4 );
       
   121     CleanupStack::PopAndDestroy( subItem3 );
       
   122     CleanupStack::PopAndDestroy( subItem2 );
       
   123     CleanupStack::PopAndDestroy( subItem1 );
       
   124     CleanupStack::PopAndDestroy( subscription );
       
   125 #endif
       
   126 
       
   127 #ifdef RD_MPX_TNM_INTEGRATION
       
   128 
       
   129     // Create Thumbnail Manager instance. This object is the observer.
       
   130     iTNManager = CThumbnailManager::NewL( *this );
       
   131 #endif //RD_MPX_TNM_INTEGRATION
       
   132     }
       
   133 
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // Two-Phased Constructor
       
   137 // ---------------------------------------------------------------------------
       
   138 //
       
   139 CMPXDeleteHelper* CMPXDeleteHelper::NewL(MMPXCollectionUtility& aCollectionUtility,
       
   140                                          MMPXHarvesterUtility& aHarvesterUtility,
       
   141                                          MMPXCHelperObserver& aObserver)
       
   142     {
       
   143     CMPXDeleteHelper* self =
       
   144         new(ELeave)CMPXDeleteHelper( aCollectionUtility,
       
   145                                      aHarvesterUtility,
       
   146                                      aObserver );
       
   147     CleanupStack::PushL( self );
       
   148     self->ConstructL();
       
   149     CleanupStack::Pop( self );
       
   150     return self;
       
   151     }
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // Destructor
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 CMPXDeleteHelper::~CMPXDeleteHelper()
       
   158     {
       
   159     if( iPbUtil )
       
   160         {
       
   161         iPbUtil->Close();
       
   162         }
       
   163     delete iDeletePath;
       
   164     delete iFiles;
       
   165     delete iMessageArray;
       
   166 #ifdef RD_MPX_TNM_INTEGRATION
       
   167 
       
   168     delete iTNManager;
       
   169 #endif //RD_MPX_TNM_INTEGRATION
       
   170     if ( iUsbManConnected )
       
   171         {
       
   172         iUsbMan.Close();
       
   173         }
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 // Start the delete operation
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 void CMPXDeleteHelper::DeleteL( CMPXCollectionPath& aPath )
       
   181     {
       
   182     MPX_DEBUG1("CMPXDeleteHelper::DeleteL()");
       
   183     MPX_DEBUG_PATH(aPath);
       
   184     TInt deletePercentFactor = 100 / KDeleteUpdateCount;
       
   185 
       
   186     if( iPbUtil )
       
   187         {
       
   188         iPbUtil->Close();
       
   189         iPbUtil = NULL;
       
   190         }
       
   191     iPbUtil = MMPXPlaybackUtility::UtilityL();
       
   192 
       
   193     iDeletePath = CMPXCollectionPath::NewL( aPath );
       
   194     iState = EMPXInitDelete;
       
   195     iDeleteCount = 0;
       
   196     iMessageArray->Reset();
       
   197     RArray<TMPXItemId> selections;
       
   198     CleanupClosePushL(selections);
       
   199     iDeletePath->SelectionL(selections);
       
   200     iItemsCount = selections.Count();
       
   201     CleanupStack::PopAndDestroy(&selections);
       
   202     iRetrievedItemsCount = 0;
       
   203 
       
   204     // Calculate percent increment factor used during a delete.
       
   205     if ( (iItemsCount > 0) && (iItemsCount < KDeleteUpdateCount) )
       
   206         {
       
   207         TReal factor = (KDeleteUpdateCount/iItemsCount) * deletePercentFactor;
       
   208         iDeleteIncFactor = factor;
       
   209         }
       
   210     else
       
   211         {
       
   212         iDeleteIncFactor = deletePercentFactor;
       
   213         }
       
   214 
       
   215     TRequestStatus* status = &iStatus;
       
   216     *status = KRequestPending;
       
   217     User::RequestComplete(status, KErrNone);
       
   218 
       
   219     SetActive();
       
   220     }
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // From MMPXCollectionObserver
       
   224 // to-do: this should be changed to HandleCollectionMessage
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 void CMPXDeleteHelper::HandleCollectionMessage(CMPXMessage* aMessage, TInt /*aErr*/)
       
   228     {
       
   229     if( aMessage &&
       
   230         aMessage->IsSupported(KMPXMessageGeneralEvent) &&
       
   231         aMessage->IsSupported(KMPXMessageGeneralType) )
       
   232         {
       
   233         TInt event( aMessage->ValueTObjectL<TInt>( KMPXMessageGeneralEvent ) );
       
   234         TInt op( aMessage->ValueTObjectL<TInt>( KMPXMessageGeneralType ) );
       
   235 
       
   236         MPX_DEBUG3( "CMPXDeleteHelper::HandleCollectionMessageL event = %d, type = %d",
       
   237                     event, op );
       
   238 
       
   239         if( event == TMPXCollectionMessage::EBroadcastEvent )
       
   240             {
       
   241             if( op == EMcMsgFormatStart ||
       
   242                 op == EMcMsgDiskRemoved ||
       
   243                 op == EMcMsgUSBMassStorageStart ||
       
   244                 op == EMcMsgUSBMTPStart )
       
   245                 {
       
   246                 iCancelled = ETrue;
       
   247                 Cancel();
       
   248                 }
       
   249             }
       
   250 
       
   251         }
       
   252     }
       
   253 
       
   254 // ---------------------------------------------------------------------------
       
   255 // Start the delete operation
       
   256 // ---------------------------------------------------------------------------
       
   257 //
       
   258 void CMPXDeleteHelper::DoTaskStep()
       
   259     {
       
   260     MPX_DEBUG1("CMPXDeleteHelper::DoTaskStep()");
       
   261 
       
   262     TRequestStatus* status = &iStatus;
       
   263     *status = KRequestPending;
       
   264 
       
   265     TRAPD( error, DoTaskStepL() );
       
   266 
       
   267     User::RequestComplete( status, error );
       
   268     }
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // Start the delete operation
       
   272 // to-do: delete file first before removing it from the collection
       
   273 // ---------------------------------------------------------------------------
       
   274 //
       
   275 void CMPXDeleteHelper::DoTaskStepL()
       
   276     {
       
   277     MPX_DEBUG1("CMPXDeleteHelper::DoTaskStepL()");
       
   278 
       
   279     switch(iState)
       
   280         {
       
   281         case EMPXInitDelete:
       
   282             {
       
   283             StartDeleteL();  
       
   284             iState = EMPXPreparation;
       
   285             break;
       
   286             }
       
   287         case EMPXPreparation:
       
   288             {
       
   289             RetrieveFileListL();
       
   290             iState = EMPXDelete;
       
   291             break;
       
   292             }
       
   293 
       
   294         case EMPXDelete:
       
   295             {
       
   296             DeleteL();
       
   297             break;
       
   298             }
       
   299 
       
   300         default:
       
   301             break;
       
   302         }
       
   303     }
       
   304 
       
   305 // ----------------------------------------------------------------------------
       
   306 // Handles request completion event
       
   307 // ----------------------------------------------------------------------------
       
   308 //
       
   309 void CMPXDeleteHelper::RunL()
       
   310     {
       
   311     MPX_DEBUG3("CMPXDeleteHelper::RunL. [iMoreToDo %d] [iStatus %d]", iMoreToDo, iStatus.Int());
       
   312 
       
   313     // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode
       
   314     TUsbDeviceState deviceState = EUsbDeviceStateConfigured;
       
   315     if ( !iUsbManConnected )
       
   316         {
       
   317         ConnectUsbMan();
       
   318         }
       
   319     
       
   320     if ( iUsbManConnected )
       
   321         {
       
   322         if ( iUsbMan.GetDeviceState( deviceState ) != KErrNone )
       
   323             {
       
   324             deviceState = EUsbDeviceStateConfigured;
       
   325             }
       
   326         }
       
   327     
       
   328     if ( deviceState == EUsbDeviceStateAddress ||
       
   329          deviceState == EUsbDeviceStateConfigured )
       
   330         {
       
   331         TInt usbStatus;
       
   332         RProperty::Get(KPSUidUsbWatcher, KUsbWatcherSelectedPersonality, usbStatus);
       
   333         if ((usbStatus == KUsbPersonalityIdMTP) || (usbStatus == KUsbPersonalityIdPCSuiteMTP))
       
   334             {
       
   335             MPX_DEBUG1("USB is active, Stop Delete");
       
   336             CompleteDelete( KErrLocked );
       
   337             return;
       
   338             }
       
   339         }
       
   340     
       
   341     if (iMoreToDo && iStatus.Int() == KErrNone)
       
   342         {
       
   343         DoTaskStep();
       
   344         SetActive();
       
   345         }
       
   346     else
       
   347         {
       
   348         CompleteDelete(iStatus.Int());
       
   349         }
       
   350     }
       
   351 
       
   352 // ---------------------------------------------------------------------------
       
   353 // Cancel the delete operation
       
   354 // ---------------------------------------------------------------------------
       
   355 //
       
   356 void CMPXDeleteHelper::DoCancel()
       
   357     {
       
   358     MPX_DEBUG3("CMPXDeleteHelper::DoCancel iStatus %d, iState %d", iStatus.Int(), iState);
       
   359 
       
   360     CompleteDelete(iStatus.Int());
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // End state for a delete operation
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CMPXDeleteHelper::CompleteDelete( TInt aErr )
       
   368     {
       
   369     MPX_DEBUG2("CMPXDeleteHelper::CompleteDelete %d", aErr);
       
   370 
       
   371     TRAP_IGNORE( DoCompleteDeleteL( aErr ) );
       
   372     }
       
   373 
       
   374 // ---------------------------------------------------------------------------
       
   375 // End state for a delete operation
       
   376 // ---------------------------------------------------------------------------
       
   377 //
       
   378 void CMPXDeleteHelper::DoCompleteDeleteL( TInt aErr )
       
   379     {
       
   380     MPX_DEBUG3("CMPXDeleteHelper::CompleteDeleteL error %d cancelled %d", aErr, iCancelled);
       
   381     if( iState != EMPXIdle )
       
   382         {
       
   383         // Finally callback to observer and complete task queue event
       
   384         // to-do: change HandleOperationCompletedL to HandleOperationComplete
       
   385         TInt error = iHadInUse ? KErrInUse : aErr;
       
   386         // Error cases that need to be ignored when mmc card is removed
       
   387         if( error == KErrBadName ||
       
   388             error == KErrNotReady ||
       
   389             error == KErrAbort ||
       
   390             error == KSQLErrGeneral ||
       
   391             (iCancelled && error == KErrNotFound) )
       
   392             {
       
   393             error = KErrNone;
       
   394             }
       
   395 
       
   396         // Reset all states
       
   397         Reset();
       
   398 
       
   399         // Close Harvester database transaction
       
   400         TRAP_IGNORE(iHarvester.CloseTransactionL() );
       
   401         
       
   402         // Send a complete delete command to finish off the delete operation
       
   403         //
       
   404         CMPXCommand* cmd = CMPXCommand::NewL();
       
   405         CleanupStack::PushL( cmd );
       
   406         cmd->SetTObjectValueL(KMPXCommandGeneralId,KMPXCommandIdCollectionCompleteDelete);
       
   407         cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue);
       
   408         cmd->SetTObjectValueL(KMPXCommandCollectionDeleteCompactDb, ETrue);
       
   409         cmd->SetCObjectValueL(KMPXCommandCollectionDeleteMsgArray, iMessageArray);
       
   410         iCollectionUtil.Collection().CommandL(*cmd);
       
   411         CleanupStack::PopAndDestroy( cmd );
       
   412 
       
   413         TRAP_IGNORE(iObserver.HandleOperationCompleteL( EDeleteOp, error, NULL ) );
       
   414 
       
   415         // Message array ownership passed to engine
       
   416         delete iMessageArray;
       
   417         iMessageArray = NULL;
       
   418         iMessageArray = CMPXMessageArray::NewL();
       
   419 
       
   420         if( iPbUtil )
       
   421             {
       
   422             iPbUtil->Close();
       
   423             iPbUtil = NULL;
       
   424             }
       
   425         iCancelled = EFalse;
       
   426         }
       
   427     }
       
   428 
       
   429 // ---------------------------------------------------------------------------
       
   430 // Resets members to get ready for the next client request
       
   431 //
       
   432 // ---------------------------------------------------------------------------
       
   433 //
       
   434 void CMPXDeleteHelper::Reset()
       
   435     {
       
   436     MPX_DEBUG1("CMPXDeleteHelper::Reset");
       
   437     iMoreToDo = ETrue;
       
   438     iHadInUse = EFalse;
       
   439     iDeleteCount = 0;
       
   440     iDeletePercent = 0;
       
   441     iDeleteIncFactor = 1;
       
   442 
       
   443     iState = EMPXIdle;
       
   444 
       
   445     delete iDeletePath;
       
   446     iDeletePath = NULL;
       
   447 
       
   448     iFiles->Reset();
       
   449     }
       
   450 
       
   451 // ---------------------------------------------------------------------------
       
   452 // Perfom cleanup of all unused data before delete
       
   453 //
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 void CMPXDeleteHelper::StartDeleteL()
       
   457     {
       
   458     //
       
   459     // set up the command to send to the collection
       
   460     //
       
   461     CMPXCommand* command = CMPXCommand::NewL();
       
   462     CleanupStack::PushL(command);
       
   463     
       
   464     command->SetTObjectValueL<TMPXCommandId>(
       
   465         TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionPrepareDelete);
       
   466     command->SetTObjectValueL<TBool>(
       
   467         TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue);
       
   468     command->SetCObjectValueL(
       
   469         TMPXAttribute(KMPXCommandIdCollectionPrepareDelete, EMPXCommandCollectionRetrievePath), 
       
   470         iDeletePath);
       
   471     
       
   472     // send sync prepare delete URI command    
       
   473     iCollectionUtil.Collection().CommandL(*command);
       
   474     CleanupStack::PopAndDestroy(command);
       
   475 }
       
   476     
       
   477 //
       
   478 // Retrieve files associated with the path
       
   479 //
       
   480 // ---------------------------------------------------------------------------
       
   481 //
       
   482 void CMPXDeleteHelper::RetrieveFileListL()
       
   483     {
       
   484     //
       
   485     // set up the command to send to the collection
       
   486     //
       
   487     CMPXCommand* command = CMPXCommand::NewL();
       
   488     CleanupStack::PushL(command);
       
   489 
       
   490     command->SetTObjectValueL<TMPXCommandId>(
       
   491         TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionRetrieveUriForDeletion);
       
   492     command->SetTObjectValueL<TBool>(
       
   493         TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue);
       
   494     command->SetCObjectValueL(
       
   495         TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrievePath),
       
   496         iDeletePath);
       
   497 
       
   498     // send sync retrieve URI command
       
   499     iCollectionUtil.Collection().CommandL(*command);
       
   500 
       
   501     //
       
   502     // return command should contain error and URI array
       
   503     //
       
   504     if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveUriError)) ||
       
   505         !command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveMediaUriArray)))
       
   506         {
       
   507         User::Leave(KErrAbort);
       
   508         }
       
   509 
       
   510     //
       
   511     // abandon operation if an error occured removing a media from the collection
       
   512     //
       
   513     TInt error =
       
   514          command->ValueTObjectL<TInt>(
       
   515             TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveUriError));
       
   516     User::LeaveIfError(error);
       
   517 
       
   518     //
       
   519     // retrieve the list of files to be deleted
       
   520     //
       
   521     CDesCArray* files =
       
   522         command->ValueNoNewLCObjectL<CDesCArray>(
       
   523             TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveMediaUriArray));
       
   524     CleanupStack::PushL(files);
       
   525     ::CopyArrayL(*files, *iFiles);
       
   526     iRetrievedItemsCount +=files->MdcaCount();
       
   527     CleanupStack::PopAndDestroy(files);
       
   528     //
       
   529     // retrieve the updated path. If the original path ends at a particular artist,
       
   530     // album, genre, or composer, the path will have been expended to include the
       
   531     // songs under that category
       
   532     //
       
   533     delete iDeletePath;
       
   534     iDeletePath = NULL;
       
   535     iDeletePath =
       
   536         command->ValueCObjectL<CMPXCollectionPath>(
       
   537             TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrievePath));
       
   538 
       
   539     CleanupStack::PopAndDestroy(command);
       
   540     }
       
   541 
       
   542 // ---------------------------------------------------------------------------
       
   543 // Deletes the file from the file system then deletes it from the collection
       
   544 // ---------------------------------------------------------------------------
       
   545 //
       
   546 void CMPXDeleteHelper::DeleteL()
       
   547     {
       
   548     MPX_FUNC("CMPXDeleteHelper::DeleteL()");
       
   549     // Close the item that we are about to delete
       
   550     //
       
   551     RArray<TMPXItemId> selections;
       
   552     CleanupClosePushL(selections);
       
   553     iDeletePath->SelectionL(selections);
       
   554 
       
   555     TMPXItemId mediaId(0);
       
   556     if (selections.Count())
       
   557         {
       
   558         // If more than one item
       
   559         mediaId = selections[0];
       
   560         }
       
   561     else
       
   562         {
       
   563         mediaId = iDeletePath->Id(iDeletePath->Levels() - 1);
       
   564         }
       
   565 
       
   566     CleanupStack::PopAndDestroy(&selections);
       
   567 
       
   568     // Send the real id to playback engine for deletion
       
   569     iPbUtil->CommandL( EPbCmdCloseItem, mediaId );
       
   570 
       
   571     //
       
   572     // delete the media file from the file system and harvester's database first
       
   573     // before deleting it from the collection
       
   574     //
       
   575     if (DeleteFileL())
       
   576         {
       
   577         //
       
   578         // set up the command to send to the collection
       
   579         //
       
   580         CMPXCommand* command = CMPXMedia::NewL();
       
   581         CleanupStack::PushL(command);
       
   582 
       
   583         command->SetTObjectValueL<TMPXCommandId>(
       
   584             TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionRemove);
       
   585         command->SetTObjectValueL<TBool>(
       
   586             TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue);
       
   587         command->SetCObjectValueL(
       
   588             TMPXAttribute(KMPXCommandIdCollectionRemove,EMPXCommandCollectionRemovePath),
       
   589             iDeletePath);
       
   590         command->SetTObjectValueL<TInt>(
       
   591             TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveMediaCount), 1);
       
   592         command->SetTObjectValueL<TBool>(KMPXCommandCollectionRemoveSuppressMsgs,ETrue);
       
   593         command->SetCObjectValueL<CMPXMessageArray>(KMPXCommandCollectionChangeMsgs, iMessageArray);
       
   594         // send sync remove command
       
   595         MPX_PERF_START( MPX_PERF_DELETE_COLLECTION );
       
   596         iCollectionUtil.Collection().CommandL(*command);
       
   597 		MPX_PERF_END( MPX_PERF_DELETE_COLLECTION );
       
   598 
       
   599         //
       
   600         // return command should contain error, completed and media Id information
       
   601         //
       
   602         if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveError)) ||
       
   603             !command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveCompleted)))
       
   604             {
       
   605             User::Leave(KErrAbort);
       
   606             }
       
   607 
       
   608         //
       
   609         // abandon operation if an error occured removing a media from the collection
       
   610         //
       
   611         TInt error =
       
   612              command->ValueTObjectL<TInt>(
       
   613                 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveError));
       
   614         User::LeaveIfError(error);
       
   615 
       
   616         //
       
   617         // require to send async remove command again if command completed is EFalse
       
   618         //
       
   619         TBool completed =
       
   620              command->ValueTObjectL<TBool>(
       
   621                 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveCompleted));
       
   622         iMoreToDo = !completed;
       
   623 
       
   624         //
       
   625         // retrieve the updated path with the removed media deselected and use this
       
   626         // path for the next remove command
       
   627         //
       
   628         delete iDeletePath;
       
   629         iDeletePath = NULL;
       
   630         iDeletePath =
       
   631             command->ValueCObjectL<CMPXCollectionPath>(
       
   632                 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemovePath));
       
   633 
       
   634         CleanupStack::PopAndDestroy(command);
       
   635 
       
   636         if (iFiles->MdcaCount())
       
   637             {
       
   638             iFiles->Delete(0);
       
   639             }
       
   640 
       
   641         // Commit every 100 items deleted, message array ownership passed to engine
       
   642         //
       
   643         iDeleteCount++;
       
   644         if( iDeleteCount%KBatchCommit == 0 )
       
   645             {
       
   646 			// Commit Harvester DB
       
   647             TRAP_IGNORE( iHarvester.CloseTransactionL() );
       
   648 
       
   649             // Commit Collection DB
       
   650             CMPXCommand* cmd = CMPXCommand::NewL();
       
   651             CleanupStack::PushL( cmd );
       
   652             cmd->SetTObjectValueL(KMPXCommandGeneralId,KMPXCommandIdCollectionCompleteDelete);
       
   653             cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue);
       
   654             cmd->SetTObjectValueL(KMPXCommandCollectionDeleteCompactDb, ETrue);
       
   655             cmd->SetCObjectValueL(KMPXCommandCollectionDeleteMsgArray, iMessageArray);
       
   656             iCollectionUtil.Collection().CommandL(*cmd);
       
   657 
       
   658             delete iMessageArray;
       
   659             iMessageArray = NULL;
       
   660             iMessageArray = CMPXMessageArray::NewL();
       
   661             CleanupStack::PopAndDestroy( cmd );
       
   662             }
       
   663         }
       
   664     //
       
   665     // File not deleted from the file system, skip to the next
       
   666     //
       
   667     else
       
   668         {
       
   669         TArray<TInt> selectionIndices = iDeletePath->Selection();
       
   670         if (selectionIndices.Count())
       
   671             {
       
   672             iDeletePath->Deselect(selectionIndices[0]);
       
   673             }
       
   674 
       
   675         iFiles->Delete(0);
       
   676         }
       
   677     
       
   678     if (iFiles->MdcaCount() == 0)
       
   679         {
       
   680         if (iRetrievedItemsCount >= iItemsCount)
       
   681             {
       
   682             iMoreToDo = EFalse;    
       
   683             iRetrievedItemsCount = 0;
       
   684             }
       
   685         else
       
   686             {
       
   687             iState = EMPXPreparation;
       
   688             }
       
   689         }
       
   690     
       
   691     // Send delete status when necessary.
       
   692     TInt deleteThreshold = ((iDeletePercent+iDeleteIncFactor)*iItemsCount)/100;
       
   693     if ( deleteThreshold > iItemsCount )
       
   694         {
       
   695         deleteThreshold = iItemsCount;
       
   696         }
       
   697     if ( iDeleteCount >= deleteThreshold )
       
   698         {
       
   699         iDeletePercent += iDeleteIncFactor;
       
   700         if ( (iDeletePercent > 100) || (iDeleteCount == iItemsCount) )
       
   701             {
       
   702             iDeletePercent = 100;
       
   703             }
       
   704         CMPXMedia* media = CMPXMedia::NewL();
       
   705         CleanupStack::PushL( media );
       
   706         media->SetTObjectValueL( KMPXMediaGeneralCount, iDeletePercent );
       
   707         iObserver.HandleOperationCompleteL( EDeleteStatusOp, KErrNone, media );
       
   708         CleanupStack::Pop( media );
       
   709         }
       
   710     }
       
   711 
       
   712 // ---------------------------------------------------------------------------
       
   713 // Deletes the file from the file system and harvester's database
       
   714 // ---------------------------------------------------------------------------
       
   715 //
       
   716 TBool CMPXDeleteHelper::DeleteFileL()
       
   717     {
       
   718     TBool deleted(ETrue);
       
   719 
       
   720     if (iFiles->MdcaCount() > 0)
       
   721         {
       
   722         TPtrC uri = iFiles->MdcaPoint(0);
       
   723 
       
   724         if( uri.Length() > 0 )
       
   725             {
       
   726             // For playlist files, it's possible that we are deleting the file which
       
   727             // is not where the playlist is originated from. e.g. Playlist has been
       
   728             // renamed to Playlist(01) in the collection, after deleting Playlist(01)
       
   729             // from the collection, we are now attempting to delete Playlist(01).m3u
       
   730             // which is not the originating file. This is a known risk.
       
   731             CDesCArrayFlat* files = new (ELeave)CDesCArrayFlat(1);
       
   732             CleanupStack::PushL(files);
       
   733             files->AppendL(uri);
       
   734 
       
   735 			MPX_PERF_START( MPX_PERF_DELHELPER_HARVESTER_DELETE );
       
   736             TRAPD(err, iHarvester.DeleteFilesL(*files, EFalse)); // to-do: create a sync DeleteFileL in harvester
       
   737 			MPX_PERF_END( MPX_PERF_DELHELPER_HARVESTER_DELETE );
       
   738 
       
   739             // if the file cannot be found or is currently in use, skip to the next
       
   740             // media removal, but inform the client at the end that one of the files
       
   741             // is in use should that be the case
       
   742             if (err == KErrInUse)
       
   743                 {
       
   744                 iHadInUse = ETrue;
       
   745                 deleted = EFalse;
       
   746                 }
       
   747             else if ( err == KErrNotFound ||
       
   748                       err == KErrPathNotFound )
       
   749                 {
       
   750                 // Cleanup harvester for broken links
       
   751                 // Have to trap ignore because .vir virtual playlists
       
   752                 // do not exist and we do not know the file is a playlist
       
   753                 // Since it is already KErrNotFound or KErrPathNotFound,
       
   754                 //
       
   755                 TRAP_IGNORE(iHarvester.RemoveFilesL(*files));
       
   756                 }
       
   757             else
       
   758                 {
       
   759                 User::LeaveIfError(err);
       
   760                 }
       
   761 
       
   762             CleanupStack::PopAndDestroy(files);  //lint !e961
       
   763 #ifdef RD_MPX_TNM_INTEGRATION
       
   764             const TDesC& file = iFiles->MdcaPoint(0);
       
   765             // remove from thumbnail manager
       
   766             CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(
       
   767                     file, KImageFileType );
       
   768             iTNManager->DeleteThumbnails( *source );
       
   769             CleanupStack::PopAndDestroy( source );
       
   770             // remove from local drive
       
   771 #endif //RD_MPX_TNM_INTEGRATION
       
   772             }
       
   773         }
       
   774     return deleted;
       
   775     }
       
   776 
       
   777 // ---------------------------------------------------------------------------
       
   778 // Stop deleting
       
   779 // ---------------------------------------------------------------------------
       
   780 //
       
   781 void CMPXDeleteHelper::Stop()
       
   782     {
       
   783     if ( iState != EMPXIdle )
       
   784         {
       
   785         iMoreToDo = EFalse;
       
   786         }
       
   787     }
       
   788 
       
   789 // ---------------------------------------------------------------------------
       
   790 // Callback but not used here
       
   791 // ---------------------------------------------------------------------------
       
   792 void CMPXDeleteHelper::ThumbnailPreviewReady( 
       
   793         MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ )
       
   794     {
       
   795     }
       
   796         
       
   797 
       
   798 // ---------------------------------------------------------------------------
       
   799 // Callback but not used here
       
   800 // ---------------------------------------------------------------------------
       
   801 void CMPXDeleteHelper::ThumbnailReady( TInt /*aError*/, 
       
   802         MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ )
       
   803     {
       
   804     }
       
   805     
       
   806 // ---------------------------------------------------------------------------
       
   807 // CMPXDeleteHelper::ConnectUsbMan
       
   808 // ---------------------------------------------------------------------------
       
   809 void CMPXDeleteHelper::ConnectUsbMan()
       
   810     {
       
   811     MPX_FUNC("CMPXDeleteHelper::ConnectUsbMan()");
       
   812     if ( iUsbMan.Connect() == KErrNone )
       
   813         {
       
   814         iUsbManConnected = ETrue;
       
   815         }
       
   816     }
       
   817 
       
   818 // END OF FILE