email/mail/ViewerSrc/CMailForwardoperation.cpp
branchRCL_3
changeset 27 7fdbb852d323
parent 0 72b543305e3a
--- /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