/*
* 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
// -----------------------------------------------------------------------------
//
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;
        }
    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);
    }

// ---------------------------------------------------------------------------
// 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>
