--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/email/mail/ViewerSrc/CMailForwardoperation.cpp Wed Sep 01 12:31:54 2010 +0100
@@ -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 <CMailMessage.h>
+#include <MsgMailViewer.rsg>
+#include <e32base.h>
+#include <mtmuibas.h>
+#include <mtmuidef.hrh>
+#include <mtmdef.h>
+#include <impicmds.h>
+#include <imapcmds.h>
+#include <MsgAttachmentInfo.h>
+#include <mmsvattachmentmanager.h>
+#include <MsvPrgReporter.h>
+#include <MuiuMsvSingleOpWatcher.h>
+
+// 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); index<attachmentManager.AttachmentCount(); ++index )
+ {
+ CMsvAttachment* info = attachmentManager.GetAttachmentInfoL( index );
+ CleanupStack::PushL( info );
+
+ if( !info->Complete() )
+ {
+ // 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