videocollection/mpxmyvideoscollection/src/vcxmyvideosasyncfileoperations.cpp
changeset 0 96612d01cf9f
child 11 5294c000a26d
child 15 cf5481c2bc0b
child 34 bbb98528c666
equal deleted inserted replaced
-1:000000000000 0:96612d01cf9f
       
     1 /*
       
     2 * Copyright (c) 2008 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 the License "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 for MPX My Videos Collection Move, Copy and Delete operations.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32cmn.h>
       
    22 #include <s32mem.h>
       
    23 #include <mpxlog.h>
       
    24 #include <mpxmediacontainerdefs.h>
       
    25 #include <mpxmediageneraldefs.h>
       
    26 #include <mpxcollectionpluginobserver.h>
       
    27 #include <mpxmessagegeneraldefs.h>
       
    28 #include <mpxcommandgeneraldefs.h>
       
    29 #include <mpxcollectioncommanddefs.h>
       
    30 #include <mpxmessagecontainerdefs.h>
       
    31 #include <vcxmyvideosuids.h>
       
    32 #include <drmutility.h>
       
    33 #include <bautils.h>
       
    34 #include "vcxmyvideoscollectionplugin.h"
       
    35 #include "vcxmyvideoscollection.hrh"
       
    36 #include "vcxmyvideoscollectionutil.h"
       
    37 #include "vcxmyvideosdownloadutil.h"
       
    38 #include "vcxmyvideosvideocache.h"
       
    39 #include "vcxmyvideoscategories.h"
       
    40 #include "vcxmyvideosmessagelist.h"
       
    41 #include "vcxmyvideosasyncfileoperations.h"
       
    42 
       
    43 // ============================ MEMBER FUNCTIONS ==============================
       
    44 
       
    45 // ----------------------------------------------------------------------------
       
    46 // Two-phased constructor.
       
    47 // ----------------------------------------------------------------------------
       
    48 //
       
    49 CVcxMyVideosAsyncFileOperations* CVcxMyVideosAsyncFileOperations::NewL(
       
    50     CVcxMyVideosCollectionPlugin& aCollection )
       
    51     {
       
    52     MPX_FUNC("CVcxMyVideosAsyncFileOperations::NewL");
       
    53 
       
    54     CVcxMyVideosAsyncFileOperations* self = new (ELeave) CVcxMyVideosAsyncFileOperations(
       
    55             aCollection );
       
    56     CleanupStack::PushL(self);
       
    57     self->ConstructL();
       
    58     CleanupStack::Pop(self);
       
    59     return self;
       
    60     }
       
    61 
       
    62 // ----------------------------------------------------------------------------
       
    63 // Destructor.
       
    64 // ----------------------------------------------------------------------------
       
    65 //
       
    66 CVcxMyVideosAsyncFileOperations::~CVcxMyVideosAsyncFileOperations()
       
    67     {
       
    68     MPX_FUNC("CVcxMyVideosAsyncFileOperations::~CVcxMyVideosAsyncFileOperations");
       
    69         
       
    70     iOperationIdArray.Close();
       
    71     iOperationResult.Close();
       
    72     }
       
    73 
       
    74 // ----------------------------------------------------------------------------
       
    75 // Constructor.
       
    76 // ----------------------------------------------------------------------------
       
    77 //
       
    78 CVcxMyVideosAsyncFileOperations::CVcxMyVideosAsyncFileOperations( CVcxMyVideosCollectionPlugin& aCollection )
       
    79 : iCollection( aCollection )
       
    80     {
       
    81     MPX_FUNC("CVcxMyVideosAsyncFileOperations::CVcxMyVideosAsyncFileOperations");
       
    82     }
       
    83 
       
    84 // ----------------------------------------------------------------------------
       
    85 // Symbian 2nd phase constructor can leave.
       
    86 // ----------------------------------------------------------------------------
       
    87 //
       
    88 void CVcxMyVideosAsyncFileOperations::ConstructL ()
       
    89     {
       
    90     MPX_FUNC("CVcxMyVideosAsyncFileOperations::ConstructL");
       
    91     }
       
    92     
       
    93 // ----------------------------------------------------------------------------
       
    94 // CVcxMyVideosCollectionPlugin::DeleteVideoL
       
    95 // ----------------------------------------------------------------------------
       
    96 //
       
    97 void CVcxMyVideosAsyncFileOperations::DeleteVideoL( TUint32 aMdsId, TBool aForce )
       
    98     {
       
    99     MPX_FUNC("CVcxMyVideosAsyncFileOperations::DeleteVideoL");
       
   100             
       
   101     TInt pos;
       
   102     CMPXMedia* videoInCache = iCollection.iCache->FindVideoByMdsIdL( aMdsId, pos );
       
   103                     
       
   104     if ( !videoInCache )
       
   105         {
       
   106         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: delete failed, MPX item not found from cache.");
       
   107         User::Leave( KErrNotFound );
       
   108         }
       
   109     
       
   110     TUint32 downloadId = TVcxMyVideosCollectionUtil::DownloadIdL( *videoInCache );            
       
   111     if ( downloadId )
       
   112         {
       
   113         TVcxMyVideosDownloadState dlState =
       
   114                 TVcxMyVideosCollectionUtil::DownloadStateL( *videoInCache );
       
   115                         
       
   116         if ( aForce )
       
   117             {
       
   118             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: aForce is ETrue, the video will be deleted even if download is ongoing");
       
   119             }
       
   120         else if ( dlState != EVcxMyVideosDlStateNone )
       
   121             {
       
   122             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: delete failed since there is download going on.");
       
   123             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: use download cancel instead.");
       
   124             User::Leave( KErrArgument );
       
   125             }
       
   126         else
       
   127             {
       
   128             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: download id was != 0 but download state was EVcxMyVideosDlStateNone");
       
   129             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: -> we delete the video, it is prob gone from Download Manager already.");
       
   130             }        
       
   131         }
       
   132             
       
   133     if ( !videoInCache->IsSupported( KMPXMediaGeneralUri ) )
       
   134         {
       
   135         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations::DeleteVideoL() KMPXMediaGeneralUri attribute missing -> leaving");
       
   136         User::Leave( KErrArgument );
       
   137         }
       
   138     
       
   139     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: trying to delete: %S",
       
   140             &videoInCache->ValueText( KMPXMediaGeneralUri ));
       
   141     TInt err = iCollection.iFs.Delete( videoInCache->ValueText( KMPXMediaGeneralUri ) );
       
   142         
       
   143     if ( err != KErrNone )
       
   144         {
       
   145         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: file delete failed: %d", err );
       
   146 
       
   147         if ( err == KErrNotFound || err == KErrPathNotFound )
       
   148             {
       
   149             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: file was not found, trying to remove mds object anyways");
       
   150             TInt result = iCollection.iMyVideosMdsDb->RemoveVideo( aMdsId );
       
   151             if ( result == KErrNone )
       
   152                 {
       
   153                 MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d removed from mds", aMdsId); 
       
   154                 //mds events will clean cache
       
   155                 }
       
   156             else
       
   157                 {
       
   158                 if ( result == KErrNotFound )
       
   159                     {
       
   160                     // file is gone, and mds item is gone -> try to delete from cache
       
   161                     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d not found from MDS, trying to delete from cache", aMdsId );
       
   162                     TInt result = iCollection.iCache->RemoveL( aMdsId );
       
   163                     if ( result == KErrNone )
       
   164                         {
       
   165                         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d deleted from cache, generating event", aMdsId );
       
   166                         iCollection.iMessageList->AddEventL( TMPXItemId( aMdsId, 0),
       
   167                                 EMPXItemDeleted, EVcxMyVideosListNoInfo );
       
   168                         iCollection.iMessageList->SendL();
       
   169                         } 
       
   170                     }
       
   171                 else
       
   172                     {
       
   173                     //file is gone, mds item and cache are still present, couldnt remove them
       
   174                     MPX_DEBUG3("CVcxMyVideosAsyncFileOperations:: failed to remove %d from mds (%d)", aMdsId, result);
       
   175                     User::Leave( result );
       
   176                     }
       
   177                 }
       
   178             }            
       
   179         else
       
   180             {
       
   181             // file delete failed and file still exists
       
   182             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: leaving mds object intact");
       
   183             User::Leave( err );
       
   184             }
       
   185         }
       
   186     else
       
   187         {
       
   188         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: file delete successful, deleting item from MDS also to speed things up");
       
   189         TInt result = iCollection.iMyVideosMdsDb->RemoveVideo( aMdsId );
       
   190         if ( result == KErrNone )
       
   191             {
       
   192             MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d removed from mds", aMdsId);
       
   193             //mds events will clean cache
       
   194             }
       
   195         else
       
   196             {
       
   197             if ( result == KErrNotFound )
       
   198                 {
       
   199                 // file is gone, and mds item is gone -> try to delete from cache
       
   200                 MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d not found from MDS, trying to delete from cache", aMdsId );
       
   201                 TInt result = iCollection.iCache->RemoveL( aMdsId );
       
   202                 if ( result == KErrNone )
       
   203                     {
       
   204                     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: %d deleted from cache, generating event", aMdsId );
       
   205                     iCollection.iMessageList->AddEventL( TMPXItemId( aMdsId, 0),
       
   206                             EMPXItemDeleted, EVcxMyVideosListNoInfo );
       
   207                     iCollection.iMessageList->SendL();
       
   208                     }
       
   209                 }
       
   210             else
       
   211                 {
       
   212                 //mds item and cache are still present, couldnt remove them
       
   213                 MPX_DEBUG3("CVcxMyVideosAsyncFileOperations:: failed to remove %d from mds (%d)", aMdsId, result);
       
   214                 User::Leave( result );
       
   215                 }
       
   216             }
       
   217         }   
       
   218     }
       
   219     
       
   220 // ----------------------------------------------------------------------------
       
   221 // CVcxMyVideosAsyncFileOperations::HandleMoveOrCopyStepL
       
   222 // ----------------------------------------------------------------------------
       
   223 //
       
   224 TBool CVcxMyVideosAsyncFileOperations::HandleMoveOrCopyStepL()
       
   225     {
       
   226     CMPXMedia& cmd = iCollection.iActiveTask->GetCommand();
       
   227     
       
   228     TBool done;
       
   229     
       
   230     TBool isMoveOperation = EFalse;    
       
   231     TUint32 cmdId = cmd.ValueTObjectL<TUint32>( KVcxMediaMyVideosCommandId );    
       
   232     if ( cmdId == KVcxCommandMyVideosMove )
       
   233         {
       
   234         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: move operation");
       
   235         isMoveOperation = ETrue;
       
   236         }
       
   237         
       
   238     // Start operations
       
   239     if ( iCurrentOperationIndex == 0 )
       
   240         {
       
   241         if ( !cmd.IsSupported( KMPXMediaArrayContents ) )
       
   242             {
       
   243             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: error, no array defined");
       
   244             User::Leave( KErrArgument );
       
   245             }
       
   246     
       
   247         CMPXMediaArray* idMediaArray = cmd.Value<CMPXMediaArray>(
       
   248                 KMPXMediaArrayContents );
       
   249 
       
   250         if ( idMediaArray->Count() == 0 )
       
   251             {
       
   252             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: error, no items in array ");
       
   253             User::Leave( KErrArgument );
       
   254             }
       
   255         
       
   256         iTargetDrive = cmd.ValueTObjectL<TInt32>( KVcxMediaMyVideosInt32Value );
       
   257         
       
   258         TMPXItemId mpxId;    
       
   259         iOperationIdArray.Reset();
       
   260         TInt count = idMediaArray->Count();
       
   261         for ( TInt i = 0; i < count; i++ )
       
   262             {
       
   263             mpxId = idMediaArray->AtL( i )->
       
   264                             ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
   265             MPX_DEBUG3("CVcxMyVideosAsyncFileOperations:: MPX ID: (%d, %d) will be moved ",
       
   266                     mpxId.iId1,
       
   267                     mpxId.iId2);
       
   268             iOperationIdArray.AppendL( idMediaArray->AtL( i )->
       
   269                     ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId ).iId1 );
       
   270             }
       
   271         
       
   272         iCollection.SendMyVideosMessageL( KVcxMessageMyVideosMoveOrCopyStarted, &cmd );
       
   273 
       
   274         iOperationResult.Reset();
       
   275         }
       
   276 
       
   277     TRAPD( err, MoveOrCopyVideoL( iOperationIdArray[iCurrentOperationIndex],
       
   278             iTargetDrive, isMoveOperation ));
       
   279 
       
   280     iOperationResult.AppendL( err );
       
   281     
       
   282     iCurrentOperationIndex++;
       
   283     
       
   284     // End operations
       
   285     if ( iCurrentOperationIndex > (iOperationIdArray.Count() - 1) )
       
   286         {
       
   287         iCurrentOperationIndex = 0;
       
   288         done                   = ETrue;
       
   289         if ( isMoveOperation )
       
   290             {
       
   291             SendOperationRespL( KVcxMessageMyVideosMoveResp );
       
   292             }
       
   293         else
       
   294             {
       
   295             SendOperationRespL( KVcxMessageMyVideosCopyResp );
       
   296             }
       
   297         }
       
   298     else
       
   299         {
       
   300         done = EFalse;
       
   301         }
       
   302         
       
   303     return done;
       
   304     }
       
   305 
       
   306 // ----------------------------------------------------------------------------
       
   307 // CVcxMyVideosAsyncFileOperations::CancelOperationL
       
   308 // Called when leave or cancel occurs for the operation, generates resp msg.
       
   309 // ----------------------------------------------------------------------------
       
   310 //
       
   311 void CVcxMyVideosAsyncFileOperations::CancelOperationL( TInt aErr )
       
   312     {
       
   313     if ( iCollection.iActiveTask->IsActive() )
       
   314         {
       
   315         TInt mvCmdId = -1;
       
   316         CMPXMedia& cmd = iCollection.iActiveTask->GetCommand();
       
   317         TMPXCommandId commandId = *cmd.Value<TMPXCommandId>( KMPXCommandGeneralId );
       
   318         
       
   319         if ( commandId == KVcxCommandIdMyVideos )
       
   320             {
       
   321             mvCmdId = cmd.ValueTObjectL<TUint32>( KVcxMediaMyVideosCommandId );
       
   322             }
       
   323                     
       
   324         TInt messageId; 
       
   325         
       
   326         switch ( mvCmdId )
       
   327             {
       
   328             case KVcxCommandMyVideosMove:
       
   329                 MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: generating KVcxMessageMyVideosMoveResp");
       
   330                 messageId = KVcxMessageMyVideosMoveResp;
       
   331                 break;
       
   332                 
       
   333             case KVcxCommandMyVideosCopy:
       
   334                 MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: generating KVcxMessageMyVideosCopyResp");
       
   335                 messageId = KVcxMessageMyVideosCopyResp;
       
   336                 break;
       
   337                 
       
   338             case KVcxCommandMyVideosDelete:
       
   339                 MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: generating KVcxMessageMyVideosDeleteResp");
       
   340                 messageId = KVcxMessageMyVideosDeleteResp;
       
   341                 break;
       
   342             
       
   343             default:
       
   344                 MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: no resp msg for this operation");
       
   345                 return;
       
   346             }
       
   347                         
       
   348         // generates response array and resp message
       
   349         for ( TInt i = iCurrentOperationIndex; i < iOperationIdArray.Count(); i++ )
       
   350             {
       
   351             iOperationResult.Append( aErr );
       
   352             }
       
   353         iCurrentOperationIndex = 0;
       
   354 
       
   355         SendOperationRespL( messageId );
       
   356         }
       
   357     else
       
   358         {
       
   359         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: no move,copy or delete operations were going on (nor anything else)");
       
   360         User::Leave( KErrNotFound );
       
   361         }
       
   362     }
       
   363 
       
   364 // ----------------------------------------------------------------------------
       
   365 // CVcxMyVideosAsyncFileOperations::SendOperationRespL
       
   366 // ----------------------------------------------------------------------------
       
   367 //
       
   368 void CVcxMyVideosAsyncFileOperations::SendOperationRespL( TInt aCmdId )
       
   369     {
       
   370     CMPXMessage* message = TVcxMyVideosCollectionUtil::CreateEmptyMediaListL();
       
   371     CleanupStack::PushL( message ); // 1->
       
   372 
       
   373     CMPXMediaArray* messageArray = message->Value<CMPXMediaArray>(
       
   374             KMPXMediaArrayContents );
       
   375     message->SetTObjectValueL<TUid>(KMPXMessageCollectionId,
       
   376             TUid::Uid(KVcxUidMyVideosMpxCollection));        
       
   377             
       
   378     // Add results
       
   379     CMPXMedia* media;
       
   380     TInt count = iOperationIdArray.Count();
       
   381     for ( TInt i = 0; i < count; i++ )
       
   382         {
       
   383         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: item added to array");
       
   384         
       
   385         media = CMPXMedia::NewL();
       
   386         CleanupStack::PushL( media ); // 2->
       
   387         media->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId,
       
   388                 TMPXItemId( iOperationIdArray[i], 0) );
       
   389         media->SetTObjectValueL<TInt32>( KVcxMediaMyVideosInt32Value,
       
   390                 iOperationResult[i] );
       
   391         
       
   392         messageArray->AppendL( media );
       
   393         CleanupStack::Pop( media ); // <-2                            
       
   394         }
       
   395         
       
   396     // Set message attributes
       
   397     //
       
   398     message->SetTObjectValueL<TMPXMessageId>( KMPXMessageGeneralId,
       
   399             TMPXItemId( KVcxCommandIdMyVideos, 0 ));
       
   400 
       
   401     message->SetTObjectValueL<TInt>( KVcxMediaMyVideosCommandId, aCmdId );
       
   402     
       
   403     iCollection.iMessageList->AddL( message );
       
   404     CleanupStack::Pop( message ); // <-1
       
   405     iCollection.iMessageList->SendL();
       
   406     }
       
   407 
       
   408 // ----------------------------------------------------------------------------
       
   409 // CVcxMyVideosAsyncFileOperations::MoveOrCopyVideoL
       
   410 // ----------------------------------------------------------------------------
       
   411 //
       
   412 void CVcxMyVideosAsyncFileOperations::MoveOrCopyVideoL( TUint32 aMdsId, TInt aTargetDrive,
       
   413         TBool aMove )
       
   414     {
       
   415     MPX_FUNC("CVcxMyVideosAsyncFileOperations::MoveOrCopyVideoL");
       
   416 
       
   417     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: mds id = %d", aMdsId);
       
   418     
       
   419     //get media from cache or mds
       
   420     TInt pos;
       
   421     CMPXMedia* videoInCache = iCollection.iCache->FindVideoByMdsIdL( aMdsId, pos );
       
   422 
       
   423     CMPXMedia* video = NULL;
       
   424     if ( videoInCache )
       
   425         {
       
   426         video = CMPXMedia::NewL( *videoInCache );
       
   427         }
       
   428         
       
   429     if ( !video )
       
   430         {
       
   431         video = iCollection.iMyVideosMdsDb->CreateVideoL( aMdsId, EFalse /* brief details */ );
       
   432         }
       
   433         
       
   434     if ( !video )
       
   435         {
       
   436         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: mds id %d not found from mds or cache", aMdsId);
       
   437         User::Leave( KErrNotFound );
       
   438         }
       
   439 
       
   440     CleanupStack::PushL( video ); // 1->
       
   441     
       
   442     // sanity checks
       
   443     if ( video->ValueTObjectL<TUint32>( KVcxMediaMyVideosDownloadId ) != 0 )
       
   444         {
       
   445         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: file is being downloaded, fail, leaving with KErrInUse code.");
       
   446         User::Leave( KErrInUse );
       
   447         }
       
   448 
       
   449     const TInt KMaxPathLength = 255;    
       
   450     TBuf<KMaxPathLength> sourcePath( video->ValueText( KMPXMediaGeneralUri ) );
       
   451             
       
   452     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: source path = %S", &sourcePath);
       
   453 
       
   454     if ( !DriveHasEnoughFreeSpaceL( sourcePath, aTargetDrive ) )
       
   455         {
       
   456         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: target drive full -> skipping");
       
   457         User::Leave( KErrDiskFull );
       
   458         }
       
   459 
       
   460     TInt sourceDrive;
       
   461     User::LeaveIfError( iCollection.iFs.CharToDrive( sourcePath[0], sourceDrive ) );
       
   462 
       
   463     if ( sourceDrive == aTargetDrive )
       
   464         {
       
   465         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: source and target drives are the same, doing nothing.");
       
   466         CleanupStack::PopAndDestroy( video ); // <-1
       
   467         return;
       
   468         }
       
   469 
       
   470     TBuf<KMaxPathLength> targetPath;
       
   471     
       
   472     GenerateTargetPathForMoveOrCopyL( sourcePath, targetPath, aTargetDrive );
       
   473 
       
   474     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: target path = %S", &targetPath );
       
   475     
       
   476     // update mds and cache
       
   477     CMPXMedia* mediaForMoveOp = NULL;
       
   478     CMPXMedia* mediaForCopyOp = NULL;
       
   479     if ( aMove )
       
   480         {
       
   481         // Update existing media.
       
   482         // Create new media object with only KMPXMediaGeneralId, and KMPXMediaGeneralUri
       
   483         // attributes set, that way update is lighter operation.
       
   484         mediaForMoveOp = CMPXMedia::NewL();
       
   485         CleanupStack::PushL( mediaForMoveOp ); // 2->
       
   486         mediaForMoveOp->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId,
       
   487                video->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ) );
       
   488         mediaForMoveOp->SetTextValueL( KMPXMediaGeneralUri, targetPath );
       
   489         
       
   490         iCollection.SetVideoL( *mediaForMoveOp );
       
   491         }
       
   492     else
       
   493         {
       
   494         // Create new media.
       
   495         mediaForCopyOp = CMPXMedia::CopyL( *video );
       
   496         CleanupStack::PushL( mediaForCopyOp ); // 2->
       
   497         mediaForCopyOp->SetTextValueL( KMPXMediaGeneralUri, targetPath );
       
   498         iCollection.AddVideoToMdsAndCacheL( *mediaForCopyOp );
       
   499         }
       
   500         
       
   501     //copy file, delete original if move case
       
   502     TRAPD( err, BaflUtils::EnsurePathExistsL( iCollection.iFs, targetPath ) );
       
   503     
       
   504     TUint att = 0;
       
   505     iCollection.iFs.Att( sourcePath, att);    
       
   506     if ( aMove && (att & KEntryAttReadOnly) )
       
   507         {
       
   508         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: move operation and source file is read only -> skipping");
       
   509         err = KErrAccessDenied;
       
   510         }
       
   511          
       
   512     if ( err == KErrNone )
       
   513         {
       
   514         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: copying: %S", &sourcePath);
       
   515         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: to     : %S", &targetPath);
       
   516         err = BaflUtils::CopyFile( iCollection.iFs, sourcePath, targetPath );
       
   517         if ( err == KErrNone )
       
   518             {
       
   519             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: Copy succeeded");
       
   520             if ( aMove )
       
   521                 {
       
   522                 MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: move case");
       
   523                 err = BaflUtils::DeleteFile( iCollection.iFs, sourcePath );
       
   524                 if ( err != KErrNone )
       
   525                     {
       
   526                     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: delete for source file failed: %d", err );
       
   527                     MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: deleting target file");
       
   528                     TInt delErr = BaflUtils::DeleteFile( iCollection.iFs, targetPath );
       
   529                     if ( delErr != KErrNone )
       
   530                         {
       
   531                         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: delete for target file failed: %d", delErr );
       
   532                         }
       
   533                     }
       
   534                 }
       
   535             }
       
   536         else
       
   537             {
       
   538             MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: CopyFile failed: %d", err);
       
   539             }
       
   540         }
       
   541     
       
   542     // roll mds and cache back if file operations failed
       
   543     if ( err != KErrNone )
       
   544         {
       
   545         if ( aMove )
       
   546             {
       
   547             MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: move failed %d", err );
       
   548             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: setting media path back and leaving." );
       
   549             mediaForMoveOp->SetTextValueL( KMPXMediaGeneralUri, sourcePath );
       
   550             iCollection.SetVideoL( *mediaForMoveOp );
       
   551             }
       
   552         else
       
   553             {
       
   554             MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: copy failed %d", err );
       
   555             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: deleting the added media object and leaving");
       
   556             iCollection.iMyVideosMdsDb->RemoveVideo( mediaForCopyOp->ValueTObjectL<TMPXItemId>(
       
   557                     KMPXMediaGeneralId ).iId1 );
       
   558             }
       
   559         User::Leave( err );
       
   560         }
       
   561     
       
   562     if ( aMove )
       
   563         {
       
   564         CleanupStack::PopAndDestroy( mediaForMoveOp ); // <-2
       
   565         }
       
   566     else
       
   567         {
       
   568         CleanupStack::PopAndDestroy( mediaForCopyOp ); // <-2
       
   569         }
       
   570     CleanupStack::PopAndDestroy( video ); // <-1
       
   571     }    
       
   572 
       
   573 // ----------------------------------------------------------------------------
       
   574 // CVcxMyVideosAsyncFileOperations::DriveHasEnoughFreeSpaceL
       
   575 // ----------------------------------------------------------------------------
       
   576 //
       
   577 TBool CVcxMyVideosAsyncFileOperations::DriveHasEnoughFreeSpaceL( const TDesC& aPath, TInt aDrive )
       
   578     {
       
   579     TEntry entry;
       
   580     User::LeaveIfError( iCollection.iFs.Entry( aPath, entry ) );
       
   581     TUint32 size = static_cast<TUint32>( entry.iSize );
       
   582     
       
   583     TVolumeInfo volInfo;
       
   584     User::LeaveIfError( iCollection.iFs.Volume( volInfo, aDrive ) );
       
   585     
       
   586     TInt64 freeSpace = volInfo.iFree;
       
   587 
       
   588     const TInt K4MBSlack = 0x400000;
       
   589 
       
   590     MPX_DEBUG3("CVcxMyVideosAsyncFileOperations:: space needed: %d, space available: %d", size + K4MBSlack,
       
   591             freeSpace );
       
   592     
       
   593     if ( freeSpace < ( size + K4MBSlack ) )
       
   594         {
       
   595         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: target drive does not have enough free space");
       
   596         return EFalse;
       
   597         }
       
   598     else
       
   599         {
       
   600         return ETrue;
       
   601         }
       
   602     }
       
   603 
       
   604 // ----------------------------------------------------------------------------
       
   605 // CVcxMyVideosAsyncFileOperations::GenerateTargetPathForMoveOrCopyL
       
   606 // ----------------------------------------------------------------------------
       
   607 //    
       
   608 void CVcxMyVideosAsyncFileOperations::GenerateTargetPathForMoveOrCopyL(
       
   609         const TDesC& aSourcePath, TDes& aTargetPath, TInt aTargetDrive )
       
   610     {
       
   611     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: source path = %S", &aSourcePath );
       
   612     
       
   613     TChar targetDriveChar;
       
   614     User::LeaveIfError( iCollection.iFs.DriveToChar( aTargetDrive, targetDriveChar ) );    
       
   615     aTargetPath.Append( targetDriveChar );
       
   616     aTargetPath.Append( ':' );
       
   617     
       
   618     TInt sourceDrive;
       
   619     User::LeaveIfError( iCollection.iFs.CharToDrive( aSourcePath[0], sourceDrive ) );
       
   620 
       
   621     TInt systemDrive = iCollection.iFs.GetSystemDrive();
       
   622     
       
   623     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: source drive: %d", sourceDrive);
       
   624     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: target drive: %d", aTargetDrive);
       
   625     MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: system drive: %d", systemDrive);
       
   626 
       
   627     _LIT(KDataDes, "data");
       
   628         
       
   629     if ( sourceDrive == systemDrive )
       
   630         {
       
   631         //remove *:\data\* from the path
       
   632         TPtrC pathData( aSourcePath.Mid(3,4) );
       
   633         MPX_DEBUG2("CVcxMyVideosAsyncFileOperations:: sourcePath.Mid(3,4)= %S", &pathData);
       
   634 
       
   635         if ( aSourcePath.Mid(3,4) == KDataDes )
       
   636             {
       
   637             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: source drive is system drive and 'data' exists in sourcePath");
       
   638             MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: not copying 'data' to the target path");
       
   639             aTargetPath.Append( aSourcePath.Mid( 7 ) );
       
   640             }
       
   641         else
       
   642             {
       
   643             aTargetPath.Append( aSourcePath.Mid( 2 ) );
       
   644             }
       
   645         }    
       
   646     else if ( aTargetDrive == systemDrive )
       
   647         {
       
   648         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: target drive is system drive -> adding 'data' to path");
       
   649         aTargetPath.Append( '\\' );
       
   650         aTargetPath.Append( KDataDes );
       
   651         aTargetPath.Append( aSourcePath.Mid( 2 ) );
       
   652         }
       
   653     else 
       
   654         {
       
   655         MPX_DEBUG1("CVcxMyVideosAsyncFileOperations:: source and target drives are not system drive, not adding or removing 'data'");        
       
   656         aTargetPath.Append( aSourcePath.Mid( 2 ) );        
       
   657         }
       
   658     const TInt KMaxPathLength = 255;
       
   659     TBuf<KMaxPathLength> uniquePath;
       
   660     TVcxMyVideosCollectionUtil::MakeUniqueFileNameL( iCollection.iFs, aTargetPath, uniquePath );
       
   661     aTargetPath = uniquePath;
       
   662     }
       
   663 
       
   664 // ----------------------------------------------------------------------------
       
   665 // CVcxMyVideosAsyncFileOperations::HandleDeleteStepL
       
   666 // ----------------------------------------------------------------------------
       
   667 //
       
   668 TBool CVcxMyVideosAsyncFileOperations::HandleDeleteStepL()
       
   669     {
       
   670     CMPXMedia& cmd = iCollection.iActiveTask->GetCommand();
       
   671     
       
   672     //no sanity checks for array items, since we want to generate all events, even if there is nothing to delete
       
   673     
       
   674     TBool done;
       
   675     
       
   676     TUint32 cmdId = cmd.ValueTObjectL<TUint32>( KVcxMediaMyVideosCommandId );    
       
   677         
       
   678     // Start operations
       
   679     if ( iCurrentOperationIndex == 0 )
       
   680         {
       
   681         iOperationIdArray.Reset();
       
   682 
       
   683         if ( cmd.IsSupported( KMPXMediaArrayContents ) )
       
   684             {    
       
   685             CMPXMediaArray* idMediaArray = cmd.Value<CMPXMediaArray>(
       
   686                 KMPXMediaArrayContents );
       
   687                 
       
   688             TMPXItemId mpxId;
       
   689             TInt count = idMediaArray->Count();
       
   690             for ( TInt i = 0; i < count; i++ )
       
   691                 {
       
   692                 mpxId = idMediaArray->AtL( i )->
       
   693                                 ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
   694                 MPX_DEBUG3("CVcxMyVideosAsyncFileOperations:: MPX ID: (%d, %d) will be deleted ",
       
   695                         mpxId.iId1,
       
   696                         mpxId.iId2);
       
   697                 iOperationIdArray.AppendL( idMediaArray->AtL( i )->
       
   698                         ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId ).iId1 );
       
   699                 }
       
   700 
       
   701             }
       
   702                     
       
   703         iCollection.SendMyVideosMessageL( KVcxMessageMyVideosDeleteStarted, &cmd );
       
   704 
       
   705         iOperationResult.Reset();
       
   706         }
       
   707 
       
   708     if ( iOperationIdArray.Count() > 0 )
       
   709         {
       
   710         TRAPD( err, DeleteVideoL( iOperationIdArray[iCurrentOperationIndex] ) );
       
   711         iOperationResult.AppendL( err );
       
   712         }
       
   713         
       
   714     iCurrentOperationIndex++;
       
   715     
       
   716     // End operations
       
   717     if ( iCurrentOperationIndex > (iOperationIdArray.Count() - 1) )
       
   718         {
       
   719         iCurrentOperationIndex = 0;
       
   720         done                   = ETrue;
       
   721 
       
   722         SendOperationRespL( KVcxMessageMyVideosDeleteResp );
       
   723         }
       
   724     else
       
   725         {
       
   726         done = EFalse;
       
   727         }
       
   728         
       
   729     return done;
       
   730     }
       
   731 
       
   732