diff -r 000000000000 -r 72b543305e3a email/mail/ViewerSrc/CMailForwardoperation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/mail/ViewerSrc/CMailForwardoperation.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,509 @@ +/* +* Copyright (c) 2002-2006 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: Mail forward operation +* +*/ + +// INCLUDE FILES +#include "CMailForwardOperation.h" +#include "MsgMailViewerDocument.h" +#include "MailLog.h" +#include "MailUtils.h" +#include "MsgMailDRMHandler.h" +#include "cmailwaitoperation.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// CONSTANTS +enum TOperationState + { + ESuspendOperation = 1, + ELoadAttachments, + EGetAttachments, + EConnectToService, + EUpdateEntryFlags, + EForwardMessage + }; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::CMailForwardOperation +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CMailForwardOperation::CMailForwardOperation( + CMsgMailViewerDocument& aDocument, + TRequestStatus& aObserverRequestStatus ): + CMailOperation( aDocument.Session(), + CActive::EPriorityStandard, + aObserverRequestStatus ), + iDocument( aDocument ), + iOperationState( KErrArgument ) + { + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +inline void CMailForwardOperation::ConstructL() + { + iSelection = new(ELeave) CMsvEntrySelection; + iMtm = iDocument.Mtm().Type(); + // Issue first step + NexStateL(); + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CMailForwardOperation* CMailForwardOperation::NewL( + MMsvProgressReporter& aReporter, + CMsgMailViewerDocument& aDocument, + TRequestStatus& aObserverRequestStatus, + TBool aSetSuspend ) + { + CMailForwardOperation* self = new( ELeave ) CMailForwardOperation( + aDocument, + aObserverRequestStatus ); + + CleanupStack::PushL( self ); + self->iReporter = &aReporter; + self->iOperationState = aSetSuspend ? ESuspendOperation : ELoadAttachments; + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// Destructor +CMailForwardOperation::~CMailForwardOperation() + { + LOG("CMailForwardOperation::~CMailForwardOperation"); + Cancel(); + delete iOperation; + delete iSelection; + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::SuspendL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::SuspendL( TBool aSetSuspend ) + { + LOG1("CMailForwardOperation::SuspendL:%d", aSetSuspend); + if ( aSetSuspend ) + { + ASSERT( iOperation == NULL ); + iOperation = CMailWaitOperation::NewL( + iDocument.Session(), + iStatus ); + LOG1("CMailForwardOperation::SuspendL::%08x", + iOperation); + SetActive(); + iOperationState = ESuspendOperation; + } + else + { + if ( iOperationState == ESuspendOperation ) + { + delete iOperation; + iOperation = NULL; + iOperationState = ELoadAttachments; + } + } + } + +// ----------------------------------------------------------------------------- +// Called when UI gets Operation completed notification +// ----------------------------------------------------------------------------- +// +TBool CMailForwardOperation::CompletedL( TInt /*aCompletionCode*/ ) + { + TBool ret(ETrue); + /* if ( aCompletionCode == KErrCancel && + (iOperationState == ESuspendOperation || + iOperationState == EGetAttachments || + iOperationState == EConnectToService ) ) + { + LOG("CMailForwardOperation::CompletedL - continue"); + // Let's forward what we can + iOperationState = EUpdateEntryFlags; + NexStateL(); + ret = EFalse; + }*/ + return ret; + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::ProgressL +// ----------------------------------------------------------------------------- +// +const TDesC8& CMailForwardOperation::ProgressL() + { + LOG("CMailForwardOperation::ProgressL"); + // Used CMsvProgressReporterOperation is set to display only wait bar. + // --> So there is no need to resolve the progress + return KNullDesC8(); + } +// ----------------------------------------------------------------------------- +// CMailForwardOperation::DoCancel +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::DoCancel() + { + LOG1("CMailForwardOperation::DoCancel iOperationState:%d", + iOperationState); + LOG1("CMailForwardOperation::DoCancel iOperation::%08x", + iOperation); + if ( iOperation ) + { + iOperation->Cancel(); + } + + if( iOperationState == EGetAttachments ) + { // Actually we are still LOADING attachments in this case, but this + // state machine has been implemented so that iOperationState has + // already been incremented... + LOG("CMailForwardOperation::DoCancel, Canceling attachment loading"); + iDocument.MailMessage().Cancel(); + // Note: Canceling CMailMessage::LoadAttachmentsL() does not cancel + // our own pending request or even notify us, so we must do it manually + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + } + + // Complete observer + CompleteObserver( iStatus.Int() ); + } +// ----------------------------------------------------------------------------- +// CMailForwardOperation::RunL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::RunL() + { + LOG1("CMailForwardOperation::RunL iStatus:%d", iStatus.Int()); + + if ( iStatus.Int() != KErrNone || !NexStateL() ) + { + CompleteObserver( iStatus.Int() ); + // Deque(); + } + } +// ----------------------------------------------------------------------------- +// CMailForwardOperation::RunError +// ----------------------------------------------------------------------------- +// +TInt CMailForwardOperation::RunError( TInt aError ) + { + LOG1("CMailForwardOperation::RunError aError:%d", aError); + CompleteObserver( aError ); + return KErrNone; // must return KErrNone to active sheduler + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::MessageLoadingL +// From +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::MessageLoadingL( + TInt aStatus, CMailMessage& /*aMessage*/) + { + if( aStatus == CMailMessage::EAttachmentsReady ) + { + // next state + LOG("CMailForwardOperation::MessageLoadingL"); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + } +// ----------------------------------------------------------------------------- +// CMailForwardOperation::CompleteObserver +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::CompleteObserver( TInt aStatus ) + { + TRequestStatus* status = &iObserverRequestStatus; + User::RequestComplete( status, aStatus ); + } + + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::ConnectToServiceL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::ConnectToServiceL() + { + LOG("CMailForwardOperation::ConnectToServiceL"); + // connect to service + TBuf8<1> param; + + // set context to imap service + TMsvId imapservice = iDocument.Mtm().Entry().OwningService(); + iDocument.Mtm().SwitchCurrentEntryL( imapservice ); + + if ( !iDocument.Mtm().Entry().Entry().Connected() ) + { + CMsvEntrySelection* imapbox = new(ELeave) CMsvEntrySelection; + CleanupStack::PushL(imapbox); + imapbox->AppendL( imapservice ); + ASSERT( iOperation == NULL ); + + iOperation = + iDocument.MtmUi().InvokeAsyncFunctionL( + KIMAP4MTMConnect, *imapbox, iStatus, param ); + LOG1("CMailForwardOperation::ConnectToServiceL::%08x", + iOperation); + CleanupStack::PopAndDestroy( imapbox ); + SetActive(); + } + else + { + // We are online, start fetch + ASSERT( iSelection ); + FetchAttachmentsL( *iSelection ); + } + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::CheckAttachmentsL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::CheckAttachmentsL() + { + MMsvAttachmentManager& attachmentManager = + iDocument.MailMessage().AttachmentManager(); + LOG1("CMailForwardOperation::CheckAttachmentsL attachmentCount:%d", + attachmentManager.AttachmentCount()); + + TInt maxSize(0); + // attachment count not static + for( TInt index(0); indexComplete() ) + { + // if not fetched, append to the list + iSelection->AppendL( info->Id() ); + // check if this is 1st or largest unfetched attachment + if ( info->Size() > maxSize ) + { + maxSize = info->Size(); + } + } + CleanupStack::PopAndDestroy( info ); + } + + FetchAttachmentsL( *iSelection, maxSize ); + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::LoadAttachmentsL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::LoadAttachmentsL() + { + iDocument.MailMessage().LoadAttachmentsL( *this ); + iStatus = KRequestPending; + SetActive(); + } +// ----------------------------------------------------------------------------- +// CMailForwardOperation::ForwardMessageL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::ForwardMessageL() + { + LOG("CMailForwardOperation::ForwardMessageL"); + + iOperationState = EForwardMessage; + TMsvId msgId = iDocument.MailMessage().MessageEntry().Id(); + TMsvPartList parts = + KMsvMessagePartBody | + KMsvMessagePartDescription | + KMsvMessagePartAttachments; + iDocument.SetEntryWithoutNotificationL( msgId ); + CBaseMtmUi& mtmUi = iDocument.MtmUi(); + + mtmUi.SetPreferences( + mtmUi.Preferences() | + EMtmUiFlagEditorPreferEmbedded ); + // Set context to message + iDocument.Mtm().SwitchCurrentEntryL( msgId ); + iDocument.Mtm().Entry().Entry(); + + // hide the progress note + iReporter->MakeProgressVisibleL( EFalse ); + + ASSERT( iOperation == NULL ); + iOperation = mtmUi.ForwardL( + iDocument.DefaultMsgFolder(), + parts, + iStatus ); + LOG1("CMailForwardOperation::ForwardMessageL::%08x", + iOperation); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CMailForwardOperation::UpdateEntryFlagsL +// ----------------------------------------------------------------------------- +// +void CMailForwardOperation::UpdateEntryFlagsL() + { + LOG("CMailForwardOperation::UpdateEntryFlagsL"); + TMsvId msgID = iDocument.MailMessage().MessageEntry().Id(); + iDocument.Mtm().SwitchCurrentEntryL( msgID ); + + TMsvEntry msgEntry = iDocument.Mtm().Entry().Entry(); + ASSERT( msgEntry.iType == KUidMsvMessageEntry ); + msgEntry.SetComplete( ETrue ); + + ASSERT( iOperation == NULL ); + iOperation = iDocument.Mtm().Entry().ChangeL( + msgEntry, + iStatus ); + LOG1("CMailForwardOperation::UpdateEntryFlagsL::%08x", + iOperation); + iOperationState = EUpdateEntryFlags; + SetActive(); + } + +// ------------------------------------------------------------------------------ +// CMailForwardOperation::FetchAttachmentsL() +// ------------------------------------------------------------------------------ +// +void CMailForwardOperation::FetchAttachmentsL( + CMsvEntrySelection& aSelection, TInt aMaxSize) + { + LOG1("CMailForwardOperation::FetchAttachmentsL aMaxSize:%d", aMaxSize); + // if some files are not on device, fetch them + if ( aSelection.Count() ) + { + TInt status( MailUtils::EQueryForward ); + if ( !iDocument.IsOnLineL() ) + { + status |= MailUtils::EConnectionOffline; + } + // check if large attachment is not fetched and if user + // wants to fetch it + if ( MailUtils::LargeAttachmentQueryL( aMaxSize, status ) ) + { + ConnectToServiceL(); + } + else + { + // User does not want to fetch, let's just forward the message. + // After this entry completed flag is updated incorrectly, but + // that should not cause any problems. If completed flag is not set + // forward operation tries to make connection to mailbox. + UpdateEntryFlagsL(); + } + } + else + { + // Attachments are fetched, make sure entry flag is updated + UpdateEntryFlagsL(); + } + + } + +// ------------------------------------------------------------------------------ +// CMailForwardOperation::FetchAttachmentsL() +// ------------------------------------------------------------------------------ +// +void CMailForwardOperation::FetchAttachmentsL( + CMsvEntrySelection& aSelection ) + { + TBuf8<1> param; + // Do actual fetch operation + ASSERT( iOperation == NULL ); + iOperation = iDocument.Mtm().InvokeAsyncFunctionL( + KIMAP4MTMPopulate, aSelection, param, iStatus ); + LOG1("CMailForwardOperation::FetchAttachmentsL::%08x", + iOperation); + SetActive(); + } + +// ------------------------------------------------------------------------------ +// void CMailForwardOperation::NexStateL() +// ------------------------------------------------------------------------------ +// +TBool CMailForwardOperation::NexStateL() + { + // Reset previous operation + delete iOperation; + iOperation = NULL; + + TBool valid( ETrue ); + switch( iOperationState ) + { + case ESuspendOperation: + SuspendL( ETrue ); + break; + + case ELoadAttachments: + LoadAttachmentsL(); + iOperationState++; + break; + + case EGetAttachments: + CheckAttachmentsL(); + iOperationState++; + break; + + case EConnectToService: + // Now we are online let's fetch 'em + FetchAttachmentsL( *iSelection ); + iOperationState++; + break; + + case EUpdateEntryFlags: + // Now we are ready to forward + // Attachment model is not updated, but that's not a problem? + UpdateEntryFlagsL(); + iOperationState++; + break; + + case EForwardMessage: + ForwardMessageL(); + iOperationState++; + break; + default: + LOG("CMailForwardOperation::NexStateL - all done"); + valid = EFalse; + break; + }; + + return valid; + } + +// End of File