harvester/composerplugins/imagecomposer/src/imagecomposerao.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2006-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:  Composer image active object
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <e32debug.h>
       
    21 
       
    22 #include <mderelation.h>
       
    23 #include <mderelationquery.h>
       
    24 #include <mdelogiccondition.h>
       
    25 
       
    26 #include "mdeharvestersession.h"
       
    27 #include "mdeproperty.h"
       
    28 #include "mdenamespacedef.h"
       
    29 #include "imagecomposerao.h"
       
    30 #include "harvesterlog.h"
       
    31 #include "mdeconstants.h"
       
    32 #include "mdsutils.h"
       
    33 #include "mderelationcondition.h"
       
    34 #include "mdeobjectdef.h"
       
    35 #include "harvestercommon.h"
       
    36 
       
    37 using namespace MdeConstants;
       
    38 
       
    39 _LIT( KJpegMimeType, "image/jpeg" );
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // NewL
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 CImageComposerAO* CImageComposerAO::NewL()
       
    46     {
       
    47     WRITELOG( "CImageComposerAO::NewL()" );
       
    48 
       
    49     CImageComposerAO* self = new (ELeave) CImageComposerAO();
       
    50     CleanupStack::PushL( self );
       
    51     self->ConstructL();
       
    52     CleanupStack::Pop( self );
       
    53     return self;
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // ~CImageComposerAO
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CImageComposerAO::~CImageComposerAO() // destruct
       
    61     {   
       
    62     WRITELOG( "CImageComposerAO::~CImageComposerAO()" );
       
    63     
       
    64     Cancel();
       
    65     
       
    66     iItemQueue.Close();
       
    67     
       
    68     iForceObjectIds.Close();
       
    69     iNextItemsSkip.Close();
       
    70     
       
    71     if ( iMdeObject )
       
    72         {
       
    73         delete iMdeObject;
       
    74         }
       
    75     if ( iExifUtil )
       
    76     	{
       
    77     	delete iExifUtil;
       
    78     	}
       
    79 
       
    80     delete iRelationQuery;
       
    81     iFs.Close();
       
    82     
       
    83     delete iMdEHarvesterSession;
       
    84     }
       
    85 
       
    86 // ---------------------------------------------------------------------------
       
    87 // CComposerImagePlugin
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 CImageComposerAO::CImageComposerAO() : // first-phase C++ constructor
       
    91 		CActive( KHarvesterPriorityComposerPlugin )
       
    92     {
       
    93     WRITELOG( "CImageComposerAO::CImageComposerAO()" );
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // ConstructL
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 void CImageComposerAO::ConstructL() // second-phase constructor
       
   101     {
       
   102     WRITELOG( "CImageComposerAO::ConstructL()" );
       
   103     iMdeObject = NULL;
       
   104     iNextRequest = ERequestReady;
       
   105     iDefaultNamespace = NULL;
       
   106     iImageObjectDef = NULL;
       
   107     iObjectDef = NULL;
       
   108     iLocationObjectDef = NULL;
       
   109 
       
   110     CActiveScheduler::Add( this );
       
   111     
       
   112     iExifUtil = CHarvesterExifUtil::NewL();
       
   113     User::LeaveIfError( iFs.Connect() );
       
   114     }
       
   115     
       
   116 // ---------------------------------------------------------------------------
       
   117 // DoCancel
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 void CImageComposerAO::DoCancel()
       
   121     {
       
   122     WRITELOG( "CImageComposerAO::DoCancel()" );
       
   123     }
       
   124     
       
   125 // ---------------------------------------------------------------------------
       
   126 // AddToQueue
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 void CImageComposerAO::AddToQueue( const RArray<TItemId>& aItems, TBool aForce )
       
   130     {
       
   131     WRITELOG( "CImageComposerAO::AddToQueue()" );
       
   132     
       
   133     // check if we should skip some items
       
   134     const TInt itemsCount = aItems.Count();
       
   135     for ( TInt i = 0; i < itemsCount; ++i )
       
   136         {
       
   137         TInt res = iNextItemsSkip.FindInOrder( aItems[i],
       
   138         		TLinearOrder<TItemId>( CImageComposerAO::CompareTItemIds ) );
       
   139         if ( res != KErrNotFound && res >= 0 )
       
   140             {
       
   141             RArray<TItemId> objectId;
       
   142             objectId.Append( aItems[i] );
       
   143             TRAP_IGNORE( iMdEHarvesterSession->ResetPendingL( objectId ) );
       
   144             iNextItemsSkip.Remove( res );
       
   145             
       
   146             if( iNextItemsSkip.Count() == 0 )
       
   147             	{
       
   148             	iNextItemsSkip.Compress();
       
   149             	}
       
   150             objectId.Close();
       
   151             }
       
   152         else
       
   153             {
       
   154             iItemQueue.Append( aItems[i] );
       
   155             if ( aForce )
       
   156             	{
       
   157             	iForceObjectIds.Append( aItems[i] );
       
   158             	}
       
   159             }
       
   160         }
       
   161     if ( iNextRequest == ERequestReady )
       
   162     	{
       
   163     	SetNextRequest( ERequestGetObject );
       
   164     	}
       
   165     }
       
   166     
       
   167 // ---------------------------------------------------------------------------
       
   168 // IsComposingComplete()
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 TBool CImageComposerAO::IsComposingComplete()
       
   172     {
       
   173     WRITELOG( "CImageComposerAO::IsComposingComplete()" );
       
   174     return iNextRequest == ERequestReady;
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------------------------
       
   178 // SetSession
       
   179 // ---------------------------------------------------------------------------
       
   180 //
       
   181 void CImageComposerAO::SetSession( CMdESession* aSession )
       
   182     {
       
   183     WRITELOG( "CImageComposerAO::SetSession()" );
       
   184     iSession = aSession;
       
   185     iExifUtil->SetSession(iSession);
       
   186     if( iSession )
       
   187     	{
       
   188     	iDefaultNamespace = NULL;
       
   189     	TRAP_IGNORE( iDefaultNamespace = &iSession->GetDefaultNamespaceDefL() );
       
   190     	
       
   191     	TRAP_IGNORE( iImageObjectDef = &iDefaultNamespace->GetObjectDefL( 
       
   192     			Image::KImageObject ) );
       
   193     	TRAP_IGNORE( iObjectDef = &iDefaultNamespace->GetObjectDefL( 
       
   194     			Object::KBaseObject ) );
       
   195     	TRAP_IGNORE( iLocationObjectDef = &iDefaultNamespace->GetObjectDefL( 
       
   196     			Location::KLocationObject ) );
       
   197     	
       
   198     	
       
   199 		iMdEHarvesterSession = NULL;
       
   200     	TRAP_IGNORE( iMdEHarvesterSession 
       
   201     	        = CMdEHarvesterSession::NewL ( *iSession ));
       
   202     	}
       
   203     }
       
   204 
       
   205 // ---------------------------------------------------------------------------
       
   206 // RemoveSession
       
   207 // ---------------------------------------------------------------------------
       
   208 //
       
   209 void CImageComposerAO::RemoveSession()
       
   210     {
       
   211     iSession = NULL;
       
   212     iExifUtil->SetSession( NULL );
       
   213 
       
   214     delete iMdEHarvesterSession;
       
   215     iMdEHarvesterSession = NULL;
       
   216     
       
   217     iDefaultNamespace = NULL;
       
   218     iImageObjectDef = NULL;
       
   219     iObjectDef = NULL;
       
   220     iLocationObjectDef = NULL;
       
   221     }
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // RunL
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 void CImageComposerAO::RunL()
       
   228     {
       
   229     WRITELOG( "CImageComposerAO::RunL()" );
       
   230     User::LeaveIfError( iStatus.Int() );
       
   231     
       
   232     if ( !iDefaultNamespace && iSession )
       
   233         {
       
   234         iDefaultNamespace = &iSession->GetDefaultNamespaceDefL();
       
   235         }
       
   236     
       
   237     switch ( iNextRequest )
       
   238         {
       
   239         case ERequestGetObject:
       
   240             {
       
   241             if( iItemQueue.Count() <= 0 )
       
   242             	{
       
   243             	SetNextRequest( ERequestReady );
       
   244             	}
       
   245             else
       
   246             	{
       
   247             	TItemId mdeObjectId = KNoId;
       
   248 	            TRAPD( err, GetObjectFromMdeL( mdeObjectId ) );
       
   249 	            
       
   250 	            if ( err == KErrNone )
       
   251 	                {    
       
   252 	                SetNextRequest( ERequestCompose );
       
   253 	                }
       
   254 	            // if object does not exists, find next
       
   255 	            else if ( err == KErrNotFound || err == KErrAbort )
       
   256 	                 {
       
   257 	                 if ( err == KErrAbort && mdeObjectId != KNoId )
       
   258 	                	 {
       
   259 		                 RArray<TItemId> objectId;
       
   260 		                 objectId.Append( mdeObjectId );
       
   261 		                 CleanupClosePushL( objectId );
       
   262 		                 iMdEHarvesterSession->ResetPendingL( objectId );
       
   263 		                 CleanupStack::PopAndDestroy( &objectId );
       
   264 	                	 }
       
   265 	                 SetNextRequest( ERequestGetObject );
       
   266 	                 }
       
   267 	                 
       
   268 	            // something goes really wrong
       
   269 	            else
       
   270 	                 {
       
   271 	                 User::Leave( err );
       
   272 	                 }
       
   273             	}
       
   274 
       
   275             }
       
   276             break;
       
   277             
       
   278         case ERequestCompose:
       
   279             {
       
   280             ComposeL();
       
   281 
       
   282             if ( iMdeObject )
       
   283                 {
       
   284                 RArray<TItemId> objectId;
       
   285                 objectId.Append( iMdeObject->Id() );
       
   286                 TRAP_IGNORE( iMdEHarvesterSession->ResetPendingL( objectId ) );
       
   287                 objectId.Close();
       
   288 
       
   289                 delete iMdeObject;
       
   290                 iMdeObject = NULL;
       
   291                 }
       
   292             }
       
   293             break;
       
   294             
       
   295         case ERequestReady:
       
   296             {
       
   297             }
       
   298             break;
       
   299             
       
   300         default:
       
   301             {
       
   302             User::Leave( KErrUnknown );
       
   303             }
       
   304             break;
       
   305         }
       
   306     }
       
   307     
       
   308 // ---------------------------------------------------------------------------
       
   309 // RunError
       
   310 // ---------------------------------------------------------------------------
       
   311 //
       
   312 #ifdef _DEBUG
       
   313 TInt CImageComposerAO::RunError( TInt aError )
       
   314 #else
       
   315 TInt CImageComposerAO::RunError( TInt )
       
   316 #endif
       
   317     {
       
   318     WRITELOG1( "CImageComposerAO::RunError() - error code: %d", aError );
       
   319     if ( iMdeObject && iSession )
       
   320     	{
       
   321     	TRAP_IGNORE( iSession->CancelObjectL( *iMdeObject ) );
       
   322     	}
       
   323     SetNextRequest( ERequestGetObject );
       
   324 
       
   325     return KErrNone;
       
   326     }
       
   327 
       
   328 // ---------------------------------------------------------------------------
       
   329 // GetObjectFromMde
       
   330 // ---------------------------------------------------------------------------
       
   331 //
       
   332 void CImageComposerAO::GetObjectFromMdeL(TItemId& aMdEObjectId)
       
   333     {
       
   334 #ifdef _DEBUG
       
   335     _LIT( KPanicCategoryNsd, "NSD=NULL" );
       
   336     _LIT( KPanicCategoryOd,  "OD=NULL" );
       
   337     _LIT( KPanicCategoryId,  "ID=NULL" );
       
   338     _LIT( KPanicCategoryLd,  "LD=NULL" );
       
   339     __ASSERT_DEBUG( iDefaultNamespace, User::Panic( KPanicCategoryNsd, KErrBadHandle ) );
       
   340     __ASSERT_DEBUG( iObjectDef, User::Panic( KPanicCategoryOd,  KErrBadHandle ) );
       
   341     __ASSERT_DEBUG( iImageObjectDef, User::Panic( KPanicCategoryId,  KErrBadHandle ) );
       
   342     __ASSERT_DEBUG( iLocationObjectDef, User::Panic( KPanicCategoryLd,  KErrBadHandle ) );
       
   343 #endif    
       
   344     
       
   345     WRITELOG( "CImageComposerAO::GetObjectFromMdeL() - start" );
       
   346     
       
   347     if ( !iSession )
       
   348     	{
       
   349     	WRITELOG( "CImageComposerAO::GetObjectFromMdeL() - iSession is NULL" );
       
   350     	User::Leave( KErrSessionClosed );
       
   351     	}
       
   352 
       
   353     TItemId objectId = KNoId;
       
   354     
       
   355     // get the object id from queue
       
   356     if( iItemQueue.Count() > 0 )
       
   357     	{
       
   358     	objectId = iItemQueue[0];
       
   359     	aMdEObjectId = objectId;
       
   360     	iItemQueue.Remove( 0 );
       
   361     	}
       
   362     else
       
   363     	{
       
   364     	iItemQueue.Compress();
       
   365     	}
       
   366     
       
   367     // get object from db (NULL if not found)
       
   368     CMdEObject* mdeObject = iSession->GetObjectL( objectId, *iImageObjectDef );
       
   369 
       
   370     CleanupStack::PushL( mdeObject );
       
   371     
       
   372     if ( !mdeObject )
       
   373         {
       
   374         WRITELOG1( "CImageComposerAO::GetObjectFromMdeL() - could not find object id %d", objectId );
       
   375         User::Leave( KErrNotFound );
       
   376         }
       
   377 
       
   378     TInt force;
       
   379     force = iForceObjectIds.Find( objectId );
       
   380     if ( force != KErrNotFound )
       
   381     	{
       
   382     	iForceObjectIds.Remove( force );
       
   383     	
       
   384     	if( iForceObjectIds.Count() == 0 )
       
   385     		{
       
   386     		iForceObjectIds.Compress();
       
   387     		}
       
   388     	}
       
   389     else
       
   390     	{
       
   391 	    // check if file's and object's last modified dates are equal
       
   392 	    CMdEPropertyDef& lastModifiedDatePropDef = mdeObject->Def().GetPropertyDefL( 
       
   393 	    		Object::KLastModifiedDateProperty );
       
   394 	    CMdEProperty* lastModifiedDateProp = NULL;
       
   395 	    mdeObject->Property( lastModifiedDatePropDef, lastModifiedDateProp );
       
   396 	    if( lastModifiedDateProp )
       
   397 	    	{
       
   398 	    	TTime time = ((CMdETimeProperty*)lastModifiedDateProp)->Value();
       
   399 	
       
   400 	    	TEntry entry;
       
   401 	    	TInt error = iFs.Entry( mdeObject->Uri(), entry );
       
   402 	
       
   403 	    	if( error != KErrNone || entry.iModified == time )
       
   404 	    		{
       
   405 	    		User::Leave( KErrAbort );
       
   406 	    		}
       
   407 	    	}
       
   408 	    else
       
   409 	    	{
       
   410 	    	User::Leave( KErrNotFound );
       
   411 	    	}   
       
   412     	}
       
   413     
       
   414     CleanupStack::Pop( mdeObject );
       
   415     iMdeObject = mdeObject;
       
   416     
       
   417     WRITELOG( "CImageComposerAO::GetObjectFromMdeL() - end" );
       
   418     }
       
   419 
       
   420 // ---------------------------------------------------------------------------
       
   421 // ComposeL
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 void CImageComposerAO::ComposeL()
       
   425     {
       
   426 #ifdef _DEBUG
       
   427     _LIT( KPanicCategoryNsd, "NSD=NULL" );
       
   428     _LIT( KPanicCategoryOd,  "OD=NULL" );
       
   429     _LIT( KPanicCategoryId,  "ID=NULL" );
       
   430     _LIT( KPanicCategoryLd,  "LD=NULL" );
       
   431     __ASSERT_DEBUG( iDefaultNamespace, User::Panic( KPanicCategoryNsd, KErrBadHandle ) );
       
   432     __ASSERT_DEBUG( iObjectDef, User::Panic( KPanicCategoryOd,  KErrBadHandle ) );
       
   433     __ASSERT_DEBUG( iImageObjectDef, User::Panic( KPanicCategoryId,  KErrBadHandle ) );
       
   434     __ASSERT_DEBUG( iLocationObjectDef, User::Panic( KPanicCategoryLd,  KErrBadHandle ) );
       
   435 #endif    
       
   436     
       
   437 #ifdef _DEBUG    
       
   438     WRITELOG( "CImageComposerAO::ComposeL()" );
       
   439     WRITELOG1( "CImageComposerAO::ComposeL() - Compose Start Object ID: %d", iMdeObject->Id() );
       
   440 #endif
       
   441 
       
   442     if ( !iSession )
       
   443     	{
       
   444     	WRITELOG( "CImageComposerAO::ComposeL() - iSession is NULL!" );
       
   445     	User::Leave( KErrSessionClosed );
       
   446     	}
       
   447 
       
   448     // 1. Read Exif image from the file to a buffer...
       
   449     RFile64 file;
       
   450     CleanupClosePushL( file );
       
   451     WRITELOG( "CImageComposerAO::ComposeL() - open file for reading" );
       
   452     User::LeaveIfError( file.Open( iFs, iMdeObject->Uri(), EFileRead ) );
       
   453 
       
   454     TInt64 dataSize = 0;
       
   455     file.Size( dataSize );
       
   456     HBufC8* exif = HBufC8::NewL( dataSize );
       
   457     CleanupStack::PushL( exif );
       
   458     TPtr8 exifPtr = exif->Des();
       
   459     User::LeaveIfError( file.Read( exifPtr ) );
       
   460     CleanupStack::Pop( exif );             // exif needs to be popped and pushed again
       
   461     CleanupStack::PopAndDestroy( &file );  // to get file out of CleanupStack
       
   462     CleanupStack::PushL( exif );
       
   463     
       
   464     HBufC8* modifiedExif = NULL;
       
   465     
       
   466     iExifUtil->ComposeExifDataL(*iMdeObject, exifPtr, modifiedExif);
       
   467    
       
   468     // modifiedExif is NULL if no changes were made
       
   469     if ( modifiedExif )
       
   470         {
       
   471         CleanupStack::PushL( modifiedExif );
       
   472         
       
   473         if ( !iMdeObject->OpenForModifications() )
       
   474             {
       
   475             // we have get version
       
   476             const TItemId objectId = iMdeObject->Id();
       
   477             delete iMdeObject;
       
   478             iMdeObject = NULL;
       
   479             iMdeObject = iSession->OpenObjectL( objectId, *iImageObjectDef );
       
   480             if ( !iMdeObject )
       
   481                 {
       
   482                 User::Leave( KErrAccessDenied );
       
   483                 }
       
   484             }
       
   485 
       
   486     	// set position to begin of file
       
   487         WRITELOG( "CImageComposerAO::ComposeL() - open file for writing" );
       
   488         User::LeaveIfError( file.Open( iFs, iMdeObject->Uri(), EFileWrite ) );
       
   489         CleanupClosePushL( file );
       
   490 
       
   491         TInt64 pos = 0;
       
   492         WRITELOG( "CImageComposerAO::ComposeL() - seek to position 0" );
       
   493         User::LeaveIfError( file.Seek( ESeekStart, pos ) );
       
   494 
       
   495         WRITELOG( "CImageComposerAO::ComposeL() - write buffer (exif) to file" );
       
   496         User::LeaveIfError( file.Write( modifiedExif->Des(), modifiedExif->Des().Length() ) );
       
   497 
       
   498         CleanupStack::PopAndDestroy( 2, modifiedExif ); // file, modifiedExif
       
   499         TEntry fileEntry;
       
   500         iFs.Entry( iMdeObject->Uri(), fileEntry );
       
   501 
       
   502         WRITELOG( "CImageComposerAO::ComposeL() - store Size and LastModifiedDate properties to MDE" );
       
   503         CMdEPropertyDef& sizePropDef = iImageObjectDef->GetPropertyDefL( Object::KSizeProperty );
       
   504             {
       
   505             CMdEProperty* sizeProp = NULL;
       
   506             iMdeObject->Property( sizePropDef, sizeProp, 0 );
       
   507 
       
   508             if ( sizeProp )
       
   509                 {
       
   510                 sizeProp->SetUint32ValueL( fileEntry.iSize );
       
   511                 }
       
   512             else
       
   513                 {
       
   514                 iMdeObject->AddUint32PropertyL( sizePropDef, fileEntry.iSize );
       
   515                 }
       
   516             }
       
   517 
       
   518         CMdEPropertyDef& lastModDatePropDef = iImageObjectDef->GetPropertyDefL(
       
   519         		Object::KLastModifiedDateProperty );
       
   520             {
       
   521             CMdEProperty* lastModDateProp = NULL;
       
   522             iMdeObject->Property( lastModDatePropDef, lastModDateProp, 0 );
       
   523 
       
   524             if ( lastModDateProp )
       
   525                 {
       
   526                 lastModDateProp->SetTimeValueL( fileEntry.iModified );
       
   527                 }
       
   528             else
       
   529                 {
       
   530                 iMdeObject->AddTimePropertyL( lastModDatePropDef, fileEntry.iModified );
       
   531                 }
       
   532             }
       
   533         iSession->CommitObjectL( *iMdeObject );
       
   534         iNextItemsSkip.InsertInOrder( iMdeObject->Id(),
       
   535         		TLinearOrder<TItemId>( CImageComposerAO::CompareTItemIds ) );
       
   536         }
       
   537 
       
   538     CleanupStack::PopAndDestroy( exif );
       
   539 
       
   540     WRITELOG( "CImageComposerAO::ComposeL() - Start writing GPS tags" );
       
   541     
       
   542     WriteGPSTagsL( iMdeObject->Id() );
       
   543 
       
   544 #ifdef _DEBUG
       
   545     WRITELOG1( "CImageComposerAO::ComposeL() - Compose End Object ID: %d", iMdeObject->Id() );
       
   546 #endif
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // WriteGPSTagsL
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 void CImageComposerAO::WriteGPSTagsL( TItemId aObjectId )
       
   554     {
       
   555 #ifdef _DEBUG
       
   556     _LIT( KPanicCategoryNsd, "NSD=NULL" );
       
   557     _LIT( KPanicCategoryOd,  "OD=NULL" );
       
   558     _LIT( KPanicCategoryId,  "ID=NULL" );
       
   559     _LIT( KPanicCategoryLd,  "LD=NULL" );
       
   560     __ASSERT_DEBUG( iDefaultNamespace, User::Panic( KPanicCategoryNsd, KErrBadHandle ) );
       
   561     __ASSERT_DEBUG( iObjectDef, User::Panic( KPanicCategoryOd,  KErrBadHandle ) );
       
   562     __ASSERT_DEBUG( iImageObjectDef, User::Panic( KPanicCategoryId,  KErrBadHandle ) );
       
   563     __ASSERT_DEBUG( iLocationObjectDef, User::Panic( KPanicCategoryLd,  KErrBadHandle ) );
       
   564 #endif    
       
   565     
       
   566     delete iRelationQuery;
       
   567     iRelationQuery = NULL;
       
   568     
       
   569     if ( !iSession )
       
   570     	{
       
   571     	User::Leave( KErrSessionClosed );
       
   572     	}
       
   573     
       
   574     iRelationQuery = iSession->NewRelationQueryL( *iDefaultNamespace, this );
       
   575     
       
   576     iRelationQuery->SetResultMode( EQueryResultModeItem );
       
   577     iRelationQuery->Conditions().SetOperator( ELogicConditionOperatorAnd );
       
   578     
       
   579     CMdERelationCondition& filterCond = iRelationQuery->Conditions().
       
   580     		AddRelationConditionL( ERelationConditionSideRight );
       
   581     
       
   582     // Left object in relation must have this ID.
       
   583     filterCond.LeftL().AddObjectConditionL( aObjectId );
       
   584     
       
   585     // Right object in relation must be a location object.
       
   586     filterCond.RightL().AddObjectConditionL( *iLocationObjectDef );
       
   587     
       
   588     iRelationQuery->FindL( 1, 1 ); // results to a call to HandleQueryCompleted()
       
   589     }
       
   590     
       
   591 // ---------------------------------------------------------------------------
       
   592 // SetNextRequest
       
   593 // ---------------------------------------------------------------------------
       
   594 //
       
   595 void CImageComposerAO::SetNextRequest( TRequestType aNextRequest )
       
   596     {
       
   597     iNextRequest = aNextRequest;
       
   598     
       
   599     if ( !IsActive() )
       
   600         {
       
   601         iStatus = KRequestPending;
       
   602         SetActive();
       
   603         TRequestStatus* ptrStatus = &iStatus;
       
   604         User::RequestComplete( ptrStatus, KErrNone );
       
   605         }
       
   606     }
       
   607     
       
   608 // ---------------------------------------------------------------------------
       
   609 // HandleQueryNewResults
       
   610 // ---------------------------------------------------------------------------
       
   611 //
       
   612 void CImageComposerAO::HandleQueryNewResults( CMdEQuery& /*aQuery*/,
       
   613 	TInt /*aFirstNewItemIndex*/, TInt /*aNewItemCount*/ )
       
   614     {
       
   615     }
       
   616     
       
   617 // ---------------------------------------------------------------------------
       
   618 // HandleQueryNewResults
       
   619 // ---------------------------------------------------------------------------
       
   620 //
       
   621 void CImageComposerAO::HandleQueryNewResults( CMdEQuery& /*aQuery*/,
       
   622 	TInt /*aNewObjectItemCount*/, TInt /*aNewRelationItemCount*/,
       
   623 	TInt /*aNewEventItemCount*/ )
       
   624     {
       
   625     }
       
   626 
       
   627 // ---------------------------------------------------------------------------
       
   628 // HandleQueryCompleted
       
   629 // ---------------------------------------------------------------------------
       
   630 //
       
   631 void CImageComposerAO::HandleQueryCompleted( CMdEQuery& aQuery, TInt aError )
       
   632     {
       
   633     if ( aError != KErrNone )
       
   634     	{
       
   635     	WRITELOG1( "CImageComposerAO::HandleQueryCompleted() - query error: %d", aError );
       
   636     	SetNextRequest( ERequestGetObject );
       
   637     	return;
       
   638     	}
       
   639     if ( aQuery.Count() == 0 )
       
   640         {
       
   641         WRITELOG( "CImageComposerAO::HandleQueryCompleted() - no gps items found" );
       
   642         SetNextRequest( ERequestGetObject );
       
   643         return;
       
   644         }
       
   645 
       
   646 #ifdef _DEBUG        
       
   647     TRAPD( error, StartWritingGPSTagsL( aQuery ) );
       
   648     WRITELOG1( "CImageComposerAO::HandleQueryCompleted() - error code from StartWritingGPSTagsL: %d", error );
       
   649 #else
       
   650     TRAP_IGNORE( StartWritingGPSTagsL( aQuery ) );
       
   651 #endif
       
   652     
       
   653     SetNextRequest( ERequestGetObject );
       
   654     }
       
   655 
       
   656 // ---------------------------------------------------------------------------
       
   657 // StartWritingGPSTagsL
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 void CImageComposerAO::StartWritingGPSTagsL( CMdEQuery& aQuery )
       
   661     {
       
   662 #ifdef _DEBUG
       
   663     _LIT( KPanicCategoryNsd, "NSD=NULL" );
       
   664     _LIT( KPanicCategoryOd,  "OD=NULL" );
       
   665     _LIT( KPanicCategoryId,  "ID=NULL" );
       
   666     _LIT( KPanicCategoryLd,  "LD=NULL" );
       
   667     __ASSERT_DEBUG( iDefaultNamespace, User::Panic( KPanicCategoryNsd, KErrBadHandle ) );
       
   668     __ASSERT_DEBUG( iObjectDef, User::Panic( KPanicCategoryOd,  KErrBadHandle ) );
       
   669     __ASSERT_DEBUG( iImageObjectDef, User::Panic( KPanicCategoryId,  KErrBadHandle ) );
       
   670     __ASSERT_DEBUG( iLocationObjectDef, User::Panic( KPanicCategoryLd,  KErrBadHandle ) );
       
   671 #endif    
       
   672     
       
   673     if ( !iSession )
       
   674     	{
       
   675     	WRITELOG( "CImageComposerAO::StartWritingGPSTagsL - iSession is NULL!" );
       
   676     	User::Leave( KErrSessionClosed );
       
   677     	}
       
   678     
       
   679     CMdERelation& result = static_cast<CMdERelation&>( aQuery.ResultItem( 0 ) );
       
   680     TItemId rightId = result.RightObjectId();
       
   681     CMdEObject* location = iSession->GetObjectL( rightId, *iLocationObjectDef );
       
   682     CleanupStack::PushL( location );
       
   683     
       
   684     TItemId leftId = result.LeftObjectId();
       
   685     CMdEObject* mdeObject = iSession->GetObjectL( leftId, *iObjectDef );
       
   686     CleanupStack::PushL( mdeObject );
       
   687     
       
   688     DoWriteExifL( mdeObject, location );
       
   689     
       
   690     CleanupStack::PopAndDestroy( mdeObject );
       
   691     CleanupStack::PopAndDestroy( location );
       
   692     }
       
   693 
       
   694 
       
   695 // ---------------------------------------------------------------------------
       
   696 // DoWriteExifL
       
   697 // ---------------------------------------------------------------------------
       
   698 //
       
   699 void CImageComposerAO::DoWriteExifL( CMdEObject* aMdEObject, CMdEObject* aLocationObject )
       
   700     {
       
   701 #ifdef _DEBUG
       
   702     _LIT( KPanicCategoryNsd, "NSD=NULL" );
       
   703     _LIT( KPanicCategoryOd,  "OD=NULL" );
       
   704     _LIT( KPanicCategoryId,  "ID=NULL" );
       
   705     _LIT( KPanicCategoryLd,  "LD=NULL" );
       
   706     __ASSERT_DEBUG( iDefaultNamespace, User::Panic( KPanicCategoryNsd, KErrBadHandle ) );
       
   707     __ASSERT_DEBUG( iObjectDef, User::Panic( KPanicCategoryOd,  KErrBadHandle ) );
       
   708     __ASSERT_DEBUG( iImageObjectDef, User::Panic( KPanicCategoryId,  KErrBadHandle ) );
       
   709     __ASSERT_DEBUG( iLocationObjectDef, User::Panic( KPanicCategoryLd,  KErrBadHandle ) );
       
   710 #endif
       
   711     
       
   712     WRITELOG( "CImageComposerAO::DoWriteExifL()" );
       
   713     if ( !aMdEObject || !aLocationObject )
       
   714         {
       
   715         WRITELOG( "CImageComposerAO::DoWriteExifL() - null parameter(s)!" );
       
   716         User::Leave( KErrArgument );
       
   717         }
       
   718 
       
   719     CMdEProperty* itemTypeProperty = NULL;
       
   720     CMdEProperty* latitudeProperty = NULL;
       
   721     CMdEProperty* longitudeProperty = NULL;
       
   722     CMdEProperty* altitudeProperty = NULL;
       
   723     CMdEProperty* qualityProperty = NULL;
       
   724 
       
   725     aMdEObject->Property( iObjectDef->GetPropertyDefL(
       
   726     		Object::KItemTypeProperty ), itemTypeProperty, 0 );
       
   727     aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   728     		Location::KLatitudeProperty ), latitudeProperty, 0 );
       
   729     aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   730     		Location::KLongitudeProperty ), longitudeProperty, 0 );
       
   731     aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   732     		Location::KAltitudeProperty ), altitudeProperty, 0 );
       
   733     aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   734     		Location::KQualityProperty ), qualityProperty, 0 );
       
   735 
       
   736     if ( !itemTypeProperty )
       
   737         {
       
   738         WRITELOG( "CImageComposerAO::DoWriteExifL() - NULL item type property!" );
       
   739         User::Leave( KErrBadHandle );
       
   740         }
       
   741     const TDesC& uri = aMdEObject->Uri();
       
   742 
       
   743     const TDesC& mimeType = itemTypeProperty->TextValueL();
       
   744 
       
   745     if ( !IsJpeg( const_cast<TDesC&>(mimeType) ) )
       
   746         {
       
   747         WRITELOG( "CImageComposerAO::DoWriteExifL() - object mimetype is not image/jpeg!" );
       
   748         User::Leave( KErrNotSupported );
       
   749         }
       
   750 
       
   751     // Check whether the file is open
       
   752     TBool isOpen( EFalse );
       
   753     iFs.IsFileOpen( uri, isOpen );
       
   754     if ( isOpen )
       
   755         {
       
   756         WRITELOG( "CImageComposerAO::DoWriteExifL() - file handle is open!" );
       
   757         User::Leave( KErrInUse );
       
   758         }
       
   759 
       
   760     TInt64 imageFileSize = 0;
       
   761     RFile64 file;
       
   762     User::LeaveIfError( file.Open( iFs, uri, EFileRead ) );
       
   763     CleanupClosePushL( file );
       
   764 
       
   765     User::LeaveIfError( file.Size( imageFileSize ) );
       
   766     HBufC8* imageData = HBufC8::NewL( imageFileSize );
       
   767     CleanupStack::PushL( imageData );
       
   768     TPtr8 myImagePtr = imageData->Des();
       
   769 
       
   770     WRITELOG( "CImageComposerAO::DoWriteExifL() - reading IMAGE file" );
       
   771     const TInt readError = file.Read( myImagePtr ) ;
       
   772     if ( readError != KErrNone )
       
   773         {
       
   774         WRITELOG( "CImageComposerAO::DoWriteExifL() - error while reading image file!" );
       
   775         User::Leave( KErrGeneral );
       
   776         }
       
   777 
       
   778     WRITELOG( "CImageComposerAO::DoWriteExifL() - reading IMAGE file - DONE! - closing file" );
       
   779     CleanupStack::Pop( imageData );
       
   780     CleanupStack::PopAndDestroy( &file );
       
   781     CleanupStack::PushL( imageData );
       
   782 
       
   783     HBufC8* modifiedExif = NULL;
       
   784     iExifUtil->ComposeLocationL( aLocationObject, myImagePtr, modifiedExif );
       
   785 
       
   786     // write the EXIF data to the image
       
   787 
       
   788     if ( modifiedExif )
       
   789         {
       
   790         CleanupStack::PushL( modifiedExif );
       
   791 
       
   792         CMdEObject* mdeObject = iSession->OpenObjectL( aMdEObject->Id(), 
       
   793         		*iImageObjectDef );
       
   794         if ( !mdeObject )
       
   795             {
       
   796             User::Leave( KErrAccessDenied );
       
   797             }
       
   798         CleanupStack::PushL( mdeObject );
       
   799 
       
   800         User::LeaveIfError( file.Open( iFs, mdeObject->Uri(), EFileWrite ) );
       
   801         CleanupClosePushL( file );
       
   802 
       
   803         // set position to begin of file
       
   804         TInt64 pos = 0;
       
   805         User::LeaveIfError( file.Seek( ESeekStart, pos ) );
       
   806 
       
   807         User::LeaveIfError( file.Write( modifiedExif->Des(), modifiedExif->Des().Length() ) );
       
   808 
       
   809         CleanupStack::PopAndDestroy( &file );
       
   810         TEntry fileEntry;
       
   811         iFs.Entry( mdeObject->Uri(), fileEntry );
       
   812 
       
   813         CMdEPropertyDef& sizePropDef = iImageObjectDef->GetPropertyDefL( Object::KSizeProperty );
       
   814         CMdEProperty* sizeProp = NULL;
       
   815         mdeObject->Property( sizePropDef, sizeProp, 0 );
       
   816 
       
   817         if ( sizeProp )
       
   818             {
       
   819             sizeProp->SetUint32ValueL( fileEntry.iSize );
       
   820             }
       
   821         else
       
   822             {
       
   823             mdeObject->AddUint32PropertyL( sizePropDef, fileEntry.iSize );
       
   824             }
       
   825 
       
   826         CMdEPropertyDef& lastModDatePropDef = iImageObjectDef->GetPropertyDefL(
       
   827         		Object::KLastModifiedDateProperty );
       
   828         CMdEProperty* lastModDateProp = NULL;
       
   829         mdeObject->Property( lastModDatePropDef, lastModDateProp, 0 );
       
   830 
       
   831         if ( lastModDateProp )
       
   832             {
       
   833             lastModDateProp->SetTimeValueL( fileEntry.iModified );
       
   834             }
       
   835         else
       
   836             {
       
   837             mdeObject->AddTimePropertyL( lastModDatePropDef, fileEntry.iModified );
       
   838             }
       
   839 
       
   840         iSession->CommitObjectL( *mdeObject );
       
   841         iNextItemsSkip.InsertInOrder( mdeObject->Id(),
       
   842         		TLinearOrder<TItemId>( CImageComposerAO::CompareTItemIds ) );
       
   843         CleanupStack::PopAndDestroy( mdeObject );
       
   844         CleanupStack::PopAndDestroy( modifiedExif );
       
   845         }
       
   846 
       
   847     // remove empty (=unneeded) location objects
       
   848     if ( !latitudeProperty && !longitudeProperty && !altitudeProperty ) // && !satellitesProperty ) // check these first...
       
   849         {
       
   850         // get the rest of the properties
       
   851         CMdEProperty* cellIdProperty = NULL;
       
   852         CMdEProperty* countryCodeProperty = NULL;
       
   853         CMdEProperty* networkCodeProperty = NULL;
       
   854         CMdEProperty* locationAreaCodeProperty = NULL;
       
   855         CMdEProperty* speedProperty = NULL;
       
   856         CMdEProperty* directionProperty = NULL;
       
   857         CMdEProperty* qualityProperty = NULL;
       
   858 
       
   859         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   860         		Location::KCellIdProperty ), cellIdProperty, 0 );
       
   861         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   862         		Location::KCountryCodeProperty ), countryCodeProperty, 0 );
       
   863         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   864         		Location::KNetworkCodeProperty ), networkCodeProperty, 0 );
       
   865         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   866         		Location::KLocationAreaCodeProperty ), locationAreaCodeProperty, 0 );
       
   867         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   868         		Location::KSpeedProperty ), speedProperty, 0 );
       
   869         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   870         		Location::KDirectionProperty ), directionProperty, 0 );
       
   871         aLocationObject->Property( iLocationObjectDef->GetPropertyDefL(
       
   872         		Location::KQualityProperty ), qualityProperty, 0 );
       
   873 
       
   874         // if object doesn't contain any properties, remove it
       
   875         if ( !cellIdProperty && !countryCodeProperty && !networkCodeProperty
       
   876             && !locationAreaCodeProperty && !speedProperty && !directionProperty && !qualityProperty )
       
   877             {
       
   878             iSession->RemoveObjectL( aLocationObject->Id(), iDefaultNamespace );
       
   879             }
       
   880         }
       
   881     
       
   882     CleanupStack::PopAndDestroy( imageData );
       
   883 
       
   884     }
       
   885 
       
   886 // ---------------------------------------------------------------------------
       
   887 // IsJpeg
       
   888 // ---------------------------------------------------------------------------
       
   889 //
       
   890 TBool CImageComposerAO::IsJpeg( const TDesC& aMimeType )
       
   891     {
       
   892     WRITELOG( "CImageComposerAO::IsJpeg()" );
       
   893 
       
   894     if ( MdsUtils::Compare( KJpegMimeType, aMimeType ) == 0 )
       
   895         {
       
   896         WRITELOG( "CImageComposerAO::IsJpeg() - image is Jpeg" );
       
   897         return ETrue;        
       
   898         }
       
   899 
       
   900     return EFalse;
       
   901     }
       
   902 
       
   903