emailservices/emailstore/base_plugin/src/BasePlugin.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 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:  Email interface implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //MsgStore.
       
    20 //<cmail>
       
    21 #include "MsgStore.h"
       
    22 #include "MsgStoreAccount.h"
       
    23 #include "MsgStoreMailBox.h"
       
    24 #include "MsgStoreMessage.h"
       
    25 #include "MsgStoreFolder.h"
       
    26 #include "MsgStorePropertyContainer.h"
       
    27 #include "MsgStorePropertyKeys.h"
       
    28 #include "MsgStoreSortCriteria.h"
       
    29 #include "MsgStoreSortResultIterator.h"
       
    30 //Freestyle.
       
    31 #include "CFSMailCommon.h"
       
    32 #include "CFSMailMessage.h"
       
    33 //</cmail>
       
    34 //Base plugin.
       
    35 #include "BasePlugin.h"
       
    36 #include "BasePluginPanic.h"
       
    37 #include "baseplugincommonutils.h"
       
    38 #include "MailIterator.h"
       
    39 #include "baseplugindelayedopsprivate.h"
       
    40 // Other
       
    41 #include <e32base.h>
       
    42 #include <utf.h>
       
    43 
       
    44 //<cmail>
       
    45 #include "FreestyleEmailUiConstants.h"
       
    46 //</cmail>
       
    47 
       
    48 //size of the read buffer when reading body content from the quoted
       
    49 //message when replying/forwarding.
       
    50 const TInt KQuotedReadBufferSize = 1024*64;
       
    51 
       
    52 
       
    53 /**
       
    54  *
       
    55  */
       
    56 CBasePlugin* CBasePlugin::NewLC()
       
    57     {
       
    58     CBasePlugin* api = new (ELeave) CBasePlugin();
       
    59     CleanupStack::PushL( api );
       
    60     api->ConstructL();
       
    61     return api;
       
    62     } 
       
    63 
       
    64 /**
       
    65  *
       
    66  */
       
    67 CBasePlugin* CBasePlugin::NewL()
       
    68    {
       
    69    CBasePlugin* api =  CBasePlugin::NewLC();
       
    70    CleanupStack:: Pop(api);
       
    71    return api;
       
    72    }
       
    73 
       
    74 
       
    75 /**
       
    76  *
       
    77  */
       
    78 EXPORT_C void CBasePlugin::ConstructL()
       
    79     {
       
    80     __LOG_CONSTRUCT( "baseplugin", "CBasePlugin" )
       
    81 
       
    82     __LOG_ENTER( "ConstructL" )
       
    83     iMsgStore = CMsgStore::NewL( EFalse );
       
    84     
       
    85     iDelayedOpsManager = CDelayedOpsManager::NewL( *this );
       
    86 
       
    87     __LOG_EXIT
       
    88     }
       
    89 
       
    90 
       
    91 /**
       
    92  *
       
    93  */
       
    94 EXPORT_C CBasePlugin::CBasePlugin()
       
    95 : iMailboxes( RMap<TInt, CMailboxInfo>::CompareInt )
       
    96    {
       
    97    }
       
    98 
       
    99 
       
   100 /**
       
   101  *
       
   102  */
       
   103 EXPORT_C CBasePlugin::~CBasePlugin()
       
   104     {
       
   105     //needs to be first thing to do as it might force execution of operations
       
   106     //that depend on the plugin's current state.
       
   107     delete iDelayedOpsManager;
       
   108     
       
   109     iMailboxes.ResetAndDestroy();
       
   110     iMailboxes.Close();
       
   111 
       
   112     if ( iObservers.Count() > 0 )
       
   113         {
       
   114         TRAP_IGNORE( iMsgStore->RemoveObserverL( this ) );
       
   115         }
       
   116     iObservers.Close();
       
   117 
       
   118     delete iMsgStore;
       
   119 
       
   120     iReqs.ResetAndDestroy();
       
   121     iReqs.Close();
       
   122     
       
   123     ResetCache();
       
   124 
       
   125     __LOG_DESTRUCT
       
   126     }
       
   127     
       
   128 
       
   129 #pragma mark --- "MFSMAILPLUGIN - MAILBOX RELATED" ---
       
   130 
       
   131 
       
   132 /**
       
   133  * Note that as the msgstore performs the delete immediately the observer will get
       
   134  * called from within this method.
       
   135  */
       
   136 EXPORT_C void CBasePlugin::DeleteMailBoxByUidL(
       
   137     const TFSMailMsgId& aMailBoxId,
       
   138     MFSMailRequestObserver& aOperationObserver,
       
   139 	const TInt aRequestId )
       
   140     {
       
   141     __LOG_ENTER( "DeleteMailBoxByUidL" )
       
   142 
       
   143     RPointerArray< CMsgStoreAccount > accounts;
       
   144     iMsgStore->AccountsL( accounts );
       
   145     CleanupResetAndDestroyClosePushL( accounts );
       
   146 
       
   147     TFSProgress progress = { TFSProgress::EFSStatus_RequestCancelled, 0, 0, 0 };
       
   148     progress.iError = KErrNotFound;
       
   149 
       
   150     TInt count = accounts.Count();
       
   151     for( TInt i = 0; i < count; i++ )
       
   152         {
       
   153         CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] );
       
   154         CleanupStack::PushL( msbox );
       
   155       
       
   156         if( aMailBoxId.Id() == msbox->Id() )
       
   157             {
       
   158             __LOG_WRITE_INFO( "Found, about to start the delete.." )
       
   159 
       
   160             //remove from the cache.
       
   161             if ( KErrNotFound != iMailboxes.Find( msbox->Id() ) )
       
   162                 {
       
   163                 iMailboxes.RemoveL( msbox->Id() );
       
   164                 }
       
   165             
       
   166             iMsgStore->DeleteAccountL( *accounts[i] );
       
   167             CleanupStack::PopAndDestroy( msbox );
       
   168             
       
   169             progress.iError = KErrNone;
       
   170             progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
       
   171             
       
   172             __LOG_WRITE_INFO( "Delete complete." )
       
   173             break;
       
   174             }
       
   175       
       
   176         CleanupStack::PopAndDestroy( msbox );
       
   177         }
       
   178 
       
   179     CleanupStack::PopAndDestroy( &accounts );
       
   180 
       
   181     aOperationObserver.RequestResponseL( progress, aRequestId );
       
   182     __LOG_EXIT
       
   183     }
       
   184 
       
   185 
       
   186 /**
       
   187  *
       
   188  */
       
   189 EXPORT_C void CBasePlugin::ListMailBoxesL( RArray<TFSMailMsgId>& aMailboxes )
       
   190     {
       
   191     __LOG_ENTER( "ListMailBoxesL" )
       
   192     
       
   193     RPointerArray< CMsgStoreAccount > accounts;
       
   194     iMsgStore->AccountsL( accounts );
       
   195     CleanupResetAndDestroyClosePushL( accounts );
       
   196 
       
   197     TFSMailMsgId fsid;
       
   198     fsid.SetPluginId( TUid::Uid( GetPluginId() ) );
       
   199     
       
   200     __LOG_WRITE_FORMAT1_INFO( "Plugin id: 0x%X,", GetPluginId() )
       
   201     
       
   202     TInt count = accounts.Count();
       
   203     for ( TInt i = 0; i < count; i++ )
       
   204         {
       
   205         __LOG_WRITE_FORMAT1_INFO( "Owner id: 0x%X,", accounts[i]->Owner() )
       
   206         
       
   207         if ( accounts[i]->Owner() == GetPluginId() )
       
   208             {
       
   209             CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] );
       
   210             CleanupStack::PushL( msbox );
       
   211 
       
   212             fsid.SetId( msbox->Id() );
       
   213             aMailboxes.AppendL( fsid );
       
   214         
       
   215             __LOG_WRITE_FORMAT1_INFO( "Found mailbox with id of 0x%X,", msbox->Id() )
       
   216             __LOG_WRITE_FORMAT1_INFO( "and account name of %S.", &accounts[i]->Name() )
       
   217 
       
   218             CleanupStack::PopAndDestroy( msbox );
       
   219             }
       
   220         }
       
   221 
       
   222     CleanupStack::PopAndDestroy( &accounts );
       
   223     __LOG_EXIT
       
   224     }
       
   225 
       
   226 
       
   227 /**
       
   228  *
       
   229  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   230  */
       
   231 EXPORT_C CFSMailBox* CBasePlugin::GetMailBoxByUidL( const TFSMailMsgId& aMailBox )
       
   232     {
       
   233     __LOG_ENTER( "GetMailBoxByUidL" )
       
   234 
       
   235     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBox.Id() );
       
   236     
       
   237     CFSMailBox* result = CFSMailBox::NewL( aMailBox );
       
   238     CleanupStack::PushL( result ); 
       
   239 
       
   240     CFSMailAddress* ownMailBox = CFSMailAddress::NewLC();
       
   241     ownMailBox->SetEmailAddress( *mailBox.iMailBoxName );
       
   242     
       
   243     if ( !( mailBox.iMailBoxDisplayName->Length() ) )
       
   244         {
       
   245         ownMailBox->SetDisplayName( KNullDesC );
       
   246         result->SetName( *mailBox.iMailBoxName );
       
   247         }
       
   248     else
       
   249         {
       
   250         ownMailBox->SetDisplayName( *(mailBox.iMailBoxDisplayName) );
       
   251         result->SetName( *(mailBox.iMailBoxDisplayName) );
       
   252         }
       
   253         
       
   254     result->SetOwnMailAddressL( ownMailBox );
       
   255     
       
   256     CleanupStack::Pop( ownMailBox );
       
   257 
       
   258     MMRInfoProcessor* infoProcessor = CBaseMrInfoProcessor::NewL( *this );
       
   259     result->SetMRInfoProcessorL( infoProcessor );
       
   260     
       
   261     CleanupStack::Pop( result );
       
   262     
       
   263     __LOG_EXIT
       
   264     return result;
       
   265     }
       
   266 
       
   267 
       
   268 #pragma mark --- "MFSMAILPLUGIN - FOLDER RELATED" ---
       
   269 
       
   270 /**
       
   271  *
       
   272  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   273  */
       
   274 EXPORT_C TFSMailMsgId CBasePlugin::GetStandardFolderIdL(
       
   275     const TFSMailMsgId& aMailBoxId,
       
   276     const TFSFolderType aFolderType )
       
   277     
       
   278     {
       
   279     __LOG_ENTER( "GetStandardFolderIdL" )
       
   280     
       
   281     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   282     
       
   283     TFSMailMsgId result;
       
   284     result.SetPluginId( TUid::Uid( GetPluginId() ) );
       
   285     
       
   286     if( EFSInbox <= aFolderType && aFolderType <= EFSDeleted )
       
   287         {
       
   288         result.SetId( mailBox.iRootFolders.iFolders[ aFolderType ] );
       
   289         }
       
   290 
       
   291     __LOG_EXIT
       
   292     return result;
       
   293     }
       
   294 
       
   295 
       
   296 /**
       
   297  * Note that the unseen count is not set by the plugin as this information is not
       
   298  * readily available.
       
   299  *
       
   300  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   301  */
       
   302 EXPORT_C CFSMailFolder* CBasePlugin::GetFolderByUidL(
       
   303     const TFSMailMsgId& aMailBoxId,
       
   304     const TFSMailMsgId& aFolderId )
       
   305 
       
   306     {
       
   307     __LOG_ENTER( "GetFolderByUidL" )
       
   308     
       
   309     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   310 
       
   311     TUint totalCount, unreadCount;
       
   312     mailBox().MessageCountsL( aFolderId.Id(), totalCount, unreadCount );
       
   313 
       
   314     //prepare the fsfw folder.
       
   315     CFSMailFolder* result = CFSMailFolder::NewLC( aFolderId );
       
   316 
       
   317     result->SetMailBoxId( aMailBoxId );
       
   318     result->SetMessageCount( totalCount );
       
   319     result->SetUnreadCount( unreadCount );
       
   320 
       
   321     //get the folder name from the msgstore folder object.
       
   322     __LOG_WRITE_INFO( "About to get the folder's name." )
       
   323     CMsgStoreFolder* msgStoreFolder = mailBox().FolderL( aFolderId.Id() );
       
   324     CleanupStack::PushL( msgStoreFolder );
       
   325 
       
   326     TUint idx;
       
   327     if ( msgStoreFolder->FindProperty( KMsgStorePropertyFolderDisplayName, idx ) )
       
   328         {
       
   329         const TDesC& name = msgStoreFolder->PropertyValueDesL( idx );
       
   330         result->SetFolderName( const_cast<TDesC&>( name ) );
       
   331         }
       
   332     else
       
   333         {
       
   334         //the root folders will get names from the UI. the base plugin should not
       
   335         //deal with any localization.
       
   336         result->SetFolderName( KNullDesC() );
       
   337         }
       
   338 
       
   339     TFSFolderType folderType = EFSOther;
       
   340     TUint i = 0;
       
   341     if ( msgStoreFolder->FindProperty( KMsgStorePropertyFolderType, i ) )
       
   342         {
       
   343         __LOG_WRITE_INFO( "Getting the folder's type." )
       
   344         folderType = (TFSFolderType)( msgStoreFolder->PropertyValueUint32L( i ) );
       
   345         result->SetFolderType( folderType );
       
   346         }
       
   347 
       
   348     TFSMailMsgId parentId( GetPluginId(), msgStoreFolder->ParentId() );
       
   349     result->SetParentFolderId( parentId );
       
   350     CleanupStack::PopAndDestroy( msgStoreFolder );
       
   351 
       
   352     RPointerArray<CMsgStoreFolder> folders;
       
   353     CleanupResetAndDestroyClosePushL( folders );
       
   354     
       
   355     mailBox().FoldersL( aFolderId.Id(), folders );
       
   356     result->SetSubFolderCount( folders.Count() );
       
   357     
       
   358     BlockCopyMoveFromFoldersL( aFolderId, folderType, *result );
       
   359 
       
   360     CleanupStack::PopAndDestroy( &folders );
       
   361     CleanupStack::Pop( result );
       
   362 
       
   363     __LOG_EXIT
       
   364     return result;
       
   365     } //GetFolderByUidL.
       
   366 
       
   367 
       
   368 /**
       
   369  * @param aFolderId parent folder id.
       
   370  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   371  * @return if the folder already exists returns the existing one.
       
   372  */
       
   373 EXPORT_C CFSMailFolder* CBasePlugin::CreateFolderL(
       
   374     const TFSMailMsgId& aMailBoxId,
       
   375     const TFSMailMsgId& aParentFolderId,
       
   376     const TDesC& aFolderName,
       
   377     const TBool aSync )
       
   378 
       
   379     {
       
   380     __LOG_ENTER( "CreateFolderL" )
       
   381     
       
   382     CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBoxId.Id() );
       
   383 
       
   384     CMsgStorePropertyContainer* props = CMsgStorePropertyContainer::NewL();
       
   385     CleanupStack::PushL( props );
       
   386 
       
   387     props->AddPropertyL( KMsgStorePropertyName, aFolderName );
       
   388     props->AddPropertyL( KMsgStorePropertyFolderType, EMsgStoreOther );
       
   389 
       
   390     TMsgStoreId parent = aParentFolderId.Id();
       
   391     TMsgStoreId folderId =
       
   392         mailboxInfo().CreateFolderL( parent, *props, aSync );
       
   393     CleanupStack::PopAndDestroy( props );
       
   394 
       
   395     //return the FS folder.
       
   396     TFSMailMsgId fid( GetPluginId(), folderId );
       
   397 
       
   398     CFSMailFolder* result = CFSMailFolder::NewLC( fid );
       
   399 
       
   400     result->SetParentFolderId( aParentFolderId );
       
   401     result->SetFolderName( aFolderName );
       
   402 
       
   403     result->SetMailBoxId( aMailBoxId );
       
   404     result->SetMessageCount( 0 );
       
   405     result->SetUnreadCount( 0 );
       
   406 
       
   407     BlockCopyMoveFromFoldersL( fid, EFSOther, *result );
       
   408     
       
   409     CleanupStack::Pop( result );
       
   410     __LOG_EXIT
       
   411     return result;
       
   412     }
       
   413 
       
   414 
       
   415 /**
       
   416  *
       
   417  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   418  */
       
   419 EXPORT_C void CBasePlugin::DeleteFolderByUidL(
       
   420     const TFSMailMsgId& aMailBoxId,
       
   421     const TFSMailMsgId& aFolder )
       
   422     
       
   423     {
       
   424     __LOG_ENTER( "DeleteFolderByUidL" )
       
   425 
       
   426     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   427     mailBox().DeleteFolderL( aFolder.Id() );
       
   428     
       
   429     __LOG_EXIT
       
   430     }
       
   431 
       
   432 /**
       
   433  *
       
   434  */
       
   435 EXPORT_C void CBasePlugin::ListFoldersL(
       
   436     const TFSMailMsgId& aMailBoxId,
       
   437     const TFSMailMsgId& aFolderId,
       
   438     RPointerArray<CFSMailFolder>& aFolderList )
       
   439     
       
   440     {
       
   441     __LOG_ENTER( "ListFoldersL, aFolderId" )
       
   442     
       
   443     TMsgStoreId folderId;
       
   444     if ( 0 == aFolderId.Id() )
       
   445     	{
       
   446     	folderId = aMailBoxId.Id();
       
   447     	}
       
   448     else
       
   449     	{
       
   450     	folderId = aFolderId.Id();
       
   451     	}
       
   452     
       
   453 	DoListFoldersL( aMailBoxId, folderId, EFalse, aFolderList );
       
   454     __LOG_EXIT 
       
   455     }
       
   456 
       
   457 /**
       
   458  *
       
   459  */
       
   460 EXPORT_C void CBasePlugin::ListFoldersL(
       
   461     const TFSMailMsgId& aMailBoxId,
       
   462     RPointerArray<CFSMailFolder>& aFolderList )
       
   463     
       
   464     {
       
   465     __LOG_ENTER( "ListFoldersL" )
       
   466     DoListFoldersL( aMailBoxId, KMsgStoreInvalidId, ETrue, aFolderList );
       
   467     __LOG_EXIT
       
   468     }
       
   469 
       
   470 
       
   471 #pragma mark --- "MFSMAILPLUGIN - MESSAGE RELATED" ---
       
   472 
       
   473 
       
   474 /**
       
   475  *
       
   476  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   477  */
       
   478 EXPORT_C MFSMailIterator* CBasePlugin::ListMessagesL(
       
   479     const TFSMailMsgId& aMailBoxId,
       
   480     const TFSMailMsgId& aFolderId,
       
   481     const TFSMailDetails aDetails,
       
   482     const RArray<TFSMailSortCriteria>& aSorting )
       
   483    
       
   484     {
       
   485     __LOG_ENTER( "ListMessagesL" )
       
   486     
       
   487     CMailboxInfo& mailbox = GetMailboxInfoL( aMailBoxId.Id() );
       
   488     
       
   489     RMsgStoreSortCriteria criteria;
       
   490     CleanupClosePushL( criteria );
       
   491  
       
   492     criteria.iFolderId = aFolderId.Id();
       
   493     if( aSorting.Count() > 0 )
       
   494         {
       
   495         criteria.iSortBy = static_cast<TMsgStoreSortByField>( aSorting[0].iField - 1);
       
   496         criteria.iSortOrder = static_cast<TMsgStoreSortOrder>( aSorting[0].iOrder );
       
   497         criteria.iSecondarySortOrder = EMsgStoreSortDescending;
       
   498         }
       
   499     else
       
   500         {
       
   501         __LOG_WRITE_INFO( "No sorting criteria supplied, falling back to the default." )
       
   502         criteria.iSortBy = EMsgStoreSortByReceivedDate;
       
   503         criteria.iSortOrder = EMsgStoreSortDescending;
       
   504         }
       
   505     
       
   506     //determine the details to request from the msgstore.
       
   507     if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails
       
   508         || EFSMsgDataSubject & aDetails )
       
   509         {
       
   510         criteria.AddResultPropertyL( KMsgStorePropertySubject );
       
   511         }
       
   512 
       
   513     if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails
       
   514         || EFSMsgDataDate & aDetails )
       
   515         {
       
   516         criteria.AddResultPropertyL( KMsgStorePropertyReceivedAt );
       
   517         criteria.AddResultPropertyL( KMsgStorePropertySent );
       
   518         }
       
   519 
       
   520     if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails
       
   521         || EFSMsgDataSender & aDetails )
       
   522         {
       
   523         criteria.AddResultPropertyL( KMsgStorePropertyFrom );
       
   524         }
       
   525     
       
   526     if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails
       
   527         || EFSMsgDataIdOnly & aDetails )
       
   528         {
       
   529         /**@ no result properties added means the msgstore leaves with -6; ask
       
   530         about it because EFSMsgDataIdOnly means id-only.*/
       
   531         criteria.AddResultPropertyL( KMsgStorePropertyTo );
       
   532         }
       
   533 
       
   534     if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails )
       
   535         {
       
   536         criteria.AddResultPropertyL( KMsgStorePropertyFlags );
       
   537         criteria.AddResultPropertyL( KMsgStorePropertySize );
       
   538         criteria.AddResultPropertyL( KMsgStorePropertyCc );
       
   539         criteria.AddResultPropertyL( KMsgStorePropertyBcc );
       
   540         }
       
   541 
       
   542     CMsgStoreSortResultIterator* msIter = mailbox().SortL( criteria );
       
   543     CleanupStack::PopAndDestroy( &criteria );
       
   544 
       
   545     CleanupStack::PushL( msIter );
       
   546     HMailIterator* result = new (ELeave) HMailIterator( *this, msIter, aMailBoxId );
       
   547     CleanupStack::Pop( msIter );
       
   548     
       
   549     __LOG_EXIT
       
   550     return result;
       
   551     }
       
   552 
       
   553 /**
       
   554  *
       
   555  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   556  */
       
   557 EXPORT_C CFSMailMessage* CBasePlugin::GetMessageByUidL(
       
   558     const TFSMailMsgId& aMailBoxId,
       
   559     const TFSMailMsgId& /*aFolderId*/,
       
   560     const TFSMailMsgId& aMessageId,
       
   561     const TFSMailDetails aDetails )
       
   562     
       
   563     {
       
   564     __LOG_ENTER( "GetMessageByUidL" )
       
   565     
       
   566     CMsgStoreMessage* message = GetCachedMsgL( aMailBoxId.Id(), aMessageId.Id() );
       
   567 
       
   568     CFSMailMessage* result = CFSMailMessage::NewLC( aMessageId );
       
   569     TranslateMsgStorePropsL( aMailBoxId, *message, *result, aDetails );
       
   570     result->SetMailBoxId( aMailBoxId );
       
   571     CleanupStack::Pop( result );
       
   572 
       
   573     __LOG_EXIT
       
   574     return result;
       
   575     }
       
   576 
       
   577 
       
   578 /**
       
   579  *
       
   580  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   581  */
       
   582 EXPORT_C void CBasePlugin::DeleteMessagesByUidL(
       
   583     const TFSMailMsgId& aMailBoxId,
       
   584     const TFSMailMsgId& aFolderId,
       
   585     const RArray<TFSMailMsgId>& aMessages )
       
   586     
       
   587     {
       
   588     __LOG_ENTER( "DeleteMessagesByUidL" )
       
   589 
       
   590     CDelayedDeleteMessagesOp* delayedOp = CDelayedDeleteMessagesOp::NewLC(
       
   591         aMailBoxId.Id(), aFolderId.Id(), aMessages );
       
   592     iDelayedOpsManager->EnqueueOpL( delayedOp );
       
   593     CleanupStack::Pop( delayedOp );
       
   594 
       
   595     __LOG_EXIT
       
   596     }
       
   597 
       
   598 
       
   599 /**
       
   600  * Drafts folder assumed.
       
   601  *
       
   602  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   603  */
       
   604 EXPORT_C CFSMailMessage* CBasePlugin::CreateMessageToSendL(
       
   605     const TFSMailMsgId& aMailBox )
       
   606     
       
   607     {
       
   608     __LOG_ENTER( "CreateMessageToSendL" )
       
   609     
       
   610     CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBox.Id() );
       
   611 
       
   612     CMsgStorePropertyContainer* props = CMsgStorePropertyContainer::NewL();
       
   613     CleanupStack::PushL( props );
       
   614     props->AddOrUpdatePropertyL( KMsgStorePropertyContentType, KFSMailContentTypeMultipartMixed );
       
   615 
       
   616     // Set reply-to address, if it exists
       
   617     HBufC* replyToAddressString = GetReplyToAddressL( aMailBox );
       
   618     
       
   619     if ( NULL != replyToAddressString )
       
   620         {
       
   621         CleanupStack::PushL( replyToAddressString );
       
   622         
       
   623         if ( replyToAddressString->Length() > 0 )
       
   624             {
       
   625             RMsgStoreAddress replyToAddress;
       
   626             CleanupClosePushL( replyToAddress );
       
   627             
       
   628             replyToAddress.iEmailAddress.Create( *replyToAddressString );
       
   629             replyToAddress.iDisplayName.Create( KNullDesC );
       
   630             
       
   631             props->AddOrUpdatePropertyL( KMsgStorePropertyReplyTo, replyToAddress );
       
   632             
       
   633             CleanupStack::PopAndDestroy( &replyToAddress );
       
   634             }        
       
   635         CleanupStack::PopAndDestroy( replyToAddressString );
       
   636         }
       
   637     
       
   638     CMsgStoreMessage* message = mailboxInfo().CreateMessageL(
       
   639         mailboxInfo.iRootFolders.iFolders[EFSDraftsFolder], *props );
       
   640 
       
   641     CleanupStack::PopAndDestroy( props );
       
   642     CleanupStack::PushL( message );
       
   643     
       
   644     //create the body part.
       
   645     props = CMsgStorePropertyContainer::NewL();
       
   646     CleanupStack::PushL( props );
       
   647     
       
   648     props->AddOrUpdatePropertyL(
       
   649         KMsgStorePropertyContentType, KFSMailContentTypeMultipartAlternative );
       
   650     CMsgStoreMessagePart* bodyPart = message->AddChildPartL( *props );
       
   651     
       
   652     CleanupStack::PopAndDestroy( props );
       
   653     CleanupStack::PushL( bodyPart );
       
   654     
       
   655     //create the plain text part.
       
   656     props = CMsgStorePropertyContainer::NewL();
       
   657     CleanupStack::PushL( props );
       
   658 
       
   659     props->AddPropertyL(
       
   660         KMsgStorePropertyContentType, KFSMailContentTypeTextPlain );
       
   661 
       
   662     _LIT(KMessageBodyCharset, "UTF-8");
       
   663     props->AddPropertyL( KMsgStorePropertyCharset, KMessageBodyCharset );
       
   664 
       
   665     _LIT(KMessageBodyDisposition, "inline");
       
   666     props->AddPropertyL(
       
   667         KMsgStorePropertyContentDisposition, KMessageBodyDisposition );
       
   668 
       
   669     HBufC* signature = GetSignatureL( aMailBox );
       
   670     if ( signature )
       
   671         {
       
   672         CleanupStack::PushL( signature );       
       
   673 
       
   674         props->AddPropertyL(
       
   675             KMsgStorePropertySize, static_cast<TUint32>( signature->Length() ) );
       
   676         props->AddPropertyL(
       
   677             KMsgStorePropertyRetrievedSize,
       
   678             static_cast<TUint32>( signature->Length() ) );
       
   679         }
       
   680     
       
   681     CMsgStoreMessagePart* textPlain = bodyPart->AddChildPartL( *props );
       
   682     if ( signature )
       
   683         {
       
   684         CleanupStack::Pop( signature );
       
   685         }
       
   686     CleanupStack::PopAndDestroy( props );           
       
   687     if ( signature )
       
   688         {
       
   689         CleanupStack::PushL( signature );
       
   690         }
       
   691     CleanupStack::PushL( textPlain );
       
   692     
       
   693     //add signature, if it exists
       
   694 	if ( NULL != signature && signature->Length() )
       
   695         {
       
   696         TPtrC8 ptr8(
       
   697             reinterpret_cast<const TUint8*>( signature->Ptr() ),
       
   698             signature->Size() );
       
   699         
       
   700         textPlain->ReplaceContentL( ptr8 );
       
   701 		}
       
   702 
       
   703 	CleanupStack::PopAndDestroy( textPlain );
       
   704     if ( signature )
       
   705         {
       
   706         CleanupStack::PopAndDestroy( signature );
       
   707         }
       
   708     CleanupStack::PopAndDestroy( bodyPart );
       
   709 	
       
   710 	//done.
       
   711     message->CommitL();
       
   712     
       
   713     TFSMailMsgId folderId( GetPluginId(), message->ParentId() );
       
   714     TFSMailMsgId msgId( GetPluginId(), message->Id() );
       
   715     CleanupStack::PopAndDestroy( message );
       
   716 
       
   717     CFSMailMessage* result = CFSMailMessage::NewL( msgId );    
       
   718     
       
   719     result->SetMailBoxId( aMailBox );
       
   720     result->SetFolderId( folderId );
       
   721     result->SetContentType( KFSMailContentTypeMultipartMixed );
       
   722     
       
   723     __LOG_EXIT
       
   724     return result;
       
   725     }
       
   726 
       
   727 
       
   728 /**
       
   729  *
       
   730  */
       
   731 EXPORT_C CFSMailMessage* CBasePlugin::CreateForwardMessageL(
       
   732     const TFSMailMsgId& aMailBox,
       
   733     const TFSMailMsgId& aOriginal,
       
   734     const TDesC& aHeaderDescriptor )
       
   735     {
       
   736     return CreateForwardReplyMessageL( aMailBox, aOriginal, EFalse, aHeaderDescriptor, ETrue );
       
   737     }
       
   738 
       
   739 
       
   740 /**
       
   741  * Relying on the UI for the subject and recipients.
       
   742  */
       
   743 EXPORT_C CFSMailMessage* CBasePlugin::CreateReplyMessageL(
       
   744     const TFSMailMsgId& aMailBoxId,
       
   745     const TFSMailMsgId& aOriginalMessageId,
       
   746     const TBool aReplyToAll,
       
   747     const TDesC& aHeaderDescriptor )
       
   748     {
       
   749     return CreateForwardReplyMessageL( aMailBoxId, aOriginalMessageId, aReplyToAll, aHeaderDescriptor, EFalse );
       
   750     }
       
   751 
       
   752 
       
   753 /**
       
   754  *
       
   755  */
       
   756 EXPORT_C CFSMailMessage* CBasePlugin::CreateMrReplyMessageL(
       
   757     const TFSMailMsgId& aMailBoxId,
       
   758     MMRInfoObject& /*aMeetingRequest*/,
       
   759     const TFSMailMsgId& aOriginalMessageId )
       
   760     {
       
   761     return CreateReplyMessageL( aMailBoxId, aOriginalMessageId, EFalse, KNullDesC );
       
   762     }
       
   763 
       
   764 
       
   765 /**
       
   766  *
       
   767  * @param aMailBoxId if not found leaves with KErrNotFound.
       
   768  */
       
   769 EXPORT_C void CBasePlugin::StoreMessageL(
       
   770     const TFSMailMsgId& aMailBoxId,
       
   771     CFSMailMessage& aMessage )
       
   772     
       
   773     {
       
   774     __LOG_ENTER( "StoreMessageL" )
       
   775     
       
   776     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   777 
       
   778     CMsgStoreMessage* message = mailBox().FetchMessageL(
       
   779         aMessage.GetMessageId().Id(), KMsgStoreInvalidId );
       
   780     CleanupStack::PushL( message );
       
   781 
       
   782     //determine whether the message is in the inbox folder or some of its
       
   783     //children; the translation is different for inbox and all the other folders.
       
   784     TBool inInbox = EFalse;
       
   785     TMsgStoreId parentId = message->ParentId();
       
   786     while ( KMsgStoreInvalidId != parentId
       
   787     	&& EMsgStoreFolderContainer == mailBox().ContainerTypeById( parentId ) )
       
   788     	{
       
   789     	if ( parentId == mailBox.iRootFolders.iFolders[EFSInbox] )
       
   790     		{
       
   791     		inInbox = ETrue;
       
   792     		break;
       
   793     		}
       
   794     	else
       
   795     		{
       
   796     		CMsgStoreFolder* parent = mailBox().FolderL( parentId );
       
   797     		parentId = parent->ParentId();
       
   798     		delete parent;
       
   799     		}
       
   800     	}
       
   801     
       
   802     TranslateEmailFwMessageL( aMessage, *message, inInbox );
       
   803     message->StorePropertiesL();
       
   804     
       
   805     CleanupStack::PopAndDestroy( message );
       
   806     
       
   807     ResetCache();
       
   808     __LOG_EXIT
       
   809     }
       
   810 
       
   811 
       
   812 /**
       
   813  * Async operation, starts fetching.
       
   814  * @param aRequestId
       
   815  */
       
   816 EXPORT_C void CBasePlugin::FetchMessagesL(
       
   817     const TFSMailMsgId& /*aMailBox*/,
       
   818     const TFSMailMsgId& /*aFolder*/,
       
   819     const RArray<TFSMailMsgId>& /*aMessageIds*/,
       
   820     TFSMailDetails /*aDetails*/,
       
   821     MFSMailRequestObserver& /*aObserver*/,
       
   822     TInt /*aRequestId*/ )
       
   823 
       
   824     {
       
   825     /**@ is this really necessary for the base plugin ?*/
       
   826     }
       
   827 
       
   828 
       
   829 /**
       
   830  *
       
   831  */
       
   832 EXPORT_C void CBasePlugin::GetMessagesL(
       
   833     const TFSMailMsgId& /*aMailBoxId*/,
       
   834     const TFSMailMsgId& /*aParentFolderId*/,
       
   835     const RArray<TFSMailMsgId>& /*aMessageIds*/,
       
   836     RPointerArray<CFSMailMessage>& /*aMessageList*/,
       
   837     const TFSMailDetails /*aDetails*/ )
       
   838     
       
   839     {
       
   840     /**@ is this really necessary for the base plugin ?*/
       
   841     }
       
   842 
       
   843 
       
   844 /**
       
   845  * CFSMailPlugin::SendMessageL
       
   846  */
       
   847 EXPORT_C void CBasePlugin::SendMessageL( CFSMailMessage& aMessage )    
       
   848     {
       
   849     __LOG_ENTER( "SendMessageL1" )
       
   850 
       
   851     TMsgStoreId mailBoxId = aMessage.GetMailBoxId().Id();
       
   852     TMsgStoreId msgId = aMessage.GetMessageId().Id();
       
   853     
       
   854     CMsgStoreMessage* message = GetCachedMsgL( mailBoxId, msgId );
       
   855     __LOG_WRITE8_FORMAT1_INFO( "Fetched message : 0x%X.", msgId )
       
   856 
       
   857     TranslateEmailFwMessageL( aMessage, *message, EFalse );
       
   858     //the sendmessagel will store the message's properties!
       
   859 
       
   860     TTime sentTime;
       
   861     sentTime.UniversalTime();
       
   862     aMessage.SetDate( sentTime );
       
   863 
       
   864     CMailboxInfo& mailBox = GetMailboxInfoL( aMessage.GetMailBoxId().Id() );
       
   865     SendMessageL( mailBox(), *message, sentTime );
       
   866 
       
   867     __LOG_EXIT
       
   868     }
       
   869 
       
   870 
       
   871 /**
       
   872  * Plugin could use this method to "send" a message if the CFSMailPlugin's is
       
   873  * not necessary. The method also stores the message properties before doing so.
       
   874  * This allows for optimizing away of unnecessary writes to the msgstore.
       
   875  * @param aSentTime the sent time you want set for the message.
       
   876  */
       
   877 EXPORT_C void CBasePlugin::SendMessageL(
       
   878     CMsgStoreMailBox& aMailBox,
       
   879     CMsgStoreMessage& aMsg,
       
   880     const TTime& aSentTime )    
       
   881     {
       
   882     __LOG_ENTER( "SendMessageL2" )
       
   883 
       
   884     //set the sent stamp.
       
   885     aMsg.AddOrUpdatePropertyL( KMsgStorePropertySent, aSentTime );
       
   886     // Due to no Received Time in the sent messages, it caused sorting problem
       
   887     // from MsgStore
       
   888     aMsg.AddOrUpdatePropertyL( KMsgStorePropertyReceivedAt, aSentTime );
       
   889     aMsg.StorePropertiesL();
       
   890 
       
   891     // move the msg to the outbox.
       
   892     TFSMailMsgId id( GetPluginId(), aMailBox.Id() );
       
   893     TFSMailMsgId drafts = GetStandardFolderIdL( id, EFSDraftsFolder );
       
   894     TFSMailMsgId outbox = GetStandardFolderIdL( id, EFSOutbox );
       
   895 
       
   896     aMailBox.CopyMessageL( aMsg.Id(), drafts.Id(), outbox.Id() );
       
   897     
       
   898     CDelayedDeleteMessagesOp* delayedOp = CDelayedDeleteMessagesOp::NewLC(
       
   899         aMailBox.Id(), KMsgStoreInvalidId, aMsg.Id() );
       
   900     iDelayedOpsManager->EnqueueOpL( delayedOp );
       
   901     CleanupStack::Pop( delayedOp );
       
   902 
       
   903     __LOG_EXIT
       
   904     }
       
   905 
       
   906 /**
       
   907  *
       
   908  */
       
   909 EXPORT_C void CBasePlugin::MoveMessagesL(
       
   910     const TFSMailMsgId& aMailBoxId,
       
   911     const RArray<TFSMailMsgId>& aMessageIds,
       
   912     const TFSMailMsgId& aSourceFolderId,
       
   913     const TFSMailMsgId& aDestinationFolderId )
       
   914 
       
   915     {
       
   916     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   917 
       
   918     TInt count = aMessageIds.Count();
       
   919     for ( TUint i = 0; i < count; i++ )
       
   920         {
       
   921         mailBox().MoveMessageL(
       
   922             aMessageIds[i].Id(),
       
   923             aSourceFolderId.Id(),
       
   924             aDestinationFolderId.Id() );
       
   925         }    
       
   926     }
       
   927 
       
   928 
       
   929 /**
       
   930  *
       
   931  */
       
   932 EXPORT_C void CBasePlugin::CopyMessagesL(
       
   933     const TFSMailMsgId& aMailBoxId,
       
   934     const RArray<TFSMailMsgId>& aMessageIds,
       
   935     RArray<TFSMailMsgId>& aNewMessages,
       
   936     const TFSMailMsgId& aSourceFolderId,
       
   937     const TFSMailMsgId& aDestinationFolderId )
       
   938 
       
   939     {
       
   940     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
   941 
       
   942     TFSMailMsgId newId( GetPluginId(), KMsgStoreInvalidId );
       
   943     
       
   944     TInt count = aMessageIds.Count();
       
   945     for ( TUint i = 0; i < count; i++ )
       
   946         {
       
   947         TMsgStoreId msgStoreId = mailBox().CopyMessageL(
       
   948             aMessageIds[i].Id(),
       
   949             aSourceFolderId.Id(),
       
   950             aDestinationFolderId.Id() );
       
   951         
       
   952         newId.SetId( msgStoreId );
       
   953         aNewMessages.AppendL( newId );
       
   954         }
       
   955     }
       
   956 
       
   957 
       
   958 #pragma mark --- "Plugin Helpers" ---
       
   959 
       
   960 
       
   961 /**
       
   962  * Get the MsgStore mailbox instance for the specified FSEF mailbox id.
       
   963  *
       
   964  * @param aId mailbox id, if none can be found leaves with KErrNotFound.
       
   965  */
       
   966 EXPORT_C CMailboxInfo& CBasePlugin::GetMailboxInfoL(
       
   967     TMsgStoreId aId )
       
   968     {
       
   969     
       
   970     __ASSERT_DEBUG( NULL != iMsgStore, ::BasePluginPanic( ENoMsgStoreSessionAssert ) );
       
   971     
       
   972     //if not present in the cache, add it.
       
   973     if ( !iMailboxes.ContainsKey(aId) )
       
   974         {
       
   975         RPointerArray< CMsgStoreAccount > accounts;
       
   976         iMsgStore->AccountsL( accounts );
       
   977         CleanupResetAndDestroyClosePushL( accounts );
       
   978 
       
   979         TBool found = EFalse;
       
   980 
       
   981         TInt count = accounts.Count();
       
   982         for ( TInt i = 0; i < count; i++ )
       
   983             {
       
   984             CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] );
       
   985             CleanupStack::PushL( msbox );
       
   986 
       
   987             if ( aId == msbox->Id() )
       
   988                 {
       
   989                 CMailboxInfo* mailBox = new (ELeave) CMailboxInfo( this );
       
   990                 CleanupStack::PushL( mailBox );
       
   991                 mailBox->iMailBox = msbox;
       
   992                 //always observe for mailbox changes to keep the cache
       
   993                 //up-to-date.
       
   994                 mailBox->iMailBox->AddObserverL( this );
       
   995 
       
   996                 mailBox->iMailBoxName = accounts[i]->Name().AllocL();
       
   997                 mailBox->iBrandingId = KNullDesC().AllocL();
       
   998                 
       
   999                 RBuf mailboxDisplayName;
       
  1000                 mailboxDisplayName.CleanupClosePushL();
       
  1001                 GetMailboxDisplayNameL( aId, mailboxDisplayName );
       
  1002                 mailBox->iMailBoxDisplayName = mailboxDisplayName.AllocL();
       
  1003                 CleanupStack::PopAndDestroy( &mailboxDisplayName );
       
  1004                 
       
  1005                 MsgStoreFolderUtils::GetRootFoldersL( *msbox, mailBox->iRootFolders );
       
  1006 
       
  1007                 TInt64* key = new (ELeave) TInt64( msbox->Id() );
       
  1008                 CleanupDeletePushL( key );
       
  1009                 iMailboxes.InsertL( key, mailBox );   //the map owns the memory.
       
  1010 
       
  1011                 CleanupStack::Pop( key );
       
  1012                 CleanupStack::Pop( mailBox );
       
  1013                 CleanupStack::Pop( msbox );
       
  1014                 
       
  1015                 found = ETrue;
       
  1016                 break;
       
  1017                 }
       
  1018 
       
  1019             CleanupStack::PopAndDestroy( msbox );
       
  1020             }
       
  1021 
       
  1022         CleanupStack::PopAndDestroy( &accounts );
       
  1023         
       
  1024         if( !found )
       
  1025             {
       
  1026             User::Leave( KErrNotFound );
       
  1027             }
       
  1028         }
       
  1029     
       
  1030     return iMailboxes.GetValueL( aId );
       
  1031     } //GetMailboxInfoL.
       
  1032 
       
  1033 
       
  1034 /**
       
  1035  * Get the MsgStore mailbox instance for the specified FSEF mailbox id.
       
  1036  *
       
  1037  * @param aId mailbox id, if none can be found leaves with KErrNotFound.
       
  1038  */
       
  1039 void CBasePlugin::GetMailboxDisplayNameL(
       
  1040     TMsgStoreId aId,
       
  1041     RBuf& aDisplayName )
       
  1042     {
       
  1043     
       
  1044     __ASSERT_DEBUG( NULL != iMsgStore, ::BasePluginPanic( ENoMsgStoreSessionAssert ) );
       
  1045     
       
  1046     RPointerArray< CMsgStoreAccount > accounts;
       
  1047     iMsgStore->AccountsL( accounts );
       
  1048     CleanupResetAndDestroyClosePushL( accounts );
       
  1049 
       
  1050     TInt count = accounts.Count();
       
  1051     for ( TInt i = 0; i < count; i++ )
       
  1052         {
       
  1053         CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] );
       
  1054         CleanupStack::PushL( msbox );
       
  1055 
       
  1056         if( aId == msbox->Id() )
       
  1057             {
       
  1058             TUint index = 0;
       
  1059             if ( msbox->FindProperty( KMsgStorePropertyName, index ) )
       
  1060                 {
       
  1061                     const TDesC& string = msbox->PropertyValueDesL( index );
       
  1062                     if (string.Length() > 0)
       
  1063                         {
       
  1064                         aDisplayName.Close();
       
  1065                         aDisplayName.CreateL( string );
       
  1066                         }
       
  1067                 }
       
  1068                 CleanupStack::PopAndDestroy( msbox );
       
  1069                 break;
       
  1070             }
       
  1071         else
       
  1072             {
       
  1073 	             CleanupStack::PopAndDestroy( msbox );
       
  1074 	        }
       
  1075         }
       
  1076 
       
  1077         CleanupStack::PopAndDestroy( &accounts );
       
  1078     } //GetMailboxDisplayNameL.
       
  1079 
       
  1080 /**
       
  1081  * @param aFolderId if set to KMsgStoreInvalidId makes a recursive list.
       
  1082  */
       
  1083 void CBasePlugin::DoListFoldersL(
       
  1084     TFSMailMsgId aMailBoxId,
       
  1085     TMsgStoreId aFolderId,
       
  1086     TBool aRecursive,
       
  1087     RPointerArray<CFSMailFolder>& aFolderList )
       
  1088     
       
  1089     {
       
  1090     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
       
  1091     
       
  1092     RPointerArray<CMsgStoreFolder> folders;
       
  1093     CleanupResetAndDestroyClosePushL( folders );
       
  1094     
       
  1095     if ( aRecursive )
       
  1096         {
       
  1097         mailBox().FoldersL( folders );
       
  1098         }
       
  1099     else
       
  1100         {
       
  1101         mailBox().FoldersL( aFolderId, folders );
       
  1102         }
       
  1103     
       
  1104     TFSMailMsgId folderId;
       
  1105     folderId.SetPluginId( TUid::Uid( GetPluginId() ) );
       
  1106     
       
  1107     TInt count = folders.Count();
       
  1108     for( TInt i = 0; i < count; i++ )
       
  1109         {
       
  1110         folderId.SetId( folders[i]->Id() );
       
  1111         
       
  1112         CFSMailFolder* folder = GetFolderByUidL( aMailBoxId, folderId );
       
  1113 
       
  1114         CleanupStack::PushL( folder );
       
  1115         aFolderList.AppendL( folder );
       
  1116         CleanupStack::Pop( folder );
       
  1117         }
       
  1118     
       
  1119     CleanupStack::PopAndDestroy( &folders );
       
  1120     }
       
  1121 
       
  1122 
       
  1123 /**
       
  1124  *
       
  1125  */
       
  1126 CFSMailAddress* CBasePlugin::FetchEmailAddressL(
       
  1127     CMsgStorePropertyContainer& aMessage,
       
  1128     TUint aIdx )
       
  1129 
       
  1130     {
       
  1131     RMsgStoreAddress value;
       
  1132     CleanupClosePushL( value );
       
  1133 
       
  1134     aMessage.PropertyValueAddressL( aIdx, value );
       
  1135 
       
  1136     CFSMailAddress* result = CFSMailAddress::NewL();
       
  1137     result->SetEmailAddress( value.iEmailAddress );
       
  1138     if ( KNullDesC() != value.iDisplayName )
       
  1139         {
       
  1140         result->SetDisplayName( value.iDisplayName );
       
  1141         }
       
  1142     else
       
  1143         {
       
  1144         /**@ the UI would crash if there was no display name.*/
       
  1145         result->SetDisplayName( value.iEmailAddress );
       
  1146         }
       
  1147 
       
  1148     CleanupStack::PopAndDestroy( &value );
       
  1149     
       
  1150     return result;
       
  1151     }
       
  1152 
       
  1153 
       
  1154 /**
       
  1155  *
       
  1156  */
       
  1157 EXPORT_C CMsgStoreMessagePart* CBasePlugin::GetBodyPartL(
       
  1158     CMsgStoreMessage& aMessage,
       
  1159     const TDesC& aContentType )
       
  1160     {
       
  1161     CMsgStoreMessagePart* result = NULL;
       
  1162     
       
  1163     RPointerArray<CMsgStoreMessagePart> parts;
       
  1164     CleanupResetAndDestroyClosePushL( parts );
       
  1165 
       
  1166     aMessage.ChildPartsL( parts );
       
  1167     if ( 0 < parts.Count() )
       
  1168         {
       
  1169         RPointerArray<CMsgStoreMessagePart> childParts;
       
  1170         CleanupResetAndDestroyClosePushL( childParts );
       
  1171         parts[0]->ChildPartsL( childParts );
       
  1172         
       
  1173         TInt count = childParts.Count();
       
  1174         if ( 0 < count )
       
  1175             {
       
  1176             for ( TInt i = 0; i < count; i++ )
       
  1177                 {
       
  1178                 TUint idx = 0;
       
  1179                 if ( childParts[i]->FindProperty( KMsgStorePropertyContentType, idx, idx ) )
       
  1180                     {
       
  1181                     const TDesC& contentType = childParts[i]->PropertyValueDesL( idx );
       
  1182                     if ( contentType == aContentType )
       
  1183                         {
       
  1184                         result = childParts[i];
       
  1185                         childParts.Remove( i );
       
  1186                         break;
       
  1187                         }
       
  1188                     }
       
  1189                 }
       
  1190             
       
  1191             }
       
  1192         else
       
  1193             {
       
  1194             TUint idx = 0;
       
  1195             if ( parts[0]->FindProperty( KMsgStorePropertyContentType, idx, idx ) )
       
  1196                 {
       
  1197                 const TDesC& contentType = parts[0]->PropertyValueDesL( idx );
       
  1198                 if ( contentType == aContentType )
       
  1199                     {
       
  1200                     result = parts[0];
       
  1201                     parts.Remove( 0 );
       
  1202                     }
       
  1203                 }
       
  1204             }
       
  1205             
       
  1206         CleanupStack::PopAndDestroy( &childParts );
       
  1207         }
       
  1208         
       
  1209     CleanupStack::PopAndDestroy( &parts );
       
  1210 
       
  1211     return result;
       
  1212     } //GetBodyPartL.
       
  1213 
       
  1214 /**
       
  1215  *
       
  1216  */
       
  1217 EXPORT_C CFSMailMessage* CBasePlugin::CreateForwardReplyMessageL(
       
  1218     const TFSMailMsgId& aMailBox,
       
  1219     const TFSMailMsgId& aOriginal,
       
  1220     const TBool aReplyToAll,
       
  1221     const TDesC& aHeaderDescriptor,
       
  1222     TBool aKeepAttachments,
       
  1223     TBool aKeepMeetingRequestInfo )
       
  1224     {
       
  1225     __LOG_ENTER( "CreateForwardReplyMessageL" )
       
  1226     CMailboxInfo& mailBox = GetMailboxInfoL( aMailBox.Id() );
       
  1227 
       
  1228     CMsgStoreMessage* message = mailBox().FetchMessageL(
       
  1229         aOriginal.Id(), KMsgStoreInvalidId );
       
  1230     CleanupStack::PushL( message );
       
  1231 
       
  1232     TMsgStoreId newMsgId = mailBox().CopyMessageL(
       
  1233         aOriginal.Id(), message->ParentId(),
       
  1234         mailBox.iRootFolders.iFolders[EFSDraftsFolder] );
       
  1235     
       
  1236     CMsgStoreMessage* newMsg = mailBox().FetchMessageL( newMsgId, KMsgStoreInvalidId );
       
  1237     CleanupStack::PushL( newMsg );
       
  1238 
       
  1239     if ( !aReplyToAll )
       
  1240         {
       
  1241         //Clear all To, Cc addresses for Reply, Forward
       
  1242         RemoveAllPropertiesL( *newMsg, KMsgStorePropertyTo );
       
  1243         RemoveAllPropertiesL( *newMsg, KMsgStorePropertyCc );
       
  1244         }
       
  1245     else
       
  1246         {
       
  1247         //Remove the mailbox address from the reply to addresses
       
  1248         HBufC* mailBoxAdd = GetMailBoxAddressL( aMailBox );
       
  1249         CleanupStack::PushL( mailBoxAdd );
       
  1250         
       
  1251         if ( NULL != mailBoxAdd )
       
  1252             {           
       
  1253             TUint idx1 = 0;
       
  1254             while (newMsg->FindProperty( KMsgStorePropertyTo, idx1, idx1 ) )
       
  1255                 {
       
  1256                 RMsgStoreAddress tempAdd;
       
  1257                 CleanupClosePushL( tempAdd );
       
  1258                 
       
  1259                 newMsg->PropertyValueAddressL( idx1, tempAdd );
       
  1260                 if ( tempAdd.iEmailAddress == *mailBoxAdd )
       
  1261                     {
       
  1262                     newMsg->RemovePropertyL( idx1 );
       
  1263                     CleanupStack::PopAndDestroy( &tempAdd );
       
  1264                     break;
       
  1265                     }
       
  1266                 CleanupStack::PopAndDestroy( &tempAdd );
       
  1267                 ++idx1;
       
  1268                 }
       
  1269         
       
  1270             idx1 = 0;
       
  1271             while (newMsg->FindProperty( KMsgStorePropertyCc, idx1, idx1 ) )
       
  1272                 {
       
  1273                 RMsgStoreAddress tempAdd;
       
  1274                 CleanupClosePushL( tempAdd );
       
  1275                         
       
  1276                 newMsg->PropertyValueAddressL( idx1, tempAdd );
       
  1277                 if ( tempAdd.iEmailAddress == *mailBoxAdd )
       
  1278                     {
       
  1279                     newMsg->RemovePropertyL( idx1 );
       
  1280                     CleanupStack::PopAndDestroy( &tempAdd );
       
  1281                     break;
       
  1282                     }
       
  1283                 CleanupStack::PopAndDestroy( &tempAdd );
       
  1284                 ++idx1;
       
  1285                 } 
       
  1286             }
       
  1287         
       
  1288         CleanupStack::PopAndDestroy( mailBoxAdd );
       
  1289         }
       
  1290     
       
  1291 	SetReplyOrForwardToFieldL( *newMsg );
       
  1292 
       
  1293     //Clear the response flag.
       
  1294 	TUint idx = 0;
       
  1295     if ( newMsg->FindProperty( KMsgStorePropertyFlags, idx ) )
       
  1296         {
       
  1297         TUint32 flags = newMsg->PropertyValueUint32L( idx );
       
  1298         flags &= ~EFSMsgFlag_Answered;
       
  1299         newMsg->AddOrUpdatePropertyL( KMsgStorePropertyFlags, flags );
       
  1300         }
       
  1301 
       
  1302     //Clear the From field, ReplyTo field
       
  1303     RemoveAllPropertiesL( *newMsg, KMsgStorePropertyFrom );
       
  1304     RemoveAllPropertiesL( *newMsg, KMsgStorePropertyReplyTo );
       
  1305     
       
  1306     //Use reply-to address, if it exists
       
  1307     HBufC* replyToAddressString = GetReplyToAddressL( aMailBox );
       
  1308        
       
  1309     if ( NULL != replyToAddressString )
       
  1310         {
       
  1311         CleanupStack::PushL( replyToAddressString );
       
  1312            
       
  1313         if ( replyToAddressString->Length() > 0 )
       
  1314             {
       
  1315             RMsgStoreAddress replyToAddress;
       
  1316             CleanupClosePushL( replyToAddress );
       
  1317                
       
  1318             replyToAddress.iEmailAddress.Create( *replyToAddressString );
       
  1319             replyToAddress.iDisplayName.Create( KNullDesC );
       
  1320                
       
  1321             newMsg->AddOrUpdatePropertyL( KMsgStorePropertyReplyTo, replyToAddress );
       
  1322                
       
  1323             CleanupStack::PopAndDestroy( &replyToAddress );
       
  1324             }
       
  1325         CleanupStack::PopAndDestroy( replyToAddressString );
       
  1326        }
       
  1327           
       
  1328     newMsg->StorePropertiesL();
       
  1329 
       
  1330     //deal with the attachments accordingly.
       
  1331     /**@ the case where the attachments haven't been downloaded but some smart
       
  1332      * reply/fw tag is present in the msg body needs to be dealt with in the specific
       
  1333      * plugins.*/
       
  1334     if ( aKeepAttachments == EFalse )
       
  1335         {
       
  1336         RPointerArray<CMsgStoreMessagePart> parts;
       
  1337         CleanupResetAndDestroyClosePushL( parts );
       
  1338 
       
  1339         newMsg->ChildPartsL( parts );
       
  1340         TInt count = parts.Count();
       
  1341 
       
  1342         for ( TInt i = 1; i < count; i++ )
       
  1343             {
       
  1344             newMsg->RemoveChildPartL( parts[i]->Id() );
       
  1345             }
       
  1346             
       
  1347         CleanupStack::PopAndDestroy( &parts );
       
  1348         }
       
  1349 
       
  1350     if ( aKeepMeetingRequestInfo == EFalse )
       
  1351     	{
       
  1352     	idx = 0;
       
  1353     	if ( newMsg->FindProperty( KMsgStorePropertyMeetingRequest, idx ) )
       
  1354     		{
       
  1355     		CBasePlugin::RemoveAllPropertiesL( *newMsg, KMsgStorePropertyMeetingRequest );
       
  1356     		}
       
  1357     	}
       
  1358     
       
  1359     CFSMailMessage* result = CFSMailMessage::NewL(
       
  1360         TFSMailMsgId( GetPluginId(), newMsgId ) );
       
  1361     CleanupStack::PushL( result );
       
  1362     
       
  1363     TranslateMsgStorePropsL( aMailBox, *newMsg, *result );
       
  1364     result->SetMailBoxId( aMailBox );
       
  1365 
       
  1366     /**@ candidate for refactoring out to a separate body dealing method.*/
       
  1367     CMsgStoreMessagePart* srcPart = GetBodyPartL( *message );
       
  1368     if ( NULL != srcPart )
       
  1369         {
       
  1370         CleanupStack::PushL( srcPart );
       
  1371         CMsgStoreMessagePart* dstPart = GetBodyPartL( *newMsg );
       
  1372 
       
  1373         if ( NULL != dstPart )
       
  1374             {
       
  1375             CleanupStack::PushL( dstPart );
       
  1376             
       
  1377             HBufC* signature = GetSignatureL( aMailBox );
       
  1378             if ( NULL != signature )
       
  1379                 {
       
  1380                 CleanupStack::PushL( signature );
       
  1381                 TPtrC8 ptr8(
       
  1382                     reinterpret_cast<const TUint8*>( signature->Ptr() ),
       
  1383                     signature->Size() );
       
  1384                 dstPart->ReplaceContentL( ptr8 );
       
  1385                 CleanupStack::PopAndDestroy( signature );
       
  1386 
       
  1387                 __LOG_WRITE_INFO( "Set the email signature." )
       
  1388                 }
       
  1389 
       
  1390             //the quoted message header.
       
  1391             if ( aHeaderDescriptor != KNullDesC )
       
  1392                 {
       
  1393                 TPckgBuf<TReplyForwardParams> rfParsPckg;
       
  1394                 rfParsPckg.Copy( aHeaderDescriptor );
       
  1395                 
       
  1396                 TPtrC8 ptrHeader8(
       
  1397                     reinterpret_cast<const TUint8*>( rfParsPckg().iHeader->Ptr() ),
       
  1398                     rfParsPckg().iHeader->Size() );
       
  1399                 NULL != signature ? dstPart->AppendToContentL( ptrHeader8 )
       
  1400                     : dstPart->ReplaceContentL( ptrHeader8 );
       
  1401 
       
  1402                 __LOG_WRITE8_FORMAT1_INFO(
       
  1403                     "Original body content length: %d.", srcPart->ContentLengthL() )
       
  1404 
       
  1405                 //copy the body content from the original.
       
  1406                 TInt startOffset = 0;
       
  1407                 RBuf8 buf;
       
  1408                 buf.Create( KQuotedReadBufferSize );
       
  1409                 CleanupClosePushL( buf );
       
  1410 
       
  1411                 do
       
  1412                     {
       
  1413                     srcPart->FetchContentToBufferL( buf, startOffset );
       
  1414                     dstPart->AppendToContentL( buf );
       
  1415                     
       
  1416                     startOffset += buf.Size();
       
  1417                     }
       
  1418                 while ( buf.Size() == KQuotedReadBufferSize );
       
  1419 
       
  1420                 CleanupStack::PopAndDestroy( &buf );
       
  1421 
       
  1422                 TInt newFetchedSize = dstPart->ContentLengthL();
       
  1423                 __LOG_WRITE8_FORMAT1_INFO(
       
  1424                     "Reply/fw body content length: %d.", newFetchedSize )
       
  1425 
       
  1426                 TInt idx = dstPart->AddOrUpdatePropertyL(
       
  1427                     KMsgStorePropertySize, static_cast<TUint32>( newFetchedSize ) );
       
  1428                 dstPart->StorePropertyL( idx );
       
  1429                 idx = dstPart->AddOrUpdatePropertyL(
       
  1430                     KMsgStorePropertyRetrievedSize, static_cast<TUint32>( newFetchedSize ) );
       
  1431                 dstPart->StorePropertyL( idx );
       
  1432                 
       
  1433                 result->SetContentSize( newFetchedSize );
       
  1434                 result->SetFetchedContentSize( newFetchedSize );
       
  1435 
       
  1436                 //determine whether the original msg was truncated.
       
  1437                 TBool wasTruncated = EFalse;
       
  1438                 TUint srcIdx = 0;
       
  1439                 if ( srcPart->FindProperty( KMsgStorePropertySize, srcIdx ) )
       
  1440                     {
       
  1441                     TUint size = srcPart->PropertyValueUint32L( srcIdx );
       
  1442 
       
  1443                     srcIdx = 0;
       
  1444                     if ( srcPart->FindProperty( KMsgStorePropertyRetrievedSize, srcIdx ) )
       
  1445                         {
       
  1446                         TUint retrievedSize = srcPart->PropertyValueUint32L( srcIdx );
       
  1447                         
       
  1448                         if ( retrievedSize < size )
       
  1449                             {
       
  1450                             wasTruncated = ETrue;
       
  1451                             }
       
  1452                         }
       
  1453                     }
       
  1454                     
       
  1455                 //if truncated append msg that the whole msg is available server-side.
       
  1456                 if ( wasTruncated )
       
  1457                     {
       
  1458                     _LIT( KTwoLineFeeds, "\n\n" );
       
  1459                     TPtrC8 ptrTwoLineFeeds8(
       
  1460                         reinterpret_cast<const TUint8*>( KTwoLineFeeds().Ptr() ),
       
  1461                         KTwoLineFeeds().Size() );
       
  1462                     dstPart->AppendToContentL( ptrTwoLineFeeds8 );
       
  1463 
       
  1464                     TPtrC8 ptrSmartTag8(
       
  1465                         reinterpret_cast<const TUint8*>( rfParsPckg().iSmartTag->Ptr() ),
       
  1466                         rfParsPckg().iSmartTag->Size() );
       
  1467                     dstPart->AppendToContentL( ptrSmartTag8 );
       
  1468                     }
       
  1469                 }
       
  1470 
       
  1471             /**@ incorrect but per activesync request - the base plugin doesn't know anything about how the unicode characters
       
  1472             are being encoded by the specific implementations when they talk to their backends.*/
       
  1473             _LIT(KMessageBodyCharset, "UTF-8");
       
  1474             dstPart->AddPropertyL( KMsgStorePropertyCharset, KMessageBodyCharset );
       
  1475 
       
  1476             CleanupStack::PopAndDestroy( dstPart );
       
  1477             }
       
  1478         CleanupStack::PopAndDestroy( srcPart );
       
  1479         }
       
  1480     
       
  1481     CleanupStack::Pop( result );
       
  1482     CleanupStack::PopAndDestroy( newMsg );
       
  1483     CleanupStack::PopAndDestroy( message );
       
  1484     
       
  1485     __LOG_EXIT
       
  1486     return result;
       
  1487     } //CreateForwardReplyMessageL.
       
  1488 
       
  1489 
       
  1490 /**
       
  1491  * If there is a reply to address, add it to the TO list
       
  1492  * else add the FROM address to the TO address list   
       
  1493  */
       
  1494 /*private*/ void CBasePlugin::SetReplyOrForwardToFieldL( CMsgStoreMessage& aMsg )
       
  1495 	{
       
  1496     RMsgStoreAddress toAddr;
       
  1497     CleanupClosePushL( toAddr );
       
  1498     
       
  1499     TBool usingReplyTo = EFalse;
       
  1500     
       
  1501     TUint idx = 0;
       
  1502     if( aMsg.FindProperty( KMsgStorePropertyReplyTo, idx ) )
       
  1503     	{
       
  1504     	//if both address and name are null strings no memory will be allocated.
       
  1505         aMsg.PropertyValueAddressL( idx, toAddr );
       
  1506         
       
  1507         if ( toAddr.iEmailAddress.Length() || toAddr.iDisplayName.Length() )
       
  1508         	{
       
  1509         	usingReplyTo = ETrue;
       
  1510         	}
       
  1511     	}
       
  1512 
       
  1513     if ( EFalse == usingReplyTo )
       
  1514 		{
       
  1515         idx = 0;
       
  1516         if ( aMsg.FindProperty( KMsgStorePropertyFrom, idx ) )
       
  1517         	{
       
  1518             aMsg.PropertyValueAddressL( idx, toAddr );
       
  1519         	}
       
  1520 		}
       
  1521 
       
  1522     aMsg.AddPropertyL( KMsgStorePropertyTo, toAddr );
       
  1523     CleanupStack::PopAndDestroy( &toAddr );
       
  1524 	}
       
  1525 
       
  1526 
       
  1527 /**
       
  1528  * RefreshMailboxCacheL - This will refresh the mailbox instance cache maintained within the base plugin.  
       
  1529  *
       
  1530  */
       
  1531 EXPORT_C CMailboxInfo& CBasePlugin::RefreshMailboxCacheL( TMsgStoreId aMailBoxId )
       
  1532     {
       
  1533     //save the observers
       
  1534     CMailboxInfo& oldMailBox = GetMailboxInfoL( aMailBoxId );
       
  1535     
       
  1536     RPointerArray<MFSMailEventObserver> observers;
       
  1537     // the elements are not owned by the base plugin, so just close the array
       
  1538     CleanupClosePushL( observers );
       
  1539 
       
  1540     TUint count = oldMailBox.iObservers.Count();
       
  1541     for ( TUint i = 0; i < count; i++ )
       
  1542     	{
       
  1543     	observers.AppendL( oldMailBox.iObservers[i] );
       
  1544     	}
       
  1545     
       
  1546     //remove from the cache
       
  1547     if ( KErrNotFound != iMailboxes.Find( aMailBoxId ) )
       
  1548         {
       
  1549         iMailboxes.RemoveL( aMailBoxId );
       
  1550         }
       
  1551 
       
  1552     //force the refresh and restore the observes
       
  1553     CMailboxInfo& newMailBox = GetMailboxInfoL( aMailBoxId );
       
  1554     
       
  1555     for ( TUint i = 0; i < count; i++ )
       
  1556     	{
       
  1557     	newMailBox.iObservers.AppendL( observers[i] );
       
  1558     	}
       
  1559     
       
  1560     CleanupStack::PopAndDestroy( &observers );
       
  1561     return newMailBox;
       
  1562     }
       
  1563 
       
  1564 
       
  1565 /**
       
  1566  * RefreshCachedMailBoxDisplayNameL -   This will check to see if the mailbox display name has changed.  If so it will
       
  1567  *                                      update the cached mailbox display name and set mailBoxNameHasChanged to ETrue 
       
  1568  *
       
  1569  */
       
  1570 void CBasePlugin::RefreshCachedMailBoxDisplayNameL( TBool& aMailBoxNameHasChanged, const TMsgStoreId& aMailBoxId )
       
  1571     {
       
  1572     aMailBoxNameHasChanged = EFalse;
       
  1573     
       
  1574     RBuf currentDisplayName;
       
  1575     currentDisplayName.CleanupClosePushL();
       
  1576     GetMailboxDisplayNameL( aMailBoxId, currentDisplayName );
       
  1577     
       
  1578     CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBoxId );
       
  1579     TDesC* cachedDisplayName( mailboxInfo.iMailBoxDisplayName );
       
  1580 
       
  1581     if ( ( cachedDisplayName && currentDisplayName != *cachedDisplayName ) ||
       
  1582          ( !cachedDisplayName && currentDisplayName.Length() ) )
       
  1583         {
       
  1584         aMailBoxNameHasChanged = ETrue;
       
  1585         delete mailboxInfo.iMailBoxDisplayName;
       
  1586         mailboxInfo.iMailBoxDisplayName = NULL;
       
  1587         mailboxInfo.iMailBoxDisplayName = currentDisplayName.AllocL();
       
  1588         }
       
  1589     
       
  1590     CleanupStack::PopAndDestroy( &currentDisplayName );
       
  1591     }
       
  1592