// Copyright (c) 2007-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:// CIMPLAINBODYTEXT.CPP//#include "MIUTMSG.H"#include "MIUTCONV.H"#include "MIUT_ERR.H"#include "CIMPLAINBODYTEXT.H"#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS #include "cimmessagepart.h" #include "cimconvertcharconv.h"#include "miut_errconsts.h"#endif#include <cmsvplainbodytext.h>/**NewL Factory method.@param aEmailMessage. The CImEmailMessage refernce corresponding to the message whose body text is being processed.@param aMsvEntry. The CMsvEntry correspoding to the message being processed.@param aEntryType. The TImEmailEntryType for the message.@param aChunkLength. The length of the chunk that will be stored/restored in a single operation.@param aWriteMode. Indicates whether CMsvStore needs to be opened in Read/Write mode. ETrue indicates Write mode. EFalse indicates Read mode.@return CImPlainBodyText.Pointer to CImPlainBodyText.*/ CImPlainBodyText* CImPlainBodyText::NewL(CImEmailMessage& aEmailMessage, CMsvEntry& aMsvEntry, CImEmailMessage::TImEmailEntryType aEntryType, TInt aChunkLength, TBool aWriteMode) { CImPlainBodyText* self = new (ELeave) CImPlainBodyText(aEmailMessage, aMsvEntry); CleanupStack::PushL(self); self->ConstructL(aChunkLength, aEntryType, aWriteMode); CleanupStack::Pop(); return self; }/**Constructor@param aEmailMessage. The CImEmailMessage refernce corresponding to the message whose body text is @param aMsvEntry. The CMsvEntry correspoding to the message being processed.@return None.*/CImPlainBodyText::CImPlainBodyText(CImEmailMessage& aEmailMessage, CMsvEntry& aMsvEntry): CMsgActive(EPriorityNormal), iEmailMessage(aEmailMessage), iMsvEntry(aMsvEntry) { }/**The 2nd Phase construction.*/ void CImPlainBodyText::ConstructL(TInt aChunkLength, CImEmailMessage::TImEmailEntryType aEntryType, TBool aWriteMode) { iMessageId = iMsvEntry.EntryId(); RArray<TMsvId> textIdArray; CleanupClosePushL (textIdArray); iEmailMessage.GetBodyTextEntryIdL(iMessageId, aEntryType); // A message may contain more than one text part. TInt count = iEmailMessage.Selection().Count(); for(TInt i=0;i<count;++i) { textIdArray.Append(iEmailMessage.Selection().At(i)); } TUint charset = 0; // Will contain the charset when GetCharacterSetL returns. TBool override = EFalse; // Will be set to ETrue if the existing charset was overidden. iEmailMessage.GetCharacterSetL(iMessageId,charset,override); if(aWriteMode) { RFs& fileSvrSession = iMsvEntry.Session().FileSession(); CCnvCharacterSetConverter* characterConverter = CCnvCharacterSetConverter::NewL(); CleanupStack::PushL(characterConverter); CImConvertCharconv* charConv = CImConvertCharconv::NewL(*characterConverter, fileSvrSession); CleanupStack::PushL(charConv); TUint defaultCharset = charConv->DefaultCharset(); CleanupStack::PopAndDestroy(2,characterConverter); // charConv, characterConverter iMsvEntry.SetEntryL(textIdArray[0]); iStore = iMsvEntry.EditStoreL(); // Body text is stored in MailStore as 16 bit so set iIs8Bit to EFalse. iPlainTextArray.Append(iStore->InitialisePlainBodyTextForWriteL(EFalse, charset, defaultCharset)); } else { TInt textIdCount = textIdArray.Count(); for(TInt i=0; i<textIdCount; ++i) { // Pointing to the text entry. iMsvEntry.SetEntryL(textIdArray[i]); CMsvStore* store = iMsvEntry.ReadStoreL(); CleanupStack::PushL(store); iPlainTextArray.Append( store->InitialisePlainBodyTextForReadL(aChunkLength)); // if the existing charset was overidden by calling CImEmailMessage::SetCharacterSetL if(override) { iPlainTextArray[i]->SetCharacterSetL(charset); } CleanupStack::PopAndDestroy(store); store = NULL; } } CleanupStack::PopAndDestroy(&textIdArray); CActiveScheduler::Add(this); }/**Destructor*/EXPORT_C CImPlainBodyText::~CImPlainBodyText() { delete iStoreMessagePart; iPlainTextArray.ResetAndDestroy(); iPlainTextArray.Close(); delete iStore; }/**Store the plain body text part in chunks.@param aChunk. The 8 bit chunk that is to be stored.@param aStatus. The TRequestStatus parameter for this request.@leave KErrAccessDenied. If CMsvStore was opened in Read mode or If CommitL is already called.@leave Other Standard system-wide error codes.@return void.*/EXPORT_C void CImPlainBodyText::StoreChunkL(const TDesC8& aChunk, TRequestStatus& aStatus) { iPlainTextArray[0]->StoreChunkL(aChunk, aStatus); }/**Store the plain body text part in chunks,synchronous version.@param aChunk. The 8 bit chunk that is to be stored.@leave KErrAccessDenied. If CMsvStore was opened in Read mode or If CommitL is already called.@leave Other Standard system-wide error codes.@return void.*/EXPORT_C void CImPlainBodyText::StoreChunkL(const TDesC8& aChunk) { iPlainTextArray[0]->StoreChunkL(aChunk); }/**Store the body part in chunks(16 bit version).@param aChunk The 16 bit chunk that is to be stored.@param aStatus The TRequestStatus parameter for this request.@leave KErrNotSupported If the 8-bit storage was enabled.@leave KErrAccessDenied If CMsvStore was opened in Read mode or IfCommitL is already called.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::StoreChunkL(const TDesC16& aChunk, TRequestStatus& aStatus) { iPlainTextArray[0]->StoreChunkL(aChunk, aStatus); }/**Store the body part in chunks(16 bit synchronous version).@param aChunk The 16 bit chunk that is to be stored.@leave KErrNotSupported If the 8-bit storage was enabled. @leave KErrAccessDenied If CMsvStore was opened in Read mode or If CommitL is already called.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::StoreChunkL(const TDesC16& aChunk) { iPlainTextArray[0]->StoreChunkL(aChunk); }/**Converts and stores the CRichText contents to a plain text.@param aRichText The CRichText object that will be stored as plain body text.@leave KErrNotSupported If the 8-bit storage was enabled.@leave KErrAccessDenied If CMsvStore was opened in Read mode or If CommitL is already called.@leave Other Standard system-wide error codes.@return void.*/EXPORT_C void CImPlainBodyText::StoreRichTextAsPlainTextL(CRichText& aRichText) { iPlainTextArray[0]->StoreRichTextAsPlainTextL(aRichText); }/**Retrieve the next chunk of the plain body text.@param aChunk The output parameter contains the requested chunk.@param aStatus. The TRequestStatus for this request.@leave KErrAccessDenied If CMsvStore was opened in Write mode.@leave KErrNotSupported If 16-bit storage is enabled.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::NextChunkL(TDes8& aChunk, TRequestStatus& aStatus) { __ASSERT_DEBUG(iChunkRetrievalState == EIdleState, gPanic(EImcmNonIdleRetrievalState)); iChunkRetrievalState = ENextChunk8Bit; iChunk8 = &aChunk; iChunk16 = NULL; iPlainTextArray[iIndex]->NextChunkL(aChunk, iStatus); SetActive(); Queue(aStatus); }/**Retrieve the next chunk of the plain body text.@param aChunk The output parameter contains the requested chunk.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrNotSupported If 16-bit storage is enabled.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::NextChunkL(TDes8& aChunk) { iPlainTextArray[iIndex]->NextChunkL(aChunk); // If there is more than one text part for the message move to next text part. if(aChunk.Length() == 0 && iIndex + 1 < iPlainTextArray.Count()) { iPlainTextArray[++iIndex]->NextChunkL(aChunk); } }/**Restore the plain body text into chunks.@param aChunk The output parameter contains the requested chunk on completion.@param aStatus The TRequestStatus parameter for this request.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::NextChunkL(TDes16& aChunk, TRequestStatus& aStatus) { __ASSERT_DEBUG(iChunkRetrievalState == EIdleState, gPanic(EImcmNonIdleRetrievalState)); iChunkRetrievalState = ENextChunk16Bit; iChunk16 = &aChunk; iChunk8 = NULL; iPlainTextArray[iIndex]->NextChunkL(aChunk, iStatus); SetActive(); Queue(aStatus); }/**Restores the plain body text into chunks.@param aChunk The output parameter contains the requested chunk on completion.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::NextChunkL(TDes16& aChunk) { iPlainTextArray[iIndex]->NextChunkL(aChunk); // If there is more than one text part for the message move to next text part. if(aChunk.Length() == 0 && iIndex + 1 < iPlainTextArray.Count()) { iPlainTextArray[++iIndex]->NextChunkL(aChunk); } }/**Retrieve the next chunk of the plain body text.@param aChunk The output parameter contains the requested chunk.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrNotSupported If 16-bit storage is enabled.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::PreviousChunkL(TDes8& aChunk, TRequestStatus& aStatus) { __ASSERT_DEBUG(iChunkRetrievalState == EIdleState, gPanic(EImcmNonIdleRetrievalState)); iChunkRetrievalState = EPreviousChunk8Bit; iChunk8 = &aChunk; iChunk16 = NULL; iPlainTextArray[iIndex]->PreviousChunkL(aChunk, iStatus); SetActive(); Queue(aStatus); }/**Retrieve the next chunk of the plain body text.@param aChunk The output parameter contains the requested chunk.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrNotSupported If 16-bit storage is enabled.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::PreviousChunkL(TDes8& aChunk) { iPlainTextArray[iIndex]->PreviousChunkL(aChunk); // If message had more than one text part move to previous text part. if(aChunk.Length() == 0 && iIndex - 1 >= 0) { iPlainTextArray[--iIndex]->PreviousChunkL(aChunk); } } /**Restore the plain body text into chunks.@param aChunk The output parameter contains the requested chunk on completion.@param aStatus The TRequestStatus parameter for this request.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::PreviousChunkL(TDes16& aChunk, TRequestStatus& aStatus) { __ASSERT_DEBUG(iChunkRetrievalState == EIdleState, gPanic(EImcmNonIdleRetrievalState)); iChunkRetrievalState = EPreviousChunk16Bit; iChunk16 = &aChunk; iChunk8 = NULL; iPlainTextArray[iIndex]->PreviousChunkL(aChunk, iStatus); SetActive(); Queue(aStatus); }/**Restore the plain body text into chunks.@param aChunk The output parameter contains the requested chunk on completion.@leave KErrNotSupported If CMsvStore was opened in Write mode.@leave KErrUnderflow If aChunk MaxLength is less than iChunkMaxLength.@leave Other Standard system-wide error codes.@return void*/EXPORT_C void CImPlainBodyText::PreviousChunkL(TDes16& aChunk) { iPlainTextArray[iIndex]->PreviousChunkL(aChunk); // If message had more than one text part move to previous text part. if(aChunk.Length() == 0 && iIndex - 1 >= 0) { iPlainTextArray[--iIndex]->PreviousChunkL(aChunk); } } void CImPlainBodyText::DoRunL() { __ASSERT_DEBUG(iChunkRetrievalState != EIdleState, gPanic(EImcmIdleRetrievalState)); TBool callComplete = ETrue; switch(iChunkRetrievalState) { // DoRunL is called as a result to a call to 8-bit asynchronous NextChunkL. case ENextChunk8Bit: { // Check if there are more than one body text part. if(iChunk8->Length() == 0 && iIndex + 1 < iPlainTextArray.Count()) { iPlainTextArray[++iIndex]->NextChunkL(*iChunk8, iStatus); SetActive(); callComplete = EFalse; } break; } case ENextChunk16Bit: { // Check if there are more than one body text part if(iChunk16->Length() == 0 && iIndex + 1 < iPlainTextArray.Count()) { iPlainTextArray[iIndex]->NextChunkL(*iChunk16, iStatus); SetActive(); callComplete = EFalse; } break; } case EPreviousChunk8Bit: { // DoRunL is called as a result to a call to 8-bit asynchronous PreviousChunkL. if(iChunk8->Length() == 0 && iIndex - 1 >= 0) { iPlainTextArray[--iIndex]->NextChunkL(*iChunk8, iStatus); SetActive(); callComplete = EFalse; } break; } case EPreviousChunk16Bit: { if(iChunk16->Length() == 0 && iIndex - 1 >= 0) { iPlainTextArray[--iIndex]->PreviousChunkL(*iChunk16, iStatus); SetActive(); callComplete = EFalse; } break; } default: { __ASSERT_DEBUG(iChunkRetrievalState != EIdleState, gPanic(EImcmIdleRetrievalState)); break; } } if(callComplete) { Complete(iStatus.Int()); iChunkRetrievalState = EIdleState; } }/**Commits the email message after it has been completed.@param aStatus The TRequestStatus parameter for this request.@return void*/EXPORT_C void CImPlainBodyText::CommitL(TRequestStatus& aStatus) { iPlainTextArray[0]->CommitL(); delete iStore; iStore = NULL; iStoreMessagePart = CImStoreMessagePart::StorePlainBodyTextL(aStatus, iMsvEntry, iMessageId); }/**Commits the email message after it has been completed along with mime header for this message.@param aStatus The TRequestStatus parameter for this request.@param aMimeHeader The CMimeHeader for this message.@return void*/EXPORT_C void CImPlainBodyText::CommitL(TRequestStatus& aStatus, CImMimeHeader& aMimeHeader) { // Commit the file.This will close the plainbody text file. iPlainTextArray[0]->CommitL(); delete iStore; iStore = NULL; iStoreMessagePart = CImStoreMessagePart::StorePlainBodyTextL(aStatus, iMsvEntry, iMessageId, aMimeHeader); }/**Cancels the relavent CMsvPlainBodyText object*/ void CImPlainBodyText::DoCancel() { iPlainTextArray[iIndex]->Cancel(); }