--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncscomposeview.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,2960 @@
+/*
+* 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> //<cmail>
+#include <MsgAttachmentUtils.h>//<cmail>
+//<cmail>
+#include <featmgr.h>
+#include "CFSMailBox.h"
+#include "CFSMailMessage.h"
+#include "CFSMailAddress.h"
+#include "CFSMailClient.h"
+#include "CFSMailCommon.h"
+#include <csxhelp/cmail.hlp.hrh>
+//</cmail>
+//<cmail> Touch
+#include <akntoolbar.h>
+#include <akntoolbarextension.h>
+#include <AknUtils.h>
+//</cmail> Touch
+#include <FreestyleEmailUi.rsg>
+#include <freestyleemailui.mbg>
+
+#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"
+
+
+// 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)//<cmail>
+ {
+ 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;
+ }
+
+// CFSEmailUiMsgDetailsVisualiser::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
+ CAlfControlGroup& attListControlGroup = iEnv.NewControlGroupL( KSendAttachmentManagerDisplayGroup ); // owned by AlfEnv
+ 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 );
+ }
+
+// -----------------------------------------------------------------------------
+// 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;
+ }
+ }
+
+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 just to be safe
+ iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
+ iAsyncCallback->CallBack();
+ }
+ else if(iFakeSyncGoingOn || iExecutingDoExitL) //we starts this low priority active obj so that iwait in plugins finish
+ {
+ iActiveHelper->Cancel();
+ iActiveHelper->Start();
+ }
+ else
+ {
+ DoSafeExit( ESaveDraft );
+ //iAppUi.Exit();
+ }
+
+ if(iFetchLogic)
+ {
+ iFetchLogic->CancelFetchings();
+ }
+
+ //ResetComposer(); // already done in DoExitL
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::Id()
+// Returns View's ID.
+// -----------------------------------------------------------------------------
+//
+TUid CNcsComposeView::Id() const
+ {
+ FUNC_LOG;
+ return MailEditorId;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ChildDoActivateL()
+// Activate the Compose view
+// -----------------------------------------------------------------------------
+//
+// <cmail> Toolbar
+/*void CNcsComposeView::DoActivateL( const TVwsViewId& aPrevViewId,
+ TUid aCustomMessageId, const TDesC8& aCustomMessage )*/
+void CNcsComposeView::ChildDoActivateL( const TVwsViewId& aPrevViewId,
+ TUid aCustomMessageId, const TDesC8& aCustomMessage )
+// </cmail> Toolbar
+ {
+ FUNC_LOG;
+ if ( !iFirstStartCompleted )
+ {
+ DoFirstStartL();
+ }
+ Toolbar()->SetDimmed(ETrue);
+ // Set status pane indicators
+ iStatusPaneIndicators = iAppUi.GetStatusPaneIndicatorContainer();
+ iStatusPaneIndicators->ShowStatusPaneIndicators();
+
+ // Notify base class about view being entered unless we 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 open 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()) //<cmail>
+ 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();
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::OfferToolbarEventL
+// -----------------------------------------------------------------------------
+void CNcsComposeView::OfferToolbarEventL( TInt aCommand )
+ {
+ FUNC_LOG;
+ bool attachmentAddition = EFalse;
+ switch (aCommand)
+ {
+ case EFsEmailUiTbCmdSend:
+ if (iContainer && iContainer->AreAddressFieldsEmpty())
+ {
+ RefreshToolbar();
+ }
+ else
+ {
+ HandleCommandL( ENcsCmdSend );
+ }
+ break;
+ case EFsEmailUiTbCmdAddRecipient:
+ if (iContainer)
+ {
+ iContainer->AppendAddressesL();
+ }
+ 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 just to be safe
+ iAsyncAttachmentAdd->Set( TCallBack( AsyncAddAttachment, this ) );
+ iAsyncAttachmentAdd->CallBack();
+ }
+ }
+
+// <cmail> Toolbar
+// -----------------------------------------------------------------------------
+// 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)
+ {
+ // DimAllOptions if remotesearch is in progress, cos it takes you in a different view
+ TBool dimAllOptions = iContainer->IsRemoteSearchInprogress();
+ SetToolbarItemDimmed( EFsEmailUiTbCmdExpandInsert, dimAllOptions );
+ SetToolbarItemDimmed( EFsEmailUiTbCmdSend,
+ iContainer->AreAddressFieldsEmpty() );
+ if ( (iContainer->IsFocusBcc() || iContainer->IsFocusCc() || iContainer->IsFocusTo()) && !dimAllOptions )
+ {
+ SetToolbarItemDimmed( EFsEmailUiTbCmdAddRecipient, EFalse );
+ }
+ else
+ {
+ SetToolbarItemDimmed( EFsEmailUiTbCmdAddRecipient, ETrue );
+ }
+ }
+ }
+// </cmail> Toolbar
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::ChildDoDeactivate()
+// Deactivate the Compose view
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::ChildDoDeactivate()
+ {
+ FUNC_LOG;
+
+ 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 ) );
+
+ //<cmail>
+ //we are forbiding to change MSK label, cause popup will be opend
+ iContainer->SwitchChangeMskOff(ETrue);
+ //</cmail>
+
+ 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 currently, 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_MORE_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 (default text is as subject)
+ 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() )
+ {
+ // 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->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 );
+ DoSafeExit(); // Exit after sending failed for other reason than KErrBadName
+ }
+ }
+ break;
+ case ENcsCmdAddAttachment:
+ {
+ //<cmail> Touch
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // show the toolbar
+ UpdateToolbarL();
+ if ( Toolbar() && Toolbar()->ToolbarExtension() )
+ {
+ Toolbar()->ToolbarExtension()->SetShown( ETrue );
+ }
+ }
+ else
+ {
+ //</cmail>
+ iAttachmentAddType = MsgAttachmentUtils::EUnknown;
+ iAsyncAttachmentAdd->Cancel(); // cancel any outstanding callback just to be safe
+ iAsyncAttachmentAdd->Set( TCallBack( AsyncAddAttachment, this ) );
+ iAsyncAttachmentAdd->CallBack();
+ iContainer->SetMskL();
+ //<cmail> Touch
+ }
+ //</cmail>
+ }
+ break;
+ case EFsEmailUiCmdOpenAttachment:
+ case EFsEmailUiCmdOpenAttachmentList:
+ {
+ DoOpenAttachmentListL();
+ }
+ break;
+ case ENcsCmdRemoveAttachment: // remove one and only attachment
+ case ENcsCmdRemoveAllAttachments:
+ {
+ AttachmentsListControl()->RemoveAllAttachmentsL();
+ SetAttachmentLabelContentL();
+ }
+ break;
+ case ENcsCmdPriorityHigh:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Low );
+ iNewMessage->SetFlag( EFSMsgFlag_Important );
+ iNewMessage->SaveMessageL();
+ iStatusPaneIndicators->SetPriorityFlag(EMsgPriorityHigh);
+ }
+ break;
+ case ENcsCmdPriorityNormal:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Low );
+ iNewMessage->ResetFlag( EFSMsgFlag_Important );
+ iNewMessage->SaveMessageL();
+ iStatusPaneIndicators->SetPriorityFlag(EMsgPriorityNormal);
+ }
+ break;
+ case ENcsCmdPriorityLow:
+ {
+ iNewMessage->ResetFlag( EFSMsgFlag_Important );
+ iNewMessage->SetFlag( EFSMsgFlag_Low );
+ iNewMessage->SaveMessageL();
+ 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()) //<cmail>
+ TFsEmailUiUtility::ShowInfoNoteL( R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS, ETrue );
+ }
+ else
+ {
+ // error occured in saving -> show an error message
+ if(!iAppUi.AppUiExitOngoing()) //<cmail>
+ 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:
+ {
+ // This is for a special case when SaveDeleteQuery appears and user presses immediately End key
+ // we are first checking if Queryexists ,if yes then we forward event to iDlg->offerkeyEventL and
+ // then call Asynchronously Exit method so that iDlg->OfferkeyEventL gets some time before calling
+ // Async Exit method
+ // <cmail> these things are now handeled in prepare for exit
+ /*if ( iCheckQuery )
+ {
+ TKeyEvent check = { EKeyEscape, EStdKeyNull, 0, 0 };
+ TKeyResponse ret = iDlg->OfferKeyEventL(check, EEventKey );
+ iDlg = NULL;
+
+ iAsyncCallback->Cancel(); // cancel any outstanding callback just to be safe
+ iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
+ iAsyncCallback->CallBack();
+ }
+ else
+ {
+ DoSafeExit( ESaveDraft );*/
+ iAppUi.Exit();
+ //}
+ //</cmail>
+ }
+ 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();
+
+ TRAPD(r, iMailBox->SendMessageL( *iNewMessage ) );
+ if ( KErrNone != r )
+ {
+ iMailSendFailed = ETrue;
+ User::Leave( r );
+ }
+
+ // <cmail> 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 );
+ }
+ // </cmail>
+
+ 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_DELETE );
+ array->AppendL( *deleteItem );
+ CleanupStack::PopAndDestroy( deleteItem );
+
+ iDlg = new (ELeave) CAknListQueryDialog( &selectedOption );
+ iDlg->PrepareLC( R_DRAFT_QUERY_DIALOG );
+ // CleanupStack::Pop(iDlg);
+ 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()) //<cmail>
+ TFsEmailUiUtility::ShowInfoNoteL( R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS, ETrue );
+ }
+ else
+ {
+
+ // error occured in saving -> show an error message
+ if(!iAppUi.AppUiExitOngoing()) //<cmail>
+ 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:
+ {
+ TRAPD( error, SaveToDraftsL( ETrue ) );
+ if ( KErrNone != error )
+ {
+ }
+ iFakeSyncGoingOn = ETrue; //<cmail> for delete messages fake sync callscalls
+ 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; //<cmail>
+
+ 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;
+ }
+
+ //iCheckQuery = EFalse; //<cmail>
+ 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;
+ TRAPD( error, ok = attachmentControl->AppendAttachmentToListL(self->iAttachmentAddType) );
+ if ( ok && error == KErrNone )
+ {
+ TRAPD( error, self->SetAttachmentLabelContentL() );
+ return error;
+ }
+ 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 ) // Safety
+ {
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
+ attachmentControl = AttachmentsListControl();
+
+ // read number of attachments
+ TInt count = attachmentControl->Model()->Count();
+
+ if ( count > 1 )
+ {
+ TInt totalSizeInBytes = attachmentControl->Model()->TotalAttachmentSize();
+ HBufC* stringBuf = NULL;
+
+ HBufC* sizeDesc = TFsEmailUiUtility::CreateSizeDescLC( totalSizeInBytes );
+ stringBuf = StringLoader::LoadL( R_NCS_ATTACHMENTS_FIELD_TEXT,
+ *sizeDesc, count );
+ CleanupStack::PopAndDestroy( sizeDesc );
+
+ CleanupStack::PushL( stringBuf );
+ iContainer->SetAttachmentLabelTextL( *stringBuf );
+ CleanupStack::PopAndDestroy( stringBuf );
+ iContainer->SetFocusToAttachmentField();
+ }
+ else if ( count == 1 )
+ {
+ CFSEmailUiSendAttachmentsListModelItem* item =
+ static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
+ attachmentControl->Model()->Item( 0 ) );
+
+ HBufC* sizeBuf = TFsEmailUiUtility::CreateSizeDescLC( item->FileSize() );
+ iContainer->SetAttachmentLabelTextL( item->FileName(), *sizeBuf );
+ CleanupStack::PopAndDestroy( sizeBuf );
+
+ iContainer->SetFocusToAttachmentField();
+ }
+ else
+ {
+ iContainer->SetAttachmentLabelTextL( KNullDesC );
+ iContainer->HideAttachmentLabel();
+ }
+ }
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::AttachmentsListControl()
+//
+// -----------------------------------------------------------------------------
+//
+CFreestyleEmailUiSendAttachmentsListControl* CNcsComposeView::AttachmentsListControl()
+ {
+ FUNC_LOG;
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl(0);
+ if ( iFirstStartCompleted ) // Safety
+ {
+ CFSEmailUiSendAttachmentsListVisualiser* attachmentView =
+ static_cast<CFSEmailUiSendAttachmentsListVisualiser*>(
+ iAvkonViewAppUi->View( SendAttachmentMngrViewId ) );
+ 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;//<cmail> this is actually a waited async method
+ iNewMessage = iMailBox->CreateMessageToSend();
+ iFakeSyncGoingOn = EFalse;
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iFakeSyncGoingOn = ETrue;
+ TFsEmailUiUtility::MoveMessageToDraftsL( *iMailBox, *iNewMessage );
+ iFakeSyncGoingOn = EFalse;//<cmail>
+
+ if ( iNewMessage->GetContentType() != KFSMailContentTypeMultipartMixed )
+ {
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+ }
+
+ 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();
+ TFsEmailUiUtility::CreatePlainTextPartL( *iNewMessage, iNewMessageTextPart );
+ InitFieldsL();
+ IncludeMessageTextL();
+ 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;
+ //<cmail> this is actually a waited async method
+ iFakeSyncGoingOn = ETrue;
+ iNewMessage = iMailBox->CreateMessageToSend();
+ iFakeSyncGoingOn = EFalse;
+ //</cmail>
+ if ( !iNewMessage )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
+ iNewMessage->SaveMessageL();
+
+ 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::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 field and the read-only quote field
+ TInt readOnlyLength = iNewMessageTextPart->ReadOnlyPartSize() / 2; // convert bytes to words
+ 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::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 )
+ {
+ 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 )
+ {
+ // get addresses from UI to MSG object
+ RPointerArray<CFSMailAddress> toAddresses;
+ CleanupResetAndDestroyClosePushL( toAddresses );
+ NcsUtility::ConvertAddressArrayL( iContainer->GetToFieldAddressesL( aParseAddresses ), toAddresses );
+ iNewMessage->GetToRecipients().ResetAndDestroy();
+ for ( TInt i = 0 ; i < toAddresses.Count() ; i++ )
+ {
+ iNewMessage->AppendToRecipient( toAddresses[i] );
+ // Ownership of the message pointer was transferred from our array to iNewMessage
+ toAddresses[i] = NULL;
+ }
+ CleanupStack::PopAndDestroy( &toAddresses );
+ }
+
+ if ( commitCcField )
+ {
+ RPointerArray<CFSMailAddress> ccAddresses;
+ CleanupResetAndDestroyClosePushL( ccAddresses );
+ NcsUtility::ConvertAddressArrayL( iContainer->GetCcFieldAddressesL( aParseAddresses ), ccAddresses );
+ iNewMessage->GetCCRecipients().ResetAndDestroy();
+ for ( TInt i = 0 ; i < ccAddresses.Count() ; i++ )
+ {
+ iNewMessage->AppendCCRecipient( ccAddresses[i] );
+ // Ownership of the message pointer was transferred from our array to iNewMessage
+ ccAddresses[i] = NULL;
+ }
+ CleanupStack::PopAndDestroy( &ccAddresses );
+ }
+
+ if ( commitBccField )
+ {
+ RPointerArray<CFSMailAddress> bccAddresses;
+ CleanupResetAndDestroyClosePushL( bccAddresses );
+ NcsUtility::ConvertAddressArrayL( iContainer->GetBccFieldAddressesL( aParseAddresses ), bccAddresses );
+ iNewMessage->GetBCCRecipients().ResetAndDestroy();
+ for ( TInt i = 0; i < bccAddresses.Count() ; i++ )
+ {
+ iNewMessage->AppendBCCRecipient( bccAddresses[i] );
+ // Ownership of the message pointer was transferred from our array to iNewMessage
+ bccAddresses[i] = NULL;
+ }
+ CleanupStack::PopAndDestroy( &bccAddresses );
+ }
+
+ 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 );
+
+ TInt error = KErrNone;
+ if ( iNewMessageTextPart )
+ {
+ TRAP( error, iNewMessageTextPart->SaveL() );
+ }
+ }
+
+ // Save message if at least one field committed
+ if ( iNewMessage || commitToField || commitCcField || commitBccField
+ || commitSubjectField || commitBodyField )
+ {
+ TInt error = KErrNone;
+ TRAP( error, iNewMessage->SaveMessageL() );
+ RefreshToolbar();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// 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;
+
+ //<cmail>
+ TBool emptyMessage = ETrue;
+
+ if ( iAutoSaver && iContainer )
+ {
+ iAutoSaver->Enable( EFalse );
+
+ // check that there's 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;
+ }
+ //</cmail>
+
+ // 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 ) // <cmail> 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 );
+ }
+ }
+
+ // <cmail>
+ // 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();
+ }
+ // </cmail>
+
+ ExitComposer();
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DoOpenAttachmentList
+// Saves current editor message to drafts and opens attachment list view
+// -----------------------------------------------------------------------------
+void CNcsComposeView::DoOpenAttachmentListL()
+ {
+ FUNC_LOG;
+
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl
+ = AttachmentsListControl();
+
+ if ( attachmentControl->Model()->Count() == 1 )
+ {
+ CFSEmailUiSendAttachmentsListModelItem* item =
+ static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
+ attachmentControl->Model()->Item( 0 ) );
+ if ( !item->IsRemote() ) // we cannot open remote attachments
+ {
+ CFSMailMessagePart* msgPart = iNewMessage->ChildPartL( item->MailMsgPartId() );
+ CleanupStack::PushL( msgPart );
+ TFsEmailUiUtility::OpenAttachmentL( *msgPart );
+ CleanupStack::PopAndDestroy( msgPart );
+ }
+ }
+ // open attachment list
+ else
+ {
+ // set current email parameters to package buffer
+ TEditorLaunchParams editorParams;
+ editorParams.iMailboxId = iNewMessage->GetMailBoxId();
+ editorParams.iMsgId = iNewMessage->GetMessageId();
+ editorParams.iFolderId = iNewMessage->GetFolderId();
+ editorParams.iActivatedExternally = EFalse;
+ TPckgBuf<TEditorLaunchParams> buf( editorParams );
+
+ // save email to drafts
+ iAttachmentListSaveDraft = ETrue;
+ TRAPD( saveDraftError, DoSaveDraftL( EFalse ) );
+ if ( saveDraftError != KErrNone )
+ {
+ // error occured in saving -> show an error message
+ if ( !iAppUi.AppUiExitOngoing() ) //<cmail>
+ TFsEmailUiUtility::ShowErrorNoteL( R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE, ETrue );
+ return;
+ }
+
+ // open attachment list view
+ iAppUi.EnterFsEmailViewL(
+ SendAttachmentMngrViewId,
+ TUid::Uid( KEditorCmdOpenAttachmentsList ),
+ buf );
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::LaunchAttachmentActionMenuL
+// Show action menu for the attachments line
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::LaunchAttachmentActionMenuL()
+ {
+ FUNC_LOG;
+
+ // Remove old items from action menu
+ CFSEmailUiActionMenu::RemoveAllL();
+
+ // Construct item list
+ RFsEActionMenuIdList itemList;
+ CleanupClosePushL( itemList );
+
+ CFreestyleEmailUiSendAttachmentsListControl* attachmentControl =
+ AttachmentsListControl();
+ TInt count = attachmentControl->Model()->Count();
+ TBool remoteAtt = AttachmentsListControl()->Model()->HasRemoteAttachments();
+ TBool readOnlyAtt = AttachmentsListControl()->Model()->HasReadOnlyAttachments();
+
+ // Open/View all
+ if ( count == 1 && !remoteAtt )
+ {
+ itemList.AppendL( FsEActionAttachmentOpen );
+ }
+ else if ( count > 1 )
+ {
+ itemList.AppendL( FsEActionAttachmentViewAll );
+ }
+
+ // Add
+ itemList.AppendL( FsEActionAttachmentAdd );
+
+ // Remove/Remove all
+ if ( !readOnlyAtt )
+ {
+ if ( count == 1 )
+ {
+ itemList.AppendL( FsEActionAttachmentRemove );
+ }
+ else if ( count > 1 )
+ {
+ itemList.AppendL( FsEActionAttachmentRemoveAll );
+ }
+ }
+
+ // Execute action list
+ TActionMenuCustomItemId itemId = CFSEmailUiActionMenu::ExecuteL( itemList );
+ CleanupStack::PopAndDestroy( &itemList );
+
+ // Handle action menu selection
+ switch ( itemId )
+ {
+ case FsEActionAttachmentOpen:
+ HandleCommandL( EFsEmailUiCmdOpenAttachment );
+ break;
+ case FsEActionAttachmentViewAll:
+ HandleCommandL( EFsEmailUiCmdOpenAttachmentList );
+ break;
+ case FsEActionAttachmentRemove:
+ HandleCommandL( ENcsCmdRemoveAttachment );
+ break;
+ case FsEActionAttachmentRemoveAll:
+ HandleCommandL( ENcsCmdRemoveAllAttachments );
+ break;
+ case FsEActionAttachmentAdd:
+ HandleCommandL( ENcsCmdAddAttachment );
+ break;
+ default:
+ break;
+ }
+
+ }
+
+//<cmail>
+// -----------------------------------------------------------------------------
+// CNcsComposeView::DismissAttachmentActionMenuL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::DismissAttachmentActionMenuL()
+ {
+ FUNC_LOG;
+ CFSEmailUiActionMenu::Dismiss( ETrue );
+ }
+//</cmail>
+
+// -----------------------------------------------------------------------------
+// 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
+ TInt waitNoteId = KErrNotFound;
+ if ( TFsEmailUiUtility::IsMessageBodyLargeL(iOrigMessage) )
+ {
+ waitNoteId = TFsEmailUiUtility::ShowGlobalWaitNoteLC( R_FSE_WAIT_OPENING_TEXT );
+ }
+
+ 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
+ if ( waitNoteId != KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy( (TAny*)waitNoteId );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// 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();
+ }
+
+ 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 );
+ IncludeMessageTextL( ETrue );
+ iContainer->SetFocusToMessageFieldL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::InitUiGeneralL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::InitUiGeneralL()
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety check
+ {
+ AppUi()->AddToStackL( iContainer );
+ iContainer->SetMenuBar( Cba() );
+
+ // <cmail>
+ // TInt ccVisible = iCrHandler->EditorCCVisible();
+ // iContainer->SetCcFieldVisibleL( ccVisible == 1, EFalse );
+ // TInt bccVisible = iCrHandler->EditorBCVisible();
+ // iContainer->SetBccFieldVisibleL( bccVisible == 1, EFalse );
+ // </cmail>
+
+ iContainer->UpdateScrollBarL();
+
+ // 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();
+ 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 );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// 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 ) );
+ 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 already created sooner
+ iAppUi.EventL(
+ TFSEventMailChanged, mailboxId, &messageIdArray, &folderId, NULL );
+ CleanupStack::PopAndDestroy( &messageIdArray );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeView::FetchLogicComplete
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeView::FetchLogicComplete( TComposerFetchState /*aState*/, TInt aError )
+ {
+ FUNC_LOG;
+ if ( iFirstStartCompleted ) // Safety
+ {
+ if ( !aError )
+ {
+ TRAP( aError, InitReplyOrForwardUiL() );
+ iAutoSaver->Enable( ETrue );
+ }
+ else
+ {
+ // something went wrong
+ DoSafeExit(ENoSave);
+ iMailFetchingErrCode = aError;
+ }
+ }
+ if ( iFetchWaitDialog && !iFetchDialogCancelled )
+ {
+ TRAP_IGNORE(iFetchWaitDialog->ProcessFinishedL());
+ iFetchWaitDialog = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// 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);
+ }
+
+// ---------------------------------------------------------------------------
+// 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);
+ }
+
+//</cmail>