engine/collectionframework/datasource/plugins/glxdatasourcemde2.5/src/glxdatasourcetaskmdscommand.cpp
branchRCL_3
changeset 59 8e5f6eea9c9f
equal deleted inserted replaced
57:ea65f74e6de4 59:8e5f6eea9c9f
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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:   
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 /**
       
    21  * @internal reviewed 11/07/2007 by M Byrne
       
    22  */
       
    23 
       
    24 
       
    25 #include "glxdatasourcetaskmdscommand.h"
       
    26 
       
    27 #include <bautils.h>
       
    28 #include <e32math.h>
       
    29 #include <glxcommandrequest.h>
       
    30 #include <glxpanic.h>
       
    31 #include <glxtndatabase.h>
       
    32 #include <glxtnthumbnailcreator.h>
       
    33 #include <glxtracer.h>
       
    34 #include <caf/manager.h>
       
    35 #include <mdeconstants.h>
       
    36 #include <mdeeventdef.h>
       
    37 #include <mdelogiccondition.h>
       
    38 #include <mdeobject.h>
       
    39 #include <mdeobjectdef.h>
       
    40 #include <mdeobjectquery.h>
       
    41 #include <mdepropertydef.h>
       
    42 #include <mderelationcondition.h>
       
    43 #include <mderelationdef.h>
       
    44 #include <mderelationquery.h>
       
    45 #include <mdesession.h>
       
    46 #include <mdetextproperty.h>
       
    47 #include <mpxcollectionmessagedefs.h>
       
    48 #include <mpxcommandgeneraldefs.h>
       
    49 #include <mpxmedia.h>
       
    50 #include <mpxmediaarray.h>
       
    51 #include <mpxmediacollectiondetaildefs.h>
       
    52 #include <mpxmediacontainerdefs.h>
       
    53 #include <mpxmediageneraldefs.h>
       
    54 #include <mpxmessagegeneraldefs.h>
       
    55 #include <mpxmessageprogressdefs.h>
       
    56 #include <pathinfo.h>
       
    57 
       
    58 #include <glxstringcache.h>
       
    59 
       
    60 #include <glxcollectionplugincamera.hrh>
       
    61 #include <glxcollectionplugintags.hrh>
       
    62 #include <glxcollectionpluginalbums.hrh>
       
    63 #include <glxcollectionpluginall.hrh>
       
    64 
       
    65 #include "glxdatasourcemds.h"
       
    66 #include "glxdatasourcemdsutility.h"
       
    67 #include "glxdatasourcemds.hrh"
       
    68 
       
    69 #include <glxpluginalbums.rsg>
       
    70 
       
    71 #include <data_caging_path_literals.hrh>
       
    72 #include <f32file.h>
       
    73 #include <barsc.h>
       
    74 #include <bautils.h>
       
    75 
       
    76 // CONSTANTS
       
    77 _LIT(KPropertyDefNameDescription, "Comment");
       
    78 _LIT(KPropertyDefNameTitle, "Title" );
       
    79 _LIT(KPropertyDefNameSize, "Size");
       
    80 _LIT(KPropertyDefNameCreationDate, "CreationDate");
       
    81 _LIT(KPropertyDefNameLastModifiedDate, "LastModifiedDate");
       
    82 _LIT(KPropertyDefNameAlbumType, "Type");
       
    83 _LIT(KPropertyDefItemType, "ItemType");
       
    84 // Item type for Album
       
    85 _LIT( KAlbumItemType, "application/vnd.nokia.mde.album" );
       
    86 // Item type for Tag
       
    87 _LIT( KTagItemType, "application/vnd.nokia.mde.tag" );
       
    88 
       
    89 const TInt KDriveLetterLength = 1;
       
    90 _LIT(KColonBackslash, ":\\");
       
    91 _LIT(KFileNameFormatString, "(%+02u)");
       
    92 
       
    93 // Items to be deleted from File server at a time before calling scheduler wait
       
    94 const TInt KDeletedItemCount = 10;
       
    95 const TInt KDeleteOperationInterval = 1000;
       
    96 
       
    97 // ----------------------------------------------------------------------------
       
    98 // Destructor
       
    99 // ----------------------------------------------------------------------------
       
   100 //
       
   101 CGlxDataSourceTaskMdeCommand::~CGlxDataSourceTaskMdeCommand()
       
   102 	{
       
   103     TRACER("CGlxDataSourceTaskMdeCommand::~CGlxDataSourceTaskMdeCommand()");
       
   104 	iLeftIds.Close();
       
   105     iRightIds.Close();
       
   106     delete iTitle;
       
   107     delete iObjectToRename;
       
   108     delete iStringCache;
       
   109     if(iTimer && iTimer->IsActive())
       
   110 		{
       
   111 		iTimer->Cancel();
       
   112 		}
       
   113 	delete iTimer;
       
   114     delete iSchedulerWait;    
       
   115     }
       
   116 
       
   117 
       
   118 // ----------------------------------------------------------------------------
       
   119 // Constructor
       
   120 // ----------------------------------------------------------------------------
       
   121 //
       
   122 CGlxDataSourceTaskMdeCommand::CGlxDataSourceTaskMdeCommand(
       
   123        CGlxCommandRequest* aRequest, MGlxDataSourceRequestObserver& aObserver, 
       
   124        CGlxDataSource* aDataSource)
       
   125     : CGlxDataSourceTaskMde(aRequest, aObserver, aDataSource) 
       
   126 	{
       
   127     TRACER("CGlxDataSourceTaskMdeCommand::CGlxDataSourceTaskMdeCommand()");
       
   128 	// No implementation required
       
   129 	}
       
   130 
       
   131 // ----------------------------------------------------------------------------
       
   132 // Second phase constructor
       
   133 // ----------------------------------------------------------------------------
       
   134 //
       
   135 void CGlxDataSourceTaskMdeCommand::ConstructL()
       
   136 	{
       
   137     TRACER("CGlxDataSourceTaskMdeCommand::ConstructL()");
       
   138 	iResponse = CMPXCommand::NewL(static_cast<CGlxCommandRequest*>(iRequest)->Command());
       
   139 #ifdef USE_S60_TNM
       
   140     DataSource()->CancelFetchThumbnail();
       
   141 #else    
       
   142     DataSource()->ThumbnailCreator().CancelRequest( TGlxMediaId(0) );
       
   143 #endif    
       
   144     
       
   145     iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   146     iSchedulerWait = new (ELeave) CActiveSchedulerWait();
       
   147 	}
       
   148 
       
   149 /// @todo minor: Rowland Cook 12/06/2007 Add method decription.
       
   150 // ----------------------------------------------------------------------------
       
   151 // CGlxDataSourceTaskMdeCommand::ExecuteRequestL
       
   152 // ----------------------------------------------------------------------------
       
   153 //
       
   154 void CGlxDataSourceTaskMdeCommand::ExecuteRequestL()
       
   155 	{
       
   156     TRACER("CGlxDataSourceTaskMdeCommand::ExecuteRequestL()");
       
   157     __ASSERT_DEBUG(DataSource()->NamespaceDef(), Panic(EGlxPanicIllegalState));
       
   158     
       
   159 	const CMPXCommand& command = static_cast<CGlxCommandRequest*>(iRequest)->Command();
       
   160 	
       
   161 	if ( command.IsSupported(KMPXCommandGeneralCollectionId) )
       
   162 		{
       
   163 		iCollectionUid = command.ValueTObjectL<TUid>(KMPXCommandGeneralCollectionId);
       
   164 		}
       
   165 	else
       
   166 		{
       
   167 		// if the collection Uid has not been set on the command, use the Ud of the plugin in use.
       
   168 		iCollectionUid = iRequest->CollectionPluginUid();
       
   169 		}
       
   170 	
       
   171 	TGlxCommandParser::ParseL(*this, command);
       
   172 	}
       
   173 
       
   174 // ----------------------------------------------------------------------------
       
   175 // Add container
       
   176 // ----------------------------------------------------------------------------
       
   177 //
       
   178 void CGlxDataSourceTaskMdeCommand::AddContainerL(const TDesC& aContainerName)
       
   179 	{
       
   180     TRACER("CGlxDataSourceTaskMdeCommand::AddContainerL()");
       
   181 	iTitle = aContainerName.AllocL();
       
   182 	AppendContainerTitleCountQueryL(ECommandAddContainer, aContainerName);
       
   183     ExecuteQueryL();
       
   184     }
       
   185 
       
   186 // ----------------------------------------------------------------------------
       
   187 // Add items to container by id
       
   188 // ----------------------------------------------------------------------------
       
   189 //
       
   190 void CGlxDataSourceTaskMdeCommand::AddToContainerL(const RArray<TGlxMediaId>& aSourceIds,
       
   191         const RArray<TGlxMediaId>& aTargetContainers)
       
   192 	{
       
   193     TRACER("CGlxDataSourceTaskMdeCommand::AddToContainerL(const RArray<TGlxMediaId>& aSourceIds,const RArray<TGlxMediaId>& aTargetContainers)");	
       
   194 	__ASSERT_DEBUG(aSourceIds.Count() && aTargetContainers.Count(), 
       
   195 	        Panic(EGlxPanicEmptyArray));
       
   196 	
       
   197     iLeftIds.Reset();
       
   198     iRightIds.Reset();
       
   199 
       
   200 	CMdEQuery* query = DataSource()->Session().NewRelationQueryL(
       
   201 	        *DataSource()->NamespaceDef(), this); 
       
   202 	AppendQueryL(query, ECommandAddToContainer);
       
   203     
       
   204     CMdELogicCondition& rootCondition = query->Conditions();
       
   205     CMdERelationCondition& containerRelationCondition = 
       
   206     rootCondition.AddRelationConditionL(DataSource()->ContainsDef(),
       
   207             ERelationConditionSideLeft);
       
   208     CMdELogicCondition& leftLogicCondition = containerRelationCondition.LeftL();
       
   209     CMdELogicCondition& rightLogicCondition = containerRelationCondition.RightL();
       
   210     leftLogicCondition.SetOperator(ELogicConditionOperatorOr);
       
   211     rightLogicCondition.SetOperator(ELogicConditionOperatorOr);
       
   212 
       
   213     TItemId containerId = ContainerItemId(aTargetContainers[0]);
       
   214     // It is currenly a safe assumption that all containers are of the same type (either albums or tags)
       
   215     // and thus they will either all be on the left or all be on the right of the logic condition. Therefore, 
       
   216     // we only need to test the first container to see if it is on the left or on the right. 
       
   217     CMdEObject* container = DataSource()->Session().GetObjectL(containerId);
       
   218     if (!container)
       
   219         {
       
   220         User::Leave(KErrNotFound);
       
   221         }
       
   222     TBool containerIsLeft = DataSource()->ContainerIsLeft(container->Def());
       
   223     
       
   224     delete container;
       
   225     container = NULL;
       
   226     
       
   227 
       
   228     if (containerIsLeft)
       
   229         {
       
   230         // the container is on the left
       
   231         NGlxDataSourceMdsUtility::CopyMediaIdArrayL(iLeftIds, aTargetContainers);
       
   232         NGlxDataSourceMdsUtility::CopyMediaIdArrayL(iRightIds, aSourceIds);
       
   233         }
       
   234     else
       
   235         {
       
   236         // the container is on the right
       
   237         NGlxDataSourceMdsUtility::CopyMediaIdArrayL(iRightIds, aTargetContainers);
       
   238         NGlxDataSourceMdsUtility::CopyMediaIdArrayL(iLeftIds, aSourceIds);
       
   239         }
       
   240     
       
   241     leftLogicCondition.AddObjectConditionL(iLeftIds);
       
   242     rightLogicCondition.AddObjectConditionL(iRightIds);
       
   243 
       
   244     query->SetResultMode(EQueryResultModeItem);	 
       
   245 
       
   246     ExecuteQueryL();
       
   247     
       
   248     }
       
   249 
       
   250 // ----------------------------------------------------------------------------
       
   251 // Add item to containers by URI.
       
   252 // ----------------------------------------------------------------------------
       
   253 //
       
   254 void CGlxDataSourceTaskMdeCommand::AddToContainerL(const TDesC& aSourceUri, 
       
   255 		                        const RArray< TGlxMediaId >& aTargetContainers)
       
   256     {
       
   257     TRACER("CGlxDataSourceTaskMdeCommand::AddToContainerL()");
       
   258     CMdEObject* sourceObject = DataSource()->Session().GetObjectL(aSourceUri);
       
   259     if (!sourceObject)
       
   260         {
       
   261         User::Leave(KErrNotFound);
       
   262         }
       
   263     RArray<TGlxMediaId> sourceIds;
       
   264     CleanupClosePushL(sourceIds);
       
   265     sourceIds.AppendL(TGlxMediaId(sourceObject->Id()));
       
   266     
       
   267     AddToContainerL(sourceIds, aTargetContainers);
       
   268     CleanupStack::PopAndDestroy(&sourceIds);
       
   269     }
       
   270 
       
   271 // ----------------------------------------------------------------------------
       
   272 // Copy files to another drive.
       
   273 // ----------------------------------------------------------------------------
       
   274 //
       
   275 void CGlxDataSourceTaskMdeCommand::CopyL(const RArray<TGlxMediaId>& aSourceIds, 
       
   276         const TDesC& aDrive)
       
   277     {
       
   278     TRACER("CGlxDataSourceTaskMdeCommand::CopyL()");
       
   279     FileOperationL(aSourceIds.Array(), aDrive, ECopy);
       
   280     }
       
   281 
       
   282 // ----------------------------------------------------------------------------
       
   283 // Move files to another drive.
       
   284 // ----------------------------------------------------------------------------
       
   285 //
       
   286 void CGlxDataSourceTaskMdeCommand::MoveL(const RArray<TGlxMediaId>& aSourceIds, 
       
   287         const TDesC& aDrive)
       
   288     {
       
   289     TRACER("CGlxDataSourceTaskMdeCommand::MoveL()");
       
   290     FileOperationL(aSourceIds.Array(), aDrive, EMove);
       
   291     }
       
   292 
       
   293 // ----------------------------------------------------------------------------
       
   294 // Remove items from a container.
       
   295 // ----------------------------------------------------------------------------
       
   296 //
       
   297 void CGlxDataSourceTaskMdeCommand::RemoveFromContainerL(
       
   298         const RArray<TGlxMediaId>& aItemIds, const TGlxMediaId& aContainerId)
       
   299     {
       
   300     TRACER("CGlxDataSourceTaskMdeCommand::RemoveFromContainerL()");
       
   301     // Answer to question in @bug above: No
       
   302     
       
   303 	CMdEObject* object = NULL;
       
   304 	object = DataSource()->Session().GetObjectL(aContainerId.Value());
       
   305     CleanupStack::PushL(object);
       
   306 	if (!object)
       
   307     	{
       
   308     	User::Leave(KErrNotFound);
       
   309     	}
       
   310 	
       
   311 	CMdEQuery* query = DataSource()->Session().NewRelationQueryL(
       
   312 	        *DataSource()->NamespaceDef(), this); 
       
   313 	AppendQueryL(query, ECommandRemoveFromContainer); // query is now owned by the query array.
       
   314     
       
   315     CMdELogicCondition& rootCondition = query->Conditions();
       
   316 
       
   317     CMdERelationCondition& containerRelationCondition = 
       
   318     rootCondition.AddRelationConditionL(
       
   319             DataSource()->ContainsDef(), ERelationConditionSideLeft);
       
   320     CMdELogicCondition* containerLogicCondition = NULL;
       
   321     CMdELogicCondition* itemLogicCondition = NULL;
       
   322     // Containers are on the left for albums, right for tags
       
   323     if ( DataSource()->ContainerIsLeft(object->Def()) )
       
   324     	{
       
   325     	containerLogicCondition = &containerRelationCondition.LeftL();
       
   326     	itemLogicCondition = &containerRelationCondition.RightL();
       
   327     	}
       
   328     else
       
   329     	{
       
   330     	containerLogicCondition = &containerRelationCondition.RightL();
       
   331     	itemLogicCondition = &containerRelationCondition.LeftL();
       
   332     	}
       
   333    
       
   334     containerLogicCondition->AddObjectConditionL(aContainerId.Value());
       
   335     
       
   336     itemLogicCondition->SetOperator(ELogicConditionOperatorOr);
       
   337 
       
   338     NGlxDataSourceMdsUtility::AddObjectConditionL(*itemLogicCondition,aItemIds);
       
   339     
       
   340     query->SetResultMode(EQueryResultModeId);	 
       
   341     CleanupStack::PopAndDestroy(object);
       
   342     ExecuteQueryL();
       
   343     }
       
   344 
       
   345 // ----------------------------------------------------------------------------
       
   346 // Delete files, Remove container.
       
   347 // ----------------------------------------------------------------------------
       
   348 //
       
   349 void CGlxDataSourceTaskMdeCommand::DeleteL(const RArray<TGlxMediaId>& aItemIds)
       
   350     {
       
   351     TRACER("CGlxDataSourceTaskMdeCommand::DeleteL()");
       
   352     CMdEObjectDef* containerObjectDef = NULL;
       
   353     TInt err = ContainerObjectDef(containerObjectDef);
       
   354     if (err == KErrNone)
       
   355     	{
       
   356 	    QueueObjectQueryL(*containerObjectDef, 
       
   357 	            aItemIds, ECommandDeleteContainers);
       
   358     	}
       
   359     // Assume that only items are left
       
   360     QueueObjectQueryL(DataSource()->ObjectDef(), 
       
   361                 aItemIds, ECommandDeleteItems);
       
   362     
       
   363     ExecuteQueryL();
       
   364     }
       
   365 
       
   366 // ----------------------------------------------------------------------------
       
   367 // Rename files, Rename container.
       
   368 //
       
   369 /// @todo test this method.
       
   370 //
       
   371 // ----------------------------------------------------------------------------
       
   372 //
       
   373 void CGlxDataSourceTaskMdeCommand::RenameL(const TGlxMediaId& aSourceItemId, 
       
   374         const TDesC& aTitle)
       
   375     {
       
   376     TRACER("CGlxDataSourceTaskMdeCommand::RenameL()");
       
   377     delete iTitle;
       
   378     iTitle = NULL;
       
   379 	iTitle = aTitle.AllocL();
       
   380 	
       
   381 	RArray<TGlxMediaId> sourceIdArray;
       
   382 	CleanupClosePushL(sourceIdArray);
       
   383 	sourceIdArray.AppendL(aSourceItemId);
       
   384 	
       
   385 	QueueObjectQueryL(DataSource()->ObjectDef(), sourceIdArray , ECommandRename);
       
   386 	CleanupStack::PopAndDestroy(&sourceIdArray);
       
   387 	
       
   388 	ExecuteQueryL();
       
   389     }
       
   390 
       
   391 // ----------------------------------------------------------------------------
       
   392 // Set description.
       
   393 // ----------------------------------------------------------------------------
       
   394 //
       
   395 void CGlxDataSourceTaskMdeCommand::SetDescriptionL(const RArray<TGlxMediaId>& aItemIds, 
       
   396         const TDesC& aDescription)
       
   397     {
       
   398     TRACER("CGlxDataSourceTaskMdeCommand::SetDescriptionL()");
       
   399     CMdEPropertyDef& descriptionPropertyDef = DataSource()->MediaDef().GetPropertyDefL(
       
   400             KPropertyDefNameDescription);
       
   401     if (descriptionPropertyDef.PropertyType() != EPropertyText)
       
   402     	{
       
   403     	User::Leave(KErrCorrupt);
       
   404     	}
       
   405     
       
   406     TInt count = aItemIds.Count();
       
   407     for (TInt i = 0; i < count; i++)
       
   408     	{
       
   409     	TItemId itemId = aItemIds[i].Value();
       
   410     	CMdEObject* object = DataSource()->Session().OpenFullObjectL(itemId);
       
   411     	if (!object)
       
   412     		{
       
   413     		User::Leave(KErrNotFound);
       
   414     		}
       
   415     	CleanupStack::PushL(object);
       
   416     	CMdEProperty* descriptionProperty = NULL;
       
   417     
       
   418     			
       
   419     	TInt index = object->Property(descriptionPropertyDef, descriptionProperty);
       
   420 	    if (index < KErrNotFound)
       
   421 	    	{
       
   422 	    	User::Leave(index);
       
   423 	    	}
       
   424 	    if (index != KErrNotFound)
       
   425 	    	{
       
   426 	    	// Check whether the description string is empty
       
   427 	    	if( aDescription.Length()  )
       
   428 	    	    {	    	   
       
   429 	    	    static_cast<CMdETextProperty*>(descriptionProperty)->SetValueL(aDescription);
       
   430 	    	    }
       
   431 	    	    
       
   432 	        //if entered description string is blank then remove the old property
       
   433 	    	else
       
   434                 {
       
   435                 object->RemoveProperty(index);
       
   436                 }
       
   437 	    	}
       
   438     	else
       
   439     	    {
       
   440     	    if( aDescription.Length()  )
       
   441 	    	    {
       
   442     	    object->AddTextPropertyL(descriptionPropertyDef, aDescription);
       
   443 	    	    }
       
   444     	    }
       
   445 	    DataSource()->Session().CommitObjectL(*object); 
       
   446 	    CleanupStack::PopAndDestroy(object);
       
   447     	}
       
   448     
       
   449     HandleRequestComplete(KErrNone);
       
   450     }
       
   451 
       
   452 
       
   453 // ----------------------------------------------------------------------------
       
   454 // Set capture location.
       
   455 // ----------------------------------------------------------------------------
       
   456 //
       
   457 void CGlxDataSourceTaskMdeCommand::SetCaptureLocationL(const RArray<TGlxMediaId>& aItemIds, 
       
   458         const TCoordinate& aCoordinate)
       
   459     {
       
   460     TRACER("CGlxDataSourceTaskMdeCommand::SetCaptureLocationL()") ;   
       
   461     if (!Math::IsNaN(aCoordinate.Latitude()) || !Math::IsNaN(aCoordinate.Longitude()))
       
   462     	{
       
   463     	User::Leave(KErrArgument);
       
   464     	}
       
   465     	
       
   466 	CMdEQuery* query = DataSource()->Session().NewRelationQueryL(*DataSource()->NamespaceDef(), this); 
       
   467 	AppendQueryL(query, ECommandRemoveLocation); // query is now owned by the query array.
       
   468     
       
   469     CMdELogicCondition& rootCondition = query->Conditions();
       
   470 
       
   471     CMdERelationCondition& containerRelationCondition = rootCondition.AddRelationConditionL(
       
   472             ERelationConditionSideLeft);
       
   473     CMdELogicCondition& locationLogicCondition = containerRelationCondition.RightL();
       
   474     CMdELogicCondition& itemLogicCondition = containerRelationCondition.LeftL();
       
   475     locationLogicCondition.AddObjectConditionL(DataSource()->LocationDef());
       
   476     
       
   477     itemLogicCondition.SetOperator(ELogicConditionOperatorOr);
       
   478 
       
   479 
       
   480     itemLogicCondition.AddObjectConditionL(reinterpret_cast<const RArray<TItemId>&>(aItemIds));
       
   481     
       
   482     query->SetResultMode(EQueryResultModeId);	 
       
   483     ExecuteQueryL();
       
   484     }
       
   485 
       
   486 // ----------------------------------------------------------------------------
       
   487 // CGlxDataSourceTaskMdeCommand::ThumbnailCleanupL
       
   488 // ----------------------------------------------------------------------------
       
   489 //
       
   490 void CGlxDataSourceTaskMdeCommand::ThumbnailCleanupL()
       
   491 	{
       
   492     TRACER("CGlxDataSourceTaskMdeCommand::ThumbnailCleanupL()");
       
   493 #ifndef USE_S60_TNM
       
   494     CGlxDataSourceMde* ds = DataSource();
       
   495     ds->ThumbnailCreator().CleanupThumbnailsL(&ds->ThumbnailDatabase());
       
   496 #endif
       
   497 	HandleRequestComplete(KErrNone);	
       
   498 	}
       
   499 
       
   500 // ----------------------------------------------------------------------------
       
   501 // CGlxDataSourceTaskMdeCommand::HandleQueryCompletedL
       
   502 // ----------------------------------------------------------------------------
       
   503 //
       
   504 void CGlxDataSourceTaskMdeCommand::DoHandleQueryCompletedL(CMdEQuery& aQuery)
       
   505 	{
       
   506     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleQueryCompletedL()");
       
   507     TGlxQueryType queryType = iQueryTypes[0];
       
   508 	
       
   509     switch (queryType)
       
   510     	{
       
   511 
       
   512 	    case ECommandRemoveFromContainer: // don't break
       
   513 	    case ECommandRemoveLocation:
       
   514 			{
       
   515 			TInt queryCount = aQuery.Count();
       
   516 			RArray<TItemId> relationsToRemove;
       
   517 			CleanupClosePushL(relationsToRemove);
       
   518 			User::LeaveIfError(relationsToRemove.Reserve(queryCount));
       
   519 			
       
   520 			RArray<TItemId> successfullyRemovedReleations;
       
   521 			CleanupClosePushL(successfullyRemovedReleations);
       
   522 			User::LeaveIfError(successfullyRemovedReleations.Reserve(queryCount));
       
   523 			
       
   524 			for(TInt i = queryCount - 1; i >= 0; i--)
       
   525 				{		
       
   526 				relationsToRemove.AppendL(aQuery.ResultId(i));
       
   527 				}
       
   528 			
       
   529 			if (queryCount)
       
   530 				{
       
   531 				User::LeaveIfError(DataSource()->Session().RemoveRelationsL(
       
   532 				        relationsToRemove, successfullyRemovedReleations));
       
   533 				}
       
   534 			
       
   535 			CleanupStack::PopAndDestroy(&successfullyRemovedReleations);
       
   536 			CleanupStack::PopAndDestroy(&relationsToRemove);
       
   537 			}
       
   538 	    break;
       
   539 	    case ECommandAddToContainer:
       
   540 			{
       
   541 			DoHandleAddToContainerQueryCompletedL(aQuery);
       
   542 	        }
       
   543 	    break;
       
   544 	    case ECommandAddContainer:
       
   545 	        { 
       
   546 	        DoHandleAddContainerQueryCompletedL(aQuery);   
       
   547 	        }
       
   548 	        break;
       
   549 	    case ECommandDeleteContainers:
       
   550 	        {
       
   551 	        DoHandleDeleteContainersQueryCompletedL(aQuery);
       
   552 	        }
       
   553 	    break;
       
   554 	    case ECommandDeleteItems:
       
   555 	        {
       
   556 	        DoHandleDeleteItemsQueryCompletedL(aQuery);
       
   557 	        }
       
   558 	    break;
       
   559     	case ECommandRename:
       
   560     		{
       
   561     		DoHandleRenameQueryCompletedL(aQuery);
       
   562     		}
       
   563     	break;
       
   564     	case ECommandRenameContainer:
       
   565     		{
       
   566     		DoHandleRenameConainerQueryCompletedL(aQuery);
       
   567     		}
       
   568     	break;
       
   569     	}
       
   570     }
       
   571 // ----------------------------------------------------------------------------
       
   572 // CGlxDataSourceTaskMdeCommand::DoNextQueryL
       
   573 // ----------------------------------------------------------------------------
       
   574 //
       
   575 void CGlxDataSourceTaskMdeCommand::DoNextQueryL()
       
   576     {
       
   577     TRACER("CGlxDataSourceTaskMdeCommand::DoNextQueryL()");
       
   578     if (iQueries.Count())
       
   579         {
       
   580         ExecuteQueryL();
       
   581         }
       
   582     else
       
   583         {
       
   584         HandleRequestComplete(KErrNone);
       
   585         }
       
   586     }
       
   587 
       
   588 // ----------------------------------------------------------------------------
       
   589 // CGlxDataSourceTaskMdeCommand::FileOperationL
       
   590 // ----------------------------------------------------------------------------
       
   591 //
       
   592 void CGlxDataSourceTaskMdeCommand::FileOperationL(const TArray<TGlxMediaId>& aSourceIds, 
       
   593         const TDesC& aDrive, TFileOperation aFileOperation)
       
   594 	{
       
   595     TRACER("CGlxDataSourceTaskMdeCommand::FileOperationL()");
       
   596 	ContentAccess::CManager *manager = ContentAccess::CManager::NewL();
       
   597 	CleanupStack::PushL(manager);
       
   598 	// The following line causes a code scanner warning advising use of EikonEnv RFs instance.
       
   599 	// We don't have an EikonEnv as we are running in a server process.
       
   600 	RFs rfs; // used for BaflUtils::FileExists
       
   601 	
       
   602 	CleanupClosePushL(rfs);
       
   603 	User::LeaveIfError(rfs.Connect());
       
   604 	for (TInt i = 0; i < aSourceIds.Count(); i++)
       
   605     	{
       
   606     	CMdEObject* sourceObject = DataSource()->Session().GetObjectL(aSourceIds[i].Value());
       
   607     	if (!sourceObject)
       
   608     		{
       
   609     		User::Leave(KErrNotFound);
       
   610     		}
       
   611 
       
   612     	CleanupStack::PushL(sourceObject);
       
   613     	
       
   614     	const TDesC& sourceFileName = sourceObject->Uri();
       
   615     	TFileName sourceRootPath;
       
   616     	
       
   617     	RootPath(sourceFileName, sourceRootPath);
       
   618     	TPtrC fileNameWithoutRoot(NULL,0);
       
   619     	if (sourceFileName.Left(sourceRootPath.Length()).CompareF(sourceRootPath) == 0)
       
   620     		// This is the expected case. The file to be copied is under the 'root' of 
       
   621     		// the drive that it is located on. (For the C:, the root is C:\data, 
       
   622     		// for the D: the root is D:\)
       
   623     		{
       
   624     		fileNameWithoutRoot.Set(sourceFileName.Right(sourceFileName.Length() - 
       
   625     		        sourceRootPath.Length()));
       
   626     		}
       
   627     	else
       
   628     		{
       
   629     		fileNameWithoutRoot.Set(sourceFileName);
       
   630     		}
       
   631     		
       
   632     	TFileName destinationFileName;
       
   633     	// Set destination file name to destination 'root' path
       
   634     	RootPath(aDrive, destinationFileName);
       
   635     	// Append the file name
       
   636     	destinationFileName.Append(fileNameWithoutRoot);
       
   637     	
       
   638     	if (destinationFileName.CompareF(sourceFileName) != 0)
       
   639     		{
       
   640     		// If source and destination are not identical, perform the copy.	
       
   641 			if (BaflUtils::FileExists(rfs, destinationFileName))
       
   642 				{
       
   643 				// If the destination file name already exists find an available file name.
       
   644 				TParse destinationFileNameParse;
       
   645 				destinationFileNameParse.Set(destinationFileName,NULL,NULL); // this is a copy of the data
       
   646 				TInt destinationFileNameWithoutExtensionLength = destinationFileName.Length()
       
   647 				- destinationFileNameParse.Ext().Length();
       
   648 				TInt i = 1;
       
   649 				do
       
   650 					{
       
   651 			    	destinationFileName.SetLength(destinationFileNameWithoutExtensionLength);
       
   652 			    	destinationFileName.AppendFormat(KFileNameFormatString,i++);
       
   653 			    	destinationFileName.Append(destinationFileNameParse.Ext());		    	
       
   654 					}
       
   655 				while (BaflUtils::FileExists(rfs, destinationFileName));
       
   656 				}
       
   657 			
       
   658             // Ensure the path that we are copying to exists.
       
   659             // Fixed error ID:  ELLZ-798BP3 Lumiere 07.46.08_MC Photo: 
       
   660             // "System: System error." is displayed when copying/moving image which is saved in a user created folder.
       
   661             BaflUtils::EnsurePathExistsL(rfs,destinationFileName);
       
   662             
       
   663 	    	if (aFileOperation == ECopy)
       
   664 	    		{
       
   665 	    		User::LeaveIfError(manager->CopyFile(sourceFileName, destinationFileName));		
       
   666 	    		}
       
   667 	    	else
       
   668 	    		{
       
   669 	    		User::LeaveIfError(manager->RenameFile(sourceFileName, destinationFileName));
       
   670 	    		}
       
   671 
       
   672     		}
       
   673     	
       
   674     	CleanupStack::PopAndDestroy(sourceObject);
       
   675     	}
       
   676     
       
   677 	CleanupStack::PopAndDestroy(&rfs);
       
   678 	CleanupStack::PopAndDestroy(manager);
       
   679 	
       
   680     HandleRequestComplete(KErrNone);
       
   681 	}
       
   682 
       
   683 // ----------------------------------------------------------------------------
       
   684 // CGlxDataSourceTaskMdeCommand::ContainerItemId
       
   685 // ----------------------------------------------------------------------------
       
   686 //
       
   687 TItemId CGlxDataSourceTaskMdeCommand::ContainerItemId(const TGlxMediaId& aMediaId)
       
   688     {
       
   689     TRACER("TMdEItemId CGlxDataSourceTaskMdeCommand::ContainerItemId()");    
       
   690     return aMediaId.Value();
       
   691     }
       
   692 
       
   693 // ----------------------------------------------------------------------------
       
   694 // CGlxDataSourceTaskMdeCommand::ContainerItemId
       
   695 // ----------------------------------------------------------------------------
       
   696 //
       
   697 void CGlxDataSourceTaskMdeCommand::RootPath(const TDesC& aDrive, TDes& aRootPath)
       
   698 	{
       
   699     TRACER("CGlxDataSourceTaskMdeCommand::RootPath()");
       
   700 	if (aDrive.Left(KDriveLetterLength).CompareF(PathInfo::PhoneMemoryRootPath().Left(
       
   701 	        KDriveLetterLength)) == 0)
       
   702 		{
       
   703 		aRootPath = PathInfo::PhoneMemoryRootPath();
       
   704 		}
       
   705 	else if (aDrive.Left(KDriveLetterLength).CompareF(PathInfo::MemoryCardRootPath().Left(
       
   706 	        KDriveLetterLength)) == 0)
       
   707 		{
       
   708 		aRootPath = PathInfo::MemoryCardRootPath();
       
   709 		}
       
   710 	else if (aDrive.Left(KDriveLetterLength).CompareF(PathInfo::RomRootPath().Left(
       
   711 	        KDriveLetterLength)) == 0)
       
   712 		{
       
   713 		aRootPath = PathInfo::RomRootPath();
       
   714 		}
       
   715 	else
       
   716 		{
       
   717 		aRootPath = aDrive.Left(KDriveLetterLength);
       
   718 		aRootPath.Append(KColonBackslash);
       
   719 		}
       
   720 	}
       
   721 
       
   722 // ----------------------------------------------------------------------------
       
   723 // CGlxDataSourceTaskMdeCommand::SendProgressMessageL
       
   724 // ----------------------------------------------------------------------------
       
   725 //
       
   726 void CGlxDataSourceTaskMdeCommand::SendProgressMessageL(TInt aCurrentStep, TInt aStepCount)
       
   727 	{
       
   728     TRACER("CGlxDataSourceTaskMdeCommand::SendProgressMessageL()");
       
   729 	MGlxDataSourceUpdateObserver& observer = 
       
   730 	static_cast<CGlxCommandRequest*>(iRequest)->DataSourceUpdateObserver();
       
   731 	
       
   732 	const CMPXCommand& command = static_cast<CGlxCommandRequest*>(iRequest)->Command();
       
   733 	__ASSERT_DEBUG(command.IsSupported(KMPXCommandGeneralSessionId), Panic(
       
   734 	        EGlxPanicCommandHasNoGeneralSessionId));
       
   735 	
       
   736 	TAny* sessionId = command.ValueTObjectL<TAny*>(KMPXCommandGeneralSessionId);
       
   737 	
       
   738 	CMPXMessage* progressMessage = CMPXMessage::NewL();
       
   739 	CleanupStack::PushL(progressMessage);
       
   740 	progressMessage->SetTObjectValueL<TInt>(KMPXMessageGeneralId, KMPXMessageContentIdProgress);	
       
   741 	progressMessage->SetTObjectValueL<TInt>(TMPXAttribute(KMPXMessageContentIdProgress, 
       
   742 	        EMPXMessageProgressCurrentCount), aCurrentStep);
       
   743 	progressMessage->SetTObjectValueL<TInt>(TMPXAttribute(KMPXMessageContentIdProgress,
       
   744 	        EMPXMessageProgressTotalCount), aStepCount);
       
   745 	progressMessage->SetTObjectValueL<TAny*>(KMPXCommandGeneralSessionId, sessionId);
       
   746 	
       
   747 	observer.HandleMessage(*progressMessage);
       
   748 	
       
   749 	CleanupStack::PopAndDestroy(progressMessage);
       
   750 	}
       
   751 
       
   752 // ----------------------------------------------------------------------------
       
   753 // CGlxDataSourceTaskMdeCommand::ContainerObjectDef
       
   754 // ----------------------------------------------------------------------------
       
   755 //
       
   756 TInt CGlxDataSourceTaskMdeCommand::ContainerObjectDef(CMdEObjectDef*& aContainerObjectDef)
       
   757 {
       
   758     TRACER("CGlxDataSourceTaskMdeCommand::ContainerObjectDef()");
       
   759     TInt err = KErrNone;
       
   760 	if (iCollectionUid == TUid::Uid(KGlxTagCollectionPluginImplementationUid))
       
   761         {
       
   762         aContainerObjectDef  = &DataSource()->TagDef();      
       
   763         }
       
   764     else if (iCollectionUid  == TUid::Uid(KGlxCollectionPluginAlbumsImplementationUid))
       
   765         {
       
   766         aContainerObjectDef  = &DataSource()->AlbumDef();
       
   767         }
       
   768     else if(iCollectionUid  == TUid::Uid(KGlxCollectionPluginAllImplementationUid))
       
   769         {
       
   770         aContainerObjectDef  = &DataSource()->MediaDef();
       
   771         }
       
   772     else
       
   773     	{
       
   774     	err = KErrNotFound;
       
   775     	}
       
   776 	return err;
       
   777 }
       
   778 
       
   779 // ----------------------------------------------------------------------------
       
   780 // CGlxDataSourceTaskMdeCommand::DoHandleAddToContainerQueryCompletedL
       
   781 // ----------------------------------------------------------------------------
       
   782 //
       
   783 void CGlxDataSourceTaskMdeCommand::DoHandleAddToContainerQueryCompletedL
       
   784 															(CMdEQuery& aQuery)
       
   785 	{
       
   786     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleAddToContainerQueryCompletedL()");
       
   787 	RPointerArray<CMdEInstanceItem> relations;
       
   788 	CleanupClosePushL(relations);
       
   789 	 
       
   790 	TInt leftCount = iLeftIds.Count();
       
   791 	User::LeaveIfError(relations.Reserve(leftCount)); // this is a bigest reservation that could be required.
       
   792     for (TInt leftPos = 0; leftPos < leftCount; leftPos++)
       
   793         {
       
   794         TInt rightCount = iRightIds.Count();
       
   795         for (TInt rightPos = 0; rightPos < rightCount; rightPos++)
       
   796             {
       
   797             // Check to see if id already exists
       
   798             TBool alreadyExists = EFalse;
       
   799             for(TInt queryPos = aQuery.Count() - 1; queryPos >= 0; queryPos--)
       
   800                 {
       
   801                 CMdERelation& relation = static_cast<CMdERelation&>(aQuery.ResultItem(queryPos));
       
   802                 if (relation.LeftObjectId() == iLeftIds[leftPos]
       
   803                     && relation.RightObjectId() == iRightIds[rightPos])
       
   804                     {
       
   805                     alreadyExists = ETrue;
       
   806                     break;
       
   807                     }
       
   808                 }
       
   809             
       
   810             if (!alreadyExists)
       
   811                 {
       
   812                 CMdERelation* relation = DataSource()->Session().NewRelationL(
       
   813                         DataSource()->ContainsDef(), iLeftIds[leftPos], iRightIds[rightPos]);
       
   814                 CleanupStack::PushL(relation);
       
   815                 relations.AppendL(relation);
       
   816                 CleanupStack::Pop(relation);
       
   817                 }
       
   818             }
       
   819         
       
   820         }
       
   821 
       
   822     if (relations.Count())
       
   823     	{
       
   824     	User::LeaveIfError(DataSource()->Session().AddItemsL(relations));
       
   825     	}
       
   826     
       
   827     CleanupStack::PopAndDestroy(&relations);
       
   828 
       
   829     iLeftIds.Reset();
       
   830     iRightIds.Reset();
       
   831 	}
       
   832 
       
   833 // ----------------------------------------------------------------------------
       
   834 // CGlxDataSourceTaskMdeCommand::DoHandleAddContainerQueryCompletedL
       
   835 // ----------------------------------------------------------------------------
       
   836 //
       
   837 void CGlxDataSourceTaskMdeCommand::DoHandleAddContainerQueryCompletedL
       
   838 															(CMdEQuery& aQuery)
       
   839 
       
   840 	{
       
   841     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleAddContainerQueryCompletedL()");
       
   842    	
       
   843    	//Duplicate albums check for the default albums i.e. Favourites 
       
   844    	//as title property is left blank in MDS 2.5
       
   845    	if(iCollectionUid == TUid::Uid(KGlxCollectionPluginAlbumsImplementationUid))
       
   846    		{
       
   847    		if(SearchStringL(R_ALBUM_FAVORITES_TITLE) == 0 || 
       
   848    				SearchStringL(R_ALBUM_CAMERA_TITLE) == 0 )
       
   849     		{
       
   850     		User::Leave(KErrAlreadyExists);	
       
   851     		}        	
       
   852    		}
       
   853    	   	
       
   854     if (aQuery.Count())
       
   855         {
       
   856         // An object (or more strickly objects) with the given container name already exist
       
   857         User::Leave(KErrAlreadyExists);
       
   858         }
       
   859      
       
   860     CMdEObject* object = NULL;
       
   861     CMdEObjectDef* containerObjectDef = NULL;
       
   862     TInt err = ContainerObjectDef(containerObjectDef );
       
   863     __ASSERT_ALWAYS(err == KErrNone, Panic(EGlxPanicInvalidCollectionUid));
       
   864     
       
   865     object = DataSource()->Session().NewObjectLC(*containerObjectDef, KNullDesC);
       
   866     
       
   867     // A title property def of type text is required.
       
   868     CMdEPropertyDef& titlePropertyDef = containerObjectDef->GetPropertyDefL(
       
   869             KPropertyDefNameTitle);
       
   870     if (titlePropertyDef.PropertyType() != EPropertyText)
       
   871         {
       
   872         User::Leave(KErrCorrupt);
       
   873         }
       
   874     // Set the object title.
       
   875     object->AddTextPropertyL(titlePropertyDef, *iTitle);
       
   876     
       
   877       //ItemType property def of type text is required.
       
   878     CMdEPropertyDef& itemTypePropertyDef = containerObjectDef->GetPropertyDefL(
       
   879             KPropertyDefItemType);
       
   880     if (itemTypePropertyDef.PropertyType() != EPropertyText)
       
   881     	{
       
   882     	User::Leave(KErrCorrupt);
       
   883     	}
       
   884   
       
   885     // Checks the Container type whether it is Tag or Album	
       
   886     if (iCollectionUid == TUid::Uid(KGlxTagCollectionPluginImplementationUid))
       
   887       {
       
   888       object->AddTextPropertyL (itemTypePropertyDef, KTagItemType);
       
   889       }
       
   890     else
       
   891       {
       
   892       object->AddTextPropertyL (itemTypePropertyDef, KAlbumItemType);
       
   893       }
       
   894    
       
   895    
       
   896     // A size property is required.
       
   897   
       
   898     CMdEPropertyDef& sizePropertyDef = containerObjectDef->GetPropertyDefL(
       
   899             KPropertyDefNameSize);
       
   900     if (sizePropertyDef.PropertyType() != EPropertyUint32)
       
   901         {
       
   902         User::Leave(KErrCorrupt);
       
   903         }
       
   904     object->AddUint32PropertyL(sizePropertyDef,0);
       
   905 
       
   906     
       
   907     // A creation date property is required.
       
   908     CMdEPropertyDef& creationDateDef = containerObjectDef->GetPropertyDefL(
       
   909             KPropertyDefNameCreationDate);
       
   910     if (creationDateDef.PropertyType() != EPropertyTime)
       
   911         {
       
   912         User::Leave(KErrCorrupt);
       
   913         }
       
   914 
       
   915     // A last modified date property is required.
       
   916     CMdEPropertyDef& lmDateDef = containerObjectDef->GetPropertyDefL(
       
   917             KPropertyDefNameLastModifiedDate);
       
   918     if (lmDateDef.PropertyType() != EPropertyTime)
       
   919         {
       
   920         User::Leave(KErrCorrupt);
       
   921         }
       
   922     
       
   923     TTime uTime;
       
   924     uTime.UniversalTime();
       
   925     object->AddTimePropertyL(creationDateDef, uTime);
       
   926     object->AddTimePropertyL(lmDateDef, uTime);
       
   927     
       
   928     TItemId id = DataSource()->Session().AddObjectL(*object);
       
   929     CleanupStack::PopAndDestroy(object);
       
   930     
       
   931     iResponse->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, id);
       
   932     iResponse->SetTObjectValueL<TMPXItemId>(KMPXMessageMediaGeneralId, id);  
       
   933     iResponse->SetTObjectValueL<TMPXChangeEventType>(KMPXMessageChangeEventType,
       
   934             EMPXItemInserted); 
       
   935 	}
       
   936 // ----------------------------------------------------------------------------
       
   937 // CGlxDataSourceTaskMdeCommand::DoHandleDeleteContainersQueryCompletedL
       
   938 // ----------------------------------------------------------------------------
       
   939 //
       
   940 void CGlxDataSourceTaskMdeCommand::DoHandleDeleteContainersQueryCompletedL
       
   941 															(CMdEQuery& aQuery)
       
   942 	{
       
   943     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleDeleteContainersQueryCompletedL()");
       
   944     CMdEPropertyDef& albumTypeProperty = DataSource()->AlbumDef().GetPropertyDefL(
       
   945             KPropertyDefNameAlbumType);
       
   946     TInt queryCount = aQuery.Count();
       
   947     
       
   948     RArray<TItemId> objectsForRemoval;
       
   949     CleanupClosePushL(objectsForRemoval);
       
   950     User::LeaveIfError(objectsForRemoval.Reserve(queryCount));
       
   951 
       
   952     RArray<TItemId> sucessfullyRemovedObjects;
       
   953     CleanupClosePushL(sucessfullyRemovedObjects);
       
   954     User::LeaveIfError(sucessfullyRemovedObjects.Reserve(queryCount));
       
   955     
       
   956     // Ensure that deletion is legal and that deletion
       
   957     for(TInt queryPos = 0; queryPos < queryCount; queryPos++)
       
   958         {
       
   959         CMdEObject& object = static_cast<CMdEObject&>(aQuery.ResultItem(queryPos));
       
   960   
       
   961         CMdEProperty* albumType;
       
   962         TInt albumTypeIndex = object.Property(albumTypeProperty, albumType);
       
   963         if (KErrNotFound != albumTypeIndex)
       
   964             {
       
   965             TInt albumTypeValue = static_cast<CMdEUint16Property*>(albumType)->Value();
       
   966             if ((albumTypeValue == MdeConstants::Album::EAlbumSystemFavourite) || 
       
   967             		(albumTypeValue == MdeConstants::Album::EAlbumSystemCamera))
       
   968                {
       
   969                User::Leave(KErrAccessDenied); 
       
   970                }
       
   971             }
       
   972         objectsForRemoval.AppendL(object.Id());
       
   973         }
       
   974     
       
   975     if (queryCount)
       
   976     	{
       
   977     	User::LeaveIfError(DataSource()->Session().RemoveObjectsL(objectsForRemoval, 
       
   978     	        sucessfullyRemovedObjects));
       
   979     	}
       
   980     
       
   981     CleanupStack::PopAndDestroy(&sucessfullyRemovedObjects);
       
   982     CleanupStack::PopAndDestroy(&objectsForRemoval);
       
   983 	}
       
   984 // ----------------------------------------------------------------------------
       
   985 // CGlxDataSourceTaskMdeCommand::DoHandleDeleteItemsContainersQueryCompletedL
       
   986 // ----------------------------------------------------------------------------
       
   987 //
       
   988 void CGlxDataSourceTaskMdeCommand::DoHandleDeleteItemsQueryCompletedL
       
   989 															(CMdEQuery& aQuery)
       
   990 	{
       
   991     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleDeleteItemsQueryCompletedL()");
       
   992     TInt deleteItemCounter = 0;
       
   993     ContentAccess::CManager *manager = ContentAccess::CManager::NewL();
       
   994     CleanupStack::PushL(manager);
       
   995     TInt queryCount = aQuery.Count();
       
   996     RArray<TItemId> objectsForRemoval;
       
   997     CleanupClosePushL(objectsForRemoval);
       
   998     User::LeaveIfError(objectsForRemoval.Reserve(queryCount));
       
   999 
       
  1000     RArray<TItemId> sucessfullyRemovedObjects;
       
  1001     CleanupClosePushL(sucessfullyRemovedObjects);
       
  1002     User::LeaveIfError(sucessfullyRemovedObjects.Reserve(queryCount));
       
  1003     //Handle to a file server session
       
  1004     RFs fs; 
       
  1005     // Pushing the handle in Clean-up Stack to call Close() on file server session 
       
  1006     CleanupClosePushL( fs );
       
  1007     //Connects a client to the file server
       
  1008     User::LeaveIfError( fs.Connect() );
       
  1009     
       
  1010     TInt lastErr = KErrNone;
       
  1011     
       
  1012     // If Delete operation is cancelled before completion, 
       
  1013     // iCancelled because ETrue, break out of for loop.
       
  1014     for(TInt queryPos = queryCount - 1; (queryPos >= 0 && !iCancelled); queryPos--)
       
  1015         {
       
  1016         CMdEObject& object = static_cast<CMdEObject&>(aQuery.ResultItem(queryPos));
       
  1017         //Removes the Read Only attributes of the file 
       
  1018         fs.SetAtt(object.Uri(), 0, KEntryAttReadOnly);
       
  1019         TInt err = manager->DeleteFile(object.Uri());
       
  1020         if (err != KErrNone)
       
  1021         	{
       
  1022         	lastErr = err;
       
  1023         	}    
       
  1024         else
       
  1025             {    
       
  1026             // On successful deletion, delete the same from database
       
  1027             objectsForRemoval.AppendL(object.Id());
       
  1028             }
       
  1029 			 
       
  1030         // After every 50 items are deleted, break from the for loop 
       
  1031         // and process other pending requests if any
       
  1032         if(deleteItemCounter == KDeletedItemCount)
       
  1033 			{	
       
  1034 			iTimer->Start( KDeleteOperationInterval, KDeleteOperationInterval,
       
  1035 							TCallBack( &SchedulerStopCallback, (TAny *)this ) );	
       
  1036 			iSchedulerWait->Start();  
       
  1037 			deleteItemCounter = 0;
       
  1038 			}     
       
  1039         deleteItemCounter++;     
       
  1040         }
       
  1041     // Calling Close() on file server session 
       
  1042     CleanupStack::PopAndDestroy( &fs );
       
  1043     
       
  1044     User::LeaveIfError(lastErr);
       
  1045     
       
  1046     if (queryCount)
       
  1047     	{
       
  1048     	// Some objects may have already been removed by the harvester
       
  1049     	DataSource()->Session().RemoveObjectsL(objectsForRemoval, sucessfullyRemovedObjects);
       
  1050     	}
       
  1051     
       
  1052     CleanupStack::PopAndDestroy(&sucessfullyRemovedObjects);
       
  1053     CleanupStack::PopAndDestroy(&objectsForRemoval);
       
  1054     
       
  1055     CleanupStack::PopAndDestroy(manager);
       
  1056 	}
       
  1057 
       
  1058 // ----------------------------------------------------------------------------
       
  1059 //  CGlxDataSourceTaskMdeCommand::DoHandleRenameConainerQueryCompletedL
       
  1060 // ----------------------------------------------------------------------------
       
  1061 //
       
  1062 void CGlxDataSourceTaskMdeCommand::DoHandleRenameConainerQueryCompletedL
       
  1063                                                             (CMdEQuery& aQuery)
       
  1064 	{
       
  1065     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleRenameConainerQueryCompletedL()");
       
  1066 	__ASSERT_DEBUG(iObjectToRename, Panic(EGlxPanicLogicError));
       
  1067 	if (aQuery.Count())
       
  1068 		{
       
  1069 		User::Leave(KErrAlreadyExists);
       
  1070 		}
       
  1071 		
       
  1072 	CMdEObject* object = DataSource()->Session().OpenObjectL(iObjectToRename->Id(), iObjectToRename->Def());
       
  1073 	CleanupStack::PushL(object);
       
  1074     CMdEProperty* albumType;
       
  1075     // @todo AB test this
       
  1076     CMdEPropertyDef* albumTypeProperty = NULL;
       
  1077     TRAP_IGNORE(albumTypeProperty = &object->Def().GetPropertyDefL(KPropertyDefNameAlbumType));       
       
  1078     TInt albumTypeIndex = KErrNotFound;
       
  1079     // Must guard against non-existance of albumTypeProperty (e.g. when renaming a tag)
       
  1080     if (albumTypeProperty)
       
  1081         {
       
  1082         albumTypeIndex = object->Property(*albumTypeProperty, albumType);
       
  1083         }
       
  1084     if( KErrNotFound != albumTypeIndex )
       
  1085         {
       
  1086         TInt albumTypeValue = static_cast<CMdEUint16Property*>(albumType)->Value();
       
  1087         if ( albumTypeValue == MdeConstants::Album::EAlbumUserPredefined ) 
       
  1088             {
       
  1089             // Want to rename a predefined, localised album name so reclassify
       
  1090             // the type to be a non-localised user defined album
       
  1091             static_cast<CMdEUint16Property*>(albumType)->SetValueL(MdeConstants::Album::EAlbumUser);
       
  1092             }
       
  1093 		else if ((albumTypeValue == MdeConstants::Album::EAlbumSystemFavourite) || 
       
  1094 				(albumTypeValue == MdeConstants::Album::EAlbumSystemCamera))
       
  1095 		    {
       
  1096             // Cannot rename system albums
       
  1097 		    User::Leave(KErrAccessDenied); 
       
  1098 		    }
       
  1099         }
       
  1100 
       
  1101     
       
  1102     CMdEPropertyDef& titlePropertyDef = object->Def().GetPropertyDefL(KPropertyDefNameTitle);
       
  1103     if (titlePropertyDef.PropertyType() != EPropertyText)
       
  1104     	{
       
  1105     	User::Leave(KErrCorrupt);
       
  1106     	}
       
  1107     
       
  1108     CMdEProperty* titleProperty = NULL;
       
  1109     TInt index = object->Property(titlePropertyDef, titleProperty);
       
  1110     if (index < KErrNotFound)
       
  1111     	{
       
  1112     	User::Leave(index);
       
  1113     	}
       
  1114     if (index != KErrNotFound)
       
  1115     	{
       
  1116     	// Remove the old property
       
  1117     	object->RemoveProperty(index);
       
  1118     	}
       
  1119     // Set the object title
       
  1120     object->AddTextPropertyL(titlePropertyDef, *iTitle);
       
  1121     
       
  1122     // Get time propertydef of current session object
       
  1123     CMdEPropertyDef& timePropertyDef = object->Def().GetPropertyDefL(
       
  1124         KPropertyDefNameLastModifiedDate);
       
  1125         
       
  1126     // Check the validty of the time def
       
  1127     if (timePropertyDef.PropertyType() != EPropertyTime)
       
  1128     	{
       
  1129     	User::Leave(KErrCorrupt);
       
  1130     	}
       
  1131     	
       
  1132     // Get index and check the validity 
       
  1133     CMdEProperty* timeProperty = NULL;
       
  1134     index = object->Property(timePropertyDef, timeProperty);
       
  1135     
       
  1136     if (index < KErrNotFound)
       
  1137     	{
       
  1138     	User::Leave(index);
       
  1139     	}
       
  1140     	
       
  1141     if (index != KErrNotFound)
       
  1142     	{
       
  1143     	// Remove the old property
       
  1144     	object->RemoveProperty(index);
       
  1145     	}
       
  1146     	
       
  1147     // Take current universal time
       
  1148     TTime currentTime;
       
  1149     currentTime.UniversalTime();
       
  1150 
       
  1151     // Set the object current time
       
  1152     object->AddTimePropertyL(timePropertyDef, currentTime);
       
  1153     
       
  1154     DataSource()->Session().CommitObjectL(*object);
       
  1155     CleanupStack::PopAndDestroy(object);
       
  1156 	}
       
  1157 
       
  1158 // ----------------------------------------------------------------------------
       
  1159 //  CGlxDataSourceTaskMdeCommand::DoHandleRenameConainerQueryCompletedL
       
  1160 // ----------------------------------------------------------------------------
       
  1161 //
       
  1162 void CGlxDataSourceTaskMdeCommand::DoHandleRenameQueryCompletedL
       
  1163                                                            (CMdEQuery& aQuery)
       
  1164 	{
       
  1165     TRACER("CGlxDataSourceTaskMdeCommand::DoHandleRenameQueryCompletedL()");
       
  1166 	__ASSERT_DEBUG(aQuery.Count() == 1, Panic(EGlxPanicUnexpectedQueryResultCount ));
       
  1167 	delete iObjectToRename;
       
  1168 	iObjectToRename = static_cast<CMdEObject*>(aQuery.TakeOwnershipOfResult(0));
       
  1169 	
       
  1170     CMdEObjectDef* containerObjectDef = NULL;
       
  1171     TInt err = ContainerObjectDef(containerObjectDef);
       
  1172 	if (err == KErrNone)
       
  1173 		{
       
  1174 		AppendContainerTitleCountQueryL(ECommandRenameContainer, *iTitle);
       
  1175 		}
       
  1176 	}
       
  1177 
       
  1178 // ----------------------------------------------------------------------------
       
  1179 //  CGlxDataSourceTaskMdeCommand::AppendContainerTitleCountQueryL
       
  1180 // ----------------------------------------------------------------------------
       
  1181 //
       
  1182 void  CGlxDataSourceTaskMdeCommand::AppendContainerTitleCountQueryL
       
  1183                         (const TGlxQueryType& aQueryType, const TDesC& aTitle)
       
  1184 	{
       
  1185     TRACER("CGlxDataSourceTaskMdeCommand::AppendContainerTitleCountQueryL()");
       
  1186 	// Test to see if a container alerady exists in the database with aContainerName
       
  1187     CMdEObjectDef* containerObjectDef = NULL;
       
  1188     TInt err = ContainerObjectDef(containerObjectDef);
       
  1189     __ASSERT_ALWAYS(err == KErrNone, Panic(EGlxPanicInvalidCollectionUid));
       
  1190     
       
  1191     CMdEQuery* query = DataSource()->Session().NewObjectQueryL(*DataSource()->NamespaceDef(),
       
  1192             *containerObjectDef, this);
       
  1193     CleanupStack::PushL(query);
       
  1194     
       
  1195     CMdEPropertyDef& titlePropertyDef = DataSource()->ObjectDef().GetPropertyDefL(
       
  1196             KPropertyDefNameTitle);
       
  1197     
       
  1198     query->SetResultMode(EQueryResultModeCount);
       
  1199     
       
  1200     query->Conditions().AddPropertyConditionL(titlePropertyDef, 
       
  1201             ETextPropertyConditionCompareEquals, aTitle);
       
  1202     
       
  1203     CleanupStack::Pop(query);
       
  1204     
       
  1205     AppendQueryL(query, aQueryType); 
       
  1206 	}
       
  1207 
       
  1208 // ----------------------------------------------------------------------------
       
  1209 //  CGlxDataSourceTaskMdeCommand::SearchString
       
  1210 // ----------------------------------------------------------------------------
       
  1211 //	
       
  1212 TInt CGlxDataSourceTaskMdeCommand::SearchStringL(TInt aResourceId)
       
  1213 	{
       
  1214 	TRACER("CGlxDataSourceTaskMdeCommand::SearchStringL()");
       
  1215 	_LIT(KResourceFile, "z:glxpluginalbums.rsc");	
       
  1216    	
       
  1217    	if (!iStringCache)
       
  1218         {
       
  1219         iStringCache = CGlxStringCache::NewL();
       
  1220         }        
       
  1221     //Get the localized string from the cache    
       
  1222 	HBufC* string = iStringCache->LoadLocalizedStringLC(KResourceFile,aResourceId);		
       
  1223 	
       
  1224 	TInt result = string->CompareF(iTitle->Des());
       
  1225 	
       
  1226 	CleanupStack::PopAndDestroy(string);
       
  1227     
       
  1228     return result;    
       
  1229         	
       
  1230 	}
       
  1231 
       
  1232 // ----------------------------------------------------------------------------
       
  1233 //  CGlxDataSourceTaskMdeCommand::SchedulerStopCallback
       
  1234 // ----------------------------------------------------------------------------
       
  1235 //
       
  1236 TInt CGlxDataSourceTaskMdeCommand::SchedulerStopCallback(TAny* aPtr)
       
  1237     {
       
  1238     TRACER("CGlxDataSourceTaskMdeCommand::SchedulerStopCallback");
       
  1239     
       
  1240     CGlxDataSourceTaskMdeCommand* self = (CGlxDataSourceTaskMdeCommand*) aPtr;
       
  1241     if ( self )
       
  1242         {
       
  1243         self->SchedulerStopComplete();
       
  1244         }
       
  1245 
       
  1246     return KErrNone;
       
  1247     }
       
  1248 
       
  1249 // -----------------------------------------------------------------------------
       
  1250 // SchedulerStopComplete
       
  1251 // -----------------------------------------------------------------------------
       
  1252 //
       
  1253 void CGlxDataSourceTaskMdeCommand::SchedulerStopComplete()
       
  1254     {
       
  1255     TRACER("CGlxDataSourceTaskMdeCommand::SchedulerStopComplete");  
       
  1256     
       
  1257     if(iTimer && iTimer->IsActive())
       
  1258     	{
       
  1259     	iTimer->Cancel();
       
  1260     	}
       
  1261     
       
  1262     if(iSchedulerWait)
       
  1263 		{		
       
  1264 		iSchedulerWait->AsyncStop();    
       
  1265 		}  
       
  1266     }