--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/email/pop3andsmtpmtm/clientmtms/src/cimattachmentmanager.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,467 @@
+// Copyright (c) 2004-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:
+//
+
+#include "cimattachmentmanager.h"
+
+CImAttachmentManager::CImAttachmentManager(CImEmailMessage& aEmailMessage,CMsvEntry& aEntry) :CActive(EPriorityStandard),iClientEntry(aEntry), iEmailMessage(aEmailMessage)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CImAttachmentManager::ConstructL()
+ {
+ }
+
+CImAttachmentManager::~CImAttachmentManager()
+ {
+ delete iStore;
+ iAttachmentInfoList.ResetAndDestroy();
+ delete iMsvOperation;
+ delete iEntry;
+ }
+
+CImAttachmentManager* CImAttachmentManager::NewL(CImEmailMessage& aEmailMessage,CMsvEntry& aEntry)
+ {
+ CImAttachmentManager* self = new(ELeave) CImAttachmentManager(aEmailMessage,aEntry);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CImAttachmentManager::RunL()
+ {
+ switch(iAttachmentManagerState)
+ {
+ case EModifyAttachmentInfo:
+ {
+ if(!iStore == NULL)
+ {
+ ModifyAttachmentInfoL();
+ }
+ ChangeEntryDetailsL();
+ iAttachmentManagerState = EChangeEntryDetails;
+ }
+ break;
+ case EChangeEntryDetails:
+ {
+ delete iEntry;
+ iEntry = NULL;
+
+ User::RequestComplete(iReportStatus, iStatus.Int());
+ }
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ };
+ }
+
+void CImAttachmentManager::DoCancel()
+ {
+ if (iMsvOperation)
+ iMsvOperation->Cancel();
+
+ delete iStore;
+ iStore = NULL;
+
+ delete iEntry;
+ iEntry = NULL;
+ }
+
+TInt CImAttachmentManager::RunError(TInt aError)
+ {
+ if(iStore != NULL)
+ {
+ delete iStore;
+ iStore = NULL;
+ }
+
+ delete iEntry;
+ iEntry = NULL;
+
+ User::RequestComplete(iReportStatus, aError);
+ return KErrNone;
+ }
+
+void CImAttachmentManager::AddAttachmentL(const TDesC& aFilePath, CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ iEmailMessage.AddAttachmentL(aFilePath,aAttachmentInfo,aStatus);
+ }
+
+void CImAttachmentManager::AddAttachmentL(RFile& aFileHandle, CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ iEmailMessage.AddAttachmentL(aFileHandle,aAttachmentInfo,aStatus);
+ }
+
+void CImAttachmentManager::AddLinkedAttachmentL(const TDesC& aFilePath, CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ iEmailMessage.AddLinkedAttachmentL(aFilePath,aAttachmentInfo,aStatus);
+ }
+
+void CImAttachmentManager::AddEntryAsAttachmentL(TMsvId aEntryId, CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ iEmailMessage.AddEntryAsAttachmentL(aEntryId,aAttachmentInfo,aStatus);
+ }
+
+void CImAttachmentManager::CreateAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ iEmailMessage.CreateAttachmentL(aFileName,aAttachmentFile,aAttachmentInfo,aStatus);
+ }
+
+/**
+This API not supported.
+Leaves with KErrNotSupported.
+*/
+void CImAttachmentManager::RenameAttachmentL(TInt /*aIndex*/, const TDesC& /*aNewName*/, TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+TInt CImAttachmentManager::AttachmentCount() const
+ {
+ return iAttachmentInfoList.Count();
+ }
+
+CMsvAttachment* CImAttachmentManager::GetAttachmentInfoL(TInt aIndex)
+ {
+ __ASSERT_ALWAYS(iAttachmentInfoList.Count() || (aIndex >= 0 && aIndex < iAttachmentInfoList.Count()),User::Invariant());
+
+ CMsvAttachment* attachmentInfo = iAttachmentInfoList[aIndex];
+ return CMsvAttachment::NewL(*attachmentInfo);
+ }
+
+CMsvAttachment* CImAttachmentManager::GetAttachmentInfoL(TMsvAttachmentId aId)
+ {
+ TInt index = AttachmentIndexInMessage(aId);
+ User::LeaveIfError(index);
+
+ CMsvAttachment* attachmentInfo = iAttachmentInfoList[index];
+ return CMsvAttachment::NewL(*attachmentInfo);
+ }
+
+RFile CImAttachmentManager::GetAttachmentFileL(TInt aIndex)
+ {
+ __ASSERT_ALWAYS(iAttachmentInfoList.Count() || (aIndex >= 0 && aIndex < iAttachmentInfoList.Count()),User::Invariant());
+ // Need to reset the client entry to the owning attachment entry's TMsvId
+ TInt entryId;
+ // Stored in the integer attributes for the CMsvAttachment class
+ if(iAttachmentInfoList[aIndex]->GetIntAttribute(KUidMsvEmailAttachmentEntryId,entryId) != KErrNone)
+ {
+ // We're moving from the per-message iAttachmentInfoList to the per attachment entry list
+ entryId = iAttachmentInfoList[aIndex]->Id();
+ }
+
+ CMsvEntry* entry=CMsvEntry::NewL(iClientEntry.Session(), entryId, TMsvSelectionOrdering());
+ CleanupStack::PushL(entry);
+
+ CMsvStore* store = entry->ReadStoreL();
+ CleanupStack::PushL(store);
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ // We're on the attachment entry but we need the index into that array
+ // This is stored in another attribute
+ RFile file;
+
+ TInt entryIndex;
+ if(iAttachmentInfoList[aIndex]->GetIntAttribute(KUidMsvEmailAttachmentEntryIndex,entryIndex) == KErrNone)
+ {
+ // Home in on the original CMsvAttachment
+ file = attachmentMgr.GetAttachmentFileL(entryIndex);
+ }
+ else
+ {
+ file = attachmentMgr.GetAttachmentFileL(0);
+ }
+ CleanupStack::PopAndDestroy(2,entry);//store, entry
+
+ return file;
+ }
+
+RFile CImAttachmentManager::GetAttachmentFileL(TMsvAttachmentId aId)
+ {
+ // Lookup in the per-message array and extract the index
+ TInt index = AttachmentIndexInMessage(aId);
+ User::LeaveIfError(index);
+
+ // Need to reset the client entry to the owning attachment entry's TMsvId
+ TInt entryId;
+ // Stored in the integer attributes for the CMsvAttachment class
+ if(iAttachmentInfoList[index]->GetIntAttribute(KUidMsvEmailAttachmentEntryId,entryId) != KErrNone)
+ // We're moving from the per-message iAttachmentInfoList to the per attachment entry list
+ {
+ entryId = iAttachmentInfoList[index]->Id();
+ }
+
+ CMsvEntry* entry=CMsvEntry::NewL(iClientEntry.Session(), entryId, TMsvSelectionOrdering());
+ CleanupStack::PushL(entry);
+
+ CMsvStore* store = entry->ReadStoreL();
+ CleanupStack::PushL(store);
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ // We're on the attachment entry but we need the index into that array
+ // This is stored in another attribute
+ RFile file;
+
+ TInt entryIndex;
+ if(iAttachmentInfoList[index]->GetIntAttribute(KUidMsvEmailAttachmentEntryIndex,entryIndex) == KErrNone)
+ {
+ // Home in on the original CMsvAttachment
+ file = attachmentMgr.GetAttachmentFileL(entryIndex);
+ }
+ else
+ {
+ file = attachmentMgr.GetAttachmentFileL(0);
+ }
+ CleanupStack::PopAndDestroy(2,entry);//store, entry
+
+ return file;
+ }
+
+RFile CImAttachmentManager::GetAttachmentFileForWriteL(TInt aIndex)
+ {
+ __ASSERT_ALWAYS(iAttachmentInfoList.Count() || (aIndex >= 0 && aIndex < iAttachmentInfoList.Count()),User::Invariant());
+ // Need to reset the client entry to the owning attachment entry's TMsvId
+ TInt entryId;
+ // Stored in the integer attributes for the CMsvAttachment class
+ if(iAttachmentInfoList[aIndex]->GetIntAttribute(KUidMsvEmailAttachmentEntryId,entryId) != KErrNone)
+ {
+ // We're moving from the per-message iAttachmentInfoList to the per attachment entry list
+ entryId = iAttachmentInfoList[aIndex]->Id();
+ }
+
+ CMsvEntry* entry=CMsvEntry::NewL(iClientEntry.Session(), entryId, TMsvSelectionOrdering());
+ CleanupStack::PushL(entry);
+
+ CMsvStore* store = entry->EditStoreL();
+ CleanupStack::PushL(store);
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ // We're on the attachment entry but we need the index into that array
+ // This is stored in another attribute
+ RFile file;
+
+ TInt entryIndex;
+ if(iAttachmentInfoList[aIndex]->GetIntAttribute(KUidMsvEmailAttachmentEntryIndex,entryIndex) == KErrNone)
+ {
+ // Home in on the original CMsvAttachment
+ file = attachmentMgr.GetAttachmentFileForWriteL(entryIndex);
+ }
+ else
+ {
+ file = attachmentMgr.GetAttachmentFileForWriteL(0);
+ }
+ CleanupStack::PopAndDestroy(2, entry);//store, entry
+
+ return file;
+ }
+
+RFile CImAttachmentManager::GetAttachmentFileForWriteL(TMsvAttachmentId aId)
+ {
+ // Lookup in the per-message array and extract the index
+ TInt index = AttachmentIndexInMessage(aId);
+ User::LeaveIfError(index);
+
+
+ // Need to reset the client entry to the owning attachment entry's TMsvId
+ TInt entryId;
+ // Stored in the integer attributes for the CMsvAttachment class
+ if(iAttachmentInfoList[index]->GetIntAttribute(KUidMsvEmailAttachmentEntryId,entryId) != KErrNone)
+ {
+ // We're moving from the per-message iAttachmentInfoList to the per attachment entry list
+ entryId = iAttachmentInfoList[index]->Id();
+ }
+
+ CMsvEntry* entry=CMsvEntry::NewL(iClientEntry.Session(), entryId, TMsvSelectionOrdering());
+ CleanupStack::PushL(entry);
+
+ CMsvStore* store = entry->EditStoreL();
+ CleanupStack::PushL(store);
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ // We're on the attachment entry but we need the index into that array
+ // This is stored in another attribute
+ RFile file;
+
+ TInt entryIndex;
+ if(iAttachmentInfoList[index]->GetIntAttribute(KUidMsvEmailAttachmentEntryIndex,entryIndex) == KErrNone)
+ {
+ // Home in on the original CMsvAttachment
+ file = attachmentMgr.GetAttachmentFileForWriteL(entryIndex);
+ }
+ else
+ {
+ file = attachmentMgr.GetAttachmentFileForWriteL(0);
+ }
+ CleanupStack::PopAndDestroy(2,entry);//entry, store
+
+ return file;
+ }
+
+void CImAttachmentManager::RemoveAttachmentL(TInt aIndex, TRequestStatus& aStatus)
+ {
+ __ASSERT_ALWAYS(aIndex >= 0 && aIndex < iAttachmentInfoList.Count(),User::Invariant());
+
+ RemoveAttachmentL(iAttachmentInfoList[aIndex]->Id(),aStatus);
+ }
+
+void CImAttachmentManager::RemoveAttachmentL(TMsvAttachmentId aId, TRequestStatus& aStatus)
+ {
+ iEmailMessage.RemoveAttachmentL(aId,aStatus);
+ }
+
+void CImAttachmentManager::CancelRequest()
+ {
+ iEmailMessage.Cancel();
+ }
+
+void CImAttachmentManager::ModifyAttachmentInfoL(CMsvAttachment* aAttachmentInfo, TRequestStatus& aStatus)
+ {
+ TInt index = AttachmentIndexInMessage(aAttachmentInfo->Id());
+ User::LeaveIfError(index);
+
+ iAttachmentManagerState = EModifyAttachmentInfo;
+
+ delete iEntry;
+ iEntry = NULL;
+
+ iEntry=CMsvEntry::NewL(iClientEntry.Session(), iAttachmentInfoList[index]->Id(), TMsvSelectionOrdering());
+ iStore = iEntry->EditStoreL();
+
+ MMsvAttachmentManager& attachmentMgr = iStore->AttachmentManagerL();
+
+ aStatus = KRequestPending;
+ iReportStatus=&aStatus;
+
+ // The id stored in the Attachment info list in CImemailmessage is the
+ // attachment entry id, this is not the actual id of the attachment
+ // Reset the id as 1 , as emails have one attachment per attachment entry.
+ aAttachmentInfo->SetId(1);
+ attachmentMgr.ModifyAttachmentInfoL(aAttachmentInfo,iStatus);
+ SetActive();
+ }
+
+void CImAttachmentManager::LoadL()
+ {
+ // Flush the array before loading
+ iAttachmentInfoList.ResetAndDestroy();
+
+ // Load the attachments only if it was a message entry
+ const TMsvEmailEntry& entry=iClientEntry.Entry();
+ if(entry.iType==KUidMsvMessageEntry)
+ {
+ // CImEmailMessage fills the attachment list for CImAttachmentManager::iAttachmentInfoList
+ // get the attachment list from CImEmailMessage.
+ iEmailMessage.GetAttachmentsListL(iClientEntry.EntryId(),CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageAndEmbeddedMessages);
+ }
+ }
+
+RPointerArray<CMsvAttachment>& CImAttachmentManager::AttachmentInfoSelection()
+ {
+ return iAttachmentInfoList;
+ }
+
+TInt CImAttachmentManager::AttachmentIndexInMessage(TMsvAttachmentId aId)
+ {
+ if(!iAttachmentInfoList.Count())
+ return KErrNotFound;
+ // Traverse the list and get the index of the required attachment
+ for(TInt i = 0;i < iAttachmentInfoList.Count(); i++)
+ {
+ // Id contains unique per-message id.
+ if(aId == iAttachmentInfoList[i]->Id())
+ {
+ // found the entry
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+void CImAttachmentManager::AppendAttachmentArrayL(TMsvId aAttachmentId)
+ {
+ CMsvEntry* entry=CMsvEntry::NewL(iClientEntry.Session(), aAttachmentId, TMsvSelectionOrdering());
+ CleanupStack::PushL(entry);
+
+ CMsvStore* store = entry->ReadStoreL();
+ CleanupStack::PushL(store);
+
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ if(attachmentMgr.AttachmentCount())
+ {
+ CMsvAttachment* attachment = attachmentMgr.GetAttachmentInfoL(0);
+ attachment->SetId(aAttachmentId);
+ CleanupStack::PushL(attachment);
+ iAttachmentInfoList.AppendL(attachment);
+ CleanupStack::Pop(attachment);
+ }
+ CleanupStack::PopAndDestroy(2,entry);//store, entry
+ }
+
+void CImAttachmentManager::DeleteAttachmentInArrayL(TMsvId aDeletedAttachmentId)
+ {
+ TInt deleteAttachmentIdIndex = AttachmentIndexInMessage(aDeletedAttachmentId);
+ // leaves if error
+ User::LeaveIfError(deleteAttachmentIdIndex );
+
+ delete iAttachmentInfoList[deleteAttachmentIdIndex];
+ iAttachmentInfoList.Remove(deleteAttachmentIdIndex);
+ }
+
+void CImAttachmentManager::UpdateModifiedAttachmentInListL()
+ {
+ CMsvStore* store = iEntry->ReadStoreL();
+ CleanupStack::PushL(store);
+ MMsvAttachmentManager& attachmentMgr = store->AttachmentManagerL();
+ CMsvAttachment* attachmentInfo = attachmentMgr.GetAttachmentInfoL(0);
+ CleanupStack::PopAndDestroy(store);
+
+ CleanupStack::PushL(attachmentInfo);
+ attachmentInfo->SetId(iEntry->EntryId());
+ TInt index = AttachmentIndexInMessage(iEntry->EntryId());
+
+ // Insert the modified attachment at the index which was modified
+ iAttachmentInfoList.InsertL(attachmentInfo, index);
+ CleanupStack::Pop(attachmentInfo);
+
+ // remove the previous attachment info from the list
+ delete iAttachmentInfoList[index+1];
+ iAttachmentInfoList.Remove(index+1);
+ }
+
+void CImAttachmentManager::ChangeEntryDetailsL()
+ {
+ TInt index = AttachmentIndexInMessage(iEntry->EntryId());
+ TMsvEntry entry(iEntry->Entry());
+ entry.iSize = iAttachmentInfoList[index]->Size();
+ entry.SetComplete(iAttachmentInfoList[index]->Complete());
+
+ delete iMsvOperation;
+ iMsvOperation = NULL;
+ iMsvOperation = iEntry->ChangeL(entry,iStatus);
+ SetActive();
+ }
+
+void CImAttachmentManager::ModifyAttachmentInfoL()
+ {
+ iStore->CommitL();
+ delete iStore;
+ iStore = NULL;
+ UpdateModifiedAttachmentInListL();
+ }
+
+TInt CImAttachmentManager::UniqueAttachmentId()
+ {
+ // Initialisation of iUniqueId is left to CBase (ie 0) id's start at 1 so pre-increment
+ return ++iUniqueId;
+ }
+