email/pop3andsmtpmtm/clientmtms/src/cimattachmentmanager.cpp
changeset 0 72b543305e3a
--- /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;
+	}
+