diff -r 000000000000 -r 72b543305e3a email/mail/UtilsSrc/MsgMailDocument.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/mail/UtilsSrc/MsgMailDocument.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,643 @@ +/* +* Copyright (c) 2002 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: Base class for document classes of the +* mail viewer and editor applications +* +*/ + + +// INCLUDE FILES +#include "MailLog.h" +#include "MailUtils.h" +#include // KMsvEmailTypeListXX enums +#include // CIMHeader +#include // CImEmailMessage +#include // Smtp Settings +#include // launch parameter constants +#include // CAknInputBlock +#include // CMuiuOperationWait +#include // MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL +#include // TImEmailTransformingInfo +#include +#include +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif + +#include +#include "MsgMailDocument.h" // header +#include "MsgMailPreferences.h" // Message preferences +#include +#include + + +// ================= MEMBER FUNCTIONS ======================= + +// ---------------------------------------------------------------------------- +// C++ default constructor cannot contain any code that might leave. +// ---------------------------------------------------------------------------- +// +EXPORT_C CMsgMailDocument::CMsgMailDocument(CEikApplication& aApp) + : CMsgEditorDocument(aApp), iMessage(NULL), iHeader(NULL), + iIdle(NULL) + { + } + + +// Destructor +EXPORT_C CMsgMailDocument::~CMsgMailDocument() + { + iApaSession.Close(); + delete iHeader; + delete iMessage; + delete iMessageCEntry; + delete iIdle; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::EntryChangedL() +// Called after entry is changed by SetEntry Function. Deletes current +// header and body and reads the new ones from message store. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CMsgMailDocument::EntryChangedL() + { + delete iHeader; + delete iMessage; + delete iMessageCEntry; + iHeader = NULL; + iMessage = NULL; + iMessageCEntry = NULL; + + iHeader = CImHeader::NewLC(); + CleanupStack::Pop(); + //CMsvEntry& messageEntry = CurrentEntry(); + iMessageID = CurrentEntry().EntryId(); + LOG1("CMsgMailDocument::EntryChangedL %08x", iMessageID); + iMessageCEntry = CurrentEntry().Session().GetEntryL( + iMessageID); + iMessage = CImEmailMessage::NewL(*iMessageCEntry); + if (iMessageCEntry->HasStoreL()) + { + CMsvStore* msvStore = iMessageCEntry->ReadStoreL(); + CleanupStack::PushL(msvStore); + TRAP_IGNORE(iHeader->RestoreL(*msvStore)); + // get body encoding + if (msvStore->IsPresentL( KUidMsgFileTransformingInfo)) + { + TImEmailTransformingInfo info; + // use defaults if fails + TRAP_IGNORE(info.RestoreL(*msvStore)); + TUid charset; + charset.iUid = info.BodyTextCharset(); + SendOptions().SetSendingCharacterSet(charset); + } + CleanupStack::PopAndDestroy(); // store + } + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::CreateReplyL() +// ---------------------------------------------------------------------------- +// +EXPORT_C CMsvOperation* CMsgMailDocument::CreateReplyL( + TMsvId aDest, TMsvPartList aParts, TRequestStatus& aStatus) + { + LOG1("CMsgMailDocument::CreateReplyL %08x", + CurrentEntry().Entry().Id() ); + + CImEmailMessage* mailMessage = CImEmailMessage::NewLC( CurrentEntry() ); + + TBool plainHTMLEntry = IsPlainHTMLMessageL( mailMessage ); + HBufC* attachmentNames = GetAttachmentNamesFromMessageL( mailMessage ); + CleanupStack::PopAndDestroy( mailMessage ); + CleanupStack::PushL( attachmentNames ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + CMsvOperation* oper = Mtm().ReplyL( aDest, aParts, wait->iStatus ); + wait->Start(); + TInt status( wait->iStatus.Int() ); + CleanupStack::PopAndDestroy( wait ); + + TMsvId replyMessage = GetOperId( *oper ); + CleanupStack::PushL( oper ); + SetEntryWithoutNotificationL( replyMessage ); + + AddAttachmentNamesToMessageBodyL( *attachmentNames ); + CleanupStack::Pop( oper ); + CleanupStack::PopAndDestroy( attachmentNames ); // attachmentNames + + TRequestStatus* myStatus=&aStatus; + User::RequestComplete( myStatus, status ); + + if(plainHTMLEntry) + { + //Create Idle object so we can show note + //after options menu is closed and editor is opened. + + iIdle = CIdle::NewL(CActive::EPriorityStandard); + + iShowNoteCallBack = TCallBack( ShowHtmlNoteCallBackL, this ); + + iIdle->Start(iShowNoteCallBack); // CSI: 10 # + } + + return oper; + } + + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::ShowHtmlNoteCallBackL() +// ---------------------------------------------------------------------------- +// +TInt CMsgMailDocument::ShowHtmlNoteCallBackL( TAny* /*aCaller*/ ) // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + { + MailUtils::InformationNoteL( R_QTN_MAIL_INFO_HTML_ATTACH ); + return 0; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::CreateForwardL() +// ---------------------------------------------------------------------------- +// +EXPORT_C CMsvOperation* CMsgMailDocument::CreateForwardL( + TMsvId aDest, TMsvPartList aParts, TRequestStatus& aStatus ) + { + LOG1("CMsgMailDocument::CreateForwardL %08x", + CurrentEntry().Entry().Id() ); + CImEmailMessage* mailMessage = CImEmailMessage::NewLC( CurrentEntry() ); + + if(IsPlainHTMLMessageL( mailMessage )) + { + MailUtils::InformationNoteL( R_QTN_MAIL_INFO_HTML_ATTACH ); + } + + CleanupStack::PopAndDestroy( mailMessage ); + + return CMsgEditorDocument::CreateForwardL( aDest, aParts, aStatus ); + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::TMsvEMailEntryL() +// ---------------------------------------------------------------------------- +// +EXPORT_C const TMsvEmailEntry& CMsgMailDocument::TMsvEMailEntryL() + { + // context might be wrong + iMessageCEntry->SetEntryL(iMessageID); + + return static_cast (CMsgEditorDocument::Entry()); + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::MessageL() +// ---------------------------------------------------------------------------- +// +EXPORT_C CImEmailMessage& CMsgMailDocument::MessageL() + { + // context might be wrong + iMessageCEntry->SetEntryL(iMessageID); + return *iMessage; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::CreateNewL() +// ---------------------------------------------------------------------------- +// +EXPORT_C TMsvId CMsgMailDocument::CreateNewL(TMsvId aServiceType, + TMsvId aTarget, TInt /*aTypeList*/, TUid aMtm) + { + // Check that we're not under critical level + DiskSpaceBelowCriticalLevelL( 0 ); + CAknInputBlock::NewLC(); + // Set context to target + TMsvEntry serviceTEntry; + TMsvId serviceID; + + TInt error = Session().GetEntry(aServiceType, serviceID, serviceTEntry); + // if fails use default service (SMTP) + if (error == KErrNone) + { + aMtm = serviceTEntry.iMtm; + } + PrepareMtmL(aMtm); + Mtm().SwitchCurrentEntryL(aTarget); + Mtm().CreateMessageL(aServiceType); + CMsvEntry& newEntry = Mtm().Entry(); + + TMsvId newId = newEntry.EntryId(); + CleanupStack::PopAndDestroy(); // CAknInputBlock + + return newId; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::CreateNewEntryL() +// ---------------------------------------------------------------------------- +// +TMsvId CMsgMailDocument::CreateNewEntryL( TMsvEmailEntry& aEntry ) + { + CImHeader& header = HeaderL(); + CDesCArrayFlat* toArray = new(ELeave) CDesCArrayFlat(3); // CSI: 47 # + CleanupStack::PushL(toArray); + CDesCArrayFlat* ccArray = new(ELeave) CDesCArrayFlat(3); // CSI: 47 # + CleanupStack::PushL(ccArray); + + const TInt toCount(header.ToRecipients().Count()); + TInt i(0); + for (; i < toCount; i++) + { + toArray->AppendL(header.ToRecipients()[i]); + } + const TInt ccCount(header.CcRecipients().Count()); + for (i=0; i < ccCount; i++) + { + ccArray->AppendL(header.CcRecipients()[i]); + } + + // we'll preserve all data from original message + const TMsvId serviceId(aEntry.iServiceId); + const TMsvId relatedId(aEntry.iRelatedId); + const TUid type(aEntry.iType); + const TUid mtm(aEntry.iMtm); + const TInt32 mtmData1(aEntry.iMtmData1); + const TInt32 mtmData2(aEntry.iMtmData2); + const TTime time(aEntry.iDate); + + TMsvEmailTypeList msvEmailTypeList(KMsvEmailTypeListMessageInPreparation); + TMsvId newMessageId( CreateNewL(serviceId, + DefaultMsgFolder(), msvEmailTypeList, mtm) ); + + CMsvEntry* centry = CMsvEntry::NewL( Session(), + newMessageId, TMsvSelectionOrdering() ); + CleanupStack::PushL(centry); + aEntry = centry->Entry(); + aEntry.iServiceId = serviceId; + aEntry.iRelatedId = relatedId; + aEntry.iType = type; + aEntry.iMtm = mtm; + aEntry.iMtmData1 = mtmData1; + aEntry.iMtmData2 = mtmData2; + aEntry.SetMHTMLEmail(EFalse); // make sure that old flag is not copied + aEntry.SetBodyTextComplete(ETrue); + aEntry.SetComplete(ETrue); + aEntry.SetInPreparation(aEntry.InPreparation()); + // set visible if not in preparation state + aEntry.SetVisible(!aEntry.InPreparation()); + aEntry.iDate = time; + centry->ChangeL(aEntry); + CleanupStack::PopAndDestroy(); // centry + SetEntryL(newMessageId); + + aEntry = Entry(); + CImHeader& newHeader = HeaderL(); + + for (i=0; i < toCount; i++) + { + newHeader.ToRecipients().AppendL((*toArray)[i]); // CSI: 2 # No need to check because of the i goes from 0 to toCount. + } + for (i=0; i < ccCount; i++) + { + newHeader.CcRecipients().AppendL((*ccArray)[i]); // CSI: 2 # No need to check because of the i goes from 0 to ccCount. + } + CleanupStack::PopAndDestroy(2); // CSI: 47 # toArray, ccArray + + return newMessageId; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::SaveHeaderToStoreL() +// ---------------------------------------------------------------------------- +// +void CMsgMailDocument::SaveHeaderToStoreL() + { + ASSERT( iMessageID == CurrentEntry().Entry().Id() ); + + // get store for the message + CMsvStore* store = CurrentEntry().EditStoreL(); + CleanupStack::PushL(store); + + // set header and body encoding + TImEmailTransformingInfo info; + info.SetToDefault(ESendAsMimeEmail); + TUint charset = SendOptions().SendingCharacterSet().iUid; + info.SetHeaderAndBodyCharset( charset ); + + info.StoreL(*store); + // store message header + iHeader->StoreL(*store); + store->CommitL(); + CleanupStack::PopAndDestroy(); // store + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::IsSyncMLMail() +// @deprecated +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMsgMailDocument::IsSyncMLMail() + { + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CMsgMailDocument::ResolveMimeType +// ---------------------------------------------------------------------------- +EXPORT_C TDataType CMsgMailDocument::ResolveMimeType( RFile aFile ) + { + LOG(">CMsgMailDocument::ResolveMimeType"); + TDataType dataType; + if ( aFile.SubSessionHandle() ) + { + TUid appUid( KNullUid ); + TInt error(0); + + if (!iApaSession.Handle()) + { + error = iApaSession.Connect(); + } + if ( error == KErrNone ) + { + TDataRecognitionResult recognitionResult; + + error = iApaSession.RecognizeData(aFile, recognitionResult); + if(recognitionResult.iConfidence != CApaDataRecognizerType::ENotRecognized && + error == KErrNone) + { + dataType = recognitionResult.iDataType; + } + else + { + LOG1("CMsgMailDocument::ResolveMimeTypeL error:%d or not ENotRecognized", + error); + } + } + + } + LOG("= EIndexLast ) + { + return KErrOverflow; + } + + switch(aMessageType) + { + case EIndexAddHeaders: + { + iPrefs->SetAdditionalHeaders(aAmount); + break; + } + default: + { + break; + } + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::SetReceivedRealL() +// ----------------------------------------------------------------------------- +// +TInt CMsgMailDocument::SetReceivedRealL( // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + const TUint aMessageType, const TReal /*aValue*/ ) + { + // Check that the index has correct value + if( aMessageType >= EIndexLast ) + { + return KErrOverflow; + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::SetReceivedBinaryL() +// ----------------------------------------------------------------------------- +// +TInt CMsgMailDocument::SetReceivedBinaryL( // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + const TUint aMessageType, const TDesC8 /*aValue*/ ) + { + // Check that the index has correct value + if( aMessageType >= EIndexLast ) + { + return KErrOverflow; + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::SetReceivedStringL() +// ----------------------------------------------------------------------------- +// +TInt CMsgMailDocument::SetReceivedStringL( // CSI: 40 # We must return + // the integer value although this + // is a leaving method. + const TUint aMessageType, const TDesC16 /*aValue*/) + { + // Check that the index has correct value + if( aMessageType >= EIndexLast ) + { + return KErrOverflow; + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::DiskSpaceBelowCriticalLevelL() +// ----------------------------------------------------------------------------- +// +TBool CMsgMailDocument::DiskSpaceBelowCriticalLevelL( TInt aBytesToWrite ) + { + // Check that we're not under critical level + if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL( + Session(), aBytesToWrite) ) + { + User::Leave(KErrDiskFull); + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::AddAttachmentNamesToMessageBodyL() +// ----------------------------------------------------------------------------- +// +void CMsgMailDocument::AddAttachmentNamesToMessageBodyL( const TDesC& aString ) + { + if ( aString.Length() ) + { + CImEmailMessage* mailMessage = CImEmailMessage::NewLC( CurrentEntry() ); + const TMsvId messageId = CurrentEntry().Entry().Id(); + + CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL(); + CleanupStack::PushL( globalParaLayer ); + CCharFormatLayer* globalCharLayer = CCharFormatLayer::NewL(); + CleanupStack::PushL( globalCharLayer ); + + CRichText* bodyText = CRichText::NewL( + globalParaLayer, + globalCharLayer); + CleanupStack::PushL( bodyText ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + mailMessage->GetBodyTextL( + wait->iStatus, + messageId, + CImEmailMessage::EThisMessageOnly, + *bodyText, + *globalParaLayer, + *globalCharLayer ); + + wait->Start(); + User::LeaveIfError( wait->iStatus.Int() ); + + CleanupStack::PopAndDestroy(); // wait + + // Add the file name into the body + bodyText->InsertL( bodyText->DocumentLength(), aString); + + wait = CMuiuOperationWait::NewLC(); + mailMessage->StoreBodyTextL( messageId, *bodyText, wait->iStatus ); + wait->Start(); + User::LeaveIfError( wait->iStatus.Int() ); + // wait, globalParaLayer, globalCharLayer, bodyText + CleanupStack::PopAndDestroy(5, mailMessage); // CSI: 47 # See a comment above. + } + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::GetAttachmentNamesFromMessageL() +// ----------------------------------------------------------------------------- +// +HBufC* CMsgMailDocument::GetAttachmentNamesFromMessageL( + CImEmailMessage* aMailMessage ) + { + ASSERT( aMailMessage ); + + const TMsvId messageId = CurrentEntry().Entry().Id(); + aMailMessage->GetAttachmentsListL( + messageId, + CImEmailMessage::EAllAttachments, + CImEmailMessage::EThisMessageOnly ); + MMsvAttachmentManager& attachmentManager = + aMailMessage->AttachmentManager(); + + HBufC* namesString = KNullDesC().AllocLC(); + TInt count( attachmentManager.AttachmentCount() ); + for ( TInt index(0); index < count; ++index ) + { + CMsvAttachment* info = + attachmentManager.GetAttachmentInfoL( index ); + CleanupStack::PushL( info ); + + // <> + HBufC* filename = StringLoader::LoadLC( + R_MAIL_REPLYATTA, info->AttachmentName() ); + + namesString = namesString->ReAllocL( + namesString->Length() + + filename->Length() + 1 ); // +1 for linebreak + + TPtr ptr = namesString->Des(); + ptr.Append( CEditableText::ELineBreak ); + ptr.Append( *filename ); + + CleanupStack::PopAndDestroy(2); // CSI: 47 # info, filename + + // refresh namesString pointer on stack + CleanupStack::Pop(); // namesString + CleanupStack::PushL( namesString ); + } + + SetEntryWithoutNotificationL( messageId ); + CleanupStack::Pop(); // namesString + return namesString; + } + +// ----------------------------------------------------------------------------- +// CMsgMailDocument::IsPlainHTMLMessageL() +// ----------------------------------------------------------------------------- +// +TBool CMsgMailDocument::IsPlainHTMLMessageL( + CImEmailMessage* aMailMessage ) + { + ASSERT( aMailMessage ); + + TBool retVal = EFalse; + + TMsvEmailEntry mailEntry( CurrentEntry().Entry() ); + if ( mailEntry.MHTMLEmail() ) + { + CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL(); + CleanupStack::PushL( globalParaLayer ); + CCharFormatLayer* globalCharLayer = CCharFormatLayer::NewL(); + CleanupStack::PushL( globalCharLayer ); + + CRichText* bodyText = CRichText::NewL( + globalParaLayer, + globalCharLayer); + CleanupStack::PushL( bodyText ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + aMailMessage->GetBodyTextL( + wait->iStatus, + mailEntry.Id(), + CImEmailMessage::EThisMessageOnly, + *bodyText, + *globalParaLayer, + *globalCharLayer ); + + wait->Start(); + CleanupStack::PopAndDestroy( wait ); + + + + if ( !bodyText->DocumentLength() ) + { + retVal = ETrue; + } + else + { + retVal = EFalse; + } + + // 3 globalParaLayer, globalCharLayer, bodyText + CleanupStack::PopAndDestroy( 3 ); // CSI: 47 # See a comment above. + } + + return retVal; + } + +// End of File +