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