--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncscomposeview.cpp Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,3516 @@
+/*
+* Copyright (c) 2007 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 : Compose view class
+*
+*/
+
+// INCLUDE FILES
+#include "emailtrace.h"
+#include <aknnotewrappers.h>
+#include <NpdApi.h>
+#include <StringLoader.h>
+#include <txtrich.h>
+#include <AknWaitDialog.h>
+#include <MsgAttachmentUtils.h>
+#include <featmgr.h>
+#include "cfsmailbox.h"
+#include "cfsmailmessage.h"
+#include "cfsmailaddress.h"
+#include "cfsmailclient.h"
+#include "cfsmailcommon.h"
+#include <csxhelp/cmail.hlp.hrh>
+#include <akntoolbar.h>
+#include <akntoolbarextension.h>
+#include <AknUtils.h>
+#include <FreestyleEmailUi.rsg>
+#include <freestyleemailui.mbg>
+#include <aknstyluspopupmenu.h>
+
+#include <wlaninternalpskeys.h>
+#include "ncscomposeview.h"
+#include "ncscomposeviewcontainer.h"
+#include "ncsconstants.h"
+#include "ncsutility.h"
+#include "ncsemailaddressobject.h"
+#include "freestyleemailcenrephandler.h"
+#include "FreestyleEmailUi.hrh"
+#include "FreestyleEmailUiConstants.h"
+#include "FreestyleEmailUiSendAttachmentsListControl.h"
+#include "FreestyleEmailUiSendAttachmentsListVisualiser.h"
+#include "FreestyleEmailUiSendAttachmentsListModel.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "FreestyleEmailUiConstants.h"
+#include "FSAutoSaver.h"
+#include "FSEmail.pan"
+#include "cmailmessageext.h"
+
+
+// line separators that should not appear in Subject
+_LIT(KLineSeparators, "\u2029");
+const TChar KReplacementChar = ' ';
+
+
+#pragma mark +++COMPOSE VIEW - CONSTRUCTORS AND DESTRUCTORS
+
+// -----------------------------------------------------------------------------
+// Safe pointer deletion
+//
+// -----------------------------------------------------------------------------
+//
+template <class T> void SafeDelete( T*& aPtr )
+ {
+ delete aPtr;
+ aPtr = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::CNcsComposeView()
+// C++ default constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CNcsComposeView::CNcsComposeView( CFreestyleEmailUiAppUi& aAppUi,
+ CAlfEnv& aEnv, CAlfControlGroup& aSendAttachmentControlGroup,
+ CFSMailClient& aMailClient, CMsvSession& aMsvSession )
+ : CFsEmailUiViewBase( aSendAttachmentControlGroup, aAppUi ),
+ iMailClient( aMailClient ), iOrigMessage( NULL ), iNewMessage( NULL ),
+ iMsvSession( aMsvSession ), iEnv( aEnv ),
+ iFakeSyncGoingOn(EFalse), iFetchDialogCancelled(EFalse),
+ iExecutingDoExitL( EFalse ),
+ iMessageTextPartModified( EFalse ), iMessageModified( EFalse )
+ {
+ FUNC_LOG;
+
+ iAttachmentListSaveDraft = EFalse;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CNcsComposeView* CNcsComposeView::NewL(
+ CFSMailClient& aMailClient, CAlfEnv& aEnv,
+ CFreestyleEmailUiAppUi* aAppUi, CAlfControlGroup& aControlGroup,
+ CMsvSession& aMsvSession )
+ {
+ FUNC_LOG;
+
+ CNcsComposeView* self =
+ CNcsComposeView::NewLC( aMailClient, aEnv, aAppUi,
+ aControlGroup, aMsvSession );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::NewLC()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CNcsComposeView* CNcsComposeView::NewLC(
+ CFSMailClient& aMailClient,
+ CAlfEnv& aEnv,
+ CFreestyleEmailUiAppUi* aAppUi,
+ CAlfControlGroup& aControlGroup,
+ CMsvSession& aMsvSession )
+ {
+ FUNC_LOG;
+
+ CNcsComposeView* self = new ( ELeave ) CNcsComposeView(
+ *aAppUi, aEnv, aControlGroup, aMailClient, aMsvSession );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ConstructL()
+ {
+ FUNC_LOG;
+
+ BaseConstructL( R_NCS_COMPOSE_VIEW );
+ iFirstStartCompleted = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoFirstStartL()
+// Purpose of this function is to do first start only when msg details is
+// really needed to be shown. Implemented to make app startuo faster.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DoFirstStartL()
+ {
+ FUNC_LOG;
+ // Attachment list for compose screen, owned by AlfEnv
+ CAlfControlGroup& attListControlGroup =
+ iEnv.NewControlGroupL( KSendAttachmentManagerDisplayGroup );
+ CFSEmailUiSendAttachmentsListVisualiser* sendAttachmentVisualiser =
+ CFSEmailUiSendAttachmentsListVisualiser::NewLC(
+ iEnv, &iAppUi, attListControlGroup );
+ iAppUi.AddViewL( sendAttachmentVisualiser );
+ CleanupStack::Pop( sendAttachmentVisualiser );
+
+ iCrHandler = CFSEmailCRHandler::InstanceL(); // singleton, not owned
+
+ iEnv.AddActionObserverL( this );
+
+ iAutoSaver = CFsAutoSaver::NewL( iEnv, KAutoSaveTimeDelayMs );
+ iAutoSaver->Enable( EFalse );
+ iFirstStartCompleted = ETrue;
+ iCheckQuery = EFalse;
+ iAsyncCallback = new (ELeave) CAsyncCallBack( CActive::EPriorityLow );
+ // msk context menu added into composer
+ MenuBar()->SetContextMenuTitleResourceId( R_NCS_COMPOSE_BODY_MSK_MENUBAR );
+ iActiveHelper = CActiveHelper::NewL( this );
+
+ iAsyncAttachmentAdd =
+ new (ELeave) CAsyncCallBack( CActive::EPriorityStandard );
+
+ // Initializing the default stylus long tap popup menu
+ if( !iStylusPopUpMenu )
+ {
+ TPoint point( 0, 0 );
+ iStylusPopUpMenu = CAknStylusPopUpMenu::NewL( this, point );
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC( reader,
+ R_STYLUS_POPUP_MENU_COMPOSE_VIEW_ATTACHMENT );
+ iStylusPopUpMenu->ConstructFromResourceL( reader );
+ CleanupStack::PopAndDestroy(); // reader
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::~CNcsComposeView()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CNcsComposeView::~CNcsComposeView()
+ {
+ FUNC_LOG;
+ delete iAutoSaver;
+ if ( iAsyncCallback )
+ {
+ iAsyncCallback->Cancel();
+ delete iAsyncCallback;
+ }
+ delete iFetchLogic;
+ if( iActiveHelper )
+ {
+ iActiveHelper->Cancel();
+ delete iActiveHelper;
+ }
+ if ( iAsyncAttachmentAdd )
+ {
+ iAsyncAttachmentAdd->Cancel();
+ delete iAsyncAttachmentAdd;
+ }
+ delete iStylusPopUpMenu;
+ }
+
+void CNcsComposeView::PrepareForExit()
+ {
+ FUNC_LOG;
+ if ( iCheckQuery && iDlg )
+ {
+ TKeyEvent check = { EKeyEscape, EStdKeyNull, 0, 0 };
+ TRAP_IGNORE( iDlg->OfferKeyEventL( check, EEventKey ) );
+ iDlg = NULL;
+
+ iAsyncCallback->Cancel(); // cancel any outstanding callback
+ iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
+ iAsyncCallback->CallBack();
+ }
+ else if( iFakeSyncGoingOn || iExecutingDoExitL )
+ {
+ // low priority active obj so that iwait in plugins finish
+ iActiveHelper->Cancel();
+ iActiveHelper->Start();
+ }
+ else if ( iIncludeMessageTextAsync )
+ {
+ if ( iContainer )
+ {
+ iContainer->StopAsyncTextFormatter();
+ }
+ ResetComposer();
+ iAsyncCallback->Cancel(); // cancel any outstanding callback
+ iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
+ iAsyncCallback->CallBack();
+ }
+ else
+ {
+ DoSafeExit( ESaveDraft );
+
+ // cleaning - usefull when application is closed from task switcher
+ HideToolbar();
+ }
+
+ if( iFetchLogic )
+ {
+ iFetchLogic->CancelFetchings();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::Id()
+// Returns View's ID.
+// -----------------------------------------------------------------------------
+//
+TUid CNcsComposeView::Id() const
+ {
+ FUNC_LOG;
+ return MailEditorId;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ChildDoActivateL()
+// Activate the Compose view
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ChildDoActivateL( const TVwsViewId& aPrevViewId,
+ TUid aCustomMessageId, const TDesC8& aCustomMessage )
+ {
+ FUNC_LOG;
+
+ // needed when "Opening" (replying/forwarding)note is shown and
+ // we receive incoming call- Email application goes to background.
+ // When coming back to application the view is activated and reseted.
+ // That's why we prevent activation and the same is done in ChildDoDeactivate
+ if ( iIncludeMessageTextAsync )
+ {
+ return;
+ }
+
+ if ( !iFirstStartCompleted )
+ {
+ DoFirstStartL();
+ }
+ Toolbar()->SetDimmed( ETrue );
+ // Set status pane indicators
+ iStatusPaneIndicators = iAppUi.GetStatusPaneIndicatorContainer();
+ iStatusPaneIndicators->ShowStatusPaneIndicators();
+
+ // Notify base class about view being entered unless
+ // returned from another view
+ if ( aCustomMessageId.iUid != KEditorCmdReturnToPrevious )
+ {
+ ViewEntered( aPrevViewId );
+ }
+
+ // Cleanup the previous message before opening a new one
+ SaveAndCleanPreviousMessage();
+
+ // Get the launch parameters
+ if ( aCustomMessageId.iUid == KEditorCmdReturnToPrevious )
+ {
+ // Use previous launch parameters when returning to previously
+ // opened message
+ iMailBox = iMailClient.GetMailBoxByUidL( iLaunchParams.iMailboxId );
+ }
+ else if ( aCustomMessage.Length() > 0 )
+ {
+
+ TPckgBuf<TEditorLaunchParams> buf( iLaunchParams );
+ buf.Copy( aCustomMessage );
+ iLaunchParams = buf();
+ iMailBox = iMailClient.GetMailBoxByUidL( iLaunchParams.iMailboxId );
+
+ }
+ else
+ {
+ iLaunchParams.iActivatedExternally = ETrue;
+ }
+
+ // Inform the AppUi about external view activation to fix the view stack.
+ // Normally this happens based on the previous view AppUid in the BaseView
+ // but in case contacts action menu was used within FsEmail, this doesn'
+ // work. It doesn't hurt to call this again even if it was already called
+ // once from BaseView.
+ if ( iLaunchParams.iActivatedExternally )
+ {
+ iAppUi.ViewActivatedExternallyL( Id() );
+ }
+
+ // Try to get the mailbox by other means if using launch parameters failed
+ if ( !iMailBox )
+ {
+ TInt error( KErrNone );
+
+ // can we get it from MSV Id
+ // MSV id is passed to us when account is defined email key settings
+ if ( aCustomMessageId != TUid::Null() )
+ {
+ TRAP( error, iMailBox = TFsEmailUiUtility::GetMailboxForMtmIdL(
+ iMailClient, iMsvSession, aCustomMessageId.iUid ) );
+ }
+
+ error = KErrNone;
+
+ // try to use mailbox set as default in MCE
+ if ( !iMailBox )
+ {
+ TRAP( error, iMailBox = TFsEmailUiUtility::GetMceDefaultMailboxL(
+ iMailClient, iMsvSession ) );
+ }
+
+ // use first mail account from the list
+ if ( !iMailBox )
+ {
+ TFSMailMsgId id;
+ RPointerArray<CFSMailBox> mailboxes;
+ CleanupResetAndDestroyClosePushL( mailboxes );
+ iMailClient.ListMailBoxes( id, mailboxes );
+ if ( mailboxes.Count() > 0 )
+ {
+ iMailBox =
+ iMailClient.GetMailBoxByUidL( mailboxes[0]->GetId() );
+ }
+ CleanupStack::PopAndDestroy( &mailboxes );
+ }
+
+ // could not get mailbox so leave
+ if ( !iMailBox )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ aCustomMessageId = TUid::Uid( KEditorCmdCreateNew );
+ }
+
+
+ iMailSent = EFalse;
+ iMailSendFailed = EFalse;
+ iCustomMessageId = aCustomMessageId;
+
+ CreateContainerL();
+
+ TRAPD( err, HandleActivationCommandL( aCustomMessageId ) );
+ if ( !err )
+ {
+ err = iMailFetchingErrCode;
+ }
+
+ if ( err == KErrCancel ||
+ err == KErrCouldNotConnect ||
+ err == KErrConnectionTerminated )
+ {
+ // Just close composer without any notes if operation was cancelled.
+ // For connection errors, DownloadInfoMediator already shows error
+ // message, so no need to show another one.
+ ExitComposer();
+ }
+ else if ( err )
+ {
+ // some other error => show generic error note and close composer
+ if( !iAppUi.AppUiExitOngoing() )
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE, ETrue );
+ ExitComposer();
+ }
+ else
+ {
+ // everything went fine => do rest of the generic initialization
+ InitUiGeneralL();
+ iAppUi.StartEndKeyCapture();
+ iContainer->SetMskL();
+ iViewReady = ETrue;
+ Toolbar()->SetDimmed( EFalse );
+ RefreshToolbar();
+ iContainer->ActivateL();
+ }
+
+ // if there is a embedded app in FSEmail.
+ if( iAppUi.EmbeddedApp() )
+ {
+ // Set email editor started from embedded app flag to true
+ // so that we can switch view correct when sent email.
+ iAppUi.SetEditorStartedFromEmbeddedApp( ETrue );
+
+ RWsSession rwsSession;
+ User::LeaveIfError( rwsSession.Connect() );
+ CleanupClosePushL( rwsSession );
+
+ // Simulate a back key to exit embedded app
+ // so that email editor could show on the top level.
+ TKeyEvent KeyEvent = TKeyEvent();
+ // this is neccesary for photogalery image viewer (don't remove)
+ KeyEvent.iScanCode = EStdKeyUpArrow;
+ rwsSession.SimulateKeyEvent( KeyEvent );
+ KeyEvent.iCode = EKeyCBA2;
+ rwsSession.SimulateKeyEvent( KeyEvent );
+
+ rwsSession.Close();
+ CleanupStack::PopAndDestroy( &rwsSession );
+ }
+
+ if ( iIncludeMessageTextAsync )
+ {
+ // including message body in async way
+ IncludeMessageTextAsyncL( ETrue );
+ }
+
+ iViewFullyActivated = ETrue;
+
+ TIMESTAMP( "Editor launched" );
+ }
+
+// -----------------------------------------------------------------------------
+// Initialises toolbar items.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DynInitToolbarL( TInt aResourceId,
+ CAknToolbar* aToolbar )
+ {
+ FUNC_LOG;
+ if ( aResourceId == EFsEmailUiTbCmdExpandActions && aToolbar )
+ {
+ CAknToolbarExtension* ext = aToolbar->ToolbarExtension();
+ if ( iContainer )
+ {
+ // Set correct state for show/hide cc field button.
+ CAknButton* ccButton = Button( EFsEmailUiTbCmdCcField, ext );
+ if ( ccButton )
+ {
+ TInt index = iContainer->IsCcFieldVisible() ? 1 : 0;
+ ccButton->SetCurrentState( index, EFalse );
+
+ // Command is dimmed, if there is content in the field.
+ ccButton->SetDimmed( iContainer->GetCcFieldLength() > 0 );
+ }
+
+ // Set correct state for show/hide bcc field button.
+ CAknButton* bccButton = Button( EFsEmailUiTbCmdBccField, ext );
+ if ( bccButton )
+ {
+ TInt index = iContainer->IsBccFieldVisible() ? 1 : 0;
+ bccButton->SetCurrentState( index, EFalse );
+
+ // Command is dimmed, if there is content in the field.
+ bccButton->SetDimmed( iContainer->GetBccFieldLength() > 0 );
+ }
+ }
+ else
+ {
+ ext->HideItemL( EFsEmailUiTbCmdCcField, ETrue );
+ ext->HideItemL( EFsEmailUiTbCmdBccField, ETrue );
+ }
+
+ if ( iNewMessage )
+ {
+ // Set correct state for low priority button.
+ TBool lowPriority = iNewMessage->IsFlagSet( EFSMsgFlag_Low );
+ CAknButton* lowPriorityButton = static_cast<CAknButton*>(
+ ext->ControlOrNull( EFsEmailUiTbCmdLowPriority ) );
+ if ( lowPriorityButton )
+ {
+ TInt index = lowPriority ? 1 : 0;
+ lowPriorityButton->SetCurrentState( index, EFalse );
+ }
+
+ // Set correct state for high priority button.
+ TBool highPriority = iNewMessage->IsFlagSet( EFSMsgFlag_Important );
+ CAknButton* highPriorityButton = static_cast<CAknButton*>(
+ ext->ControlOrNull( EFsEmailUiTbCmdHighPriority ) );
+ if ( highPriorityButton )
+ {
+ TInt index = highPriority ? 1 : 0;
+ highPriorityButton->SetCurrentState( index, EFalse );
+ }
+
+ // Set correct state for follow up button.
+ TBool followUp = iNewMessage->IsFlagSet( EFSMsgFlag_FollowUp );
+ CAknButton* followUpButton = static_cast<CAknButton*>(
+ ext->ControlOrNull( EFsEmailUiTbCmdFollowUp ) );
+ if ( followUpButton )
+ {
+ TInt index = followUp ? 1 : 0;
+ followUpButton->SetCurrentState( index, EFalse );
+
+ // Hide follow up button, if follow up is not supported.
+ ext->HideItemL( EFsEmailUiTbCmdFollowUp,
+ !TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) );
+ }
+ }
+ else
+ {
+ ext->HideItemL( EFsEmailUiTbCmdLowPriority, ETrue );
+ ext->HideItemL( EFsEmailUiTbCmdHighPriority, ETrue );
+ ext->HideItemL( EFsEmailUiTbCmdFollowUp, ETrue );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::OfferToolbarEventL
+// -----------------------------------------------------------------------------
+void CNcsComposeView::OfferToolbarEventL( TInt aCommand )
+ {
+ FUNC_LOG;
+ TBool attachmentAddition = EFalse;
+ switch ( aCommand )
+ {
+ case EFsEmailUiTbCmdSend:
+ if ( iContainer && iContainer->AreAddressFieldsEmpty() )
+ {
+ RefreshToolbar();
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdSend );
+ }
+ break;
+ case EFsEmailUiTbCmdCcField:
+ {
+ CAknButton* ccFieldButton = Button( EFsEmailUiTbCmdCcField );
+ if ( ccFieldButton )
+ {
+ if ( ccFieldButton->StateIndex() )
+ {
+ HandleCommandL( ENcsCmdShowCc );
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdHideCc );
+ }
+ }
+ break;
+ }
+ case EFsEmailUiTbCmdBccField:
+ {
+ CAknButton* bccFieldButton = Button( EFsEmailUiTbCmdBccField );
+ if ( bccFieldButton )
+ {
+ if ( bccFieldButton->StateIndex() )
+ {
+ HandleCommandL( ENcsCmdShowBcc );
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdHideBcc );
+ }
+ }
+ break;
+ }
+ case EFsEmailUiTbCmdLowPriority:
+ {
+ CAknButton* lowPriorityButton = Button( EFsEmailUiTbCmdLowPriority );
+ if ( lowPriorityButton )
+ {
+ if ( lowPriorityButton->StateIndex() )
+ {
+ CAknButton* highPriorityButton = Button(
+ EFsEmailUiTbCmdHighPriority );
+ if ( highPriorityButton )
+ {
+ highPriorityButton->SetCurrentState( 0, ETrue );
+ }
+ HandleCommandL( ENcsCmdPriorityLow );
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdPriorityNormal );
+ }
+ }
+ break;
+ }
+ case EFsEmailUiTbCmdHighPriority:
+ {
+ CAknButton* highPriorityButton = Button( EFsEmailUiTbCmdHighPriority );
+ if ( highPriorityButton )
+ {
+ if ( highPriorityButton->StateIndex() )
+ {
+ CAknButton* lowPriorityButton = Button(
+ EFsEmailUiTbCmdLowPriority );
+ if ( lowPriorityButton )
+ {
+ lowPriorityButton->SetCurrentState( 0, ETrue );
+ }
+ HandleCommandL( ENcsCmdPriorityHigh );
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdPriorityNormal );
+ }
+ }
+ break;
+ }
+ case EFsEmailUiTbCmdFollowUp:
+ {
+ CAknButton* button = Button( EFsEmailUiTbCmdFollowUp );
+ if ( button && iNewMessage )
+ {
+ if ( button->StateIndex() )
+ {
+ iNewMessage->SetFlag( EFSMsgFlag_FollowUp );
+ iNewMessage->ResetFlag( EFSMsgFlag_FollowUpComplete );
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUp );
+ }
+ else
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_FollowUp
+ | EFSMsgFlag_FollowUpComplete );
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUpNone );
+ }
+ }
+ break;
+ }
+ case EFsEmailUiTbCmdInsertAudio:
+ iAttachmentAddType = MsgAttachmentUtils::EAudio;
+ attachmentAddition = ETrue;
+ break;
+ case EFsEmailUiTbCmdInsertImage:
+ iAttachmentAddType = MsgAttachmentUtils::EImage;
+ attachmentAddition = ETrue;
+ break;
+ case EFsEmailUiTbCmdInsertVideo:
+ iAttachmentAddType = MsgAttachmentUtils::EVideo;
+ attachmentAddition = ETrue;
+ break;
+ case EFsEmailUiTbCmdInsertNote:
+ iAttachmentAddType = MsgAttachmentUtils::ENote;
+ attachmentAddition = ETrue;
+ break;
+ case EFsEmailUiTbCmdInsertPresentation:
+ iAttachmentAddType = MsgAttachmentUtils::ESVG;
+ attachmentAddition = ETrue;
+ break;
+ case EFsEmailUiTbCmdInsertOther:
+ iAttachmentAddType = MsgAttachmentUtils::EUnknown;
+ attachmentAddition = ETrue;
+ break;
+ default:
+ break;
+ }
+ if ( attachmentAddition )
+ {
+ iAsyncAttachmentAdd->Cancel(); // cancel any outstanding callback
+ iAsyncAttachmentAdd->Set( TCallBack( AsyncAddAttachment, this ) );
+ iAsyncAttachmentAdd->CallBack();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ToolbarResourceId()
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeView::ToolbarResourceId() const
+ {
+ FUNC_LOG;
+ return R_FREESTYLE_EMAIL_UI_TOOLBAR_MESSAGE_EDITOR;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GetInitiallyDimmedItemsL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::GetInitiallyDimmedItemsL( const TInt aResourceId,
+ RArray<TInt>& aDimmedItems ) const
+ {
+ FUNC_LOG;
+ aDimmedItems.Reset();
+ switch ( aResourceId )
+ {
+ case R_FREESTYLE_EMAIL_UI_TOOLBAR_MESSAGE_EDITOR:
+ aDimmedItems.AppendL( EFsEmailUiTbCmdSend );
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::RefreshToolbar()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::RefreshToolbar()
+ {
+ FUNC_LOG;
+ if ( iContainer )
+ {
+ // Hide toolbar if remotesearch is in progress,
+ // because it takes you into a different view
+ TBool hideToolbar = ( iContainer->IsRemoteSearchInprogress()
+ || iAddingAttachmentDialogOpened );
+ SetToolbarItemDimmed( EFsEmailUiTbCmdSend, iContainer->AreAddressFieldsEmpty() );
+
+ CAknToolbar* toolbar(Toolbar());
+ if (toolbar)
+ {
+ toolbar->SetToolbarVisibility(!hideToolbar);
+ // If toolbar is not hidden, redraw it (otherwise only dimmed/undimmed button will be redrawn)
+ if(!hideToolbar)
+ {
+ toolbar->DrawDeferred();
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ChildDoDeactivate()
+// Deactivate the Compose view
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ChildDoDeactivate()
+ {
+ FUNC_LOG;
+
+ // see comment in ChildDoActivate
+ if ( iIncludeMessageTextAsync && !iAppUi.AppUiExitOngoing() )
+ {
+ return;
+ }
+
+ iViewFullyActivated = EFalse;
+
+ iAppUi.StopEndKeyCapture();
+
+ SafeDelete( iFetchLogic );
+
+ // Normally Comopser state has been already cleaned by now but in special
+ // cases (like external view activation while in Composer) this may not be
+ // the case. In those cases the message needs to be saved before the view
+ // is deactivated.
+ if ( !iAppUi.AppUiExitOngoing() )
+ {
+ SaveAndCleanPreviousMessage();
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DynInitMenuPaneL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DynInitMenuPaneL( TInt aResourceId,
+ CEikMenuPane* aMenuPane )
+ {
+ FUNC_LOG;
+
+ if ( !iViewReady )
+ {
+ User::Leave( KErrNcsComposeViewNotReady );
+ }
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
+
+ //we are forbiding to change MSK label, because popup will be opened
+ iContainer->SwitchChangeMskOff( ETrue );
+
+ if ( aResourceId == R_NCS_COMPOSE_MENU )
+ {
+ if ( FeatureManager::FeatureSupported(
+ KFeatureIdFfCmailIntegration ) )
+ {
+ // remove help support in pf5250
+ aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue);
+ }
+
+ // Disable send if there are no addresses in any of the AIF fields,
+ if ( iContainer->AreAddressFieldsEmpty() )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdSend );
+ }
+
+ // If no attachments, delete the remove attachments menu item
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
+ attachmentControl = AttachmentsListControl();
+ TInt count = attachmentControl->Model()->Count();
+
+ // if mail has remote attachments then attachments can't be
+ // removed via options menu
+ if ( count <= 0 ||
+ AttachmentsListControl()->Model()->HasReadOnlyAttachments() )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdRemoveAttachment );
+ aMenuPane->DeleteMenuItem( ENcsCmdRemoveAllAttachments );
+ }
+ else if ( count == 1 )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdRemoveAllAttachments );
+ }
+ else
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdRemoveAttachment );
+ }
+
+ if ( iContainer->GetCcFieldLength() > 0 &&
+ iContainer->GetBccFieldLength() > 0 )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdMore );
+ }
+
+ if ( !TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdFlag );
+ }
+ }
+
+ if ( aResourceId == R_NCS_EXTRA_RECEPIENT_FIELDS_MENU )
+ {
+ // Select which View->CC menu items to show
+ if ( iContainer->IsCcFieldVisible() )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdShowCc );
+ // if there is text in Cc field do not show "hide Cc" menu item
+ if ( iContainer->GetCcFieldLength() > 0 )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdHideCc );
+ }
+ }
+ else
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdHideCc );
+ }
+
+ // Select which View->BCC menu items to show
+ if ( iContainer->IsBccFieldVisible() )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdShowBcc );
+ // if there is text in Bcc field do not show "hide Bcc" menu item
+ if ( iContainer->GetBccFieldLength() > 0 )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdHideBcc );
+ }
+ }
+ else
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdHideBcc );
+ }
+ }
+
+ if ( aResourceId == R_NCS_PRIORITY_MENU )
+ {
+
+ if ( iNewMessage->IsFlagSet( EFSMsgFlag_Important ) )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdPriorityHigh );
+ }
+ else if ( iNewMessage->IsFlagSet( EFSMsgFlag_Low ) )
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdPriorityLow );
+ }
+ else
+ {
+ aMenuPane->DeleteMenuItem( ENcsCmdPriorityNormal );
+ }
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HandleCommandL()
+// Takes care of Command handling.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::HandleCommandL( TInt aCommand )
+ {
+ FUNC_LOG;
+
+ // Attempt to handle commands only after view is fully activated and exit
+ // has not yet been initiated.
+ if ( iViewReady && !iAppUi.ViewSwitchingOngoing() )
+ {
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iCrHandler, Panic( ENcsBasicUi ) );
+
+ switch( aCommand )
+ {
+ case ENcsCmdSend:
+ {
+ // Show query if the Subject field is empty
+ if ( iContainer->IsSubjectFieldEmpty() )
+ {
+ TInt answer = TFsEmailUiUtility::ShowConfirmationQueryL(
+ R_FREESTYLE_EMAIL_QUERY_NO_SUBJECT );
+ if ( !answer )
+ {
+ // user didn't want to send yet
+ // -> go back to the message
+ return;
+ }
+ }
+
+ TRAPD( error, DoSendL() );
+ if ( !error )
+ {
+ // Sending successful
+ HBufC* confMessage = NULL;
+ if ( !TFsEmailUiUtility::IsOfflineModeL() || WLANConnectionActive() )
+ {
+ // when sync status is currently ONLINE
+ confMessage = StringLoader::LoadLC(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_SENDING_QUEUED );
+ }
+ else
+ {
+ // when sync status is currently OFFLINE
+ confMessage = StringLoader::LoadLC(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_QUEUED_UNTIL_ONLINE );
+ }
+ CAknConfirmationNote* note =
+ new (ELeave) CAknConfirmationNote( ETrue ); //waiting
+ note->SetTimeout( CAknNoteDialog::ELongTimeout );
+ note->SetTone( CAknNoteDialog::ENoTone );
+ note->ExecuteLD( *confMessage );
+ CleanupStack::PopAndDestroy( confMessage );
+ DoSafeExit(); // Exit after successful sending
+ }
+ else if ( error == KErrBadName )
+ {
+ // sending failed because recipient address was invalid
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_INVALID_EMAIL_ADDRESS,
+ ETrue );
+ }
+ else
+ {
+ // sending failed for some other reason
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_MESSAGE_NOT_SENT,
+ ETrue );
+ // Exit after sending failed for other reason for other
+ // reason than KErrBadName
+ DoSafeExit();
+ }
+ }
+ break;
+ case ENcsCmdAddAttachment:
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // show the toolbar
+ UpdateToolbarL();
+ CAknToolbar* toolbar = Toolbar();
+ if ( toolbar )
+ {
+ CAknToolbarExtension* extension =
+ static_cast<CAknToolbarExtension*>(
+ toolbar->ControlOrNull( EFsEmailUiTbCmdExpandInsert ) );
+ if ( extension )
+ {
+ extension->SetShown( ETrue );
+ }
+ }
+ }
+ else
+ {
+ iAttachmentAddType = MsgAttachmentUtils::EUnknown;
+ iAsyncAttachmentAdd->Cancel();
+ iAsyncAttachmentAdd->Set(
+ TCallBack( AsyncAddAttachment, this ) );
+ iAsyncAttachmentAdd->CallBack();
+ iContainer->SetMskL();
+ }
+ }
+ break;
+ case EFsEmailUiCmdOpenAttachment:
+ case EFsEmailUiCmdOpenAttachmentList:
+ {
+ DoOpenAttachmentListL();
+ }
+ break;
+ case ENcsCmdRemoveAttachment:
+ case EFsEmailUiCmdRemoveAttachment:
+ {
+ TInt index( iContainer->FocusedAttachmentLabelIndex() );
+ CFreestyleEmailUiSendAttachmentsListControl* ctrl =
+ AttachmentsListControl();
+ if ( ctrl && KNoAttachmentLabelFocused != index )
+ {
+ ctrl->RemoveAttachmentFromListL( index );
+ }
+ SetAttachmentLabelContentL();
+ }
+ break;
+ case ENcsCmdRemoveAllAttachments:
+ {
+ CFreestyleEmailUiSendAttachmentsListControl* ctrl =
+ AttachmentsListControl();
+ if ( ctrl )
+ {
+ ctrl->RemoveAllAttachmentsL();
+ }
+ SetAttachmentLabelContentL();
+ }
+ break;
+ case ENcsCmdPriorityHigh:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Low );
+ iNewMessage->SetFlag( EFSMsgFlag_Important );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityHigh );
+ }
+ break;
+ case ENcsCmdPriorityNormal:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Low );
+ iNewMessage->ResetFlag( EFSMsgFlag_Important );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityNormal );
+ }
+ break;
+ case ENcsCmdPriorityLow:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Important );
+ iNewMessage->SetFlag( EFSMsgFlag_Low );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityLow );
+ }
+ break;
+ case ENcsCmdShowCc:
+ {
+ iContainer->SetCcFieldVisibleL( ETrue );
+ iCrHandler->SetEditorCCVisible( 1 );
+ }
+ break;
+ case ENcsCmdHideCc:
+ {
+ iContainer->SetCcFieldVisibleL( EFalse );
+ iCrHandler->SetEditorCCVisible( 0 );
+ }
+ break;
+ case ENcsCmdShowBcc:
+ {
+ iContainer->SetBccFieldVisibleL( ETrue );
+ iCrHandler->SetEditorBCVisible( 1 );
+ }
+ break;
+ case ENcsCmdHideBcc:
+ {
+ iContainer->SetBccFieldVisibleL( EFalse );
+ iCrHandler->SetEditorBCVisible( 0 );
+ }
+ break;
+ case ENcsCmdFlag:
+ {
+ RunFollowUpFlagDlgL();
+ }
+ break;
+ case ENcsCmdQuickText:
+ {
+ DoQuickTextL();
+ }
+ break;
+ case ENcsCmdInsertContact:
+ case ENcsInsertContact:
+ {
+ iContainer->AppendAddressesL();
+ }
+ break;
+ case ENcsCmdSaveDraft:
+ {
+
+ iContainer->FixSemicolonL();
+
+
+ TRAPD( saveDraftError, DoSaveDraftL( EFalse ) );
+ if ( saveDraftError == KErrNone )
+ {
+ // Saving successful
+ if( !iAppUi.AppUiExitOngoing() )
+ TFsEmailUiUtility::ShowInfoNoteL(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS,
+ ETrue );
+ }
+ else
+ {
+ // error occured in saving -> show an error message
+ if( !iAppUi.AppUiExitOngoing() )
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
+ ETrue );
+ }
+
+ DoSafeExit( ENoSave );
+ }
+ break;
+ case EAknCmdHelp:
+ {
+ TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID );
+ }
+ break;
+ case EAknSoftkeySelect:
+ {
+ iContainer->DoPopupSelectL();
+ }
+ break;
+ case EAknSoftkeyCancel:
+ {
+ iContainer->ClosePopupContactListL();
+ }
+ break;
+ case EAknSoftkeyClose:
+ {
+ DoSafeExit();
+ }
+ break;
+ case ENcsCmdExit:
+ {
+ TIMESTAMP( "Exit selected from editor" );
+ iAppUi.Exit();
+ }
+ break;
+ default:
+ {
+ // empty implementation
+ // these commands are passed next to FEP for processing
+ }
+ break;
+ }
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoSendL()
+// Send message
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DoSendL()
+ {
+ FUNC_LOG;
+
+ // check that addresses exist
+ if ( iContainer->AreAddressFieldsEmpty() )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ CommitL( ETrue, EAllFields, ETrue );
+
+ TRAPD(r, iMailBox->SendMessageL( *iNewMessage ) );
+ if ( KErrNone != r )
+ {
+ iMailSendFailed = ETrue;
+ User::Leave( r );
+ }
+
+ // prevent sending failure if original message is
+ // removed from server while replying/forwarding
+ TRAPD( flagError, SetReplyForwardFlagL() );
+
+ if ( KErrNone != flagError && KErrNotFound != flagError )
+ {
+ iMailSendFailed = ETrue;
+ User::Leave( flagError );
+ }
+
+ iMailSent = ETrue;
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoSaveDraftL()
+// Saves message to Drafts
+// Displays dialog asking user choice if preferred
+// Pressing cancel in the query dialog causes Leave with code KErrCancel
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::DoSaveDraftL( TBool aAskUser )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
+
+ TBool result( ETrue );
+
+ if ( aAskUser )
+ {
+ TInt selectedOption( -1 );
+ CDesCArrayFlat* array = new (ELeave) CDesCArrayFlat( 2 );
+ CleanupStack::PushL( array );
+
+ HBufC* saveItem = StringLoader::LoadLC( R_NCS_DRAFT_SAVE );
+ array->AppendL( *saveItem );
+ CleanupStack::PopAndDestroy( saveItem );
+
+ HBufC* deleteItem = StringLoader::LoadLC( R_NCS_DRAFT_DISCARD );
+ array->AppendL( *deleteItem );
+ CleanupStack::PopAndDestroy( deleteItem );
+
+ iDlg = new (ELeave) CAknListQueryDialog( &selectedOption );
+ iDlg->PrepareLC( R_DRAFT_QUERY_DIALOG );
+ iDlg->SetItemTextArray( array );
+ iDlg->SetOwnershipType( ELbmDoesNotOwnItemArray );
+
+ iCheckQuery = ETrue;
+ //we are forbiding to change MSK label, cause popup will be opend
+ iContainer->SwitchChangeMskOff( ETrue );
+ TInt ret = iDlg->RunLD();
+ iDlg = NULL;
+
+ iCheckQuery = EFalse;
+ iContainer->SwitchChangeMskOff( EFalse );
+
+ if ( !ret )
+ {
+ selectedOption = KErrCancel;
+ }
+
+ switch ( selectedOption )
+ {
+ case 0:
+ {
+ TRAPD( saveError, SaveToDraftsL( ETrue ) );
+
+ if ( saveError == KErrNone )
+ {
+ // User wanted to save to Drafts and saving was successful
+ if( !iAppUi.AppUiExitOngoing() )
+ TFsEmailUiUtility::ShowInfoNoteL(
+ R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS,
+ ETrue );
+ }
+ else
+ {
+
+ // error occured in saving -> show an error message
+ if( !iAppUi.AppUiExitOngoing() )
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
+ ETrue );
+
+ // let's return EFalse so after completing this query
+ // so the focus would stay in compose view (same behaviour
+ // as if Cancel was pressed )
+ result = EFalse;
+ }
+ }
+ break;
+ case 1:
+ {
+ TIMESTAMP( "Delete draft message selected in editor" );
+ TRAPD( error, SaveToDraftsL( ETrue ) );
+ if ( KErrNone != error )
+ {
+ }
+ // for delete messages fake sync calls
+ iFakeSyncGoingOn = ETrue;
+ error = NcsUtility::DeleteMessage( iMailClient,
+ iMailBox->GetId(),
+ iNewMessage->GetFolderId(),
+ iNewMessage->GetMessageId() );
+
+ if ( KErrNone == error &&
+ iMailBox->HasCapability(
+ EFSMBoxCapaSupportsDeletedItemsFolder ) )
+ {
+ error = NcsUtility::DeleteMessage( iMailClient,
+ iMailBox->GetId(),
+ iMailBox->GetStandardFolderId( EFSDeleted ),
+ iNewMessage->GetMessageId() );
+ }
+ iFakeSyncGoingOn = EFalse;
+
+ if( !iAppUi.AppUiExitOngoing() )
+ {
+ if ( KErrNone != error )
+ {
+ // error occured in saving -> show an error message
+ TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
+ ETrue );
+ }
+ else
+ {
+ // Simulate delete event so that drafts folder is
+ // updated correctly.
+ RArray<TFSMailMsgId> messageIds;
+ CleanupClosePushL( messageIds );
+ messageIds.AppendL( iNewMessage->GetMessageId() );
+ TFSMailMsgId folderId = iNewMessage->GetFolderId();
+ TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
+ iAppUi.EventL( TFSEventMailDeleted,
+ mailboxId, &messageIds, &folderId, NULL );
+ CleanupStack::PopAndDestroy( &messageIds );
+ }
+ }
+ }
+ break;
+ default:
+ {
+ result = EFalse;
+ }
+ break;
+ }
+ CleanupStack::PopAndDestroy( array );
+ }
+ else // no question from user
+ {
+ SaveToDraftsL( ETrue );
+ }
+
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::NewMessage()
+// Returns pointer to currently composed mail message
+// -----------------------------------------------------------------------------
+//
+CFSMailMessage* CNcsComposeView::NewMessage()
+ {
+ FUNC_LOG;
+ return iNewMessage;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::AsyncAddAttachmentL()
+// Open file dialog and add selected file as an attachment
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeView::AsyncAddAttachment( TAny* aSelfPtr )
+ {
+ FUNC_LOG;
+
+ CNcsComposeView* self = static_cast<CNcsComposeView*>( aSelfPtr );
+
+ // get pointer to attachment list view
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
+ attachmentControl = self->AttachmentsListControl();
+
+ // show file dialog and get file name
+ TBool ok = EFalse;
+ TInt error = KErrNone;
+ CAknToolbar* toolbar = self->Toolbar();
+ if ( !toolbar->IsDimmed() )
+ {
+ toolbar->SetDimmed(ETrue);
+ }
+
+ self->iAddingAttachmentDialogOpened = ETrue;
+ self->iContainer->SwitchChangeMskOff( ETrue );
+ TRAP( error, ok = attachmentControl->AppendAttachmentToListL(
+ self->iAttachmentAddType) );
+
+ if( error == KErrNoMemory )
+ {
+ TRAP_IGNORE( TFsEmailUiUtility::ShowErrorNoteL(
+ R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
+ ETrue ) );
+ }
+ self->iContainer->SwitchChangeMskOff( EFalse );
+ self->iAddingAttachmentDialogOpened = EFalse;
+
+ if ( ok && error == KErrNone )
+ {
+ TRAP( error, self->SetAttachmentLabelContentL() );
+ }
+
+ if ( !attachmentControl->IsAttachmentAddingLocked() )
+ {
+ toolbar->SetDimmed(EFalse);
+ self->RefreshToolbar();
+ toolbar->DrawDeferred();
+ }
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// RunFollowUpFlagDlgL()
+// Query user for followup flag
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::RunFollowUpFlagDlgL()
+ {
+ FUNC_LOG;
+ if ( iNewMessage && TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) )
+ {
+ TFollowUpNewState newState =
+ TFsEmailUiUtility::SetMessageFollowupFlagL(
+ *iNewMessage, EFalse );
+
+ switch ( newState )
+ {
+ case EFollowUp:
+ {
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUp );
+ }
+ break;
+ case EFollowUpComplete:
+ {
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUpComplete );
+ }
+ break;
+ case EFollowUpClear:
+ {
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUpNone );
+ }
+ break;
+ default:
+ {
+ // do nothing.
+ }
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SetAttachmentLabelContentL()
+// Open file dialog and add selected file as an attachment
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SetAttachmentLabelContentL()
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted && iContainer )
+ {
+ CFreestyleEmailUiSendAttachmentsListControl*
+ attachmentControl = AttachmentsListControl();
+ if ( !( attachmentControl && attachmentControl->Model() ) )
+ {
+ return;
+ }
+
+ // read number of attachments
+ TInt count = attachmentControl->Model()->Count();
+ if ( count > 0 )
+ {
+ // Fill in the name and size descriptor arrays
+ CDesCArrayFlat* nameArray = new (ELeave) CDesCArrayFlat( count );
+ CleanupStack::PushL( nameArray );
+ CDesCArrayFlat* sizeArray = new (ELeave) CDesCArrayFlat( count );
+ CleanupStack::PushL( sizeArray );
+
+ for ( TInt i(0); i<count; ++i )
+ {
+ CFSEmailUiSendAttachmentsListModelItem* item =
+ static_cast<CFSEmailUiSendAttachmentsListModelItem*>
+ ( attachmentControl->Model()->Item( i ) );
+ if ( item )
+ {
+ nameArray->AppendL( item->FileName() );
+ HBufC* sizeDesc =
+ TFsEmailUiUtility::CreateSizeDescLC(
+ item->FileSize() );
+ sizeArray->AppendL( *sizeDesc );
+ CleanupStack::PopAndDestroy( sizeDesc );
+ }
+ }
+ iContainer->SetAttachmentLabelTextsLD( nameArray, sizeArray );
+ iContainer->SetFocusToAttachmentField();
+
+ CleanupStack::Pop( sizeArray );
+ CleanupStack::Pop( nameArray );
+ }
+ else
+ {
+ iContainer->SetAttachmentLabelTextsLD( NULL, NULL );
+ iContainer->HideAttachmentLabel();
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::AttachmentsListControl()
+//
+// -----------------------------------------------------------------------------
+//
+CFreestyleEmailUiSendAttachmentsListControl*
+CNcsComposeView::AttachmentsListControl()
+ {
+ FUNC_LOG;
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl( NULL );
+ if ( iFirstStartCompleted ) // Safety
+ {
+ CFSEmailUiSendAttachmentsListVisualiser* attachmentView =
+ static_cast<CFSEmailUiSendAttachmentsListVisualiser*>(
+ iAvkonViewAppUi->View( SendAttachmentMngrViewId ) );
+ if ( attachmentView )
+ {
+ attachmentControl =
+ static_cast<CFreestyleEmailUiSendAttachmentsListControl*>(
+ attachmentView->ViewerControl() );
+ }
+ }
+ return attachmentControl;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ProcessCommandL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ProcessCommandL( TInt aCommand )
+ {
+ FUNC_LOG;
+
+ // Block all the commands while we are exiting
+ if ( !iExecutingDoExitL )
+ {
+ CFsEmailUiViewBase::ProcessCommandL( aCommand );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HandleActivationCommandL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::HandleActivationCommandL( TUid aCustomMessageId )
+ {
+ FUNC_LOG;
+ // Called from doactivate in which case first start is completed
+ iMailFetchingErrCode = KErrNone;
+
+ if ( aCustomMessageId == TUid::Uid( KEditorCmdCreateNew ) )
+ {
+ iOrigMessage = NULL;
+ iFakeSyncGoingOn = ETrue;
+ iNewMessage = iMailBox->CreateMessageToSend();
+ iFakeSyncGoingOn = EFalse;
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iFakeSyncGoingOn = ETrue;
+ TFsEmailUiUtility::MoveMessageToDraftsL( *iMailBox, *iNewMessage );
+ iFakeSyncGoingOn = EFalse;
+
+ if ( iNewMessage->GetContentType() !=
+ KFSMailContentTypeMultipartMixed )
+ {
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ }
+
+ TFsEmailUiUtility::CreatePlainTextPartL(
+ *iNewMessage, iNewMessageTextPart );
+ IncludeMessageTextL( ETrue );
+ AttachmentsListControl()->Model()->Clear();
+ iContainer->SelectAllToFieldTextL();
+ }
+ else if ( aCustomMessageId == TUid::Uid( KEditorCmdReply ) ||
+ aCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
+ {
+
+ iOrigMessage = iMailClient.GetMessageByUidL(
+ iLaunchParams.iMailboxId, iLaunchParams.iFolderId,
+ iLaunchParams.iMsgId, EFSMsgDataStructure );
+ if ( !iOrigMessage )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ SafeDelete( iFetchLogic );
+ iFetchLogic = CFsComposerFetchLogic::NewL(
+ iMailClient, iLaunchParams.iMailboxId,
+ iOrigMessage->GetFolderId(), iLaunchParams.iMsgId,
+ *this, iAppUi );
+ ShowFetchingWaitNoteL();
+ iFetchLogic->RunReplyLogicL();
+
+ // now fetch logic object runs its tasks and gives callback
+ // to CNcsComposeView::FetchLogicComplete when it is finished
+ }
+ else if ( aCustomMessageId == TUid::Uid( KEditorCmdForward ) )
+ {
+
+ iOrigMessage = iMailClient.GetMessageByUidL(
+ iLaunchParams.iMailboxId, iLaunchParams.iFolderId,
+ iLaunchParams.iMsgId, EFSMsgDataStructure );
+ if ( !iOrigMessage )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ SafeDelete( iFetchLogic );
+ iFetchLogic = CFsComposerFetchLogic::NewL(
+ iMailClient, iLaunchParams.iMailboxId,
+ iOrigMessage->GetFolderId(), iLaunchParams.iMsgId,
+ *this, iAppUi );
+ ShowFetchingWaitNoteL();
+ iFetchLogic->RunForwardLogicL();
+
+ // now fetch logic object runs its tasks and gives callback
+ // to CNcsComposeView::FetchLogicComplete when it is finished
+ }
+ else if ( aCustomMessageId == TUid::Uid( KEditorCmdOpen ) ||
+ aCustomMessageId == TUid::Uid( KEditorCmdReturnToPrevious ) )
+ {
+ // for now, we handle returning from attachments list just like
+ // any message opening
+ iNewMessage = iMailClient.GetMessageByUidL(
+ iLaunchParams.iMailboxId, iLaunchParams.iFolderId,
+ iLaunchParams.iMsgId, EFSMsgDataStructure );
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Show "Opening" wait note if the message body is large
+ TInt waitNoteId = KErrNotFound;
+ if ( TFsEmailUiUtility::IsMessageBodyLargeL(iNewMessage) )
+ {
+ waitNoteId = TFsEmailUiUtility::ShowGlobalWaitNoteLC(
+ R_FSE_WAIT_OPENING_TEXT );
+ }
+
+ iOrigMessage = NULL;
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ TFsEmailUiUtility::CreatePlainTextPartL(
+ *iNewMessage, iNewMessageTextPart );
+ InitFieldsL();
+ TBool spaceInBegin = ETrue;
+ IncludeMessageTextL(spaceInBegin);
+ AttachmentsListControl()->Model()->Clear();
+ GetAttachmentsFromMailL();
+ SetAttachmentLabelContentL();
+ iAttachmentListSaveDraft = ETrue;
+
+ // Close the "Opening" wait note if it was shown
+ if ( waitNoteId != KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy( (TAny*)waitNoteId );
+ }
+ }
+ else if ( aCustomMessageId == TUid::Uid( KEditorCmdInternalMailto ) )
+ {
+ FUNC_LOG;
+
+ iOrigMessage = NULL;
+ iFakeSyncGoingOn = ETrue;
+ iNewMessage = iMailBox->CreateMessageToSend();
+ iFakeSyncGoingOn = EFalse;
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+
+ TFsEmailUiUtility::CreatePlainTextPartL(
+ *iNewMessage, iNewMessageTextPart );
+
+ IncludeMessageTextL( ETrue );
+
+ CFSMailAddress* toAddress =
+ static_cast<CFSMailAddress*>( iLaunchParams.iExtra ); // not owned
+ RPointerArray<CNcsEmailAddressObject> toRecipients;
+ CleanupResetAndDestroyClosePushL( toRecipients );
+ CNcsEmailAddressObject* ncsToAddress =
+ NcsUtility::CreateNcsAddressL( *toAddress );
+ CleanupStack::PushL( ncsToAddress );
+ toRecipients.AppendL( ncsToAddress );
+ CleanupStack::Pop( ncsToAddress ); // owned by toRecipients now
+ iContainer->SetToFieldAddressesL( toRecipients );
+ CleanupStack::PopAndDestroy( &toRecipients );
+
+ iContainer->SetFocusToMessageFieldL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoQuickTextL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DoQuickTextL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ HBufC* title =
+ iEikonEnv->AllocReadResourceLC( R_NCS_QUICK_TEXT_TITLE_TEXT );
+ HBufC* buf( 0 );
+ TRAPD( err, buf = CNotepadApi::FetchTemplateL( title ) );
+ if ( err == KLeaveExit )
+ {
+ // If end key was pressed the dialog leaves with the above error code.
+ // In that case we must leave as well or the application will become
+ // stuck as the exit will be incomplete.
+ User::Leave( err );
+ }
+
+ if ( buf && err == KErrNone ) // Safety check, 0 if user cancel
+ {
+ CleanupStack::PushL( buf );
+ iContainer->AddQuickTextL( *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ CleanupStack::PopAndDestroy( title );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HandleDynamicVariantSwitchL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::HandleDynamicVariantSwitchL(
+ CFsEmailUiViewBase::TDynamicSwitchType aType )
+ {
+ FUNC_LOG;
+
+ if ( iFirstStartCompleted && iContainer )
+ {
+ if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
+ {
+ iContainer->HandleLayoutChangeL();
+ }
+ else if ( aType == CFsEmailUiViewBase::ESkinChanged )
+ {
+ iContainer->HandleSkinChangeL();
+ }
+ else
+ {
+ }
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CNcsComposeView::FadeOut()
+// enables hiding toolbar on different view -> DoActivate()
+// which is earlier than -> CFsEmailUiViewBase::DoDeactivate()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::FadeOut( TBool aDirectionOut )
+ {
+ if ( aDirectionOut && Toolbar()->IsShown() )
+ {
+ HideToolbar();
+ }
+ else if ( ! ( aDirectionOut || Toolbar()->IsShown() ) )
+ {
+ ShowToolbar();
+ }
+ }
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitReplyFieldsL()
+// Initialises the reply fields from the reply message created by the plug-in.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitReplyFieldsL( TBool /*aReplyAll*/ )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ // Get TO recipients
+ RPointerArray<CFSMailAddress>& toRecipients =
+ iNewMessage->GetToRecipients();
+ RPointerArray<CNcsEmailAddressObject> recipients;
+ CleanupResetAndDestroyClosePushL( recipients );
+ NcsUtility::ConvertAddressArrayL( toRecipients, recipients );
+ iContainer->SetToFieldAddressesL( recipients );
+ CleanupStack::PopAndDestroy( &recipients );
+
+ // Get CC recipients
+ RPointerArray<CFSMailAddress>& ccRecipients =
+ iNewMessage->GetCCRecipients();
+ NcsUtility::ConvertAddressArrayL( ccRecipients, recipients );
+ iContainer->SetCcFieldAddressesL( recipients );
+ recipients.ResetAndDestroy();
+
+ // Get BCC recipients
+ RPointerArray<CFSMailAddress>& bccRecipients =
+ iNewMessage->GetBCCRecipients();
+ NcsUtility::ConvertAddressArrayL( bccRecipients, recipients );
+ iContainer->SetBccFieldAddressesL( recipients );
+ recipients.ResetAndDestroy();
+
+ // Get subject line from original message
+ HBufC* prefix = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_REPLY_PREFIX );
+ HBufC* formattedSubject = NcsUtility::FormatSubjectLineL(
+ iOrigMessage->GetSubject(), *prefix );
+ CleanupStack::PushL( formattedSubject );
+ iContainer->SetSubjectL( *formattedSubject );
+ CleanupStack::PopAndDestroy( formattedSubject );
+ CleanupStack::PopAndDestroy( prefix );
+
+ // clear attachments
+ AttachmentsListControl()->Model()->Clear();
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::RemoveOwnAddress()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::RemoveOwnAddress(
+ RPointerArray<CNcsEmailAddressObject>& aAddressList )
+ {
+ FUNC_LOG;
+ TInt index = 0;
+ TDesC& ownAddress( iMailBox->OwnMailAddress().GetEmailAddress() );
+ while ( index < aAddressList.Count() )
+ {
+ if ( !aAddressList[index]->EmailAddress().CompareC(ownAddress) )
+ {
+ // The entry will be removed from the arry.
+ aAddressList.Remove(index);
+ break;
+ }
+ index++;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::IncludeMessageTextL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::IncludeMessageTextL(
+ TBool aEnsureSpaceInBegin /*= EFalse*/ )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ HBufC* body = NULL;
+ HBufC* rawBody = GetMessageBodyL();
+ CleanupStack::PushL( rawBody );
+
+ // Ensure there's free space in the beginning of the message if required
+ if ( aEnsureSpaceInBegin && rawBody->Length() )
+ {
+ TText firstChar = (*rawBody)[0];
+ _LIT( KNewLines, "\r\n\x2028\x2029" );
+ if ( KNewLines().Locate( firstChar ) == KErrNotFound )
+ {
+ // First character is not a new line character. Insert one.
+ body = HBufC::NewL( rawBody->Length() + KIMSLineFeed().Length() );
+ TPtr ptr = body->Des();
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *rawBody );
+ CleanupStack::PopAndDestroy( rawBody );
+ rawBody = NULL;
+ CleanupStack::PushL( body );
+ }
+ }
+ // If no modifications were needed, then just set body pointer to point
+ // the rawBody
+ if ( !body )
+ {
+ body = rawBody;
+ rawBody = NULL;
+ }
+ // Now we have possibly decorated message text in body pointer and
+ // in cleanup stack
+
+ // Divide the contents into normal body and the read-only quote fields
+ // Convert bytes length to words length
+ TInt readOnlyLength = iNewMessageTextPart->ReadOnlyPartSize() / 2;
+ if ( body )
+ {
+ TInt modifiableLength = body->Length() - readOnlyLength;
+
+ // Remove one newline from the end of the modifiable body if there's
+ // read-only quote present. This is because the field boundary appears
+ // as newline on the screen. This newline is added back when saving
+ // the message.
+ TInt lfLength = KIMSLineFeed().Length();
+ if ( readOnlyLength && modifiableLength >= lfLength &&
+ body->Mid( modifiableLength-lfLength, lfLength ) ==
+ KIMSLineFeed )
+ {
+ modifiableLength -= lfLength;
+ }
+
+ iContainer->SetBodyContentL( body->Left( modifiableLength ),
+ body->Right( readOnlyLength ) );
+ }
+
+ CleanupStack::PopAndDestroy( body );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::IncludeMessageTextAsyncL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::IncludeMessageTextAsyncL( TBool aEnsureSpaceInBegin /*= EFalse*/ )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ delete iBody;
+ iBody = NULL;
+ HBufC* rawBody = GetMessageBodyL();
+
+ // Ensure there's free space in the beginning of the message if required
+ if ( aEnsureSpaceInBegin && rawBody->Length() )
+ {
+ TText firstChar = (*rawBody)[0];
+ _LIT( KNewLines, "\r\n\x2028\x2029" );
+ if ( KNewLines().Locate( firstChar ) == KErrNotFound )
+ {
+ CleanupStack::PushL( rawBody );
+ // First character is not a new line character. Insert one.
+ iBody = HBufC::NewL( rawBody->Length() + KIMSLineFeed().Length() );
+ TPtr ptr = iBody->Des();
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *rawBody );
+ CleanupStack::PopAndDestroy( rawBody );
+ rawBody = NULL;
+ }
+ }
+ // If no modifications were needed, then just set body pointer to point
+ // the rawBody
+ if ( !iBody )
+ {
+ iBody = rawBody;
+ rawBody = NULL;
+ }
+ // Now we have possibly decorated message text in body pointer and
+ // in cleanup stack
+
+ // Divide the contents into normal body and the read-only quote fields
+ // Convert bytes length to words length
+ TInt readOnlyLength = iNewMessageTextPart->ReadOnlyPartSize() / 2;
+ //This check is unnecessary, but without that coverity complains
+ if ( iBody )
+ {
+ TInt modifiableLength = iBody->Length() - readOnlyLength;
+
+ // Remove one newline from the end of the modifiable body if there's
+ // read-only quote present. This is because the field boundary appears
+ // as newline on the screen. This newline is added back when saving
+ // the message.
+ TInt lfLength = KIMSLineFeed().Length();
+ if ( readOnlyLength && modifiableLength >= lfLength &&
+ iBody->Mid( modifiableLength-lfLength, lfLength ) == KIMSLineFeed )
+ {
+ modifiableLength -= lfLength;
+ }
+
+ iContainer->SetBodyContentAsyncL( iBody->Left( modifiableLength ),
+ iBody->Right( readOnlyLength ) );
+
+ // callback: SetBodyContentCompleteL
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SetBodyContentComplete()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SetBodyContentComplete()
+ {
+ delete iBody;
+ iBody = NULL;
+
+ if ( iOpeningWaitDialog )
+ {
+ TRAP_IGNORE( iOpeningWaitDialog->ProcessFinishedL() );
+ iOpeningWaitDialog = NULL;
+ }
+
+ iOpeningWaitNoteVisible = EFalse;
+ iIncludeMessageTextAsync = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::IsOpeningWaitNoteVisible()
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::IsOpeningWaitNoteVisible()
+ {
+ return iOpeningWaitNoteVisible;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitForwardFieldsL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitForwardFieldsL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ // set subject
+ HBufC* prefix = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_FORWARD_PREFIX );
+ HBufC* formattedSubject = NcsUtility::FormatSubjectLineL(
+ iOrigMessage->GetSubject(), *prefix );
+ CleanupStack::PushL( formattedSubject );
+ iContainer->SetSubjectL( *formattedSubject );
+ CleanupStack::PopAndDestroy( formattedSubject );
+ CleanupStack::PopAndDestroy( prefix );
+
+ // attachments
+ AttachmentsListControl()->Model()->Clear();
+ // <cmail>
+ TInt error = KErrNone;
+ TRAP( error, GetAttachmentsFromMailL() );
+ // </cmail>
+ SetAttachmentLabelContentL();
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SetPriority()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SetPriority()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ if ( iNewMessage && iNewMessage->IsFlagSet( EFSMsgFlag_Important ) )
+ {
+ iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityHigh );
+ }
+ else if ( iNewMessage && iNewMessage->IsFlagSet( EFSMsgFlag_Low ) )
+ {
+ iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityLow );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Sets follow-up flags to status pane indicators
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SetFollowUp()
+ {
+ if ( iNewMessage && iStatusPaneIndicators )
+ {
+ if ( iNewMessage->IsFlagSet( EFSMsgFlag_FollowUp ) )
+ {
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUp );
+ }
+ else if ( iNewMessage->IsFlagSet( EFSMsgFlag_FollowUpComplete ) )
+ {
+ iStatusPaneIndicators->SetFollowUpFlag(
+ CCustomStatuspaneIndicators::EFollowUpComplete );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitFieldsL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitFieldsL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
+
+ // to
+ RPointerArray<CFSMailAddress>& toRecipients =
+ iNewMessage->GetToRecipients();
+ RPointerArray<CNcsEmailAddressObject> ncsToRecipients;
+ CleanupResetAndDestroyClosePushL( ncsToRecipients );
+ NcsUtility::ConvertAddressArrayL( toRecipients, ncsToRecipients );
+ iContainer->SetToFieldAddressesL( ncsToRecipients );
+ CleanupStack::PopAndDestroy( &ncsToRecipients );
+
+ // cc
+ RPointerArray<CFSMailAddress>& ccRecipients =
+ iNewMessage->GetCCRecipients();
+ RPointerArray<CNcsEmailAddressObject> ncsCcRecipients;
+ CleanupResetAndDestroyClosePushL( ncsCcRecipients );
+ NcsUtility::ConvertAddressArrayL( ccRecipients, ncsCcRecipients );
+ iContainer->SetCcFieldAddressesL( ncsCcRecipients );
+ CleanupStack::PopAndDestroy( &ncsCcRecipients );
+
+ // bcc
+ RPointerArray<CFSMailAddress>& bccRecipients =
+ iNewMessage->GetBCCRecipients();
+ RPointerArray<CNcsEmailAddressObject> ncsBccRecipients;
+ CleanupResetAndDestroyClosePushL( ncsBccRecipients );
+ NcsUtility::ConvertAddressArrayL( bccRecipients, ncsBccRecipients );
+ iContainer->SetBccFieldAddressesL( ncsBccRecipients );
+ CleanupStack::PopAndDestroy( &ncsBccRecipients );
+
+ // set subject line
+ iContainer->SetSubjectL( iNewMessage->GetSubject() );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GetMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* CNcsComposeView::GetMessageBodyL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iNewMessageTextPart, Panic( ENcsBasicUi ) );
+
+ TInt messageSize = iNewMessageTextPart->FetchedContentSize();
+
+ HBufC* data = NULL;
+
+ if ( messageSize > 0 )
+ {
+ // fetch message body if there is something to fetch
+ data = HBufC::NewLC( messageSize );
+ TPtr dataPtr = data->Des();
+ iNewMessageTextPart->GetContentToBufferL( dataPtr, 0 );
+ CleanupStack::Pop( data );
+ }
+ else
+ {
+ data = KNullDesC().AllocL();
+ }
+
+ return data;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::CommitL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::CommitL( TBool aParseAddresses,
+ TFieldToCommit aFieldToCommit, TBool aSaveNow, TCommitType aType )
+ {
+ FUNC_LOG;
+ __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iNewMessageTextPart, Panic( ENcsBasicUi ) );
+
+ TBool commitToField = EFalse;
+ TBool commitCcField = EFalse;
+ TBool commitBccField = EFalse;
+ TBool commitSubjectField = EFalse;
+ TBool commitBodyField = EFalse;
+
+ switch ( aFieldToCommit )
+ {
+ case EAllFields:
+ commitToField = ETrue;
+ commitCcField = ETrue;
+ commitBccField = ETrue;
+ commitSubjectField = ETrue;
+ commitBodyField = ETrue;
+ break;
+ case EToField:
+ commitToField = ETrue;
+ break;
+ case ECcField:
+ commitCcField = ETrue;
+ break;
+ case EBccField:
+ commitBccField = ETrue;
+ break;
+ case EBodyField:
+ commitBodyField = ETrue;
+ break;
+ case ESubjectField:
+ commitSubjectField = ETrue;
+ break;
+ default:
+ break;
+ }
+
+ if ( commitToField )
+ {
+ RPointerArray<CFSMailAddress>& recipients =
+ iNewMessage->GetToRecipients();
+ recipients.ResetAndDestroy();
+ NcsUtility::ConvertAddressArrayL(
+ iContainer->GetToFieldAddressesL( aParseAddresses ), recipients );
+ }
+
+ if ( commitCcField )
+ {
+ RPointerArray<CFSMailAddress>& recipients =
+ iNewMessage->GetCCRecipients();
+ recipients.ResetAndDestroy();
+ NcsUtility::ConvertAddressArrayL(
+ iContainer->GetCcFieldAddressesL( aParseAddresses ), recipients );
+ }
+
+ if ( commitBccField )
+ {
+ RPointerArray<CFSMailAddress>& recipients =
+ iNewMessage->GetBCCRecipients();
+ recipients.ResetAndDestroy();
+ NcsUtility::ConvertAddressArrayL(
+ iContainer->GetBccFieldAddressesL( aParseAddresses ), recipients );
+ }
+
+ if ( commitSubjectField )
+ {
+ // get subject from UI to MSG object
+ HBufC* subject = iContainer->GetSubjectLC();
+ TPtr ptr = subject->Des();
+ // replace new line characters with spaces as Subject is normally
+ // one line only
+ AknTextUtils::ReplaceCharacters(
+ ptr, KLineSeparators, KReplacementChar );
+ iNewMessage->SetSubject( *subject );
+ CleanupStack::PopAndDestroy( subject );
+ }
+
+ if ( commitBodyField )
+ {
+ HBufC* body = iContainer->GetBodyContentLC();
+ TPtr bodyPtr = body->Des(); // this TPtr is needed only because of
+ // incorrect argument type in FW API, can be removed when API fixed
+ iNewMessageTextPart->SetContent( bodyPtr );
+ CleanupStack::PopAndDestroy( body );
+ iMessageTextPartModified = ETrue;
+ }
+
+ iMessageModified = ETrue;
+ RefreshToolbar();
+
+ if ( aSaveNow )
+ {
+ SaveMessageL();
+
+ // If this is final commit, then inform it via extension
+ if ( aType == EFinal )
+ {
+ CMailMessageExtension* messageExtension =
+ static_cast<CMailMessageExtension*>
+ ( iNewMessage->ExtensionL( KEmailMessageExtensionUid ) );
+ if ( messageExtension )
+ {
+ messageExtension->CommitL( *iNewMessage ) ;
+ iNewMessage->ReleaseExtension( messageExtension );
+ }
+ }
+ }
+ }
+
+TInt CNcsComposeView::SaveMessage()
+ {
+ FUNC_LOG;
+ TInt error = KErrNone;
+ TRAP( error, SaveMessageL() );
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// Saves the new message if it has been modifed since the last save.
+// -----------------------------------------------------------------------------
+void CNcsComposeView::SaveMessageL()
+ {
+ FUNC_LOG;
+ if ( iNewMessageTextPart && iMessageTextPartModified )
+ {
+ iNewMessageTextPart->SaveL();
+ iMessageTextPartModified = EFalse;
+ }
+
+ if ( iNewMessage && iMessageModified )
+ {
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoSafeExit
+// -----------------------------------------------------------------------------
+void CNcsComposeView::DoSafeExit( TExitMode aMode )
+ {
+ FUNC_LOG;
+ if ( !iExecutingDoExitL )
+ {
+ iExecutingDoExitL = ETrue;
+ TRAP_IGNORE( DoExitL( aMode ) );
+ iExecutingDoExitL = EFalse;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoExitL
+// -----------------------------------------------------------------------------
+void CNcsComposeView::DoExitL( TExitMode aMode )
+ {
+ FUNC_LOG;
+
+ TBool emptyMessage = ETrue;
+
+ if ( iAutoSaver && iContainer )
+ {
+ iAutoSaver->Enable( EFalse );
+
+ // check for some user input in some header field or in message body
+ TInt attaCount = AttachmentsListControl()->Model()->Count();
+ emptyMessage = iContainer->AreAddressFieldsEmpty() &&
+ iContainer->IsSubjectFieldEmpty() &&
+ iContainer->GetMessageFieldLength() < 1 &&
+ attaCount <= 0;
+ }
+
+ // Consider saving the draft if the message is not completely empty
+ if ( !emptyMessage )
+ {
+ if ( aMode == ESaveDraftQuery && !iMailSent && !iMailSendFailed )
+ {
+ TBool actionSucceeded = EFalse;
+
+ // DoSaveDraftL returns EFalse if the user query was cancelled
+ // or saving to Drafts failed
+ TRAPD( saveDraftError, actionSucceeded = DoSaveDraftL( ETrue ) );
+ if ( saveDraftError == KErrNone )
+ {
+ if ( !actionSucceeded )
+ {
+ // return to normal action
+ // (cancel was pressed in the query)
+ iAutoSaver->Enable( ETrue );
+ return;
+ }
+ }
+ else
+ {
+ }
+ }
+ else if ( aMode == ESaveDraft )
+ {
+ DoSaveDraftL( EFalse );
+ }
+ }
+ else if ( iNewMessage ) // message is empty
+ {
+ // delete the draft if it has been already saved earlier
+ TInt err = NcsUtility::DeleteMessage( iMailClient, iMailBox->GetId(),
+ iNewMessage->GetFolderId(), iNewMessage->GetMessageId() );
+ if ( !err && iMailBox->HasCapability(
+ EFSMBoxCapaSupportsDeletedItemsFolder ) )
+ {
+ err = NcsUtility::DeleteMessage( iMailClient, iMailBox->GetId(),
+ iMailBox->GetStandardFolderId( EFSDeleted ),
+ iNewMessage->GetMessageId() );
+ }
+
+ if ( !err && !iAppUi.AppUiExitOngoing() )
+ {
+ // Simulate delete event so that drafts folder is
+ // updated correctly.
+ RArray<TFSMailMsgId> messageIds;
+ CleanupClosePushL( messageIds );
+ messageIds.AppendL( iNewMessage->GetMessageId() );
+ TFSMailMsgId folderId = iNewMessage->GetFolderId();
+ TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
+ iAppUi.EventL( TFSEventMailDeleted,
+ mailboxId, &messageIds, &folderId, NULL );
+ CleanupStack::PopAndDestroy( &messageIds );
+ }
+ }
+
+ // Clear attachment control now that message has been sent
+ // othewise this will kind of leak memory by leaving attachments
+ // in the list, even if they have been sent.
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
+ attachmentControl = AttachmentsListControl();
+ if ( attachmentControl && attachmentControl->Model() )
+ {
+ attachmentControl->Model()->Clear();
+ }
+ ExitComposer();
+ TIMESTAMP( "Editor exited" );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoOpenAttachmentList
+// Opens the currently focused attachment
+// -----------------------------------------------------------------------------
+void CNcsComposeView::DoOpenAttachmentListL()
+ {
+ FUNC_LOG;
+
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl
+ = AttachmentsListControl();
+
+ TInt index( iContainer ? iContainer->FocusedAttachmentLabelIndex()
+ : KNoAttachmentLabelFocused );
+ if ( KNoAttachmentLabelFocused != index &&
+ attachmentControl && attachmentControl->Model() )
+ {
+ CFSEmailUiSendAttachmentsListModelItem* item =
+ static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
+ attachmentControl->Model()->Item( index ) );
+
+ if ( item && !item->IsRemote() ) // cannot open remote attachments
+ {
+ CFSMailMessagePart* msgPart =
+ iNewMessage->ChildPartL( item->MailMsgPartId() );
+ CleanupStack::PushL( msgPart );
+ TFsEmailUiUtility::OpenAttachmentL( *msgPart );
+ CleanupStack::PopAndDestroy( msgPart );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::LaunchStylusPopupMenu
+// Show stylus popup menu for the attachments line
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::LaunchStylusPopupMenu( const TPoint& aPenEventScreenLocation )
+ {
+ FUNC_LOG;
+
+ CFSEmailUiSendAttachmentsListModel* attachmentModel =
+ ( AttachmentsListControl() ?
+ AttachmentsListControl()->Model() : NULL );
+ TInt count( attachmentModel ? attachmentModel->Count() : 0 );
+ TBool attachmentsInModel( count > 0 );
+ CFSEmailUiSendAttachmentsListModelItem* item( NULL );
+
+ if ( attachmentsInModel )
+ {
+ item = static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
+ attachmentModel->Item(
+ iContainer->FocusedAttachmentLabelIndex() ) );
+ // Only non-remote attachments can be opened
+ TBool dimOpenMenuItem = !item || item->IsRemote();
+ iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdOpenAttachment, dimOpenMenuItem );
+
+ // Read-only attachments cannot be removed
+ TBool dimRemoveMenuItem = !item || item->IsReadOnly();
+ iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdRemoveAttachment, dimRemoveMenuItem );
+ }
+
+ // Set the position for the popup
+ iStylusPopUpMenu->SetPosition( aPenEventScreenLocation );
+
+ // Display the popup.
+ iStylusPopUpMenu->ShowMenu();
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GetAttachmentsFromMail
+// -----------------------------------------------------------------------------
+void CNcsComposeView::GetAttachmentsFromMailL()
+ {
+ FUNC_LOG;
+
+ TInt error( KErrNone );
+
+ RPointerArray<CFSMailMessagePart> attachments;
+ CleanupResetAndDestroyClosePushL( attachments );
+ TRAP( error, iNewMessage->AttachmentListL( attachments ) );
+ User::LeaveIfError( error );
+
+ for ( TInt i=0; i<attachments.Count(); ++i )
+ {
+ TFileType fileType = TFsEmailUiUtility::GetFileType(
+ attachments[i]->AttachmentNameL(),
+ attachments[i]->GetContentType() );
+
+ TBool isReadOnly = ( attachments[i]->ReadOnlyPartSize() > 0 );
+ TBool isRemote = EFalse;
+
+ if ( attachments[i]->FetchedContentSize() <
+ attachments[i]->ContentSize() )
+ {
+ if ( iMailBox->HasCapability( EFSMBoxCapaSmartForward ) )
+ {
+ isRemote = ETrue;
+ }
+ else
+ {
+ __ASSERT_DEBUG( EFalse, Panic(EFSEmailUiUnexpectedValue) );
+ User::Leave( KErrNotFound );
+ continue;
+ }
+ }
+
+ AttachmentsListControl()->AppendFileToModelL(
+ attachments[i]->GetPartId(),
+ attachments[i]->AttachmentNameL(),
+ attachments[i]->ContentSize(),
+ fileType,
+ isReadOnly,
+ isRemote );
+ }
+
+ CleanupStack::PopAndDestroy( &attachments );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::FileExistsInModel
+// -----------------------------------------------------------------------------
+TBool CNcsComposeView::FileExistsInModel( TFSMailMsgId aAttachmentId )
+ {
+ FUNC_LOG;
+
+ TInt count( AttachmentsListControl()->Model()->Count() );
+
+ for ( TInt i=0; i < count; ++i )
+ {
+ CFSEmailUiSendAttachmentsListModelItem* item =
+ static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
+ AttachmentsListControl()->Model()->Item(i) );
+ if ( aAttachmentId.Id() == item->MailMsgPartId().Id() )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GenerateReplyHeaderLC
+// -----------------------------------------------------------------------------
+HBufC* CNcsComposeView::GenerateReplyHeaderLC()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iOrigMessage, Panic( ENcsBasicUi ) );
+
+ // separator line
+ HBufC* separator =
+ StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_MESSAGE_LINE_SEPARATOR ); //1
+
+ // from line
+ RPointerArray<CNcsEmailAddressObject> senderArray;
+ CleanupResetAndDestroyClosePushL( senderArray );
+ CFSMailAddress* sender = iOrigMessage->GetSender();
+ if ( sender )
+ {
+ CNcsEmailAddressObject* ncsSender =
+ NcsUtility::CreateNcsAddressL( *sender );
+ CleanupStack::PushL( ncsSender );
+ senderArray.AppendL( ncsSender );
+ CleanupStack::Pop( ncsSender ); // now owned by senderArray
+ }
+ HBufC* fromLine =
+ NcsUtility::GenerateFromLineToMessageBodyL( senderArray );
+ CleanupStack::PopAndDestroy( &senderArray );
+ CleanupStack::PushL( fromLine ); //2
+
+ // sent line
+ HBufC* sentLine =
+ NcsUtility::GenerateSentLineToMessageBodyL( *iOrigMessage );
+ CleanupStack::PushL( sentLine ); //3
+
+ // to line
+ RPointerArray<CNcsEmailAddressObject> ncsToRecipients;
+ CleanupResetAndDestroyClosePushL( ncsToRecipients );
+ RPointerArray<CFSMailAddress>& toRecipients =
+ iOrigMessage->GetToRecipients();
+ NcsUtility::ConvertAddressArrayL( toRecipients, ncsToRecipients );
+ HBufC* toLine = NcsUtility::GenerateAddressLineToMessageBodyL(
+ ncsToRecipients, NcsUtility::ERecipientTypeTo );
+ CleanupStack::PopAndDestroy( &ncsToRecipients );
+ CleanupStack::PushL( toLine ); //4
+
+ // cc line
+ RPointerArray<CFSMailAddress>& ccRecipients =
+ iOrigMessage->GetCCRecipients();
+ TBool hasCcLine = ( ccRecipients.Count() > 0 );
+ HBufC* ccLine = NULL;
+ if ( hasCcLine )
+ {
+ RPointerArray<CNcsEmailAddressObject> ncsCcRecipients;
+ CleanupResetAndDestroyClosePushL( ncsCcRecipients );
+ NcsUtility::ConvertAddressArrayL( ccRecipients, ncsCcRecipients );
+ ccLine = NcsUtility::GenerateAddressLineToMessageBodyL(
+ ncsCcRecipients, NcsUtility::ERecipientTypeCc );
+ CleanupStack::PopAndDestroy( &ncsCcRecipients );
+ CleanupStack::PushL( ccLine ); //5
+ }
+
+ // subject line
+ HBufC* subjectLine = NcsUtility::GenerateSubjectLineToMessageBodyL(
+ iOrigMessage->GetSubject() );
+ CleanupStack::PushL( subjectLine ); //6
+
+ // Body
+ HBufC* body = NULL;
+ TBool hasBody = EFalse;
+ CFSMailMessagePart* textBodyPart = iOrigMessage->PlainTextBodyPartL();
+ if ( textBodyPart )
+ {
+ // Plain text body part present, no need
+ // to generate it from HTML body part
+ delete textBodyPart;
+ }
+ else
+ {
+ // Generate body part for reply
+ CFSMailMessagePart* htmlBodyPart = iOrigMessage->HtmlBodyPartL();
+ if ( htmlBodyPart )
+ {
+ CleanupStack::PushL( htmlBodyPart );
+
+ HBufC* htmlData =
+ HBufC::NewLC( htmlBodyPart->FetchedContentSize() );
+ TPtr pointer = htmlData->Des();
+ htmlBodyPart->GetContentToBufferL( pointer, 0 );
+
+ body = TFsEmailUiUtility::ConvertHtmlToTxtL( *htmlData );
+
+ CleanupStack::PopAndDestroy( htmlData );
+ CleanupStack::PopAndDestroy( htmlBodyPart );
+
+ CleanupStack::PushL( body ); //7
+
+ hasBody = ETrue;
+ }
+ }
+ // calculate total length
+ TInt length = 0;
+ length += separator->Length();
+ length += KIMSLineFeed().Length();
+ length += fromLine->Length();
+ length += KIMSLineFeed().Length();
+ length += sentLine->Length();
+ length += KIMSLineFeed().Length();
+ length += toLine->Length();
+ if ( hasCcLine )
+ {
+ length += KIMSLineFeed().Length();
+ length += ccLine->Length();
+ }
+ length += KIMSLineFeed().Length();
+ length += subjectLine->Length();
+ length += KIMSLineFeed().Length();
+ if ( hasBody )
+ {
+ length += body->Length();
+ }
+ length += KIMSLineFeed().Length();
+ length += KIMSLineFeed().Length();
+
+ // create buffer and write contents
+ HBufC* header = HBufC::NewL( length );
+ TPtr ptr = header->Des();
+ ptr.Append( *separator );
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *fromLine );
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *sentLine );
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *toLine );
+ if ( hasCcLine )
+ {
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *ccLine );
+ }
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( *subjectLine );
+ ptr.Append( KIMSLineFeed );
+ if ( hasBody )
+ {
+ ptr.Append( *body );
+ }
+ ptr.Append( KIMSLineFeed );
+ ptr.Append( KIMSLineFeed );
+
+ // leave header on the cleanup stack
+ if ( hasBody )
+ {
+ CleanupStack::PopAndDestroy( body ); //-7
+ }
+ CleanupStack::PopAndDestroy( subjectLine ); //-6
+ if ( hasCcLine )
+ {
+ CleanupStack::PopAndDestroy( ccLine ); //-5
+ }
+ CleanupStack::PopAndDestroy( toLine ); //-4
+ CleanupStack::PopAndDestroy( sentLine ); //-3
+ CleanupStack::PopAndDestroy( fromLine ); //-2
+ CleanupStack::PopAndDestroy( separator ); //-1
+
+ CleanupStack::PushL( header );
+
+ return header;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GenerateSmartTagLC
+// -----------------------------------------------------------------------------
+HBufC* CNcsComposeView::GenerateSmartTagLC()
+ {
+ FUNC_LOG;
+
+ HBufC* tag = StringLoader::LoadLC( R_FSE_EDITOR_SMART_TAG );
+
+ return tag;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitReplyOrForwardUiL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitReplyOrForwardUiL()
+ {
+ FUNC_LOG;
+ // Show "Opening" wait note if the message body is large
+ iOpeningWaitNoteVisible = EFalse;
+ if ( TFsEmailUiUtility::IsMessageBodyLargeL(iOrigMessage) )
+ {
+ TFsEmailUiUtility::ShowWaitNoteL( iOpeningWaitDialog,
+ R_FSE_WAIT_OPENING_TEXT, EFalse, ETrue );
+ iOpeningWaitNoteVisible = ETrue;
+ }
+
+ // disable this flag if "old style" sync mode is needed
+ // for including body of text
+ iIncludeMessageTextAsync = ETrue;
+
+ if ( iCustomMessageId == TUid::Uid( KEditorCmdReply ) )
+ {
+ GenerateReplyMessageL( EFalse );
+ InitReplyUiL( EFalse );
+ }
+ else if ( iCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
+ {
+ GenerateReplyMessageL( ETrue );
+ InitReplyUiL( ETrue );
+ }
+ else if ( iCustomMessageId == TUid::Uid( KEditorCmdForward ) )
+ {
+ GenerateForwardMessageL();
+ InitForwardUiL();
+ }
+ else
+ {
+ // This shouldn't ever happen. Panic in debug builds.
+ ASSERT( EFalse );
+ }
+
+ // Close the "Opening" wait note if it was shown
+ // and include message text was done synchronously
+ if ( !iIncludeMessageTextAsync && iOpeningWaitDialog )
+ {
+ iOpeningWaitDialog->ProcessFinishedL();
+ iOpeningWaitDialog = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GenerateReplyMessageL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::GenerateReplyMessageL( TBool aReplyAll )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+
+ TReplyForwardParams params;
+ params.iHeader = GenerateReplyHeaderLC();
+ params.iSmartTag = GenerateSmartTagLC();
+ TPckgBuf<TReplyForwardParams> buf( params );
+ HBufC* temp = HBufC::NewLC( buf.Length() );
+ temp->Des().Copy( buf );
+
+ //<cmail> this is actually a waited async method
+ iFakeSyncGoingOn = ETrue;
+ iNewMessage = iMailBox->CreateReplyMessage(
+ iLaunchParams.iMsgId, aReplyAll, *temp );
+ iFakeSyncGoingOn = EFalse;
+ //</cmail>
+ // Compose screen does not send cal messages, make sure
+ // that cal event flag is not left active by some protocol
+ if ( iNewMessage )
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_CalendarMsg );
+ }
+ CleanupStack::PopAndDestroy( temp );
+ CleanupStack::PopAndDestroy( params.iSmartTag );
+ CleanupStack::PopAndDestroy( params.iHeader );
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iFakeSyncGoingOn = ETrue; //<cmail>
+ TRAPD( error, TFsEmailUiUtility::MoveMessageToDraftsL(
+ *iMailBox, *iNewMessage ) );
+ iFakeSyncGoingOn = EFalse; //</cmail>
+ User::LeaveIfError( error );
+
+ if ( iNewMessage->GetContentType() != KFSMailContentTypeMultipartMixed )
+ {
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ iMessageModified = EFalse;
+ }
+
+ TFsEmailUiUtility::CreatePlainTextPartL( *iNewMessage, iNewMessageTextPart );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::GenerateForwardMessageL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::GenerateForwardMessageL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+
+ TReplyForwardParams params;
+ params.iHeader = GenerateReplyHeaderLC();
+ params.iSmartTag = GenerateSmartTagLC();
+ TPckgBuf<TReplyForwardParams> buf( params );
+ HBufC* temp = HBufC::NewLC( buf.Length() );
+ temp->Des().Copy( buf );
+
+ //<cmail> this is actually a waited async call
+ iFakeSyncGoingOn = ETrue;
+ iNewMessage = iMailBox->CreateForwardMessage( iLaunchParams.iMsgId, *temp );
+ iFakeSyncGoingOn = EFalse;
+ //</cmail>
+ // Compose screen does not send cal messages, make sure
+ // that cal event flag is not left active by some protocol
+ if ( iNewMessage )
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_CalendarMsg );
+ }
+ CleanupStack::PopAndDestroy( temp );
+ CleanupStack::PopAndDestroy( params.iSmartTag );
+ CleanupStack::PopAndDestroy( params.iHeader );
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iFakeSyncGoingOn = ETrue; //<cmail>
+ TRAPD( error, TFsEmailUiUtility::MoveMessageToDraftsL(
+ *iMailBox, *iNewMessage ) );
+ iFakeSyncGoingOn = EFalse; //<cmail>
+ User::LeaveIfError( error );
+
+ if ( iNewMessage->GetContentType() != KFSMailContentTypeMultipartMixed )
+ {
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ }
+
+ TFsEmailUiUtility::CreatePlainTextPartL(
+ *iNewMessage, iNewMessageTextPart );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitReplyUiL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitReplyUiL( TBool aReplyAll )
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety check
+ {
+ InitReplyFieldsL( aReplyAll );
+ // if flag is set -
+ // message text will be included asynchronously by calling method
+ // IncludeMessageTextAsyncL() at the end of view activation or when
+ // all attachments are downloaded - this is done because formatting
+ // text in CTextView with method FormatTextL() causes phone
+ // irresponsive.
+ if ( !iIncludeMessageTextAsync )
+ {
+ IncludeMessageTextL( ETrue );
+ }
+ iContainer->SetFocusToMessageFieldL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitUiGeneralL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitUiGeneralL()
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety check
+ {
+ AppUi()->AddToStackL( iContainer );
+ iContainer->SetMenuBar( Cba() );
+ iContainer->UpdateScrollBar();
+
+ // Set title pane text
+ const TDesC& mbName = iMailBox->GetName();
+ iAppUi.SetTitlePaneTextL( mbName );
+
+ // Set priority flag
+ SetPriority();
+
+ // Set follow-up flag
+ SetFollowUp();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitForwardUiL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitForwardUiL()
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety check
+ {
+ InitForwardFieldsL();
+ // if flag is set -
+ // message text will be included asynchronously by calling method
+ // IncludeMessageTextAsyncL() at the end of view activation or when
+ // all attachments are downloaded - this is done because formatting
+ // text in CTextView with method FormatTextL() causes phone
+ // irresponsive.
+ if ( !iIncludeMessageTextAsync )
+ {
+ IncludeMessageTextL( ETrue );
+ }
+ iContainer->SetFocusToToField();
+ iContainer->SelectAllToFieldTextL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SetReplyForwardFlag
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SetReplyForwardFlagL()
+ {
+ FUNC_LOG;
+
+ if ( iFirstStartCompleted && iOrigMessage )
+ {
+ if ( iCustomMessageId == TUid::Uid( KEditorCmdReply ) ||
+ iCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
+ {
+ iOrigMessage->SetFlag( EFSMsgFlag_Answered );
+ iOrigMessage->SaveMessageL();
+ }
+ else if ( iCustomMessageId == TUid::Uid( KEditorCmdForward ) )
+ {
+ iOrigMessage->SetFlag( EFSMsgFlag_Forwarded );
+ iOrigMessage->SaveMessageL();
+ }
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::MailBoxSupportsSmartReply
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::MailBoxSupportsSmartReply()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+
+ return iMailBox->HasCapability( EFSMBoxCapaSmartReply );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::MailBoxSupportsSmartForward
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::MailBoxSupportsSmartForward()
+ {
+ FUNC_LOG;
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+
+ return iMailBox->HasCapability( EFSMBoxCapaSmartForward );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HasUnfetchedAttachmentsL
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::HasUnfetchedAttachmentsL( CFSMailMessage& aMsg )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( &aMsg, Panic( ENcsBasicUi ) );
+
+ TBool ret = EFalse;
+
+ RPointerArray<CFSMailMessagePart> attachments;
+ CleanupResetAndDestroyClosePushL( attachments );
+ aMsg.AttachmentListL( attachments );
+ for ( TInt i=0; i<attachments.Count(); i++ )
+ {
+ if ( EFSFull != attachments[i]->FetchLoadState() )
+ {
+ ret = ETrue;
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( &attachments );
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HandleActionL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::HandleActionL( const TAlfActionCommand& aActionCommand )
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted && iNewMessage && iMailBox
+ && aActionCommand.Id() == KCmdEditorAutoSave )
+ {
+ CommitL( EFalse, EAllFields, ETrue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SaveToDraftsL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SaveToDraftsL( TBool aParseAddresses )
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety
+ {
+ __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
+ __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
+
+ iFakeSyncGoingOn = ETrue;
+ TRAPD( error, CommitL( aParseAddresses, EAllFields, ETrue, EFinal ) );
+ iFakeSyncGoingOn = EFalse;
+ User::LeaveIfError( error );
+
+ iFakeSyncGoingOn = ETrue;
+ TRAP( error, TFsEmailUiUtility::MoveMessageToDraftsL(
+ *iMailBox, *iNewMessage ) );
+ iFakeSyncGoingOn = EFalse;
+ User::LeaveIfError( error );
+
+ if ( !iAppUi.AppUiExitOngoing() )
+ {
+ // Simulate a new mail event to ensure that saved message becomes
+ // visible in the mail list.
+ // All protocols do not send event automatically in this case.
+ RArray<TFSMailMsgId> messageIdArray;
+ CleanupClosePushL( messageIdArray );
+ messageIdArray.Append( iNewMessage->GetMessageId() );
+ TFSMailMsgId folderId = iNewMessage->GetFolderId();
+ TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
+ iAppUi.EventL(
+ TFSEventNewMail, mailboxId, &messageIdArray, &folderId, NULL );
+ // Update displayed mail info if the mail was created previously
+ iAppUi.EventL(
+ TFSEventMailChanged, mailboxId, &messageIdArray,
+ &folderId, NULL );
+ CleanupStack::PopAndDestroy( &messageIdArray );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::FetchLogicComplete
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeView::FetchLogicComplete(
+ TComposerFetchState /*aState*/, TInt aError )
+ {
+ FUNC_LOG;
+ TBool result = EFalse;
+ if ( iFirstStartCompleted ) // Safety
+ {
+ if ( !aError )
+ {
+ TRAP( aError, InitReplyOrForwardUiL() );
+ iAutoSaver->Enable( ETrue );
+ }
+ else
+ {
+ // something went wrong
+ DoSafeExit( ENoSave );
+ iMailFetchingErrCode = aError;
+ result = ETrue;
+ }
+ }
+ if ( iFetchWaitDialog && !iFetchDialogCancelled )
+ {
+ TRAP_IGNORE( iFetchWaitDialog->ProcessFinishedL() );
+ iFetchWaitDialog = NULL;
+ }
+
+ if ( iMailFetchingErrCode == KErrNone )
+ {
+ if ( iIncludeMessageTextAsync )
+ {
+ // in case the "Opening" wait note was closed by
+ // wait note "Retrieving"
+ if ( !iOpeningWaitDialog && iOpeningWaitNoteVisible )
+ {
+ TRAP_IGNORE( TFsEmailUiUtility::ShowWaitNoteL( iOpeningWaitDialog,
+ R_FSE_WAIT_OPENING_TEXT, EFalse, ETrue ) );
+ }
+ }
+
+ if ( iViewFullyActivated && iIncludeMessageTextAsync )
+ {
+ // include message body in async way.
+ // it is done here only if view was already activated
+ // this mean that attachments were added in async way
+ // and we couldn't start async including body text
+ TRAP_IGNORE( IncludeMessageTextAsyncL( ETrue ) );
+ }
+ }
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ExitComposer
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ExitComposer()
+ {
+ FUNC_LOG;
+
+ if ( iStatusPaneIndicators )
+ {
+ iStatusPaneIndicators->HideStatusPaneIndicators();
+ }
+
+ // lower flag to indicate that view is no longer
+ // able to handle user commands
+ iViewReady = EFalse;
+
+ // view switching and alfred operations should be avoided
+ // when Appui exit has been initialised
+ if ( !iAppUi.AppUiExitOngoing() )
+ {
+ // change to previous view
+ TRAP_IGNORE( NavigateBackL() );
+ }
+
+ // Cleanup message contents to prevent ChildDoDeactivate()
+ // from saving the message to drafts again
+ ResetComposer();
+
+ SafeDelete( iFetchLogic );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::CreateContainerL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::CreateContainerL()
+ {
+ FUNC_LOG;
+ TInt flags = NULL;
+ if ( iCrHandler->EditorCCVisible() )
+ {
+ flags |= CNcsComposeViewContainer::ECcFieldVisible;
+ }
+ if ( iCrHandler->EditorBCVisible() )
+ {
+ flags |= CNcsComposeViewContainer::EBccFieldVisible;
+ }
+ TRect rect = ClientRect();
+ iContainer = CNcsComposeViewContainer::NewL( *this, rect, *iMailBox,
+ *iAutoSaver, flags );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ResetComposer
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ResetComposer()
+ {
+ FUNC_LOG;
+
+ delete iMailBox;
+ iMailBox = NULL;
+ delete iOrigMessage;
+ iOrigMessage = NULL;
+ delete iNewMessageTextPart;
+ iNewMessageTextPart = NULL;
+ delete iNewMessage;
+ iNewMessage = NULL;
+ iDlg = NULL;
+
+ if ( iContainer )
+ {
+ AppUi()->RemoveFromStack( iContainer );
+ delete iContainer;
+ iContainer = NULL;
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::SaveAndCleanPreviousMessage
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::SaveAndCleanPreviousMessage()
+ {
+ FUNC_LOG;
+
+ if ( iFirstStartCompleted && iContainer && iNewMessage && iMailBox )
+ {
+
+ TBool noAddrOrNoMesBody = iContainer->AreAddressFieldsEmpty() &&
+ iContainer->IsSubjectFieldEmpty() &&
+ (iContainer->GetMessageFieldLength() < 1);
+
+ // save to Drafts if there's some user input in some header field
+ // or in message body
+ if ( !noAddrOrNoMesBody )
+ {
+ TRAPD( error, DoSaveDraftL( EFalse ) );
+ if ( error )
+ {
+ }
+ }
+
+ // store the message IDs to launch parameters to be able to return
+ // to same message if desired
+ iLaunchParams.iMsgId = iNewMessage->GetMessageId();
+ iLaunchParams.iFolderId = iNewMessage->GetFolderId();
+ iLaunchParams.iMailboxId = iMailBox->GetId();
+ }
+ ResetComposer();
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::AsyncExit
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeView::AsyncExit( TAny* aSelfPtr )
+ {
+ FUNC_LOG;
+ CNcsComposeView* self =
+ static_cast<CNcsComposeView*>( aSelfPtr );
+
+ TRAPD( err,self->AsyncExitL() );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::AsyncExitL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::AsyncExitL()
+ {
+ FUNC_LOG;
+ if ( iFakeSyncGoingOn || iExecutingDoExitL )
+ {
+ // if some sync method is still going on, we continue waiting
+ iActiveHelper->Cancel();
+ iActiveHelper->Start();
+ }
+ else
+ {
+ ExitComposer();
+ // for some strange reason composer view is stuck and only option
+ // was to call ProcessCommandL with EAknCmdExit
+ ProcessCommandL( EAknCmdExit );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::HandleContainerChangeRequiringToolbarRefresh
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::HandleContainerChangeRequiringToolbarRefresh()
+ {
+ RefreshToolbar();
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ShowFetchingWaitNoteL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ShowFetchingWaitNoteL()
+ {
+ FUNC_LOG;
+ if ( !iAppUi.AppUiExitOngoing() )
+ {
+ if ( !iFetchWaitDialog )
+ {
+ iFetchWaitDialog = new (ELeave) CAknWaitDialog(
+ reinterpret_cast<CEikDialog**>( &iFetchWaitDialog ), EFalse);
+ iFetchWaitDialog->SetCallback( this );
+ iFetchDialogCancelled = EFalse;
+ iFetchWaitDialog->ExecuteLD( R_FSE_FETCHING_WAIT_DIALOG );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DialogDismissedL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DialogDismissedL( TInt aButtonId )
+ {
+ FUNC_LOG;
+ if ( aButtonId == EAknSoftkeyCancel && iFetchLogic )
+ {
+ iFetchDialogCancelled = ETrue;
+ iFetchLogic->CancelFetchings();
+ }
+ }
+
+TBool CNcsComposeView::IsPreparedForExit()
+ {
+ return !( iFakeSyncGoingOn ||iExecutingDoExitL );
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the speficied button from the toolbar extension, or NULL,
+// if the button is not found.
+// ---------------------------------------------------------------------------
+//
+CAknButton* CNcsComposeView::Button( TInt aCmdId,
+ CAknToolbarExtension* aExtension )
+ {
+ CAknButton* button = NULL;
+
+ // Get toolbar extension.
+ CAknToolbarExtension* extension = aExtension;
+ if ( !aExtension )
+ {
+ CAknToolbar* toolbar = Toolbar();
+ if ( toolbar )
+ {
+ extension = toolbar->ToolbarExtension();
+ }
+ }
+
+ // Get specified button from the extension.
+ if ( extension )
+ {
+ button = static_cast<CAknButton*>( extension->ControlOrNull( aCmdId ) );
+ }
+
+ return button;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns ETrue if WLAN connection is active.
+// ---------------------------------------------------------------------------
+//
+TBool CNcsComposeView::WLANConnectionActive()
+ {
+ TBool ret = EFalse;
+
+ TInt wlanState;
+ TInt err = RProperty::Get( KPSUidWlan, KPSWlanIndicator, wlanState );
+
+ if ( err == KErrNone )
+ {
+ if ( wlanState == EPSWlanIndicatorActive ||
+ wlanState == EPSWlanIndicatorActiveSecure )
+ {
+ ret = ETrue;
+ }
+ }
+
+ return ret;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::NewL()
+// ---------------------------------------------------------------------------
+//
+CActiveHelper* CActiveHelper::NewL( CNcsComposeView* aSession )
+ {
+ CActiveHelper* self = new(ELeave) CActiveHelper( aSession );
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::~CActiveHelper()
+// ---------------------------------------------------------------------------
+//
+CActiveHelper::~CActiveHelper( )
+ {
+ Cancel();
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::Start()
+// ---------------------------------------------------------------------------
+//
+void CActiveHelper::Start()
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::CActiveHelper()
+// ---------------------------------------------------------------------------
+//
+CActiveHelper::CActiveHelper( CNcsComposeView* aSession )
+ : CActive( EPriorityLow )
+ {
+ iComposeView = aSession;
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::RunL()
+// ---------------------------------------------------------------------------
+//
+void CActiveHelper::RunL()
+ {
+ if( iComposeView )
+ iComposeView->AsyncExitL();
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::DoCancel()
+// ---------------------------------------------------------------------------
+//
+void CActiveHelper::DoCancel()
+ {
+ // Empty
+ }
+
+// ---------------------------------------------------------------------------
+// CActiveHelper::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CActiveHelper::ConstructL()
+ {
+ CActiveScheduler::Add( this );
+ }
+