omads/omadsextensions/adapters/agenda/src/nsmlagendadatastore.cpp
changeset 20 e1de7d03f843
child 22 1a3f0bca12c6
equal deleted inserted replaced
19:2691f6aa1921 20:e1de7d03f843
       
     1 /*
       
     2 * Copyright (c) 2005 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:  DS agenda data store
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include "nsmldebug.h"
       
    22 #include "nsmlagendadatastore.h"
       
    23 #include "nsmlagendadataprovider.h"
       
    24 #include "nsmlchangefinder.h"
       
    25 #include "NSmlDataModBase.h"
       
    26 #include "nsmlagendadefines.hrh"
       
    27 #include <ecom.h>
       
    28 #include <barsc.h>
       
    29 #include <bautils.h>
       
    30 #include <calsession.h> 
       
    31 #include <caldataexchange.h> 
       
    32 #include <calentryview.h>
       
    33 #include <caliterator.h>
       
    34 #include <calentry.h>
       
    35 #include <caldataformat.h>
       
    36 #include <caltime.h>
       
    37 #include <nsmldsimpluids.h>
       
    38 #include <sysutil.h>
       
    39 #include <SmlDataProvider.h>
       
    40 #include <SmlDataFormat.h>
       
    41 #include <SmlDataSyncDefs.h>
       
    42 #include <data_caging_path_literals.hrh>
       
    43 #include <NSmlAgendaDataStore_1_1_2.rsg>
       
    44 #include <NSmlAgendaDataStore_1_2.rsg>
       
    45 #include <e32property.h>
       
    46 #include <DataSyncInternalPSKeys.h>
       
    47 #include <CalenImporter.h>
       
    48 #include <CalenInterimUtils2.h>
       
    49 
       
    50 #ifndef __WINS__
       
    51 // This lowers the unnecessary compiler warning (armv5) to remark.
       
    52 // "Warning:  #174-D: expression has no effect..." is caused by 
       
    53 // DBG_ARGS8 macro in no-debug builds.
       
    54 #pragma diag_remark 174
       
    55 #endif
       
    56 // ============================= MEMBER FUNCTIONS ==============================
       
    57 // -----------------------------------------------------------------------------
       
    58 // CNSmlAgendaDataStore::CNSmlAgendaDataStore
       
    59 // C++ default constructor can NOT contain any code, that
       
    60 // might leave.
       
    61 // -----------------------------------------------------------------------------
       
    62 //
       
    63 CNSmlAgendaDataStore::CNSmlAgendaDataStore() :
       
    64 	iKey( TKeyArrayFix( _FOFF( TNSmlSnapshotItem, ItemId() ), ECmpTInt ) ),
       
    65 	iPos( -1 ),
       
    66 	iHasHistory( EFalse ),
       
    67 	iModificationCount( KNSmlCompactAfterChanges ),
       
    68 	iState( ENSmlClosed ),
       
    69 	iSnapshotRegistered( EFalse ),
       
    70 	iDrive( -1 ),
       
    71 	iReplaceItemId( -1 ),
       
    72 	iRXEntryType( ENSmlNotSet ),
       
    73 	iTXEntryType( ENSmlNotSet )
       
    74 	{
       
    75 	_DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): BEGIN");
       
    76 	_DBG_FILE("CNSmlAgendaDataStore::CNSmlAgendaDataStore(): END");
       
    77 	}
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CNSmlAgendaDataStore::ConstructL
       
    81 // Symbian 2nd phase constructor can leave.
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 void CNSmlAgendaDataStore::ConstructL()
       
    85 	{
       
    86 	_DBG_FILE("CNSmlAgendaDataStore::ConstructL: BEGIN");
       
    87 
       
    88 	iStringPool.OpenL();
       
    89 	User::LeaveIfError( iRfs.Connect() );
       
    90 
       
    91 	iDataMod = new ( ELeave ) CNSmlVCalMod();
       
    92 	
       
    93 	iNewUids = new ( ELeave ) CNSmlDataItemUidSet();
       
    94 	iDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
       
    95 	iSoftDeletedUids = new ( ELeave ) CNSmlDataItemUidSet();
       
    96 	iMovedUids = new ( ELeave ) CNSmlDataItemUidSet();
       
    97 	iReplacedUids = new ( ELeave ) CNSmlDataItemUidSet();
       
    98 	
       
    99 	iDefaultStoreName = HBufC::NewL( KNSmlDefaultStoreNameMaxSize );
       
   100 	
       
   101 	iVersitTlsData = &CVersitTlsData::VersitTlsDataL();
       
   102 	// Create CalSession and CalEntryView instances
       
   103 	iVCalSession = CCalSession::NewL();
       
   104 	
       
   105 	TPtr obptr = iDefaultStoreName->Des();
       
   106 	obptr = iVCalSession->DefaultFileNameL(); 
       
   107 
       
   108 	iOwnFormat = DoOwnStoreFormatL();
       
   109 	iDataMod->SetOwnStoreFormat( *iOwnFormat );
       
   110 	
       
   111     iInterimUtils = CCalenInterimUtils2::NewL();
       
   112 	
       
   113 	_DBG_FILE("CNSmlAgendaDataStore::ConstructL: END");
       
   114 	}
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CNSmlAgendaDataStore::NewL
       
   118 // Two-phased constructor.
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 CNSmlAgendaDataStore* CNSmlAgendaDataStore::NewL()
       
   122 	{
       
   123 	_DBG_FILE("CNSmlAgendaDataStore::NewL: BEGIN");
       
   124 	
       
   125 	CNSmlAgendaDataStore* self = new ( ELeave ) CNSmlAgendaDataStore();
       
   126 	CleanupStack::PushL( self );
       
   127 	
       
   128 	self->ConstructL();
       
   129 	CleanupStack::Pop(); // self
       
   130 	
       
   131 	_DBG_FILE("CNSmlAgendaDataStore::NewL: END");
       
   132 	return self;
       
   133 	}
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CNSmlAgendaDataStore::~CNSmlAgendaDataStore
       
   137 // Destructor.
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 CNSmlAgendaDataStore::~CNSmlAgendaDataStore()
       
   141 	{
       
   142 	_DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): BEGIN");
       
   143 
       
   144     // Enable notifications
       
   145     TInt error( KErrNone );
       
   146     if ( iVCalSession )
       
   147         {
       
   148         TRAP_IGNORE( iVCalSession->EnablePubSubNotificationsL() );
       
   149         TRAP_IGNORE( iVCalSession->EnableChangeBroadcast() );
       
   150         }
       
   151 
       
   152 	delete iOwnFormat;
       
   153 	iRfs.Close();
       
   154 	iStringPool.Close();
       
   155 	
       
   156     if ( iChangeFinder )
       
   157 		{
       
   158 		TRAP( error, iChangeFinder->CloseL() );
       
   159 		}
       
   160 	if (iVersitTlsData)
       
   161 			{
       
   162 			iVersitTlsData->VersitTlsDataClose();
       
   163 			}
       
   164 	delete iChangeFinder;
       
   165 	delete iNewUids;
       
   166 	delete iDeletedUids;
       
   167 	delete iSoftDeletedUids;
       
   168 	delete iMovedUids;
       
   169 	delete iReplacedUids;
       
   170 
       
   171     delete iDefaultStoreName;
       
   172     delete iOpenedStoreName;
       
   173 	delete iDataMod;
       
   174 	delete iItemData;
       
   175 
       
   176     delete iAgendaProgressview;
       
   177     
       
   178 	delete iImporter;
       
   179     delete iExporter;
       
   180     
       
   181     delete iEntryView;
       
   182     delete iVCalSession;
       
   183     delete iInterimUtils;
       
   184     
       
   185     
       
   186     // REComSession::FinalClose();
       
   187 	
       
   188 	_DBG_FILE("CNSmlAgendaDataStore::~CNSmlAgendaDataStore(): END");
       
   189 	}
       
   190 
       
   191 // -----------------------------------------------------------------------------
       
   192 // CNSmlAgendaDataStore::DoOpenL
       
   193 // Open calendar database for access.
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 void CNSmlAgendaDataStore::DoOpenL( const TDesC& aStoreName,
       
   197                 MSmlSyncRelationship& aContext, TRequestStatus& aStatus )
       
   198     {
       
   199 	_DBG_FILE("CNSmlAgendaDataStore::DoOpenL: BEGIN");
       
   200 	iCallerStatus = &aStatus;
       
   201 	*iCallerStatus = KRequestPending;
       
   202 	if ( iState != ENSmlClosed )
       
   203 		{
       
   204 		User::RequestComplete( iCallerStatus, KErrInUse );
       
   205 		return;
       
   206 		}
       
   207 
       
   208 	if( RFs::CharToDrive( aStoreName[0], iDrive ) != KErrNone )
       
   209 		{
       
   210 		RFs::CharToDrive( KNSmlDriveC()[0], iDrive );
       
   211 		}
       
   212     
       
   213     // Open database
       
   214 	TInt err( KErrNone );	
       
   215 	if ( aStoreName == KNSmlAgendaStoreNameForDefaultDB )
       
   216 		{
       
   217 		TRAP( err, iVCalSession->OpenL( *iDefaultStoreName ) );
       
   218 		}
       
   219     else 
       
   220     	{
       
   221     	TRAP( err, iVCalSession->OpenL( aStoreName ) );
       
   222     	}
       
   223 	if ( err )
       
   224 	    {
       
   225 	    User::RequestComplete( iCallerStatus, err );
       
   226 	    return;
       
   227 	    }
       
   228 	
       
   229 	// Disable notifications
       
   230 	TRAP_IGNORE( iVCalSession->DisablePubSubNotificationsL() );
       
   231 	TRAP_IGNORE( iVCalSession->DisableChangeBroadcast() );
       
   232 	    
       
   233 	if ( iOpenedStoreName )
       
   234 		{
       
   235 		delete iOpenedStoreName;
       
   236 		iOpenedStoreName = NULL;
       
   237 		}
       
   238 	iOpenedStoreName = aStoreName.AllocL();
       
   239 	
       
   240 	// Initialize some member variables
       
   241 	// Create importer and exporter
       
   242     iImporter = CCalenImporter::NewL( *iVCalSession );
       
   243 	iExporter = CCalenExporter::NewL( *iVCalSession );
       
   244 
       
   245     // Progress view
       
   246 	iAgendaProgressview = CNSmlAgendaProgressview::NewL();
       
   247 
       
   248     iEntryView = CCalEntryView::NewL( *iVCalSession, *iAgendaProgressview );
       
   249     CActiveScheduler::Start();
       
   250     TInt completedStatus = iAgendaProgressview->GetCompletedStatus();
       
   251     if ( completedStatus != KErrNone )
       
   252         {
       
   253         User::RequestComplete( iCallerStatus, completedStatus );
       
   254         return;
       
   255         }
       
   256 
       
   257 	if ( iChangeFinder )
       
   258 		{
       
   259 		iChangeFinder->CloseL();
       
   260 		delete iChangeFinder;
       
   261 		iChangeFinder = NULL;
       
   262 		}
       
   263 	iChangeFinder = CNSmlChangeFinder::NewL( aContext, iKey, iHasHistory,
       
   264 	                                         KNSmlAgendaAdapterImplUid );
       
   265     
       
   266     // Get ID of database
       
   267 	iVCalSession->FileIdL( iOpenedStoreId );
       
   268 	
       
   269 	if( !iSnapshotRegistered )
       
   270 		{
       
   271 		RegisterSnapshotL();
       
   272 		}
       
   273      	
       
   274 	iState = ENSmlOpenAndWaiting;
       
   275     User::RequestComplete( iCallerStatus, err );
       
   276 	    
       
   277 	_DBG_FILE("CNSmlAgendaDataStore::DoOpenL: END");
       
   278     }
       
   279 
       
   280 // -----------------------------------------------------------------------------
       
   281 // CNSmlAgendaDataStore::DoCancelRequest
       
   282 // Set internal module state to previous state.
       
   283 // -----------------------------------------------------------------------------
       
   284 //
       
   285 void CNSmlAgendaDataStore::DoCancelRequest()
       
   286     {
       
   287 	_DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: BEGIN");
       
   288     if ( iState == ENSmlOpenAndWaiting )
       
   289         {
       
   290     	iState = ENSmlClosed;
       
   291         }
       
   292     else
       
   293         {
       
   294 	    iState = ENSmlOpenAndWaiting;
       
   295         }
       
   296 	_DBG_FILE("CNSmlAgendaDataStore::DoCancelRequest: END");
       
   297     }
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CNSmlAgendaDataStore::DoStoreName
       
   301 // Returns previously opened database name.
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 const TDesC& CNSmlAgendaDataStore::DoStoreName() const
       
   305     {
       
   306 	_DBG_FILE("CNSmlAgendaDataStore::DoStoreName: BEGIN");
       
   307 	_DBG_FILE("CNSmlAgendaDataStore::DoStoreName: END");
       
   308 	return *iOpenedStoreName;
       
   309     }
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CNSmlAgendaDataStore::DoBeginTransactionL
       
   313 // Not supported.
       
   314 // -----------------------------------------------------------------------------
       
   315 //
       
   316 void CNSmlAgendaDataStore::DoBeginTransactionL()
       
   317     {
       
   318 	_DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: BEGIN");
       
   319 	User::Leave( KErrNotSupported );
       
   320 	_DBG_FILE("CNSmlAgendaDataStore::DoBeginTransactionL: END");
       
   321     }
       
   322 
       
   323 // -----------------------------------------------------------------------------
       
   324 // CNSmlAgendaDataStore::DoCommitTransactionL
       
   325 // Not supported.
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CNSmlAgendaDataStore::DoCommitTransactionL( TRequestStatus& aStatus )
       
   329     {
       
   330 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: BEGIN");
       
   331 	iCallerStatus = &aStatus;
       
   332 	*iCallerStatus = KRequestPending;
       
   333 	User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   334 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitTransactionL: END");
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CNSmlAgendaDataStore::DoRevertTransaction
       
   339 // Not supported.
       
   340 // -----------------------------------------------------------------------------
       
   341 //
       
   342 void CNSmlAgendaDataStore::DoRevertTransaction( TRequestStatus& aStatus )
       
   343     {
       
   344 	_DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: BEGIN");
       
   345 	iCallerStatus = &aStatus;
       
   346 	*iCallerStatus = KRequestPending;
       
   347 	User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   348 	_DBG_FILE("CNSmlAgendaDataStore::DoRevertTransaction: END");
       
   349     }
       
   350 
       
   351 // -----------------------------------------------------------------------------
       
   352 // CNSmlAgendaDataStore::DoBeginBatchL
       
   353 // Not supported.
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CNSmlAgendaDataStore::DoBeginBatchL()
       
   357     {
       
   358 	_DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: BEGIN");
       
   359 	User::Leave( KErrNotSupported );
       
   360 	_DBG_FILE("CNSmlAgendaDataStore::DoBeginBatchL: END");
       
   361     }
       
   362 
       
   363 // -----------------------------------------------------------------------------
       
   364 // CNSmlAgendaDataStore::DoCommitBatchL
       
   365 // Not supported.
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 void CNSmlAgendaDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/,
       
   369                 TRequestStatus& aStatus )
       
   370     {
       
   371 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: BEGIN");
       
   372 	iCallerStatus = &aStatus;
       
   373 	*iCallerStatus = KRequestPending;
       
   374 	User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   375 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitBatchL: END");
       
   376     }
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // CNSmlAgendaDataStore::DoCancelBatch
       
   380 // Not supported.
       
   381 // -----------------------------------------------------------------------------
       
   382 //
       
   383 void CNSmlAgendaDataStore::DoCancelBatch()
       
   384     {
       
   385 	_DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: BEGIN");
       
   386 	// Nothing to do
       
   387 	_DBG_FILE("CNSmlAgendaDataStore::DoCancelBatch: END");
       
   388     }
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // CNSmlAgendaDataStore::DoSetRemoteStoreFormatL
       
   392 // Set SyncML Remote Server data store format.
       
   393 // -----------------------------------------------------------------------------
       
   394 //
       
   395 void CNSmlAgendaDataStore::DoSetRemoteStoreFormatL(
       
   396                 const CSmlDataStoreFormat& aServerDataStoreFormat )
       
   397     {
       
   398 	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: BEGIN");
       
   399 	
       
   400 	if ( iOwnFormat )
       
   401 	    {
       
   402 	    delete iOwnFormat;
       
   403 	    iOwnFormat = NULL;    
       
   404 	    }
       
   405 	
       
   406 	iOwnFormat = DoOwnStoreFormatL();
       
   407 	iDataMod->SetOwnStoreFormat( *iOwnFormat );
       
   408 	
       
   409     iDataMod->SetPartnerStoreFormat( ( CSmlDataStoreFormat& )
       
   410                 aServerDataStoreFormat );
       
   411     
       
   412     // Check which calendar type (vCal/iCal) is used
       
   413     // If server supports iCal then it is used
       
   414     // Otherwise vCal is used
       
   415     TInt returnValue( KErrNotSupported );
       
   416 
       
   417 #ifdef __NSML_USE_ICAL_FEATURE
       
   418 
       
   419     _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support iCal");
       
   420    	returnValue = iDataMod->SetUsedMimeType(
       
   421        	    iOwnFormat->MimeFormat( 1 ).MimeType(),
       
   422            	iOwnFormat->MimeFormat( 1 ).MimeVersion() );
       
   423 
       
   424 #endif // __NSML_USE_ICAL_FEATURE
       
   425 
       
   426     if ( returnValue == KErrNone )
       
   427         {
       
   428         _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets iCal");
       
   429         iRXEntryType = ENSmlICal;
       
   430         iTXEntryType = ENSmlICal;
       
   431         }
       
   432     else
       
   433         {
       
   434         _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Support vCal");
       
   435         returnValue = iDataMod->SetUsedMimeType(
       
   436             iOwnFormat->MimeFormat( 0 ).MimeType(),
       
   437             iOwnFormat->MimeFormat( 0 ).MimeVersion() );
       
   438         if ( returnValue == KErrNone )
       
   439             {
       
   440             _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: Sets vCal");
       
   441             iRXEntryType = ENSmlVCal;
       
   442             iTXEntryType = ENSmlVCal;
       
   443             }
       
   444         }
       
   445     if ( iRXEntryType == ENSmlNotSet || iTXEntryType == ENSmlNotSet )
       
   446         {
       
   447         // Leave if server does not support either vCal or iCal
       
   448         _DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: MimeType Not supported");
       
   449         User::Leave( KErrNotFound );        
       
   450         }
       
   451     
       
   452 	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteStoreFormatL: END");
       
   453     }
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize
       
   457 // Set SyncML Remote Server maximum object size.
       
   458 // -----------------------------------------------------------------------------
       
   459 //
       
   460 void CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize( TInt aServerMaxObjectSize )
       
   461     {
       
   462 	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: BEGIN");
       
   463 	iServerMaxObjectSize = aServerMaxObjectSize;
       
   464 	_DBG_FILE("CNSmlAgendaDataStore::DoSetRemoteMaxObjectSize: END");
       
   465     }
       
   466 
       
   467 // -----------------------------------------------------------------------------
       
   468 // CNSmlAgendaDataStore::DoMaxObjectSize
       
   469 // Set SyncML Component maximum object size.
       
   470 // -----------------------------------------------------------------------------
       
   471 //
       
   472 TInt CNSmlAgendaDataStore::DoMaxObjectSize() const
       
   473     {
       
   474 	_DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize: BEGIN");
       
   475 	_DBG_FILE("CNSmlAgendaDataStore::DoMaxObjectSize - Default: END");
       
   476 	return KNSmlAgendaOwnMaxObjectSize;
       
   477     }
       
   478 
       
   479 // -----------------------------------------------------------------------------
       
   480 // CNSmlAgendaDataStore::DoOpenItemL
       
   481 // Open calendar item for reading.
       
   482 // -----------------------------------------------------------------------------
       
   483 //
       
   484 void CNSmlAgendaDataStore::DoOpenItemL( TSmlDbItemUid aUid, TBool& aFieldChange,
       
   485                 TInt& aSize, TSmlDbItemUid& /*aParent*/, TDes8& aMimeType,
       
   486                 TDes8& aMimeVer, TRequestStatus& aStatus )
       
   487     {
       
   488 	_DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: BEGIN");
       
   489     iCallerStatus = &aStatus;
       
   490 	*iCallerStatus = KRequestPending;
       
   491 	if ( iState != ENSmlOpenAndWaiting )
       
   492 		{
       
   493 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   494 		return;
       
   495 		}
       
   496 		
       
   497  	iReplaceItemId = aUid;
       
   498  	
       
   499 	CCalEntry* entry = NULL;
       
   500 	TInt err( KErrNone );
       
   501     TRAP( err, entry = iEntryView->FetchL( aUid ) );
       
   502 	CleanupStack::PushL( entry );
       
   503 	
       
   504 	if ( err || !entry )
       
   505 		{
       
   506 		CleanupStack::PopAndDestroy( entry ); // entry
       
   507 		User::RequestComplete( iCallerStatus, KErrNotFound );
       
   508 		return;
       
   509 		}
       
   510 		
       
   511 	if ( !iSnapshotRegistered )
       
   512 		{
       
   513 		RegisterSnapshotL();
       
   514 		}
       
   515 	delete iItemData;
       
   516 	iItemData = NULL;
       
   517 	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
       
   518 
       
   519 	RBufWriteStream writeStream( *iItemData );
       
   520 	writeStream.PushL();
       
   521 	
       
   522 	// Export item from database
       
   523 	if ( iTXEntryType == ENSmlICal )
       
   524 	    {
       
   525 	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - iCal DB");
       
   526 	    iExporter->ExportICalL( *entry, writeStream );
       
   527 	    aMimeType = iOwnFormat->MimeFormat( 1 ).MimeType().DesC();
       
   528 	    aMimeVer = iOwnFormat->MimeFormat( 1 ).MimeVersion().DesC();
       
   529 	    }
       
   530     else if ( iTXEntryType == ENSmlVCal )
       
   531 	    {
       
   532 	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - vCal DB");
       
   533 	    iExporter->ExportVCalL( *entry, writeStream );
       
   534 	    aMimeType = iOwnFormat->MimeFormat( 0 ).MimeType().DesC();
       
   535 	    aMimeVer = iOwnFormat->MimeFormat( 0 ).MimeVersion().DesC();
       
   536 	    }
       
   537 	else
       
   538 	    {
       
   539 	    _DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: Export - DB Not Supported");
       
   540 	    CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
       
   541 	    User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   542 		return;
       
   543 	    }
       
   544 	
       
   545 	writeStream.CommitL();
       
   546 	iItemData->Compress();
       
   547 	iPos = 0;
       
   548 	
       
   549 #ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
       
   550 
       
   551 	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
       
   552 	         _S8( "Item from database:" ) );
       
   553 
       
   554 #endif // __NSML_MORE_DEBUG_FOR_ITEMS__
       
   555 
       
   556 	
       
   557 	iDataMod->StripTxL( *iItemData );
       
   558 	CleanupStack::PopAndDestroy( 2 ); // writeStream, entry
       
   559 	
       
   560 #ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
       
   561 
       
   562 	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
       
   563 	         _S8( "Item from database after strip:" ) );
       
   564 
       
   565 #endif // __NSML_MORE_DEBUG_FOR_ITEMS__
       
   566 	
       
   567 	aFieldChange = EFalse;
       
   568 	aSize = iItemData->Size();
       
   569 	
       
   570 	iState = ENSmlItemOpen;
       
   571 	
       
   572 	if ( iServerMaxObjectSize == 0 || aSize <= iServerMaxObjectSize )
       
   573 		{
       
   574 		User::RequestComplete( iCallerStatus, KErrNone );
       
   575 		}
       
   576 	else
       
   577 		{
       
   578 		User::RequestComplete( iCallerStatus, KErrTooBig );
       
   579 		}
       
   580 		
       
   581 	_DBG_FILE("CNSmlAgendaDataStore::DoOpenItemL: END");
       
   582     }
       
   583 
       
   584 // -----------------------------------------------------------------------------
       
   585 // CNSmlAgendaDataStore::DoCreateItemL
       
   586 // Prepare item data for writing to database. WriteItemL() writes item's data as
       
   587 // buffered.
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 void CNSmlAgendaDataStore::DoCreateItemL( TSmlDbItemUid& aUid, TInt aSize,
       
   591                 TSmlDbItemUid /*aParent*/, const TDesC8& aMimeType,
       
   592                 const TDesC8& /*aMimeVer*/, TRequestStatus& aStatus )
       
   593     {
       
   594 	_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: BEGIN");
       
   595 	iCallerStatus = &aStatus;
       
   596 	*iCallerStatus = KRequestPending;
       
   597 	iAddItemId = &aUid;
       
   598 	
       
   599 	if ( iState != ENSmlOpenAndWaiting )
       
   600 		{
       
   601 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   602 		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrNotReady: END");
       
   603 		return;
       
   604 		}
       
   605 		
       
   606 	if ( KNSmlAgendaOwnMaxObjectSize < aSize )
       
   607 		{
       
   608 		User::RequestComplete( iCallerStatus, KErrTooBig );
       
   609 		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrTooBig: END");
       
   610 		return;
       
   611 		}
       
   612 		
       
   613 	if( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
       
   614 		{
       
   615 		User::RequestComplete( iCallerStatus, KErrDiskFull );
       
   616 		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL - KErrDiskFull: END");
       
   617 		return;
       
   618 		}
       
   619 
       
   620     // Check if MIME type of new item is supported
       
   621 	TBool mimeFound( EFalse );
       
   622 	// vCal
       
   623     if ( iOwnFormat->MimeFormat( 0 ).MimeType().DesC().Compare( aMimeType )
       
   624          == 0 )
       
   625 	    {
       
   626 	    _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received vCal");
       
   627 	    mimeFound = ETrue;
       
   628 	    iRXEntryType = ENSmlVCal;
       
   629 	    }
       
   630 	        
       
   631 #ifdef __NSML_USE_ICAL_FEATURE
       
   632 
       
   633      // iCal
       
   634     else if ( iOwnFormat->MimeFormat( 1 ).MimeType().DesC().Compare( aMimeType )
       
   635               == 0 ) 
       
   636         {
       
   637         _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: received iCal");
       
   638         mimeFound = ETrue;
       
   639 	    iRXEntryType = ENSmlICal;
       
   640         }
       
   641 
       
   642 #endif // __NSML_USE_ICAL_FEATURE
       
   643 
       
   644     // Else use original iRXEntryType
       
   645     else
       
   646         {
       
   647         _DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: \
       
   648                    mime type not received");
       
   649         iRXEntryType = iTXEntryType;
       
   650         }
       
   651 
       
   652 	if ( !mimeFound )
       
   653 		{
       
   654 		User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   655 		_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL -KErrNotSupported: END");
       
   656 		return;
       
   657 		}
       
   658 
       
   659 	if( !iSnapshotRegistered )
       
   660 		{
       
   661 		RegisterSnapshotL();
       
   662 		}
       
   663 	delete iItemData;
       
   664 	iItemData = NULL;
       
   665 	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
       
   666 	iPos = 0;
       
   667 	
       
   668 	iState = ENSmlItemCreating;
       
   669 	User::RequestComplete( iCallerStatus, KErrNone );
       
   670 	_DBG_FILE("CNSmlAgendaDataStore::DoCreateItemL: END");
       
   671     }
       
   672 
       
   673 // -----------------------------------------------------------------------------
       
   674 // CNSmlAgendaDataStore::DoReplaceItemL
       
   675 // Prepare item data for writing and replacing item in database. WriteItemL()
       
   676 // writes item's data as buffered.
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 void CNSmlAgendaDataStore::DoReplaceItemL( TSmlDbItemUid aUid, TInt aSize,
       
   680                 TSmlDbItemUid /*aParent*/, TBool aFieldChange,
       
   681                 TRequestStatus& aStatus )
       
   682     {
       
   683 	_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: BEGIN");
       
   684 	iCallerStatus = &aStatus;
       
   685 	*iCallerStatus = KRequestPending;
       
   686 	
       
   687 	if ( iState != ENSmlOpenAndWaiting )
       
   688 		{
       
   689 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   690 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotReady: END");
       
   691 		return;
       
   692 		}
       
   693 
       
   694 	if ( KNSmlAgendaOwnMaxObjectSize < aSize )
       
   695 		{
       
   696 		User::RequestComplete( iCallerStatus, KErrTooBig );
       
   697 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrTooBig: END");
       
   698 		return;
       
   699 		}
       
   700 
       
   701 	if ( aFieldChange )
       
   702 		{
       
   703 		User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   704 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL \
       
   705 		           - KErrNotSupported: END");
       
   706 		return;
       
   707 		}
       
   708 	if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iRfs, aSize, iDrive ) )
       
   709 		{
       
   710 		User::RequestComplete( iCallerStatus, KErrDiskFull );
       
   711 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrDiskFull: END");
       
   712 		return;
       
   713 		}
       
   714 	
       
   715  	iReplaceItemId = aUid;
       
   716 
       
   717  	CCalEntry* entry = NULL;
       
   718  	TInt err( KErrNone );
       
   719     TRAP( err, entry = iEntryView->FetchL( aUid ) );
       
   720 	CleanupStack::PushL( entry );
       
   721  		
       
   722 	if ( !entry || err == KErrNotFound )
       
   723 		{
       
   724 		CleanupStack::PopAndDestroy( entry ); // entry
       
   725 		User::RequestComplete( iCallerStatus, KErrNotFound );
       
   726 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - KErrNotFound: END");
       
   727 		return;
       
   728 		}
       
   729     else if ( err )
       
   730         {
       
   731 		CleanupStack::PopAndDestroy( entry ); // entry
       
   732 		User::RequestComplete( iCallerStatus, err );
       
   733 		_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL - Error: END");
       
   734 		return;
       
   735         }
       
   736 
       
   737 	CleanupStack::PopAndDestroy( entry ); // entry
       
   738 		
       
   739 	if ( !iSnapshotRegistered )
       
   740 		{
       
   741 		RegisterSnapshotL();
       
   742 		}
       
   743 		
       
   744 	delete iItemData;
       
   745 	iItemData = NULL;
       
   746 	iItemData = CBufFlat::NewL( KNSmlItemDataExpandSize );
       
   747 	iPos = 0;
       
   748 	iReplaceItemId = aUid;
       
   749 	
       
   750 	iState = ENSmlItemUpdating;
       
   751 	User::RequestComplete( iCallerStatus, KErrNone );
       
   752 	_DBG_FILE("CNSmlAgendaDataStore::DoReplaceItemL: END");
       
   753     }
       
   754 
       
   755 // -----------------------------------------------------------------------------
       
   756 // CNSmlAgendaDataStore::DoReadItemL
       
   757 // Read item data to given buffer.
       
   758 // -----------------------------------------------------------------------------
       
   759 //
       
   760 void CNSmlAgendaDataStore::DoReadItemL( TDes8& aBuffer )
       
   761     {
       
   762 	_DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: BEGIN");
       
   763     if ( iState != ENSmlItemOpen || !iItemData )
       
   764         {
       
   765         iPos = -1;
       
   766         User::Leave( KErrNotReady );
       
   767         }
       
   768 
       
   769     if ( iPos == -1 )
       
   770         {
       
   771         User::Leave( KErrEof );
       
   772         }
       
   773 
       
   774     if ( aBuffer.Size() < iItemData->Size() - iPos )
       
   775         {
       
   776         iItemData->Read( iPos, aBuffer );
       
   777         iPos += aBuffer.Size();
       
   778         }
       
   779     else
       
   780         {
       
   781         iItemData->Read( iPos, aBuffer, iItemData->Size() - iPos );
       
   782         iPos = -1;
       
   783         }
       
   784 	_DBG_FILE("CNSmlAgendaDataStore::DoReadItemL: END");
       
   785     }
       
   786 
       
   787 // -----------------------------------------------------------------------------
       
   788 // CNSmlAgendaDataStore::DoWriteItemL
       
   789 // Write item data as buffered.
       
   790 // -----------------------------------------------------------------------------
       
   791 //
       
   792 void CNSmlAgendaDataStore::DoWriteItemL( const TDesC8& aData )
       
   793     {
       
   794 	_DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: BEGIN");
       
   795 	if ( iState == ENSmlItemCreating || iState == ENSmlItemUpdating )
       
   796 		{
       
   797 		if ( iItemData )
       
   798 			{
       
   799 			if ( iPos == -1 )
       
   800 				{
       
   801 				User::Leave( KErrEof );
       
   802 				}
       
   803 			iItemData->InsertL( iPos, aData );
       
   804 			iPos += aData.Size();
       
   805 			return;
       
   806 			}
       
   807 		}
       
   808 	User::Leave( KErrNotReady );
       
   809 	_DBG_FILE("CNSmlAgendaDataStore::DoWriteItemL: END");
       
   810     }
       
   811 
       
   812 // -----------------------------------------------------------------------------
       
   813 // CNSmlAgendaDataStore::DoCommitItemL
       
   814 // Commit item data to database when adding or replacing item.
       
   815 // -----------------------------------------------------------------------------
       
   816 //
       
   817 void CNSmlAgendaDataStore::DoCommitItemL( TRequestStatus& aStatus )
       
   818     {
       
   819 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: BEGIN");
       
   820 	iCallerStatus = &aStatus;
       
   821 	*iCallerStatus = KRequestPending;
       
   822 	
       
   823 	if ( iState != ENSmlItemCreating && iState != ENSmlItemUpdating )
       
   824 		{
       
   825 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   826 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL - KErrNotReady: END");
       
   827 		return;
       
   828 		}
       
   829 	
       
   830 	iItemData->Compress();
       
   831 	TInt error( KErrNone );
       
   832 	
       
   833 	if ( iState == ENSmlItemCreating )
       
   834 		{
       
   835 		TRAP( error, DoCommitCreateItemL() );
       
   836 		}
       
   837 	else // ENSmlItemUpdating
       
   838 		{
       
   839         TRAP( error, DoCommitReplaceItemL() );
       
   840 		}
       
   841 	iReplaceItemId = -1;
       
   842 	iPos = -1;
       
   843 	iState = ENSmlOpenAndWaiting;
       
   844 	iRXEntryType = iTXEntryType;
       
   845     User::RequestComplete( iCallerStatus, error );    
       
   846 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitItemL: END");
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // CNSmlAgendaDataStore::DoCloseItem
       
   851 // Return to previous state and clean item buffer.
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 void CNSmlAgendaDataStore::DoCloseItem()
       
   855     {
       
   856 	_DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: BEGIN");
       
   857 	if ( iState == ENSmlItemOpen )
       
   858 		{
       
   859 		iPos = -1;
       
   860 		iState = ENSmlOpenAndWaiting;
       
   861 		}
       
   862 	_DBG_FILE("CNSmlAgendaDataStore::DoCloseItem: END");
       
   863     }
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // CNSmlAgendaDataStore::DoMoveItemL
       
   867 // Not supported.
       
   868 // -----------------------------------------------------------------------------
       
   869 //
       
   870 void CNSmlAgendaDataStore::DoMoveItemL( TSmlDbItemUid /*aUid*/,
       
   871             TSmlDbItemUid /*aNewParent*/, TRequestStatus& aStatus )
       
   872     {
       
   873 	_DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: BEGIN");
       
   874 	iCallerStatus = &aStatus;
       
   875 	*iCallerStatus = KRequestPending;
       
   876 	if ( iState != ENSmlOpenAndWaiting )
       
   877 		{
       
   878 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   879 		return;
       
   880 		}
       
   881 	User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   882 	_DBG_FILE("CNSmlAgendaDataStore::DoMoveItemL: END");
       
   883     }
       
   884 
       
   885 // -----------------------------------------------------------------------------
       
   886 // CNSmlAgendaDataStore::DoDeleteItemL
       
   887 // Delete item from database.
       
   888 // -----------------------------------------------------------------------------
       
   889 //
       
   890 void CNSmlAgendaDataStore::DoDeleteItemL( TSmlDbItemUid aUid,
       
   891                 TRequestStatus& aStatus )
       
   892     {
       
   893 	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: BEGIN");
       
   894 	iCallerStatus = &aStatus;
       
   895 	*iCallerStatus = KRequestPending;
       
   896 	if ( iState != ENSmlOpenAndWaiting )
       
   897 		{
       
   898 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   899 		return;
       
   900 		}
       
   901 
       
   902     CCalEntry* entry = NULL;
       
   903     TInt err( KErrNone );
       
   904     TRAP( err, entry = iEntryView->FetchL( aUid ) );
       
   905     CleanupStack::PushL( entry );	
       
   906 
       
   907 	if ( !entry || err == KErrNotFound )
       
   908 		{
       
   909 		CleanupStack::PopAndDestroy( entry ); // entry
       
   910 		User::RequestComplete( iCallerStatus, KErrNotFound );
       
   911 		return;
       
   912 		}
       
   913 	else if ( err )
       
   914 	    {
       
   915 	    CleanupStack::PopAndDestroy( entry ); // entry
       
   916 		User::RequestComplete( iCallerStatus, err );
       
   917 		return;
       
   918 	    }
       
   919 	    
       
   920     iEntryView->DeleteL( *entry );
       
   921 	CleanupStack::PopAndDestroy( entry ); // entry
       
   922 	
       
   923 	if ( iChangeFinder )
       
   924 		{
       
   925 		TNSmlSnapshotItem item( aUid );
       
   926 		iChangeFinder->ItemDeleted( item );
       
   927 		}
       
   928 		
       
   929 	User::RequestComplete( iCallerStatus, KErrNone );
       
   930 	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteItemL: END");
       
   931     }
       
   932 
       
   933 // -----------------------------------------------------------------------------
       
   934 // CNSmlAgendaDataStore::DoSoftDeleteItemL
       
   935 // Delete item from database.
       
   936 // -----------------------------------------------------------------------------
       
   937 //
       
   938 void CNSmlAgendaDataStore::DoSoftDeleteItemL( TSmlDbItemUid /*aUid*/,
       
   939                 TRequestStatus& aStatus )
       
   940     {
       
   941 	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: BEGIN");
       
   942 	iCallerStatus = &aStatus;
       
   943 	*iCallerStatus = KRequestPending;
       
   944 	User::RequestComplete( iCallerStatus, KErrNotSupported );
       
   945 	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeleteItemL: END");
       
   946     }
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // CNSmlAgendaDataStore::DoDeleteAllItemsL
       
   950 // Delete all items from database.
       
   951 // -----------------------------------------------------------------------------
       
   952 //
       
   953 void CNSmlAgendaDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus )
       
   954     {
       
   955 	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: BEGIN");
       
   956 	iCallerStatus = &aStatus;
       
   957 	*iCallerStatus = KRequestPending;
       
   958 	if ( iState != ENSmlOpenAndWaiting ) 
       
   959 		{
       
   960 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
   961 		return;
       
   962 		}
       
   963 
       
   964 	// Delete all items
       
   965 	// First searh every UIDs ...
       
   966 	TInt aNumSuccessfulDeleted( 0 );
       
   967 	RArray<TCalLocalUid> uidArray;
       
   968 	CleanupClosePushL( uidArray );
       
   969 	TCalTime zeroTime;
       
   970 	zeroTime.SetTimeUtcL( Time::NullTTime() );
       
   971 	iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
       
   972 	
       
   973 	
       
   974 	// ... and then delete them
       
   975     iEntryView->DeleteL( uidArray, aNumSuccessfulDeleted );
       
   976 	CleanupStack::PopAndDestroy( &uidArray ); // uidArray
       
   977 
       
   978     // Update changefinder
       
   979 	if ( iChangeFinder )
       
   980 		{
       
   981 		iChangeFinder->ResetL();
       
   982 		}
       
   983 	iSnapshotRegistered = EFalse;
       
   984 	RegisterSnapshotL();
       
   985 	
       
   986 	User::RequestComplete( iCallerStatus, KErrNone );
       
   987 	
       
   988 	_DBG_FILE("CNSmlAgendaDataStore::DoDeleteAllItemsL: END");
       
   989     }
       
   990 
       
   991 // -----------------------------------------------------------------------------
       
   992 // CNSmlAgendaDataStore::DoHasSyncHistory
       
   993 // Return ETrue if syncronization history is available.
       
   994 // -----------------------------------------------------------------------------
       
   995 //
       
   996 TBool CNSmlAgendaDataStore::DoHasSyncHistory() const
       
   997     {
       
   998 	_DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: BEGIN");
       
   999 	TBool ret = EFalse;
       
  1000 	if ( iHasHistory )
       
  1001 		{
       
  1002 		if ( iOpenedStoreId != iChangeFinder->DataStoreUid() )
       
  1003 			{
       
  1004 			iChangeFinder->SetDataStoreUid( iOpenedStoreId );
       
  1005 			}
       
  1006 		else
       
  1007 			{
       
  1008 			ret = ETrue;
       
  1009 			}
       
  1010 		}
       
  1011 	else
       
  1012 		{
       
  1013 		iChangeFinder->SetDataStoreUid( iOpenedStoreId );
       
  1014 		}
       
  1015 	_DBG_FILE("CNSmlAgendaDataStore::DoHasSyncHistory: END");
       
  1016 	return ret;
       
  1017     }
       
  1018 
       
  1019 // -----------------------------------------------------------------------------
       
  1020 // CNSmlAgendaDataStore::DoAddedItems
       
  1021 // Give uid list of added items since last syncronization.
       
  1022 // -----------------------------------------------------------------------------
       
  1023 //
       
  1024 const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoAddedItems() const
       
  1025     {
       
  1026 	_DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: BEGIN");
       
  1027 	if ( iState == ENSmlOpenAndWaiting )
       
  1028 		{
       
  1029 		iNewUids->Reset();
       
  1030 		TRAP_IGNORE( iChangeFinder->FindNewItemsL( *iNewUids ) );
       
  1031 		}
       
  1032 	_DBG_FILE("CNSmlAgendaDataStore::DoAddedItems: END");
       
  1033 	return *iNewUids;
       
  1034     }
       
  1035 
       
  1036 // -----------------------------------------------------------------------------
       
  1037 // CNSmlAgendaDataStore::DoDeletedItems
       
  1038 // Give uid list of deleted items since last syncronization.
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoDeletedItems() const
       
  1042     {
       
  1043 	_DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: BEGIN");
       
  1044 	if ( iState == ENSmlOpenAndWaiting )
       
  1045 		{
       
  1046 		iDeletedUids->Reset();
       
  1047 		TRAP_IGNORE( iChangeFinder->FindDeletedItemsL( *iDeletedUids ) );
       
  1048 		}
       
  1049 	_DBG_FILE("CNSmlAgendaDataStore::DoDeletedItems: END");
       
  1050 	return *iDeletedUids;
       
  1051     }
       
  1052 
       
  1053 // -----------------------------------------------------------------------------
       
  1054 // CNSmlAgendaDataStore::DoSoftDeletedItems
       
  1055 // Give uid list of deleted items since last syncronization.
       
  1056 // -----------------------------------------------------------------------------
       
  1057 //
       
  1058 const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoSoftDeletedItems() const
       
  1059     {
       
  1060 	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: BEGIN");
       
  1061 	if ( iState == ENSmlOpenAndWaiting )
       
  1062 		{
       
  1063 		iSoftDeletedUids->Reset();
       
  1064 		TRAP_IGNORE(
       
  1065 		    iChangeFinder->FindSoftDeletedItemsL( *iSoftDeletedUids ) );
       
  1066 		}
       
  1067 	_DBG_FILE("CNSmlAgendaDataStore::DoSoftDeletedItems: END");
       
  1068 	return *iSoftDeletedUids;
       
  1069     }
       
  1070 
       
  1071 // -----------------------------------------------------------------------------
       
  1072 // CNSmlAgendaDataStore::DoModifiedItems
       
  1073 // Give uid list of modified items since last syncronization.
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //
       
  1076 const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoModifiedItems() const
       
  1077     {
       
  1078 	_DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: BEGIN");
       
  1079 	if ( iState == ENSmlOpenAndWaiting )
       
  1080 		{
       
  1081 		iReplacedUids->Reset();
       
  1082 		TRAP_IGNORE( iChangeFinder->FindChangedItemsL( *iReplacedUids ) );
       
  1083 		}
       
  1084 	_DBG_FILE("CNSmlAgendaDataStore::DoModifiedItems: END");
       
  1085 	return *iReplacedUids;
       
  1086     }
       
  1087 
       
  1088 // -----------------------------------------------------------------------------
       
  1089 // CNSmlAgendaDataStore::DoMovedItems
       
  1090 // Give uid list of moved items since last syncronization.
       
  1091 // -----------------------------------------------------------------------------
       
  1092 //
       
  1093 const MSmlDataItemUidSet& CNSmlAgendaDataStore::DoMovedItems() const
       
  1094     {
       
  1095 	_DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: BEGIN");
       
  1096 	if ( iState == ENSmlOpenAndWaiting )
       
  1097 		{
       
  1098 		iMovedUids->Reset();
       
  1099 		TRAP_IGNORE( iChangeFinder->FindMovedItemsL( *iMovedUids ) );
       
  1100 		}
       
  1101 	_DBG_FILE("CNSmlAgendaDataStore::DoMovedItems: END");
       
  1102 	return *iMovedUids;
       
  1103     }
       
  1104 
       
  1105 // -----------------------------------------------------------------------------
       
  1106 // CNSmlAgendaDataStore::DoResetChangeInfoL
       
  1107 // Reset change info that exist since last syncronization.
       
  1108 // -----------------------------------------------------------------------------
       
  1109 //
       
  1110 void CNSmlAgendaDataStore::DoResetChangeInfoL( TRequestStatus& aStatus )
       
  1111     {
       
  1112 	_DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: BEGIN");
       
  1113 	iCallerStatus = &aStatus;
       
  1114 	*iCallerStatus = KRequestPending;
       
  1115 	if ( iState != ENSmlOpenAndWaiting ) 
       
  1116 		{
       
  1117 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
  1118 		return;
       
  1119 		}
       
  1120 	iChangeFinder->ResetL();
       
  1121 	iSnapshotRegistered = EFalse;
       
  1122 	if( !iSnapshotRegistered )
       
  1123 		{
       
  1124 		RegisterSnapshotL();
       
  1125 		}
       
  1126 	User::RequestComplete( iCallerStatus, KErrNone );
       
  1127 	_DBG_FILE("CNSmlAgendaDataStore::DoResetChangeInfoL: END");
       
  1128     }
       
  1129 
       
  1130 // -----------------------------------------------------------------------------
       
  1131 // CNSmlAgendaDataStore::DoCommitChangeInfoL
       
  1132 // Commit change info that exist since last syncronization for given uid list.
       
  1133 // -----------------------------------------------------------------------------
       
  1134 //
       
  1135 void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus,
       
  1136                 const MSmlDataItemUidSet& aItems )
       
  1137     {
       
  1138 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
       
  1139 	iCallerStatus = &aStatus;
       
  1140 	*iCallerStatus = KRequestPending;
       
  1141 	if ( iState != ENSmlOpenAndWaiting ) 
       
  1142 		{
       
  1143 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
  1144 		return;
       
  1145 		}
       
  1146 	iChangeFinder->CommitChangesL( aItems );
       
  1147 	User::RequestComplete( iCallerStatus, KErrNone );
       
  1148 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
       
  1149     }
       
  1150 
       
  1151 // -----------------------------------------------------------------------------
       
  1152 // CNSmlAgendaDataStore::DoCommitChangeInfoL
       
  1153 // Commit change info that exist since last syncronization.
       
  1154 // -----------------------------------------------------------------------------
       
  1155 //
       
  1156 void CNSmlAgendaDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus )
       
  1157     {
       
  1158 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: BEGIN");
       
  1159 	iCallerStatus = &aStatus;
       
  1160 	*iCallerStatus = KRequestPending;
       
  1161 	if ( iState != ENSmlOpenAndWaiting ) 
       
  1162 		{
       
  1163 		User::RequestComplete( iCallerStatus, KErrNotReady );
       
  1164 		return;
       
  1165 		}
       
  1166 	iChangeFinder->CommitChangesL();
       
  1167 	User::RequestComplete( iCallerStatus, KErrNone );
       
  1168 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitChangeInfoL: END");
       
  1169     }
       
  1170     
       
  1171 // -----------------------------------------------------------------------------
       
  1172 // CNSmlAgendaDataStore::RegisterSnapshotL
       
  1173 // Register snapshot.
       
  1174 // -----------------------------------------------------------------------------
       
  1175 //
       
  1176 void CNSmlAgendaDataStore::RegisterSnapshotL()
       
  1177     {
       
  1178 	_DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): begin");
       
  1179 	CArrayFixSeg<TNSmlSnapshotItem>* snapshot =
       
  1180 	                new ( ELeave ) CArrayFixSeg<TNSmlSnapshotItem>( 64 );
       
  1181 	CleanupStack::PushL( snapshot );
       
  1182 	
       
  1183     // First find all entries ...
       
  1184 	RArray<TCalLocalUid> uidArray;
       
  1185 	CleanupClosePushL( uidArray );
       
  1186 	TCalTime zeroTime;
       
  1187 	zeroTime.SetTimeUtcL( Time::NullTTime() );
       
  1188 	iEntryView->GetIdsModifiedSinceDateL( zeroTime, uidArray );
       
  1189 	
       
  1190 	// ... and then create snapshot items
       
  1191 	for ( TInt i = 0; i < uidArray.Count(); i++ )
       
  1192 	    {
       
  1193 	    TNSmlSnapshotItem newItem = CreateSnapshotItemL( uidArray[i] );
       
  1194 	    if ( newItem.ItemId() != 0 )
       
  1195 	        {
       
  1196 	        snapshot->InsertIsqL( newItem, iKey );
       
  1197 	        }
       
  1198 	    }
       
  1199 	
       
  1200 	CleanupStack::PopAndDestroy( &uidArray );
       
  1201 		
       
  1202 	iChangeFinder->SetNewSnapshot( snapshot );
       
  1203 	
       
  1204 	// iChangeFinder takes ownership of items
       
  1205 	CleanupStack::Pop( snapshot );
       
  1206 	iSnapshotRegistered = ETrue;
       
  1207 	
       
  1208 	_DBG_FILE("CNSmlAgendaAdapter::RegisterSnapshotL(): end");
       
  1209     }
       
  1210 
       
  1211 // -----------------------------------------------------------------------------
       
  1212 // CNSmlAgendaDataStore::CreateSnapshotItemL
       
  1213 // Creates new snapshot. Method gets data from database.
       
  1214 // -----------------------------------------------------------------------------
       
  1215 TNSmlSnapshotItem CNSmlAgendaDataStore::CreateSnapshotItemL(
       
  1216                 const TCalLocalUid& aUid )
       
  1217     {
       
  1218     TNSmlSnapshotItem item( 0 );
       
  1219     CCalEntry* entry = iEntryView->FetchL( aUid );
       
  1220     CleanupStack::PushL( entry );
       
  1221 
       
  1222     if( entry )
       
  1223 		{
       
  1224 		CCalEntry::TReplicationStatus replicationStatus =
       
  1225 		                    entry->ReplicationStatusL();
       
  1226 		if ( CanBeSynchronized( replicationStatus ) )
       
  1227 			{
       
  1228 			TUint intUid = entry->LocalUidL();
       
  1229 			item.SetItemId( intUid );
       
  1230 			item.SetLastChangedDate(
       
  1231 			                entry->LastModifiedDateL().TimeUtcL() );
       
  1232 			item.SetSoftDelete( EFalse );
       
  1233 			}
       
  1234 		}
       
  1235 		
       
  1236     CleanupStack::PopAndDestroy( entry ); // entry
       
  1237 	return item;
       
  1238     }
       
  1239 
       
  1240 // -----------------------------------------------------------------------------
       
  1241 // CNSmlAgendaDataStore::DoListAgendaFilesL
       
  1242 // List possible calendar database file names.
       
  1243 // -----------------------------------------------------------------------------
       
  1244 //
       
  1245 CDesCArray* CNSmlAgendaDataStore::DoListAgendaFilesLC() const
       
  1246     {
       
  1247     CDesCArray* array = iVCalSession->ListCalFilesL();    
       
  1248 	CleanupStack::PushL( array );
       
  1249 	return array;
       
  1250     }
       
  1251 
       
  1252 // -----------------------------------------------------------------------------
       
  1253 // CNSmlAgendaDataStore::DoGetDefaultFileNameL
       
  1254 // Return default calendar database name.
       
  1255 // -----------------------------------------------------------------------------
       
  1256 //
       
  1257 const TDesC& CNSmlAgendaDataStore::DoGetDefaultFileNameL() const
       
  1258     {
       
  1259 	if ( !iDefaultStoreName )
       
  1260 		{
       
  1261         User::Leave( KErrGeneral );
       
  1262 		}
       
  1263 	return *iDefaultStoreName;
       
  1264     }
       
  1265 
       
  1266 // -----------------------------------------------------------------------------
       
  1267 // CNSmlAgendaDataStore::CanBeSynchronized
       
  1268 // Return ETrue if entry can be synchronized.
       
  1269 // -----------------------------------------------------------------------------
       
  1270 //
       
  1271 TBool CNSmlAgendaDataStore::CanBeSynchronized(
       
  1272             const CCalEntry::TReplicationStatus&
       
  1273             aReplicationStatus ) const
       
  1274 	{
       
  1275 	return ( aReplicationStatus != CCalEntry::ERestricted );	
       
  1276 	}
       
  1277 
       
  1278 // -----------------------------------------------------------------------------
       
  1279 // CNSmlAgendaDataStore::DoOwnStoreFormatL
       
  1280 // Returns adapters supported store format which is read from Calendar Plug
       
  1281 // In Adapter own resource file.
       
  1282 // -----------------------------------------------------------------------------
       
  1283 //
       
  1284 CSmlDataStoreFormat* CNSmlAgendaDataStore::DoOwnStoreFormatL()
       
  1285 	{
       
  1286 	_DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): BEGIN");
       
  1287 	TFileName fileName;
       
  1288 	TParse parse;
       
  1289 	
       
  1290 	// Check correct Data Sync protocol
       
  1291 	TInt value( EDataSyncNotRunning );
       
  1292 	TInt error = RProperty::Get( KPSUidDataSynchronizationInternalKeys,
       
  1293                                  KDataSyncStatus,
       
  1294                                  value );
       
  1295 	if ( error == KErrNone &&
       
  1296 	     value == EDataSyncRunning )
       
  1297 	    {
       
  1298 	    parse.Set( KNSmlDSAgendaDataStoreRsc_1_1_2,
       
  1299 	               &KDC_RESOURCE_FILES_DIR, NULL );
       
  1300 	    }
       
  1301 	else // error or protocol version 1.2 
       
  1302 	    {
       
  1303 	    parse.Set( KNSmlDSAgendaDataStoreRsc_1_2,
       
  1304 	               &KDC_RESOURCE_FILES_DIR, NULL );
       
  1305 	    }
       
  1306 	
       
  1307 	fileName = parse.FullName();
       
  1308 	RResourceFile resourceFile;
       
  1309 	BaflUtils::NearestLanguageFile( iRfs, fileName );
       
  1310 
       
  1311 	TRAPD( leavecode, resourceFile.OpenL( iRfs,fileName ) );
       
  1312 	if ( leavecode != 0 )
       
  1313 		{
       
  1314 		CleanupStack::PopAndDestroy(); // parse
       
  1315 		_DBG_FILE("CNSmlAgendaDataProvider::DoStoreFormatL(): Resource.OpenL has problem");
       
  1316 		User::Leave( leavecode );
       
  1317 		}
       
  1318 	CleanupClosePushL( resourceFile );
       
  1319 	HBufC8* profileRes = resourceFile.AllocReadLC( NSML_AGENDA_DATA_STORE );
       
  1320 	TResourceReader reader;
       
  1321 	reader.SetBuffer( profileRes );
       
  1322 
       
  1323 	CSmlDataStoreFormat* dsFormat = CSmlDataStoreFormat::NewLC( iStringPool,
       
  1324 	                                                            reader );
       
  1325 	CleanupStack::Pop();
       
  1326 	CleanupStack::PopAndDestroy( 2 ); // resourceFile, profileRes
       
  1327 	_DBG_FILE("CNSmlAgendaDataStore:::DoOwnStoreFormatL(): END");
       
  1328 	return dsFormat;
       
  1329 	}
       
  1330 
       
  1331 // -----------------------------------------------------------------------------
       
  1332 // CNSmlAgendaDataStore::DoCommitCreateItemL
       
  1333 // Commit item data to database when adding item.
       
  1334 // -----------------------------------------------------------------------------
       
  1335 //
       
  1336 void CNSmlAgendaDataStore::DoCommitCreateItemL()
       
  1337     {
       
  1338     _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: BEGIN");
       
  1339     iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
       
  1340 	CCalEntry::TReplicationStatus  replicationStatus;
       
  1341 	
       
  1342 	RBufReadStream readStream;
       
  1343 	readStream.Open( *iItemData );
       
  1344 	readStream.PushL();
       
  1345 
       
  1346     RPointerArray<CCalEntry> rdArray;
       
  1347 	CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
       
  1348 	if ( iRXEntryType == ENSmlICal )
       
  1349 	    {
       
  1350 	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportICalendarL");
       
  1351 	    iImporter->ImportICalendarL( readStream, rdArray );
       
  1352 	    }
       
  1353     else if ( iRXEntryType == ENSmlVCal )
       
  1354         {
       
  1355         _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: ImportVCalendarL");
       
  1356         iImporter->ImportVCalendarL( readStream, rdArray );
       
  1357         }
       
  1358     else
       
  1359         {
       
  1360         CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1361 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
       
  1362 		           KErrNotSupported: END");
       
  1363         User::Leave( KErrNotSupported );
       
  1364         }
       
  1365     
       
  1366     // If rdArray is empty or there is multiple items then return error
       
  1367 	// Multiple items are not supported
       
  1368 	if ( rdArray.Count() != 1 )
       
  1369 	    {
       
  1370 	    CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1371 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
       
  1372 		           Multiple items are not supported: END");
       
  1373         User::Leave( KErrNotSupported );
       
  1374 	    }
       
  1375 	    
       
  1376     TInt err( KErrNone );
       
  1377 
       
  1378     _DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: before StoreL");
       
  1379     TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
       
  1380     DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
       
  1381     if ( err )
       
  1382         {
       
  1383         CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1384 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL - \
       
  1385 		           Error at storing item to database: END");
       
  1386         User::Leave( KErrGeneral );
       
  1387         }
       
  1388 
       
  1389     *iAddItemId = rdArray[0]->LocalUidL();
       
  1390     
       
  1391     CCalEntry* newEntry = iEntryView->FetchL( *iAddItemId );
       
  1392     
       
  1393     if( newEntry )
       
  1394     	{
       
  1395 	    CleanupStack::PushL( newEntry );
       
  1396         
       
  1397 		replicationStatus = newEntry->ReplicationStatusL();
       
  1398 	
       
  1399     	if ( CanBeSynchronized( replicationStatus ) )
       
  1400 			{
       
  1401 			if ( iChangeFinder )
       
  1402 				{
       
  1403 				TNSmlSnapshotItem item( *iAddItemId );
       
  1404         			item.SetLastChangedDate(
       
  1405                    	newEntry->LastModifiedDateL().TimeUtcL() );
       
  1406             	item.SetSoftDelete( EFalse );
       
  1407 				TRAPD( changeFinderError, iChangeFinder->ItemAddedL( item ) );
       
  1408 				if ( changeFinderError == KErrAlreadyExists )
       
  1409 			    	{
       
  1410 			    	iChangeFinder->ItemUpdatedL( item );
       
  1411 			    	}
       
  1412 				else
       
  1413 			    	{
       
  1414 			    	User::LeaveIfError( changeFinderError );    
       
  1415 			    	}
       
  1416 				}
       
  1417 			}
       
  1418     	CleanupStack::PopAndDestroy();// newEntry,
       
  1419     	}
       
  1420     CleanupStack::PopAndDestroy( 2 ); //  rdArray, readStream   
       
  1421 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitCreateItemL: END");
       
  1422     }
       
  1423     
       
  1424 // -----------------------------------------------------------------------------
       
  1425 // CNSmlAgendaDataStore::DoCommitReplaceItemL
       
  1426 // Commit item data to database when replacing item.
       
  1427 // -----------------------------------------------------------------------------
       
  1428 //
       
  1429 void CNSmlAgendaDataStore::DoCommitReplaceItemL()
       
  1430     {
       
  1431     _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: BEGIN");
       
  1432     iState = ENSmlOpenAndWaiting; // iState set to closed to handle leave
       
  1433 	CBufFlat* oldItem = CBufFlat::NewL( KNSmlItemDataExpandSize );
       
  1434 	CleanupStack::PushL( oldItem );
       
  1435 	RBufWriteStream writeStream( *oldItem );
       
  1436 	writeStream.PushL();
       
  1437 	
       
  1438 	CCalEntry* entry = NULL;
       
  1439 	TInt error( KErrNone );
       
  1440     TRAP( error, entry = iEntryView->FetchL( iReplaceItemId ) );
       
  1441 	if ( error || !entry )
       
  1442 	{
       
  1443     	CleanupStack::PopAndDestroy( 2 ); // writeStream, oldItem
       
  1444 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
       
  1445 		           Error in fetching the item: END");
       
  1446     	User::Leave( KErrGeneral );
       
  1447     }
       
  1448     CleanupStack::PushL( entry );
       
  1449 	
       
  1450 	// Export item from database depending on transmitted item entry type
       
  1451 	if ( iTXEntryType == ENSmlVCal )
       
  1452 	    {
       
  1453 	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportVCalL");
       
  1454     	iExporter->ExportVCalL( *entry, writeStream );        
       
  1455     	}
       
  1456 #ifdef __NSML_USE_ICAL_FEATURE
       
  1457 	else if ( iTXEntryType == ENSmlICal )
       
  1458 	    {
       
  1459 	    _DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ExportICalL");
       
  1460     	iExporter->ExportICalL( *entry, writeStream );
       
  1461 	    }
       
  1462 #endif // __NSML_USE_ICAL_FEATURE
       
  1463 	else
       
  1464         {
       
  1465         CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
       
  1466 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
       
  1467 		           KErrNotSupported: END");
       
  1468         User::Leave( KErrNotSupported );
       
  1469         }
       
  1470         
       
  1471 	writeStream.CommitL();
       
  1472 	oldItem->Compress();
       
  1473 
       
  1474 	CleanupStack::PopAndDestroy( 2 ); // entry, writeStream
       
  1475 	
       
  1476 	// Get original UID, geoId and Recurrence-ID properties
       
  1477 	HBufC8* uid = NULL;
       
  1478 	HBufC8* recurrenceId = NULL;
       
  1479 	HBufC8* xRecurrenceId = NULL;
       
  1480 	HBufC8* geoId = NULL;
       
  1481 	GetPropertiesFromDataL( oldItem, uid, KVersitTokenUID()  );
       
  1482 	GetPropertiesFromDataL( oldItem, recurrenceId, KNSmlVersitTokenRecurrenceID() );
       
  1483 	GetPropertiesFromDataL( oldItem, xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );
       
  1484 	GetPropertiesFromDataL( oldItem, geoId, KNSmlVersitTokenGeoID() );
       
  1485 	CleanupStack::PushL( uid );
       
  1486 	CleanupStack::PushL( recurrenceId );
       
  1487 	CleanupStack::PushL( xRecurrenceId );
       
  1488 	CleanupStack::PushL( geoId );
       
  1489 
       
  1490 #ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
       
  1491 
       
  1492 	DBG_DUMP( ( void* )oldItem->Ptr( 0 ).Ptr(), oldItem->Size(),
       
  1493 	          _S8( "Old item from database:" ) );
       
  1494 
       
  1495 #endif // __NSML_MORE_DEBUG_FOR_ITEMS__
       
  1496 
       
  1497    	if ( iDataMod->NeedsMerge() )
       
  1498 		{
       
  1499     	// Merge data
       
  1500     	iDataMod->MergeRxL( *iItemData, *oldItem );
       
  1501 		}
       
  1502 	
       
  1503 	// Add original UID and Recurrence-ID to merged data
       
  1504 	// This first removes UID and Recurrence-ID from merged data
       
  1505 	// and then adds original ones
       
  1506 	if ( uid )
       
  1507 	    {
       
  1508 	    SetPropertiesToDataL( uid, KVersitTokenUID() );    
       
  1509 	    }
       
  1510     else
       
  1511         {
       
  1512         User::Leave( KErrNotSupported );
       
  1513         }
       
  1514 	if ( recurrenceId )
       
  1515 	    {
       
  1516 	    SetPropertiesToDataL( recurrenceId, KNSmlVersitTokenRecurrenceID() );    
       
  1517 	    }
       
  1518 	if ( xRecurrenceId )
       
  1519 	    {
       
  1520 	    SetPropertiesToDataL( xRecurrenceId, KNSmlVersitTokenXRecurrenceID() );    
       
  1521 	    }
       
  1522 	if ( geoId )
       
  1523 	    {
       
  1524 	    SetPropertiesToDataL( geoId, KNSmlVersitTokenGeoID() );    
       
  1525 	    }
       
  1526 
       
  1527 #ifdef __NSML_MORE_DEBUG_FOR_ITEMS__
       
  1528 
       
  1529 	DBG_DUMP( ( void* )iItemData->Ptr( 0 ).Ptr(), iItemData->Size(),
       
  1530 	          _S8( "New item to database:" ) );
       
  1531 
       
  1532 #endif // __NSML_MORE_DEBUG_FOR_ITEMS__
       
  1533 	
       
  1534 	CleanupStack::PopAndDestroy( 5 ); // xRecurrenceId, recurrenceId,
       
  1535 	                                  // uid, oldItem, geoId
       
  1536     
       
  1537 	// Replace item to database
       
  1538 	RBufReadStream readStream;
       
  1539 	readStream.Open( *iItemData );
       
  1540 	readStream.PushL();
       
  1541 
       
  1542 	RPointerArray<CCalEntry> rdArray;
       
  1543 	CleanupStack::PushL( PtrArrCleanupItemRArr ( CCalEntry, &rdArray ) );
       
  1544 
       
  1545 	// Import item to database depending on received item entry type
       
  1546 	if ( iRXEntryType == ENSmlVCal )
       
  1547         {
       
  1548 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportVCalendarL");
       
  1549     	iImporter->ImportVCalendarL( readStream, rdArray );
       
  1550         }
       
  1551 #ifdef __NSML_USE_ICAL_FEATURE
       
  1552 	else if ( iRXEntryType == ENSmlICal )
       
  1553 		{
       
  1554 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: ImportICalendarL");
       
  1555 		iImporter->ImportICalendarL( readStream, rdArray );
       
  1556 		}
       
  1557 #endif // __NSML_USE_ICAL_FEATURE
       
  1558     else
       
  1559         {
       
  1560         CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1561 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
       
  1562 		           KErrNotSupported: END");
       
  1563         User::Leave( KErrNotSupported );
       
  1564         }
       
  1565 
       
  1566     // If rdArray is empty or there is multiple items then return error
       
  1567 	// Multiple items are not supported
       
  1568 	if ( rdArray.Count() != 1 )
       
  1569 	    {
       
  1570 	    CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1571 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
       
  1572 		           Multiple items are not supported: END");
       
  1573         User::Leave( KErrNotSupported );
       
  1574 	    }
       
  1575 	    
       
  1576 	TInt err( KErrNone );
       
  1577 
       
  1578 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: before StoreL");
       
  1579     TRAP( err, iInterimUtils->StoreL( *iEntryView, *rdArray[0], ETrue ) );
       
  1580     DBG_ARGS(_S("CNSmlAgendaDataStore::DoCommitCreateItemL: after StoreL '%d'"), err );
       
  1581     if ( err )
       
  1582         {
       
  1583         CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1584 		_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL - \
       
  1585 		           Error at storing item to database: END");
       
  1586         User::Leave( KErrGeneral );
       
  1587         }
       
  1588 
       
  1589 	CCalEntry::TReplicationStatus  replicationStatus;
       
  1590 	
       
  1591 	CCalEntry* replacedEntry = iEntryView->FetchL( iReplaceItemId );
       
  1592 	if( replacedEntry )
       
  1593 	{
       
  1594     CleanupStack::PushL( replacedEntry );
       
  1595 	
       
  1596     replicationStatus = replacedEntry->ReplicationStatusL();
       
  1597 	            
       
  1598 	if ( CanBeSynchronized( replicationStatus ) )
       
  1599 		{
       
  1600 		if ( iChangeFinder )
       
  1601 			{
       
  1602 			TNSmlSnapshotItem item( iReplaceItemId );
       
  1603 			item.SetLastChangedDate(
       
  1604 			            replacedEntry->LastModifiedDateL().TimeUtcL());
       
  1605 			item.SetSoftDelete( EFalse );
       
  1606 			iChangeFinder->ItemUpdatedL( item );
       
  1607 			}
       
  1608 		}
       
  1609 	CleanupStack::PopAndDestroy(); // replacedEntry
       
  1610 	}
       
  1611 	
       
  1612 	CleanupStack::PopAndDestroy( 2 ); // rdArray, readStream
       
  1613 
       
  1614 	_DBG_FILE("CNSmlAgendaDataStore::DoCommitReplaceItemL: END");
       
  1615     }
       
  1616     
       
  1617 // -----------------------------------------------------------------------------
       
  1618 // CNSmlAgendaDataStore::GetPropertiesFromDataL
       
  1619 // Gets property from old item.
       
  1620 // -----------------------------------------------------------------------------
       
  1621 //
       
  1622 void CNSmlAgendaDataStore::GetPropertiesFromDataL( CBufFlat* aOldItem,
       
  1623                                                    HBufC8*& aValue,
       
  1624 	                                               const TDesC8& aProperty )
       
  1625     {
       
  1626     _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): begin");
       
  1627     
       
  1628     // Gemerate property that is searched (Linebreak + property + tokencolon)
       
  1629     HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
       
  1630                                          aProperty.Length() );
       
  1631     TPtr8 startBufferPtr( startBuffer->Des() );
       
  1632 	startBufferPtr.Append( KVersitTokenCRLF() );
       
  1633 	startBufferPtr.Append( aProperty );
       
  1634 	
       
  1635 	// Get start position of property value
       
  1636 	TInt startPos = aOldItem->Ptr( 0 ).Find( startBufferPtr );
       
  1637 	
       
  1638 	TInt endPos( KErrNotFound );
       
  1639 	if ( startPos != KErrNotFound )
       
  1640 	    {
       
  1641 	    // startPos is before UID word
       
  1642 	    startPos = startPos + KVersitTokenCRLF().Length();
       
  1643 	    
       
  1644 	    // End end position of property value
       
  1645 	    endPos = startPos + 
       
  1646 	             aOldItem->Ptr( startPos ).Find( KVersitTokenCRLF() );
       
  1647 	    
       
  1648 	    TPtrC8 tempPtr( aOldItem->Ptr( 0 ).Mid( endPos ) );
       
  1649 	    
       
  1650 	    // If next char after linebreak is ' ' or '=' then it is only
       
  1651 	    // linebreak inside of value. This does not work with base64 coding!
       
  1652 	    while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
       
  1653 	            tempPtr[KVersitTokenCRLF().Length()] == '=' )
       
  1654 	        {
       
  1655 	        endPos = endPos + KVersitTokenCRLF().Length();
       
  1656 	        TInt tempPos = aOldItem->Ptr( endPos ).Find( KVersitTokenCRLF() );
       
  1657 	        endPos = endPos + tempPos;
       
  1658 	        tempPtr.Set( aOldItem->Ptr( 0 ).Mid( endPos ) );
       
  1659 	        }
       
  1660         
       
  1661         // Then cut value to value parameter
       
  1662         delete aValue;
       
  1663 		aValue = NULL;
       
  1664 		TInt length = endPos - startPos;
       
  1665 		aValue = HBufC8::NewLC( length );
       
  1666 		TPtr8 valuePtr( aValue->Des() );
       
  1667 		aOldItem->Read( startPos, valuePtr, length );
       
  1668 		CleanupStack::Pop( aValue ); // aValue
       
  1669 	    }
       
  1670     CleanupStack::PopAndDestroy( startBuffer ); // startBuffer
       
  1671     
       
  1672     _DBG_FILE("CNSmlAgendaDataStore::GetPropertiesFromDataL(): end");
       
  1673     }
       
  1674   
       
  1675 // -----------------------------------------------------------------------------
       
  1676 // Adds property and it's value to new item.
       
  1677 // This method also removes original property and it's value.
       
  1678 // -----------------------------------------------------------------------------
       
  1679 //  
       
  1680 void CNSmlAgendaDataStore::SetPropertiesToDataL( HBufC8*& aValue,
       
  1681 	                                             const TDesC8& aProperty )
       
  1682     {
       
  1683     _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): begin");
       
  1684     
       
  1685     // Gemerate property that is searched (Linebreak + property + tokencolon)
       
  1686     HBufC8* startBuffer = HBufC8::NewLC( KVersitTokenCRLF().Size() +
       
  1687                                          aProperty.Length() );
       
  1688     TPtr8 startBufferPtr( startBuffer->Des() );
       
  1689 	startBufferPtr.Append( KVersitTokenCRLF() );
       
  1690 	startBufferPtr.Append( aProperty );
       
  1691 	
       
  1692 	// Get start position of property value
       
  1693 	TInt startPos = iItemData->Ptr( 0 ).Find( startBufferPtr );
       
  1694 	
       
  1695 	TInt endPos( KErrNotFound );
       
  1696 	if ( startPos != KErrNotFound )
       
  1697 	    {
       
  1698 	    // startPos is before UID word
       
  1699 	    startPos = startPos + KVersitTokenCRLF().Length();
       
  1700 	    
       
  1701 	    // End end position of property value
       
  1702 	    endPos = startPos + 
       
  1703 	             iItemData->Ptr( startPos ).Find( KVersitTokenCRLF() );
       
  1704 	    
       
  1705 	    TPtrC8 tempPtr( iItemData->Ptr( 0 ).Mid( endPos ) );
       
  1706 	    
       
  1707 	    // If next char after linebreak is ' ' or '=' then it is only
       
  1708 	    // linebreak inside of value. This does not work with base64 coding!
       
  1709 	    while ( tempPtr[KVersitTokenCRLF().Length()] == ' ' ||
       
  1710 	            tempPtr[KVersitTokenCRLF().Length()] == '=' )
       
  1711 	        {
       
  1712 	        endPos = endPos + KVersitTokenCRLF().Length();
       
  1713 	        TInt tempPos = iItemData->Ptr( endPos ).Find( KVersitTokenCRLF() );
       
  1714 	        endPos = endPos + tempPos;
       
  1715 	        tempPtr.Set( iItemData->Ptr( 0 ).Mid( endPos ) );
       
  1716 	        }
       
  1717         
       
  1718         // Delete original property and value
       
  1719         iItemData->Delete( startPos, endPos - startPos );
       
  1720         
       
  1721 	    }
       
  1722 
       
  1723     // Add property and new value from parameter.
       
  1724     // First find end of VEVENT or VTODO
       
  1725     
       
  1726     // Generate VEVENT END property
       
  1727     HBufC8* endVEvent = HBufC8::NewLC( KVersitTokenCRLF().Size() + 
       
  1728                                      KVersitTokenEND().Length() +
       
  1729                                      KVersitTokenColon().Length() +
       
  1730                                      KVersitVarTokenVEVENT().Length() );
       
  1731 	TPtr8 endVEventPtr( endVEvent->Des() );
       
  1732 	endVEventPtr.Append( KVersitTokenCRLF() );
       
  1733 	endVEventPtr.Append( KVersitTokenEND() );
       
  1734 	endVEventPtr.Append( KVersitTokenColon() );
       
  1735 	endVEventPtr.Append( KVersitVarTokenVEVENT() );
       
  1736 	
       
  1737 	// Generate VTODO END property
       
  1738     HBufC8* endVTodo = HBufC8::NewLC( KVersitTokenCRLF().Size() + 
       
  1739                                      KVersitTokenEND().Length() +
       
  1740                                      KVersitTokenColon().Length() +
       
  1741                                      KVersitVarTokenVTODO().Length() );
       
  1742 	TPtr8 endVTodoPtr( endVTodo->Des() );
       
  1743 	endVTodoPtr.Append( KVersitTokenCRLF() );
       
  1744 	endVTodoPtr.Append( KVersitTokenEND() );
       
  1745 	endVTodoPtr.Append( KVersitTokenColon() );
       
  1746 	endVTodoPtr.Append( KVersitVarTokenVTODO() );
       
  1747     
       
  1748     // Find end of VEVENT or VTODO
       
  1749     endPos = iItemData->Ptr( 0 ).Find( endVEventPtr );
       
  1750     if ( endPos == KErrNotFound )
       
  1751         {
       
  1752         endPos = iItemData->Ptr( 0 ).Find( endVTodoPtr );
       
  1753         if ( endPos == KErrNotFound )
       
  1754             {
       
  1755             User::Leave( KErrNotFound );
       
  1756             }
       
  1757         }
       
  1758 
       
  1759     // Add property and value from parameter
       
  1760 	iItemData->InsertL( endPos, KVersitTokenCRLF() );
       
  1761 	iItemData->InsertL( endPos + KVersitTokenCRLF().Size(),
       
  1762 	                    aValue->Des() );
       
  1763     iItemData->Compress();
       
  1764     
       
  1765     CleanupStack::PopAndDestroy( 3 ); // endVTodo, endVEvent, startBuffer
       
  1766     
       
  1767     _DBG_FILE("CNSmlAgendaDataStore::SetPropertiesToDataL(): end");
       
  1768     }
       
  1769 	
       
  1770 //  End of File