diff -r 000000000000 -r 8466d47a6819 emailservices/emailstore/base_plugin/src/BasePlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailservices/emailstore/base_plugin/src/BasePlugin.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,1592 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Email interface implementation. +* +*/ + + +//MsgStore. +// +#include "MsgStore.h" +#include "MsgStoreAccount.h" +#include "MsgStoreMailBox.h" +#include "MsgStoreMessage.h" +#include "MsgStoreFolder.h" +#include "MsgStorePropertyContainer.h" +#include "MsgStorePropertyKeys.h" +#include "MsgStoreSortCriteria.h" +#include "MsgStoreSortResultIterator.h" +//Freestyle. +#include "CFSMailCommon.h" +#include "CFSMailMessage.h" +// +//Base plugin. +#include "BasePlugin.h" +#include "BasePluginPanic.h" +#include "baseplugincommonutils.h" +#include "MailIterator.h" +#include "baseplugindelayedopsprivate.h" +// Other +#include +#include + +// +#include "FreestyleEmailUiConstants.h" +// + +//size of the read buffer when reading body content from the quoted +//message when replying/forwarding. +const TInt KQuotedReadBufferSize = 1024*64; + + +/** + * + */ +CBasePlugin* CBasePlugin::NewLC() + { + CBasePlugin* api = new (ELeave) CBasePlugin(); + CleanupStack::PushL( api ); + api->ConstructL(); + return api; + } + +/** + * + */ +CBasePlugin* CBasePlugin::NewL() + { + CBasePlugin* api = CBasePlugin::NewLC(); + CleanupStack:: Pop(api); + return api; + } + + +/** + * + */ +EXPORT_C void CBasePlugin::ConstructL() + { + __LOG_CONSTRUCT( "baseplugin", "CBasePlugin" ) + + __LOG_ENTER( "ConstructL" ) + iMsgStore = CMsgStore::NewL( EFalse ); + + iDelayedOpsManager = CDelayedOpsManager::NewL( *this ); + + __LOG_EXIT + } + + +/** + * + */ +EXPORT_C CBasePlugin::CBasePlugin() +: iMailboxes( RMap::CompareInt ) + { + } + + +/** + * + */ +EXPORT_C CBasePlugin::~CBasePlugin() + { + //needs to be first thing to do as it might force execution of operations + //that depend on the plugin's current state. + delete iDelayedOpsManager; + + iMailboxes.ResetAndDestroy(); + iMailboxes.Close(); + + if ( iObservers.Count() > 0 ) + { + TRAP_IGNORE( iMsgStore->RemoveObserverL( this ) ); + } + iObservers.Close(); + + delete iMsgStore; + + iReqs.ResetAndDestroy(); + iReqs.Close(); + + ResetCache(); + + __LOG_DESTRUCT + } + + +#pragma mark --- "MFSMAILPLUGIN - MAILBOX RELATED" --- + + +/** + * Note that as the msgstore performs the delete immediately the observer will get + * called from within this method. + */ +EXPORT_C void CBasePlugin::DeleteMailBoxByUidL( + const TFSMailMsgId& aMailBoxId, + MFSMailRequestObserver& aOperationObserver, + const TInt aRequestId ) + { + __LOG_ENTER( "DeleteMailBoxByUidL" ) + + RPointerArray< CMsgStoreAccount > accounts; + iMsgStore->AccountsL( accounts ); + CleanupResetAndDestroyClosePushL( accounts ); + + TFSProgress progress = { TFSProgress::EFSStatus_RequestCancelled, 0, 0, 0 }; + progress.iError = KErrNotFound; + + TInt count = accounts.Count(); + for( TInt i = 0; i < count; i++ ) + { + CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] ); + CleanupStack::PushL( msbox ); + + if( aMailBoxId.Id() == msbox->Id() ) + { + __LOG_WRITE_INFO( "Found, about to start the delete.." ) + + //remove from the cache. + if ( KErrNotFound != iMailboxes.Find( msbox->Id() ) ) + { + iMailboxes.RemoveL( msbox->Id() ); + } + + iMsgStore->DeleteAccountL( *accounts[i] ); + CleanupStack::PopAndDestroy( msbox ); + + progress.iError = KErrNone; + progress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete; + + __LOG_WRITE_INFO( "Delete complete." ) + break; + } + + CleanupStack::PopAndDestroy( msbox ); + } + + CleanupStack::PopAndDestroy( &accounts ); + + aOperationObserver.RequestResponseL( progress, aRequestId ); + __LOG_EXIT + } + + +/** + * + */ +EXPORT_C void CBasePlugin::ListMailBoxesL( RArray& aMailboxes ) + { + __LOG_ENTER( "ListMailBoxesL" ) + + RPointerArray< CMsgStoreAccount > accounts; + iMsgStore->AccountsL( accounts ); + CleanupResetAndDestroyClosePushL( accounts ); + + TFSMailMsgId fsid; + fsid.SetPluginId( TUid::Uid( GetPluginId() ) ); + + __LOG_WRITE_FORMAT1_INFO( "Plugin id: 0x%X,", GetPluginId() ) + + TInt count = accounts.Count(); + for ( TInt i = 0; i < count; i++ ) + { + __LOG_WRITE_FORMAT1_INFO( "Owner id: 0x%X,", accounts[i]->Owner() ) + + if ( accounts[i]->Owner() == GetPluginId() ) + { + CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] ); + CleanupStack::PushL( msbox ); + + fsid.SetId( msbox->Id() ); + aMailboxes.AppendL( fsid ); + + __LOG_WRITE_FORMAT1_INFO( "Found mailbox with id of 0x%X,", msbox->Id() ) + __LOG_WRITE_FORMAT1_INFO( "and account name of %S.", &accounts[i]->Name() ) + + CleanupStack::PopAndDestroy( msbox ); + } + } + + CleanupStack::PopAndDestroy( &accounts ); + __LOG_EXIT + } + + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C CFSMailBox* CBasePlugin::GetMailBoxByUidL( const TFSMailMsgId& aMailBox ) + { + __LOG_ENTER( "GetMailBoxByUidL" ) + + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBox.Id() ); + + CFSMailBox* result = CFSMailBox::NewL( aMailBox ); + CleanupStack::PushL( result ); + + CFSMailAddress* ownMailBox = CFSMailAddress::NewLC(); + ownMailBox->SetEmailAddress( *mailBox.iMailBoxName ); + + if ( !( mailBox.iMailBoxDisplayName->Length() ) ) + { + ownMailBox->SetDisplayName( KNullDesC ); + result->SetName( *mailBox.iMailBoxName ); + } + else + { + ownMailBox->SetDisplayName( *(mailBox.iMailBoxDisplayName) ); + result->SetName( *(mailBox.iMailBoxDisplayName) ); + } + + result->SetOwnMailAddressL( ownMailBox ); + + CleanupStack::Pop( ownMailBox ); + + MMRInfoProcessor* infoProcessor = CBaseMrInfoProcessor::NewL( *this ); + result->SetMRInfoProcessorL( infoProcessor ); + + CleanupStack::Pop( result ); + + __LOG_EXIT + return result; + } + + +#pragma mark --- "MFSMAILPLUGIN - FOLDER RELATED" --- + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C TFSMailMsgId CBasePlugin::GetStandardFolderIdL( + const TFSMailMsgId& aMailBoxId, + const TFSFolderType aFolderType ) + + { + __LOG_ENTER( "GetStandardFolderIdL" ) + + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + TFSMailMsgId result; + result.SetPluginId( TUid::Uid( GetPluginId() ) ); + + if( EFSInbox <= aFolderType && aFolderType <= EFSDeleted ) + { + result.SetId( mailBox.iRootFolders.iFolders[ aFolderType ] ); + } + + __LOG_EXIT + return result; + } + + +/** + * Note that the unseen count is not set by the plugin as this information is not + * readily available. + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C CFSMailFolder* CBasePlugin::GetFolderByUidL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aFolderId ) + + { + __LOG_ENTER( "GetFolderByUidL" ) + + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + TUint totalCount, unreadCount; + mailBox().MessageCountsL( aFolderId.Id(), totalCount, unreadCount ); + + //prepare the fsfw folder. + CFSMailFolder* result = CFSMailFolder::NewLC( aFolderId ); + + result->SetMailBoxId( aMailBoxId ); + result->SetMessageCount( totalCount ); + result->SetUnreadCount( unreadCount ); + + //get the folder name from the msgstore folder object. + __LOG_WRITE_INFO( "About to get the folder's name." ) + CMsgStoreFolder* msgStoreFolder = mailBox().FolderL( aFolderId.Id() ); + CleanupStack::PushL( msgStoreFolder ); + + TUint idx; + if ( msgStoreFolder->FindProperty( KMsgStorePropertyFolderDisplayName, idx ) ) + { + const TDesC& name = msgStoreFolder->PropertyValueDesL( idx ); + result->SetFolderName( const_cast( name ) ); + } + else + { + //the root folders will get names from the UI. the base plugin should not + //deal with any localization. + result->SetFolderName( KNullDesC() ); + } + + TFSFolderType folderType = EFSOther; + TUint i = 0; + if ( msgStoreFolder->FindProperty( KMsgStorePropertyFolderType, i ) ) + { + __LOG_WRITE_INFO( "Getting the folder's type." ) + folderType = (TFSFolderType)( msgStoreFolder->PropertyValueUint32L( i ) ); + result->SetFolderType( folderType ); + } + + TFSMailMsgId parentId( GetPluginId(), msgStoreFolder->ParentId() ); + result->SetParentFolderId( parentId ); + CleanupStack::PopAndDestroy( msgStoreFolder ); + + RPointerArray folders; + CleanupResetAndDestroyClosePushL( folders ); + + mailBox().FoldersL( aFolderId.Id(), folders ); + result->SetSubFolderCount( folders.Count() ); + + BlockCopyMoveFromFoldersL( aFolderId, folderType, *result ); + + CleanupStack::PopAndDestroy( &folders ); + CleanupStack::Pop( result ); + + __LOG_EXIT + return result; + } //GetFolderByUidL. + + +/** + * @param aFolderId parent folder id. + * @param aMailBoxId if not found leaves with KErrNotFound. + * @return if the folder already exists returns the existing one. + */ +EXPORT_C CFSMailFolder* CBasePlugin::CreateFolderL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aParentFolderId, + const TDesC& aFolderName, + const TBool aSync ) + + { + __LOG_ENTER( "CreateFolderL" ) + + CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBoxId.Id() ); + + CMsgStorePropertyContainer* props = CMsgStorePropertyContainer::NewL(); + CleanupStack::PushL( props ); + + props->AddPropertyL( KMsgStorePropertyName, aFolderName ); + props->AddPropertyL( KMsgStorePropertyFolderType, EMsgStoreOther ); + + TMsgStoreId parent = aParentFolderId.Id(); + TMsgStoreId folderId = + mailboxInfo().CreateFolderL( parent, *props, aSync ); + CleanupStack::PopAndDestroy( props ); + + //return the FS folder. + TFSMailMsgId fid( GetPluginId(), folderId ); + + CFSMailFolder* result = CFSMailFolder::NewLC( fid ); + + result->SetParentFolderId( aParentFolderId ); + result->SetFolderName( aFolderName ); + + result->SetMailBoxId( aMailBoxId ); + result->SetMessageCount( 0 ); + result->SetUnreadCount( 0 ); + + BlockCopyMoveFromFoldersL( fid, EFSOther, *result ); + + CleanupStack::Pop( result ); + __LOG_EXIT + return result; + } + + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C void CBasePlugin::DeleteFolderByUidL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aFolder ) + + { + __LOG_ENTER( "DeleteFolderByUidL" ) + + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + mailBox().DeleteFolderL( aFolder.Id() ); + + __LOG_EXIT + } + +/** + * + */ +EXPORT_C void CBasePlugin::ListFoldersL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aFolderId, + RPointerArray& aFolderList ) + + { + __LOG_ENTER( "ListFoldersL, aFolderId" ) + + TMsgStoreId folderId; + if ( 0 == aFolderId.Id() ) + { + folderId = aMailBoxId.Id(); + } + else + { + folderId = aFolderId.Id(); + } + + DoListFoldersL( aMailBoxId, folderId, EFalse, aFolderList ); + __LOG_EXIT + } + +/** + * + */ +EXPORT_C void CBasePlugin::ListFoldersL( + const TFSMailMsgId& aMailBoxId, + RPointerArray& aFolderList ) + + { + __LOG_ENTER( "ListFoldersL" ) + DoListFoldersL( aMailBoxId, KMsgStoreInvalidId, ETrue, aFolderList ); + __LOG_EXIT + } + + +#pragma mark --- "MFSMAILPLUGIN - MESSAGE RELATED" --- + + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C MFSMailIterator* CBasePlugin::ListMessagesL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aFolderId, + const TFSMailDetails aDetails, + const RArray& aSorting ) + + { + __LOG_ENTER( "ListMessagesL" ) + + CMailboxInfo& mailbox = GetMailboxInfoL( aMailBoxId.Id() ); + + RMsgStoreSortCriteria criteria; + CleanupClosePushL( criteria ); + + criteria.iFolderId = aFolderId.Id(); + if( aSorting.Count() > 0 ) + { + criteria.iSortBy = static_cast( aSorting[0].iField - 1); + criteria.iSortOrder = static_cast( aSorting[0].iOrder ); + criteria.iSecondarySortOrder = EMsgStoreSortDescending; + } + else + { + __LOG_WRITE_INFO( "No sorting criteria supplied, falling back to the default." ) + criteria.iSortBy = EMsgStoreSortByReceivedDate; + criteria.iSortOrder = EMsgStoreSortDescending; + } + + //determine the details to request from the msgstore. + if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails + || EFSMsgDataSubject & aDetails ) + { + criteria.AddResultPropertyL( KMsgStorePropertySubject ); + } + + if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails + || EFSMsgDataDate & aDetails ) + { + criteria.AddResultPropertyL( KMsgStorePropertyReceivedAt ); + criteria.AddResultPropertyL( KMsgStorePropertySent ); + } + + if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails + || EFSMsgDataSender & aDetails ) + { + criteria.AddResultPropertyL( KMsgStorePropertyFrom ); + } + + if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails + || EFSMsgDataIdOnly & aDetails ) + { + /**@ no result properties added means the msgstore leaves with -6; ask + about it because EFSMsgDataIdOnly means id-only.*/ + criteria.AddResultPropertyL( KMsgStorePropertyTo ); + } + + if ( EFSMsgDataStructure & aDetails || EFSMsgDataEnvelope & aDetails ) + { + criteria.AddResultPropertyL( KMsgStorePropertyFlags ); + criteria.AddResultPropertyL( KMsgStorePropertySize ); + criteria.AddResultPropertyL( KMsgStorePropertyCc ); + criteria.AddResultPropertyL( KMsgStorePropertyBcc ); + } + + CMsgStoreSortResultIterator* msIter = mailbox().SortL( criteria ); + CleanupStack::PopAndDestroy( &criteria ); + + CleanupStack::PushL( msIter ); + HMailIterator* result = new (ELeave) HMailIterator( *this, msIter, aMailBoxId ); + CleanupStack::Pop( msIter ); + + __LOG_EXIT + return result; + } + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C CFSMailMessage* CBasePlugin::GetMessageByUidL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& /*aFolderId*/, + const TFSMailMsgId& aMessageId, + const TFSMailDetails aDetails ) + + { + __LOG_ENTER( "GetMessageByUidL" ) + + CMsgStoreMessage* message = GetCachedMsgL( aMailBoxId.Id(), aMessageId.Id() ); + + CFSMailMessage* result = CFSMailMessage::NewLC( aMessageId ); + TranslateMsgStorePropsL( aMailBoxId, *message, *result, aDetails ); + result->SetMailBoxId( aMailBoxId ); + CleanupStack::Pop( result ); + + __LOG_EXIT + return result; + } + + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C void CBasePlugin::DeleteMessagesByUidL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aFolderId, + const RArray& aMessages ) + + { + __LOG_ENTER( "DeleteMessagesByUidL" ) + + CDelayedDeleteMessagesOp* delayedOp = CDelayedDeleteMessagesOp::NewLC( + aMailBoxId.Id(), aFolderId.Id(), aMessages ); + iDelayedOpsManager->EnqueueOpL( delayedOp ); + CleanupStack::Pop( delayedOp ); + + __LOG_EXIT + } + + +/** + * Drafts folder assumed. + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C CFSMailMessage* CBasePlugin::CreateMessageToSendL( + const TFSMailMsgId& aMailBox ) + + { + __LOG_ENTER( "CreateMessageToSendL" ) + + CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBox.Id() ); + + CMsgStorePropertyContainer* props = CMsgStorePropertyContainer::NewL(); + CleanupStack::PushL( props ); + props->AddOrUpdatePropertyL( KMsgStorePropertyContentType, KFSMailContentTypeMultipartMixed ); + + // Set reply-to address, if it exists + HBufC* replyToAddressString = GetReplyToAddressL( aMailBox ); + + if ( NULL != replyToAddressString ) + { + CleanupStack::PushL( replyToAddressString ); + + if ( replyToAddressString->Length() > 0 ) + { + RMsgStoreAddress replyToAddress; + CleanupClosePushL( replyToAddress ); + + replyToAddress.iEmailAddress.Create( *replyToAddressString ); + replyToAddress.iDisplayName.Create( KNullDesC ); + + props->AddOrUpdatePropertyL( KMsgStorePropertyReplyTo, replyToAddress ); + + CleanupStack::PopAndDestroy( &replyToAddress ); + } + CleanupStack::PopAndDestroy( replyToAddressString ); + } + + CMsgStoreMessage* message = mailboxInfo().CreateMessageL( + mailboxInfo.iRootFolders.iFolders[EFSDraftsFolder], *props ); + + CleanupStack::PopAndDestroy( props ); + CleanupStack::PushL( message ); + + //create the body part. + props = CMsgStorePropertyContainer::NewL(); + CleanupStack::PushL( props ); + + props->AddOrUpdatePropertyL( + KMsgStorePropertyContentType, KFSMailContentTypeMultipartAlternative ); + CMsgStoreMessagePart* bodyPart = message->AddChildPartL( *props ); + + CleanupStack::PopAndDestroy( props ); + CleanupStack::PushL( bodyPart ); + + //create the plain text part. + props = CMsgStorePropertyContainer::NewL(); + CleanupStack::PushL( props ); + + props->AddPropertyL( + KMsgStorePropertyContentType, KFSMailContentTypeTextPlain ); + + _LIT(KMessageBodyCharset, "UTF-8"); + props->AddPropertyL( KMsgStorePropertyCharset, KMessageBodyCharset ); + + _LIT(KMessageBodyDisposition, "inline"); + props->AddPropertyL( + KMsgStorePropertyContentDisposition, KMessageBodyDisposition ); + + HBufC* signature = GetSignatureL( aMailBox ); + if ( signature ) + { + CleanupStack::PushL( signature ); + + props->AddPropertyL( + KMsgStorePropertySize, static_cast( signature->Length() ) ); + props->AddPropertyL( + KMsgStorePropertyRetrievedSize, + static_cast( signature->Length() ) ); + } + + CMsgStoreMessagePart* textPlain = bodyPart->AddChildPartL( *props ); + if ( signature ) + { + CleanupStack::Pop( signature ); + } + CleanupStack::PopAndDestroy( props ); + if ( signature ) + { + CleanupStack::PushL( signature ); + } + CleanupStack::PushL( textPlain ); + + //add signature, if it exists + if ( NULL != signature && signature->Length() ) + { + TPtrC8 ptr8( + reinterpret_cast( signature->Ptr() ), + signature->Size() ); + + textPlain->ReplaceContentL( ptr8 ); + } + + CleanupStack::PopAndDestroy( textPlain ); + if ( signature ) + { + CleanupStack::PopAndDestroy( signature ); + } + CleanupStack::PopAndDestroy( bodyPart ); + + //done. + message->CommitL(); + + TFSMailMsgId folderId( GetPluginId(), message->ParentId() ); + TFSMailMsgId msgId( GetPluginId(), message->Id() ); + CleanupStack::PopAndDestroy( message ); + + CFSMailMessage* result = CFSMailMessage::NewL( msgId ); + + result->SetMailBoxId( aMailBox ); + result->SetFolderId( folderId ); + result->SetContentType( KFSMailContentTypeMultipartMixed ); + + __LOG_EXIT + return result; + } + + +/** + * + */ +EXPORT_C CFSMailMessage* CBasePlugin::CreateForwardMessageL( + const TFSMailMsgId& aMailBox, + const TFSMailMsgId& aOriginal, + const TDesC& aHeaderDescriptor ) + { + return CreateForwardReplyMessageL( aMailBox, aOriginal, EFalse, aHeaderDescriptor, ETrue ); + } + + +/** + * Relying on the UI for the subject and recipients. + */ +EXPORT_C CFSMailMessage* CBasePlugin::CreateReplyMessageL( + const TFSMailMsgId& aMailBoxId, + const TFSMailMsgId& aOriginalMessageId, + const TBool aReplyToAll, + const TDesC& aHeaderDescriptor ) + { + return CreateForwardReplyMessageL( aMailBoxId, aOriginalMessageId, aReplyToAll, aHeaderDescriptor, EFalse ); + } + + +/** + * + */ +EXPORT_C CFSMailMessage* CBasePlugin::CreateMrReplyMessageL( + const TFSMailMsgId& aMailBoxId, + MMRInfoObject& /*aMeetingRequest*/, + const TFSMailMsgId& aOriginalMessageId ) + { + return CreateReplyMessageL( aMailBoxId, aOriginalMessageId, EFalse, KNullDesC ); + } + + +/** + * + * @param aMailBoxId if not found leaves with KErrNotFound. + */ +EXPORT_C void CBasePlugin::StoreMessageL( + const TFSMailMsgId& aMailBoxId, + CFSMailMessage& aMessage ) + + { + __LOG_ENTER( "StoreMessageL" ) + + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + CMsgStoreMessage* message = mailBox().FetchMessageL( + aMessage.GetMessageId().Id(), KMsgStoreInvalidId ); + CleanupStack::PushL( message ); + + //determine whether the message is in the inbox folder or some of its + //children; the translation is different for inbox and all the other folders. + TBool inInbox = EFalse; + TMsgStoreId parentId = message->ParentId(); + while ( KMsgStoreInvalidId != parentId + && EMsgStoreFolderContainer == mailBox().ContainerTypeById( parentId ) ) + { + if ( parentId == mailBox.iRootFolders.iFolders[EFSInbox] ) + { + inInbox = ETrue; + break; + } + else + { + CMsgStoreFolder* parent = mailBox().FolderL( parentId ); + parentId = parent->ParentId(); + delete parent; + } + } + + TranslateEmailFwMessageL( aMessage, *message, inInbox ); + message->StorePropertiesL(); + + CleanupStack::PopAndDestroy( message ); + + ResetCache(); + __LOG_EXIT + } + + +/** + * Async operation, starts fetching. + * @param aRequestId + */ +EXPORT_C void CBasePlugin::FetchMessagesL( + const TFSMailMsgId& /*aMailBox*/, + const TFSMailMsgId& /*aFolder*/, + const RArray& /*aMessageIds*/, + TFSMailDetails /*aDetails*/, + MFSMailRequestObserver& /*aObserver*/, + TInt /*aRequestId*/ ) + + { + /**@ is this really necessary for the base plugin ?*/ + } + + +/** + * + */ +EXPORT_C void CBasePlugin::GetMessagesL( + const TFSMailMsgId& /*aMailBoxId*/, + const TFSMailMsgId& /*aParentFolderId*/, + const RArray& /*aMessageIds*/, + RPointerArray& /*aMessageList*/, + const TFSMailDetails /*aDetails*/ ) + + { + /**@ is this really necessary for the base plugin ?*/ + } + + +/** + * CFSMailPlugin::SendMessageL + */ +EXPORT_C void CBasePlugin::SendMessageL( CFSMailMessage& aMessage ) + { + __LOG_ENTER( "SendMessageL1" ) + + TMsgStoreId mailBoxId = aMessage.GetMailBoxId().Id(); + TMsgStoreId msgId = aMessage.GetMessageId().Id(); + + CMsgStoreMessage* message = GetCachedMsgL( mailBoxId, msgId ); + __LOG_WRITE8_FORMAT1_INFO( "Fetched message : 0x%X.", msgId ) + + TranslateEmailFwMessageL( aMessage, *message, EFalse ); + //the sendmessagel will store the message's properties! + + TTime sentTime; + sentTime.UniversalTime(); + aMessage.SetDate( sentTime ); + + CMailboxInfo& mailBox = GetMailboxInfoL( aMessage.GetMailBoxId().Id() ); + SendMessageL( mailBox(), *message, sentTime ); + + __LOG_EXIT + } + + +/** + * Plugin could use this method to "send" a message if the CFSMailPlugin's is + * not necessary. The method also stores the message properties before doing so. + * This allows for optimizing away of unnecessary writes to the msgstore. + * @param aSentTime the sent time you want set for the message. + */ +EXPORT_C void CBasePlugin::SendMessageL( + CMsgStoreMailBox& aMailBox, + CMsgStoreMessage& aMsg, + const TTime& aSentTime ) + { + __LOG_ENTER( "SendMessageL2" ) + + //set the sent stamp. + aMsg.AddOrUpdatePropertyL( KMsgStorePropertySent, aSentTime ); + // Due to no Received Time in the sent messages, it caused sorting problem + // from MsgStore + aMsg.AddOrUpdatePropertyL( KMsgStorePropertyReceivedAt, aSentTime ); + aMsg.StorePropertiesL(); + + // move the msg to the outbox. + TFSMailMsgId id( GetPluginId(), aMailBox.Id() ); + TFSMailMsgId drafts = GetStandardFolderIdL( id, EFSDraftsFolder ); + TFSMailMsgId outbox = GetStandardFolderIdL( id, EFSOutbox ); + + aMailBox.CopyMessageL( aMsg.Id(), drafts.Id(), outbox.Id() ); + + CDelayedDeleteMessagesOp* delayedOp = CDelayedDeleteMessagesOp::NewLC( + aMailBox.Id(), KMsgStoreInvalidId, aMsg.Id() ); + iDelayedOpsManager->EnqueueOpL( delayedOp ); + CleanupStack::Pop( delayedOp ); + + __LOG_EXIT + } + +/** + * + */ +EXPORT_C void CBasePlugin::MoveMessagesL( + const TFSMailMsgId& aMailBoxId, + const RArray& aMessageIds, + const TFSMailMsgId& aSourceFolderId, + const TFSMailMsgId& aDestinationFolderId ) + + { + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + TInt count = aMessageIds.Count(); + for ( TUint i = 0; i < count; i++ ) + { + mailBox().MoveMessageL( + aMessageIds[i].Id(), + aSourceFolderId.Id(), + aDestinationFolderId.Id() ); + } + } + + +/** + * + */ +EXPORT_C void CBasePlugin::CopyMessagesL( + const TFSMailMsgId& aMailBoxId, + const RArray& aMessageIds, + RArray& aNewMessages, + const TFSMailMsgId& aSourceFolderId, + const TFSMailMsgId& aDestinationFolderId ) + + { + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + TFSMailMsgId newId( GetPluginId(), KMsgStoreInvalidId ); + + TInt count = aMessageIds.Count(); + for ( TUint i = 0; i < count; i++ ) + { + TMsgStoreId msgStoreId = mailBox().CopyMessageL( + aMessageIds[i].Id(), + aSourceFolderId.Id(), + aDestinationFolderId.Id() ); + + newId.SetId( msgStoreId ); + aNewMessages.AppendL( newId ); + } + } + + +#pragma mark --- "Plugin Helpers" --- + + +/** + * Get the MsgStore mailbox instance for the specified FSEF mailbox id. + * + * @param aId mailbox id, if none can be found leaves with KErrNotFound. + */ +EXPORT_C CMailboxInfo& CBasePlugin::GetMailboxInfoL( + TMsgStoreId aId ) + { + + __ASSERT_DEBUG( NULL != iMsgStore, ::BasePluginPanic( ENoMsgStoreSessionAssert ) ); + + //if not present in the cache, add it. + if ( !iMailboxes.ContainsKey(aId) ) + { + RPointerArray< CMsgStoreAccount > accounts; + iMsgStore->AccountsL( accounts ); + CleanupResetAndDestroyClosePushL( accounts ); + + TBool found = EFalse; + + TInt count = accounts.Count(); + for ( TInt i = 0; i < count; i++ ) + { + CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] ); + CleanupStack::PushL( msbox ); + + if ( aId == msbox->Id() ) + { + CMailboxInfo* mailBox = new (ELeave) CMailboxInfo( this ); + CleanupStack::PushL( mailBox ); + mailBox->iMailBox = msbox; + //always observe for mailbox changes to keep the cache + //up-to-date. + mailBox->iMailBox->AddObserverL( this ); + + mailBox->iMailBoxName = accounts[i]->Name().AllocL(); + mailBox->iBrandingId = KNullDesC().AllocL(); + + RBuf mailboxDisplayName; + mailboxDisplayName.CleanupClosePushL(); + GetMailboxDisplayNameL( aId, mailboxDisplayName ); + mailBox->iMailBoxDisplayName = mailboxDisplayName.AllocL(); + CleanupStack::PopAndDestroy( &mailboxDisplayName ); + + MsgStoreFolderUtils::GetRootFoldersL( *msbox, mailBox->iRootFolders ); + + TInt64* key = new (ELeave) TInt64( msbox->Id() ); + CleanupDeletePushL( key ); + iMailboxes.InsertL( key, mailBox ); //the map owns the memory. + + CleanupStack::Pop( key ); + CleanupStack::Pop( mailBox ); + CleanupStack::Pop( msbox ); + + found = ETrue; + break; + } + + CleanupStack::PopAndDestroy( msbox ); + } + + CleanupStack::PopAndDestroy( &accounts ); + + if( !found ) + { + User::Leave( KErrNotFound ); + } + } + + return iMailboxes.GetValueL( aId ); + } //GetMailboxInfoL. + + +/** + * Get the MsgStore mailbox instance for the specified FSEF mailbox id. + * + * @param aId mailbox id, if none can be found leaves with KErrNotFound. + */ +void CBasePlugin::GetMailboxDisplayNameL( + TMsgStoreId aId, + RBuf& aDisplayName ) + { + + __ASSERT_DEBUG( NULL != iMsgStore, ::BasePluginPanic( ENoMsgStoreSessionAssert ) ); + + RPointerArray< CMsgStoreAccount > accounts; + iMsgStore->AccountsL( accounts ); + CleanupResetAndDestroyClosePushL( accounts ); + + TInt count = accounts.Count(); + for ( TInt i = 0; i < count; i++ ) + { + CMsgStoreMailBox* msbox = iMsgStore->OpenAccountL( *accounts[i] ); + CleanupStack::PushL( msbox ); + + if( aId == msbox->Id() ) + { + TUint index = 0; + if ( msbox->FindProperty( KMsgStorePropertyName, index ) ) + { + const TDesC& string = msbox->PropertyValueDesL( index ); + if (string.Length() > 0) + { + aDisplayName.Close(); + aDisplayName.CreateL( string ); + } + } + CleanupStack::PopAndDestroy( msbox ); + break; + } + else + { + CleanupStack::PopAndDestroy( msbox ); + } + } + + CleanupStack::PopAndDestroy( &accounts ); + } //GetMailboxDisplayNameL. + +/** + * @param aFolderId if set to KMsgStoreInvalidId makes a recursive list. + */ +void CBasePlugin::DoListFoldersL( + TFSMailMsgId aMailBoxId, + TMsgStoreId aFolderId, + TBool aRecursive, + RPointerArray& aFolderList ) + + { + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() ); + + RPointerArray folders; + CleanupResetAndDestroyClosePushL( folders ); + + if ( aRecursive ) + { + mailBox().FoldersL( folders ); + } + else + { + mailBox().FoldersL( aFolderId, folders ); + } + + TFSMailMsgId folderId; + folderId.SetPluginId( TUid::Uid( GetPluginId() ) ); + + TInt count = folders.Count(); + for( TInt i = 0; i < count; i++ ) + { + folderId.SetId( folders[i]->Id() ); + + CFSMailFolder* folder = GetFolderByUidL( aMailBoxId, folderId ); + + CleanupStack::PushL( folder ); + aFolderList.AppendL( folder ); + CleanupStack::Pop( folder ); + } + + CleanupStack::PopAndDestroy( &folders ); + } + + +/** + * + */ +CFSMailAddress* CBasePlugin::FetchEmailAddressL( + CMsgStorePropertyContainer& aMessage, + TUint aIdx ) + + { + RMsgStoreAddress value; + CleanupClosePushL( value ); + + aMessage.PropertyValueAddressL( aIdx, value ); + + CFSMailAddress* result = CFSMailAddress::NewL(); + result->SetEmailAddress( value.iEmailAddress ); + if ( KNullDesC() != value.iDisplayName ) + { + result->SetDisplayName( value.iDisplayName ); + } + else + { + /**@ the UI would crash if there was no display name.*/ + result->SetDisplayName( value.iEmailAddress ); + } + + CleanupStack::PopAndDestroy( &value ); + + return result; + } + + +/** + * + */ +EXPORT_C CMsgStoreMessagePart* CBasePlugin::GetBodyPartL( + CMsgStoreMessage& aMessage, + const TDesC& aContentType ) + { + CMsgStoreMessagePart* result = NULL; + + RPointerArray parts; + CleanupResetAndDestroyClosePushL( parts ); + + aMessage.ChildPartsL( parts ); + if ( 0 < parts.Count() ) + { + RPointerArray childParts; + CleanupResetAndDestroyClosePushL( childParts ); + parts[0]->ChildPartsL( childParts ); + + TInt count = childParts.Count(); + if ( 0 < count ) + { + for ( TInt i = 0; i < count; i++ ) + { + TUint idx = 0; + if ( childParts[i]->FindProperty( KMsgStorePropertyContentType, idx, idx ) ) + { + const TDesC& contentType = childParts[i]->PropertyValueDesL( idx ); + if ( contentType == aContentType ) + { + result = childParts[i]; + childParts.Remove( i ); + break; + } + } + } + + } + else + { + TUint idx = 0; + if ( parts[0]->FindProperty( KMsgStorePropertyContentType, idx, idx ) ) + { + const TDesC& contentType = parts[0]->PropertyValueDesL( idx ); + if ( contentType == aContentType ) + { + result = parts[0]; + parts.Remove( 0 ); + } + } + } + + CleanupStack::PopAndDestroy( &childParts ); + } + + CleanupStack::PopAndDestroy( &parts ); + + return result; + } //GetBodyPartL. + +/** + * + */ +EXPORT_C CFSMailMessage* CBasePlugin::CreateForwardReplyMessageL( + const TFSMailMsgId& aMailBox, + const TFSMailMsgId& aOriginal, + const TBool aReplyToAll, + const TDesC& aHeaderDescriptor, + TBool aKeepAttachments, + TBool aKeepMeetingRequestInfo ) + { + __LOG_ENTER( "CreateForwardReplyMessageL" ) + CMailboxInfo& mailBox = GetMailboxInfoL( aMailBox.Id() ); + + CMsgStoreMessage* message = mailBox().FetchMessageL( + aOriginal.Id(), KMsgStoreInvalidId ); + CleanupStack::PushL( message ); + + TMsgStoreId newMsgId = mailBox().CopyMessageL( + aOriginal.Id(), message->ParentId(), + mailBox.iRootFolders.iFolders[EFSDraftsFolder] ); + + CMsgStoreMessage* newMsg = mailBox().FetchMessageL( newMsgId, KMsgStoreInvalidId ); + CleanupStack::PushL( newMsg ); + + if ( !aReplyToAll ) + { + //Clear all To, Cc addresses for Reply, Forward + RemoveAllPropertiesL( *newMsg, KMsgStorePropertyTo ); + RemoveAllPropertiesL( *newMsg, KMsgStorePropertyCc ); + } + else + { + //Remove the mailbox address from the reply to addresses + HBufC* mailBoxAdd = GetMailBoxAddressL( aMailBox ); + CleanupStack::PushL( mailBoxAdd ); + + if ( NULL != mailBoxAdd ) + { + TUint idx1 = 0; + while (newMsg->FindProperty( KMsgStorePropertyTo, idx1, idx1 ) ) + { + RMsgStoreAddress tempAdd; + CleanupClosePushL( tempAdd ); + + newMsg->PropertyValueAddressL( idx1, tempAdd ); + if ( tempAdd.iEmailAddress == *mailBoxAdd ) + { + newMsg->RemovePropertyL( idx1 ); + CleanupStack::PopAndDestroy( &tempAdd ); + break; + } + CleanupStack::PopAndDestroy( &tempAdd ); + ++idx1; + } + + idx1 = 0; + while (newMsg->FindProperty( KMsgStorePropertyCc, idx1, idx1 ) ) + { + RMsgStoreAddress tempAdd; + CleanupClosePushL( tempAdd ); + + newMsg->PropertyValueAddressL( idx1, tempAdd ); + if ( tempAdd.iEmailAddress == *mailBoxAdd ) + { + newMsg->RemovePropertyL( idx1 ); + CleanupStack::PopAndDestroy( &tempAdd ); + break; + } + CleanupStack::PopAndDestroy( &tempAdd ); + ++idx1; + } + } + + CleanupStack::PopAndDestroy( mailBoxAdd ); + } + + SetReplyOrForwardToFieldL( *newMsg ); + + //Clear the response flag. + TUint idx = 0; + if ( newMsg->FindProperty( KMsgStorePropertyFlags, idx ) ) + { + TUint32 flags = newMsg->PropertyValueUint32L( idx ); + flags &= ~EFSMsgFlag_Answered; + newMsg->AddOrUpdatePropertyL( KMsgStorePropertyFlags, flags ); + } + + //Clear the From field, ReplyTo field + RemoveAllPropertiesL( *newMsg, KMsgStorePropertyFrom ); + RemoveAllPropertiesL( *newMsg, KMsgStorePropertyReplyTo ); + + //Use reply-to address, if it exists + HBufC* replyToAddressString = GetReplyToAddressL( aMailBox ); + + if ( NULL != replyToAddressString ) + { + CleanupStack::PushL( replyToAddressString ); + + if ( replyToAddressString->Length() > 0 ) + { + RMsgStoreAddress replyToAddress; + CleanupClosePushL( replyToAddress ); + + replyToAddress.iEmailAddress.Create( *replyToAddressString ); + replyToAddress.iDisplayName.Create( KNullDesC ); + + newMsg->AddOrUpdatePropertyL( KMsgStorePropertyReplyTo, replyToAddress ); + + CleanupStack::PopAndDestroy( &replyToAddress ); + } + CleanupStack::PopAndDestroy( replyToAddressString ); + } + + newMsg->StorePropertiesL(); + + //deal with the attachments accordingly. + /**@ the case where the attachments haven't been downloaded but some smart + * reply/fw tag is present in the msg body needs to be dealt with in the specific + * plugins.*/ + if ( aKeepAttachments == EFalse ) + { + RPointerArray parts; + CleanupResetAndDestroyClosePushL( parts ); + + newMsg->ChildPartsL( parts ); + TInt count = parts.Count(); + + for ( TInt i = 1; i < count; i++ ) + { + newMsg->RemoveChildPartL( parts[i]->Id() ); + } + + CleanupStack::PopAndDestroy( &parts ); + } + + if ( aKeepMeetingRequestInfo == EFalse ) + { + idx = 0; + if ( newMsg->FindProperty( KMsgStorePropertyMeetingRequest, idx ) ) + { + CBasePlugin::RemoveAllPropertiesL( *newMsg, KMsgStorePropertyMeetingRequest ); + } + } + + CFSMailMessage* result = CFSMailMessage::NewL( + TFSMailMsgId( GetPluginId(), newMsgId ) ); + CleanupStack::PushL( result ); + + TranslateMsgStorePropsL( aMailBox, *newMsg, *result ); + result->SetMailBoxId( aMailBox ); + + /**@ candidate for refactoring out to a separate body dealing method.*/ + CMsgStoreMessagePart* srcPart = GetBodyPartL( *message ); + if ( NULL != srcPart ) + { + CleanupStack::PushL( srcPart ); + CMsgStoreMessagePart* dstPart = GetBodyPartL( *newMsg ); + + if ( NULL != dstPart ) + { + CleanupStack::PushL( dstPart ); + + HBufC* signature = GetSignatureL( aMailBox ); + if ( NULL != signature ) + { + CleanupStack::PushL( signature ); + TPtrC8 ptr8( + reinterpret_cast( signature->Ptr() ), + signature->Size() ); + dstPart->ReplaceContentL( ptr8 ); + CleanupStack::PopAndDestroy( signature ); + + __LOG_WRITE_INFO( "Set the email signature." ) + } + + //the quoted message header. + if ( aHeaderDescriptor != KNullDesC ) + { + TPckgBuf rfParsPckg; + rfParsPckg.Copy( aHeaderDescriptor ); + + TPtrC8 ptrHeader8( + reinterpret_cast( rfParsPckg().iHeader->Ptr() ), + rfParsPckg().iHeader->Size() ); + NULL != signature ? dstPart->AppendToContentL( ptrHeader8 ) + : dstPart->ReplaceContentL( ptrHeader8 ); + + __LOG_WRITE8_FORMAT1_INFO( + "Original body content length: %d.", srcPart->ContentLengthL() ) + + //copy the body content from the original. + TInt startOffset = 0; + RBuf8 buf; + buf.Create( KQuotedReadBufferSize ); + CleanupClosePushL( buf ); + + do + { + srcPart->FetchContentToBufferL( buf, startOffset ); + dstPart->AppendToContentL( buf ); + + startOffset += buf.Size(); + } + while ( buf.Size() == KQuotedReadBufferSize ); + + CleanupStack::PopAndDestroy( &buf ); + + TInt newFetchedSize = dstPart->ContentLengthL(); + __LOG_WRITE8_FORMAT1_INFO( + "Reply/fw body content length: %d.", newFetchedSize ) + + TInt idx = dstPart->AddOrUpdatePropertyL( + KMsgStorePropertySize, static_cast( newFetchedSize ) ); + dstPart->StorePropertyL( idx ); + idx = dstPart->AddOrUpdatePropertyL( + KMsgStorePropertyRetrievedSize, static_cast( newFetchedSize ) ); + dstPart->StorePropertyL( idx ); + + result->SetContentSize( newFetchedSize ); + result->SetFetchedContentSize( newFetchedSize ); + + //determine whether the original msg was truncated. + TBool wasTruncated = EFalse; + TUint srcIdx = 0; + if ( srcPart->FindProperty( KMsgStorePropertySize, srcIdx ) ) + { + TUint size = srcPart->PropertyValueUint32L( srcIdx ); + + srcIdx = 0; + if ( srcPart->FindProperty( KMsgStorePropertyRetrievedSize, srcIdx ) ) + { + TUint retrievedSize = srcPart->PropertyValueUint32L( srcIdx ); + + if ( retrievedSize < size ) + { + wasTruncated = ETrue; + } + } + } + + //if truncated append msg that the whole msg is available server-side. + if ( wasTruncated ) + { + _LIT( KTwoLineFeeds, "\n\n" ); + TPtrC8 ptrTwoLineFeeds8( + reinterpret_cast( KTwoLineFeeds().Ptr() ), + KTwoLineFeeds().Size() ); + dstPart->AppendToContentL( ptrTwoLineFeeds8 ); + + TPtrC8 ptrSmartTag8( + reinterpret_cast( rfParsPckg().iSmartTag->Ptr() ), + rfParsPckg().iSmartTag->Size() ); + dstPart->AppendToContentL( ptrSmartTag8 ); + } + } + + /**@ incorrect but per activesync request - the base plugin doesn't know anything about how the unicode characters + are being encoded by the specific implementations when they talk to their backends.*/ + _LIT(KMessageBodyCharset, "UTF-8"); + dstPart->AddPropertyL( KMsgStorePropertyCharset, KMessageBodyCharset ); + + CleanupStack::PopAndDestroy( dstPart ); + } + CleanupStack::PopAndDestroy( srcPart ); + } + + CleanupStack::Pop( result ); + CleanupStack::PopAndDestroy( newMsg ); + CleanupStack::PopAndDestroy( message ); + + __LOG_EXIT + return result; + } //CreateForwardReplyMessageL. + + +/** + * If there is a reply to address, add it to the TO list + * else add the FROM address to the TO address list + */ +/*private*/ void CBasePlugin::SetReplyOrForwardToFieldL( CMsgStoreMessage& aMsg ) + { + RMsgStoreAddress toAddr; + CleanupClosePushL( toAddr ); + + TBool usingReplyTo = EFalse; + + TUint idx = 0; + if( aMsg.FindProperty( KMsgStorePropertyReplyTo, idx ) ) + { + //if both address and name are null strings no memory will be allocated. + aMsg.PropertyValueAddressL( idx, toAddr ); + + if ( toAddr.iEmailAddress.Length() || toAddr.iDisplayName.Length() ) + { + usingReplyTo = ETrue; + } + } + + if ( EFalse == usingReplyTo ) + { + idx = 0; + if ( aMsg.FindProperty( KMsgStorePropertyFrom, idx ) ) + { + aMsg.PropertyValueAddressL( idx, toAddr ); + } + } + + aMsg.AddPropertyL( KMsgStorePropertyTo, toAddr ); + CleanupStack::PopAndDestroy( &toAddr ); + } + + +/** + * RefreshMailboxCacheL - This will refresh the mailbox instance cache maintained within the base plugin. + * + */ +EXPORT_C CMailboxInfo& CBasePlugin::RefreshMailboxCacheL( TMsgStoreId aMailBoxId ) + { + //save the observers + CMailboxInfo& oldMailBox = GetMailboxInfoL( aMailBoxId ); + + RPointerArray observers; + // the elements are not owned by the base plugin, so just close the array + CleanupClosePushL( observers ); + + TUint count = oldMailBox.iObservers.Count(); + for ( TUint i = 0; i < count; i++ ) + { + observers.AppendL( oldMailBox.iObservers[i] ); + } + + //remove from the cache + if ( KErrNotFound != iMailboxes.Find( aMailBoxId ) ) + { + iMailboxes.RemoveL( aMailBoxId ); + } + + //force the refresh and restore the observes + CMailboxInfo& newMailBox = GetMailboxInfoL( aMailBoxId ); + + for ( TUint i = 0; i < count; i++ ) + { + newMailBox.iObservers.AppendL( observers[i] ); + } + + CleanupStack::PopAndDestroy( &observers ); + return newMailBox; + } + + +/** + * RefreshCachedMailBoxDisplayNameL - This will check to see if the mailbox display name has changed. If so it will + * update the cached mailbox display name and set mailBoxNameHasChanged to ETrue + * + */ +void CBasePlugin::RefreshCachedMailBoxDisplayNameL( TBool& aMailBoxNameHasChanged, const TMsgStoreId& aMailBoxId ) + { + aMailBoxNameHasChanged = EFalse; + + RBuf currentDisplayName; + currentDisplayName.CleanupClosePushL(); + GetMailboxDisplayNameL( aMailBoxId, currentDisplayName ); + + CMailboxInfo& mailboxInfo = GetMailboxInfoL( aMailBoxId ); + TDesC* cachedDisplayName( mailboxInfo.iMailBoxDisplayName ); + + if ( ( cachedDisplayName && currentDisplayName != *cachedDisplayName ) || + ( !cachedDisplayName && currentDisplayName.Length() ) ) + { + aMailBoxNameHasChanged = ETrue; + delete mailboxInfo.iMailBoxDisplayName; + mailboxInfo.iMailBoxDisplayName = NULL; + mailboxInfo.iMailBoxDisplayName = currentDisplayName.AllocL(); + } + + CleanupStack::PopAndDestroy( ¤tDisplayName ); + } +