/*
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
*  Description : Compose view class
*
*/

// INCLUDE FILES
#include "emailtrace.h"
#include <aknnotewrappers.h>
#include <NpdApi.h>
#include <StringLoader.h>
#include <txtrich.h>
#include <AknWaitDialog.h>
#include <MsgAttachmentUtils.h>
#include <featmgr.h>
#include "cfsmailbox.h"
#include "cfsmailmessage.h"
#include "cfsmailaddress.h"
#include "cfsmailclient.h"
#include "cfsmailcommon.h"
#include <csxhelp/cmail.hlp.hrh>
#include <akntoolbar.h>
#include <akntoolbarextension.h>
#include <AknUtils.h>
#include <FreestyleEmailUi.rsg>
#include <freestyleemailui.mbg>
#include <aknstyluspopupmenu.h>

#include <wlaninternalpskeys.h>
#include "ncscomposeview.h"
#include "ncscomposeviewcontainer.h"
#include "ncsconstants.h"
#include "ncsutility.h"
#include "ncsemailaddressobject.h"
#include "freestyleemailcenrephandler.h"
#include "FreestyleEmailUi.hrh"
#include "FreestyleEmailUiConstants.h"
#include "FreestyleEmailUiSendAttachmentsListControl.h"
#include "FreestyleEmailUiSendAttachmentsListVisualiser.h"
#include "FreestyleEmailUiSendAttachmentsListModel.h"
#include "FreestyleEmailUiUtilities.h"
#include "FreestyleEmailUiConstants.h"
#include "FSAutoSaver.h"
#include "FSEmail.pan"
#include "cmailmessageext.h"


// line separators that should not appear in Subject
_LIT(KLineSeparators, "\u2029");
const TChar KReplacementChar = ' ';


#pragma mark +++COMPOSE VIEW - CONSTRUCTORS AND DESTRUCTORS

// -----------------------------------------------------------------------------
// Safe pointer deletion
//
// -----------------------------------------------------------------------------
//
template <class T> void SafeDelete( T*& aPtr )
    {
    delete aPtr;
    aPtr = NULL;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::CNcsComposeView()
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CNcsComposeView::CNcsComposeView( CFreestyleEmailUiAppUi& aAppUi,
    CAlfEnv& aEnv, CAlfControlGroup& aSendAttachmentControlGroup,
    CFSMailClient& aMailClient, CMsvSession& aMsvSession )
    : CFsEmailUiViewBase( aSendAttachmentControlGroup, aAppUi ),
     iMailClient( aMailClient ), iOrigMessage( NULL ), iNewMessage( NULL ),
     iMsvSession( aMsvSession ), iEnv( aEnv ),
     iFakeSyncGoingOn(EFalse), iFetchDialogCancelled(EFalse),
     iExecutingDoExitL( EFalse ),
     iMessageTextPartModified( EFalse ), iMessageModified( EFalse ), 
     iIncludeMessageTextAsync( EFalse ), iChildActivationState( EChildActivationDeactivated )
    {
    FUNC_LOG; 

    iAttachmentListSaveDraft = EFalse;

    }

// -----------------------------------------------------------------------------
// CNcsComposeView::NewL()
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CNcsComposeView* CNcsComposeView::NewL( 
        CFSMailClient& aMailClient, CAlfEnv& aEnv,
        CFreestyleEmailUiAppUi* aAppUi, CAlfControlGroup& aControlGroup,
        CMsvSession& aMsvSession )
    {
    FUNC_LOG;

    CNcsComposeView* self = 
        CNcsComposeView::NewLC( aMailClient, aEnv, aAppUi,
                                aControlGroup, aMsvSession );
    CleanupStack::Pop( self );

    return self;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::NewLC()
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CNcsComposeView* CNcsComposeView::NewLC(
    CFSMailClient& aMailClient,
    CAlfEnv& aEnv,
    CFreestyleEmailUiAppUi* aAppUi,
    CAlfControlGroup& aControlGroup,
    CMsvSession& aMsvSession )
    {
    FUNC_LOG;

    CNcsComposeView* self = new ( ELeave ) CNcsComposeView( 
            *aAppUi, aEnv, aControlGroup, aMailClient, aMsvSession );
    CleanupStack::PushL( self );
    self->ConstructL();

    return self;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ConstructL()
    {
    FUNC_LOG;

    BaseConstructL( R_NCS_COMPOSE_VIEW );
    iFirstStartCompleted = EFalse;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DoFirstStartL()
// Purpose of this function is to do first start only when msg details is
// really needed to be shown. Implemented to make app startuo faster.
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DoFirstStartL()
    {
    FUNC_LOG;
    // Attachment list for compose screen, owned by AlfEnv
    CAlfControlGroup& attListControlGroup = 
        iEnv.NewControlGroupL( KSendAttachmentManagerDisplayGroup );
    CFSEmailUiSendAttachmentsListVisualiser* sendAttachmentVisualiser =
        CFSEmailUiSendAttachmentsListVisualiser::NewLC(
            iEnv, &iAppUi, attListControlGroup );
    iAppUi.AddViewL( sendAttachmentVisualiser );
    CleanupStack::Pop( sendAttachmentVisualiser );

    iCrHandler = CFSEmailCRHandler::InstanceL(); // singleton, not owned

    iEnv.AddActionObserverL( this );

    iAutoSaver = CFsAutoSaver::NewL( iEnv, KAutoSaveTimeDelayMs );
    iAutoSaver->Enable( EFalse );
    iFirstStartCompleted = ETrue;
    iCheckQuery = EFalse;
    iAsyncCallback = new (ELeave) CAsyncCallBack( CActive::EPriorityLow );
    // msk context menu added into composer
    MenuBar()->SetContextMenuTitleResourceId( R_NCS_COMPOSE_BODY_MSK_MENUBAR );
    iActiveHelper = CActiveHelper::NewL( this );

    iAsyncAttachmentAdd = 
        new (ELeave) CAsyncCallBack( CActive::EPriorityStandard );
    
    // Initializing the default stylus long tap popup menu
	if( !iStylusPopUpMenu )
		{
		TPoint point( 0, 0 );
		iStylusPopUpMenu = CAknStylusPopUpMenu::NewL( this, point );
		TResourceReader reader;
		iCoeEnv->CreateResourceReaderLC( reader,
				R_STYLUS_POPUP_MENU_COMPOSE_VIEW_ATTACHMENT );
		iStylusPopUpMenu->ConstructFromResourceL( reader );
		CleanupStack::PopAndDestroy(); // reader
		}
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::~CNcsComposeView()
// Destructor.
// -----------------------------------------------------------------------------
//
CNcsComposeView::~CNcsComposeView()
    {
    FUNC_LOG;
	delete iAutoSaver;
	if ( iAsyncCallback )
	    {
	    iAsyncCallback->Cancel();
	    delete iAsyncCallback;
	    }
    delete iFetchLogic;
    if( iActiveHelper )
        {
        iActiveHelper->Cancel();
        delete iActiveHelper;
        }
    if ( iAsyncAttachmentAdd )
        {
        iAsyncAttachmentAdd->Cancel();
        delete iAsyncAttachmentAdd;
        }
    delete iStylusPopUpMenu;
    }

void CNcsComposeView::PrepareForExit()
    {
    FUNC_LOG;
    if ( iCheckQuery && iDlg )
        {
        TKeyEvent check = { EKeyEscape, EStdKeyNull, 0, 0 };
        TRAP_IGNORE( iDlg->OfferKeyEventL( check, EEventKey ) );
        iDlg = NULL;

        iAsyncCallback->Cancel(); // cancel any outstanding callback
        iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
        iAsyncCallback->CallBack();
        }
    else if( iFakeSyncGoingOn || iExecutingDoExitL )
        {
        // low priority active obj so that iwait in plugins finish
        iActiveHelper->Cancel();
        iActiveHelper->Start();
        }
    else if ( iIncludeMessageTextAsync )
    	{
		if ( iContainer )
			{
    		iContainer->StopAsyncTextFormatter();
			}
		ResetComposer();
		iAsyncCallback->Cancel(); // cancel any outstanding callback
		iAsyncCallback->Set( TCallBack( AsyncExit, this ) );
		iAsyncCallback->CallBack();
    	}
    else
        {
        DoSafeExit( ESaveDraft );

        // cleaning - usefull when application is closed from task switcher
        HideToolbar();
        }

    if( iFetchLogic )
        {
        iFetchLogic->CancelFetchings();
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::Id()
// Returns View's ID.
// -----------------------------------------------------------------------------
//
TUid CNcsComposeView::Id() const
    {
    FUNC_LOG;
    return MailEditorId;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::ChildDoActivateL()
// Activate the Compose view
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ChildDoActivateL( const TVwsViewId& aPrevViewId,
    TUid aCustomMessageId, const TDesC8& aCustomMessage )
    {
    FUNC_LOG;
    iChildActivationState = EChildActivationStarted;
    // needed when "Opening" (replying/forwarding)note is shown and 
    // we receive incoming call- Email application goes to background.
    // When coming back to application the view is activated and reseted.
    // That's why we prevent activation and the same is done in ChildDoDeactivate
    if ( iIncludeMessageTextAsync )
        {
        return;
        }

    if ( !iFirstStartCompleted )
        {
        DoFirstStartL();
        }
    Toolbar()->SetDimmed( ETrue );
    // Set status pane indicators
    iStatusPaneIndicators = iAppUi.GetStatusPaneIndicatorContainer();
    iStatusPaneIndicators->ShowStatusPaneIndicators();

    // Notify base class about view being entered unless 
    // returned from another view
    if ( aCustomMessageId.iUid != KEditorCmdReturnToPrevious )
        {
        ViewEntered( aPrevViewId );
        }

    // Cleanup the previous message before opening a new one
    SaveAndCleanPreviousMessage();

    // Get the launch parameters
    if ( aCustomMessageId.iUid == KEditorCmdReturnToPrevious )
        {
        // Use previous launch parameters when returning to previously 
        // opened message
        iMailBox = iMailClient.GetMailBoxByUidL( iLaunchParams.iMailboxId );
        }
    else if ( aCustomMessage.Length() > 0 )
        {

        TPckgBuf<TEditorLaunchParams> buf( iLaunchParams );
        buf.Copy( aCustomMessage );
        iLaunchParams = buf();
        iMailBox = iMailClient.GetMailBoxByUidL( iLaunchParams.iMailboxId );

        }
    else
        {
        iLaunchParams.iActivatedExternally = ETrue;
        }

    // Inform the AppUi about external view activation to fix the view stack.
    // Normally this happens based on the previous view AppUid in the BaseView
    // but in case contacts action menu was used within FsEmail, this doesn' 
    // work. It doesn't hurt to call this again even if it was already called
    // once from BaseView.
    if ( iLaunchParams.iActivatedExternally )
        {
        iAppUi.ViewActivatedExternallyL( Id() );
        }

    // Try to get the mailbox by other means if using launch parameters failed
    if ( !iMailBox )
        {
        TInt error( KErrNone );

        // can we get it from MSV Id
        // MSV id is passed to us when account is defined email key settings
        if ( aCustomMessageId != TUid::Null() )
            {
            TRAP( error, iMailBox = TFsEmailUiUtility::GetMailboxForMtmIdL( 
                    iMailClient, iMsvSession, aCustomMessageId.iUid ) );
            }

        error = KErrNone;

        // try to use mailbox set as default in MCE
        if ( !iMailBox )
            {
            TRAP( error, iMailBox = TFsEmailUiUtility::GetMceDefaultMailboxL(
                    iMailClient, iMsvSession ) );
            }

        // use first mail account from the list
        if ( !iMailBox )
            {
            TFSMailMsgId id;
            RPointerArray<CFSMailBox> mailboxes;
            CleanupResetAndDestroyClosePushL( mailboxes );
            iMailClient.ListMailBoxes( id, mailboxes );
            if ( mailboxes.Count() > 0 )
                {
                iMailBox = 
                    iMailClient.GetMailBoxByUidL( mailboxes[0]->GetId() );
                }
            CleanupStack::PopAndDestroy( &mailboxes );
            }

        // could not get mailbox so leave
        if ( !iMailBox )
            {
            User::Leave( KErrGeneral );
            }

        aCustomMessageId = TUid::Uid( KEditorCmdCreateNew );
        }


    iMailSent = EFalse;
    iMailSendFailed = EFalse;
    iCustomMessageId = aCustomMessageId;

    CreateContainerL();

    TRAPD( err, HandleActivationCommandL( aCustomMessageId ) );
    if ( !err )
        {
        err = iMailFetchingErrCode;
        }

    if ( err == KErrCancel || 
         err == KErrCouldNotConnect || 
         err == KErrConnectionTerminated )
        {
        // Just close composer without any notes if operation was cancelled.
        // For connection errors, DownloadInfoMediator already shows error 
        // message, so no need to show another one.
        ExitComposer();
        }
    else if ( err )
        {
        // some other error => show generic error note and close composer
        if( !iAppUi.AppUiExitOngoing() )
            TFsEmailUiUtility::ShowErrorNoteL( 
                R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE, ETrue );
        ExitComposer();
        }
    else
        {
        // everything went fine => do rest of the generic initialization
        InitUiGeneralL();
        iAppUi.StartEndKeyCapture();
        iContainer->SetMskL();
        iViewReady = ETrue;
        Toolbar()->SetDimmed( EFalse );
        RefreshToolbar();
        iContainer->ActivateL();

        
    // if there is a embedded app in FSEmail.
    if( iAppUi.EmbeddedApp() )
            {
            // Set email editor started from embedded app flag to true 
            // so that we can switch view correct when sent email.
            iAppUi.SetEditorStartedFromEmbeddedApp( ETrue );
        
        RWsSession rwsSession;
            User::LeaveIfError( rwsSession.Connect() );
            CleanupClosePushL( rwsSession );
        
        // Simulate a back key to exit embedded app 
            // so that email editor could show on the top level.
            TKeyEvent KeyEvent = TKeyEvent();
            // this is neccesary for photogalery image viewer (don't remove)
            KeyEvent.iScanCode = EStdKeyUpArrow;
            rwsSession.SimulateKeyEvent( KeyEvent );
            KeyEvent.iCode = EKeyCBA2;
            rwsSession.SimulateKeyEvent( KeyEvent );

        rwsSession.Close();
            CleanupStack::PopAndDestroy( &rwsSession );
            }
    
    if ( iIncludeMessageTextAsync )
            {
            // including message body in async way
            IncludeMessageTextAsyncL( ETrue );
            }

        iViewFullyActivated = ETrue;
        iChildActivationState = EChildActivationProcessed;
        
    TIMESTAMP( "Editor launched" );
        return; // ok
        }
// problems with init close the view asynchronously
    iViewFullyActivated = EFalse;
    iChildActivationState = EChildActivationExitRequired;
//    iFakeSyncGoingOn = EFalse; iExecutingDoExitL = EFalse;
    iActiveHelper->Start(); // calls AsyncExit()
    TIMESTAMP( "Editor NOT launched" );
    return;
    }

// -----------------------------------------------------------------------------
// Initialises toolbar items.
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DynInitToolbarL( TInt aResourceId,
    CAknToolbar* aToolbar )
    {
    FUNC_LOG;
    if ( aResourceId == EFsEmailUiTbCmdExpandActions && aToolbar )
        {
        CAknToolbarExtension* ext = aToolbar->ToolbarExtension();
        if ( iContainer )
            {
            // Set correct state for show/hide cc field button.
            CAknButton* ccButton = Button( EFsEmailUiTbCmdCcField, ext );
            if ( ccButton )
                {
                TInt index = iContainer->IsCcFieldVisible() ? 1 : 0;
                ccButton->SetCurrentState( index, EFalse );

                // Command is dimmed, if there is content in the field.
                ccButton->SetDimmed( iContainer->GetCcFieldLength() > 0 );
                }

            // Set correct state for show/hide bcc field button.
            CAknButton* bccButton = Button( EFsEmailUiTbCmdBccField, ext );
            if ( bccButton )
                {
                TInt index = iContainer->IsBccFieldVisible() ? 1 : 0;
                bccButton->SetCurrentState( index, EFalse );

                // Command is dimmed, if there is content in the field.
                bccButton->SetDimmed( iContainer->GetBccFieldLength() > 0 );
                }
            }
        else
            {
            ext->HideItemL( EFsEmailUiTbCmdCcField, ETrue );
            ext->HideItemL( EFsEmailUiTbCmdBccField, ETrue );
            }

        if ( iNewMessage )
            {
            // Set correct state for low priority button.
            TBool lowPriority = iNewMessage->IsFlagSet( EFSMsgFlag_Low );
            CAknButton* lowPriorityButton = static_cast<CAknButton*>(
                ext->ControlOrNull( EFsEmailUiTbCmdLowPriority ) );
            if ( lowPriorityButton )
                {
                TInt index = lowPriority ? 1 : 0;
                lowPriorityButton->SetCurrentState( index, EFalse ); 
                }

            // Set correct state for high priority button.
            TBool highPriority = iNewMessage->IsFlagSet( EFSMsgFlag_Important );
            CAknButton* highPriorityButton = static_cast<CAknButton*>(
                ext->ControlOrNull( EFsEmailUiTbCmdHighPriority ) );
            if ( highPriorityButton )
                {
                TInt index = highPriority ? 1 : 0;
                highPriorityButton->SetCurrentState( index, EFalse );
                }

            // Set correct state for follow up button.
            TBool followUp = iNewMessage->IsFlagSet( EFSMsgFlag_FollowUp );
            CAknButton* followUpButton = static_cast<CAknButton*>(
                ext->ControlOrNull( EFsEmailUiTbCmdFollowUp ) );
            if ( followUpButton )
                {
                TInt index = followUp ? 1 : 0;
                followUpButton->SetCurrentState( index, EFalse );

                // Hide follow up button, if follow up is not supported.
                ext->HideItemL( EFsEmailUiTbCmdFollowUp,
                    !TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) );
                }
            }
        else
            {
            ext->HideItemL( EFsEmailUiTbCmdLowPriority, ETrue );
            ext->HideItemL( EFsEmailUiTbCmdHighPriority, ETrue );
            ext->HideItemL( EFsEmailUiTbCmdFollowUp, ETrue );
            }
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::OfferToolbarEventL
// -----------------------------------------------------------------------------
void CNcsComposeView::OfferToolbarEventL( TInt aCommand )
    {
    FUNC_LOG;
    TBool attachmentAddition = EFalse;
    switch ( aCommand )
        {
        case EFsEmailUiTbCmdSend:
            if ( iContainer && iContainer->AreAddressFieldsEmpty() )
                {
                RefreshToolbar();
                }
            else
                {
                HandleCommandL( ENcsCmdSend );
                }
            break;
        case EFsEmailUiTbCmdCcField:
            {
            CAknButton* ccFieldButton = Button( EFsEmailUiTbCmdCcField );
            if ( ccFieldButton )
                {
                if ( ccFieldButton->StateIndex() )
                    {
                    HandleCommandL( ENcsCmdShowCc );
                    }
                else
                    {
                    HandleCommandL( ENcsCmdHideCc );
                    }
                }
            break;
            }
        case EFsEmailUiTbCmdBccField:
            {
            CAknButton* bccFieldButton = Button( EFsEmailUiTbCmdBccField );
            if ( bccFieldButton )
                {
                if ( bccFieldButton->StateIndex()  )
                    {
                    HandleCommandL( ENcsCmdShowBcc );
                    }
                else
                    {
                    HandleCommandL( ENcsCmdHideBcc );
                    }
                }
            break;
            }
        case EFsEmailUiTbCmdLowPriority:
            {
            CAknButton* lowPriorityButton = Button( EFsEmailUiTbCmdLowPriority );
            if ( lowPriorityButton )
                {
                if ( lowPriorityButton->StateIndex() )
                    {
                    CAknButton* highPriorityButton = Button( 
                        EFsEmailUiTbCmdHighPriority );
                    if ( highPriorityButton )
                        {
                        highPriorityButton->SetCurrentState( 0, ETrue );
                        }
                    HandleCommandL( ENcsCmdPriorityLow );
                    }
                else
                    {
                    HandleCommandL( ENcsCmdPriorityNormal );
                    }
                }
            break;
            }
        case EFsEmailUiTbCmdHighPriority:
            {
            CAknButton* highPriorityButton = Button( EFsEmailUiTbCmdHighPriority );
            if ( highPriorityButton )
                {
                if ( highPriorityButton->StateIndex() )
                    {
                    CAknButton* lowPriorityButton = Button( 
                        EFsEmailUiTbCmdLowPriority );
                    if ( lowPriorityButton )
                        {
                        lowPriorityButton->SetCurrentState( 0, ETrue );
                        }
                    HandleCommandL( ENcsCmdPriorityHigh );
                    }
                else
                    {
                    HandleCommandL( ENcsCmdPriorityNormal );
                    }
                }
            break;
            }
        case EFsEmailUiTbCmdFollowUp:
            {
            CAknButton* button = Button( EFsEmailUiTbCmdFollowUp );
            if ( button && iNewMessage )
                {
                if ( button->StateIndex() )
                    {
                    iNewMessage->SetFlag( EFSMsgFlag_FollowUp );
                    iNewMessage->ResetFlag( EFSMsgFlag_FollowUpComplete );
                    iStatusPaneIndicators->SetFollowUpFlag( 
                        CCustomStatuspaneIndicators::EFollowUp );
                    }
                else
                    {
                    iNewMessage->ResetFlag( EFSMsgFlag_FollowUp 
                        | EFSMsgFlag_FollowUpComplete );
                    iStatusPaneIndicators->SetFollowUpFlag( 
                        CCustomStatuspaneIndicators::EFollowUpNone );
                    }
                }
            break;
            }
        case EFsEmailUiTbCmdInsertAudio:
            iAttachmentAddType = MsgAttachmentUtils::EAudio;
            attachmentAddition = ETrue;
            break;
        case EFsEmailUiTbCmdInsertImage:
            iAttachmentAddType = MsgAttachmentUtils::EImage;
            attachmentAddition = ETrue;
            break;
        case EFsEmailUiTbCmdInsertVideo:
            iAttachmentAddType = MsgAttachmentUtils::EVideo;
            attachmentAddition = ETrue;
            break;
        case EFsEmailUiTbCmdInsertNote:
            iAttachmentAddType = MsgAttachmentUtils::ENote;
            attachmentAddition = ETrue;
            break;
        case EFsEmailUiTbCmdInsertPresentation:
            iAttachmentAddType = MsgAttachmentUtils::ESVG;
            attachmentAddition = ETrue;
            break;
        case EFsEmailUiTbCmdInsertOther:
            iAttachmentAddType = MsgAttachmentUtils::EUnknown;
            attachmentAddition = ETrue;
            break;
        default:
            break;
        }
    if ( attachmentAddition )
        {
        iAsyncAttachmentAdd->Cancel(); // cancel any outstanding callback
        iAsyncAttachmentAdd->Set( TCallBack( AsyncAddAttachment, this ) );
        iAsyncAttachmentAdd->CallBack();
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::ToolbarResourceId()
// -----------------------------------------------------------------------------
//
TInt CNcsComposeView::ToolbarResourceId() const
    {
    FUNC_LOG;
    return R_FREESTYLE_EMAIL_UI_TOOLBAR_MESSAGE_EDITOR;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::GetInitiallyDimmedItemsL()
// -----------------------------------------------------------------------------
//
void CNcsComposeView::GetInitiallyDimmedItemsL( const TInt aResourceId,
        RArray<TInt>& aDimmedItems ) const
    {
    FUNC_LOG;
    aDimmedItems.Reset();
    switch ( aResourceId )
        {
        case R_FREESTYLE_EMAIL_UI_TOOLBAR_MESSAGE_EDITOR:
            aDimmedItems.AppendL( EFsEmailUiTbCmdSend );
            break;
        default:
            break;
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::RefreshToolbar()
// -----------------------------------------------------------------------------
//
void CNcsComposeView::RefreshToolbar()
    {
    FUNC_LOG;
    if ( iContainer )
        {
        // Hide toolbar if remotesearch is in progress, 
        // because it takes you into a different view
        TBool hideToolbar = ( iContainer->IsRemoteSearchInprogress() 
                || iAddingAttachmentDialogOpened );
        SetToolbarItemDimmed( EFsEmailUiTbCmdSend, iContainer->AreAddressFieldsEmpty() );
     
        CAknToolbar* toolbar(Toolbar());
        if (toolbar)
            {
            toolbar->SetToolbarVisibility(!hideToolbar);
            // If toolbar is not hidden, redraw it (otherwise only dimmed/undimmed button will be redrawn)
            if(!hideToolbar)
            	{
                toolbar->DrawDeferred();
            	}
            }
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::ChildDoDeactivate()
// Deactivate the Compose view
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ChildDoDeactivate()
    {
    FUNC_LOG;
    
    // see comment in ChildDoActivate
    if ( iIncludeMessageTextAsync && !iAppUi.AppUiExitOngoing() )
        {
        return;
        }
    
    iViewFullyActivated = EFalse;

    iAppUi.StopEndKeyCapture();

    SafeDelete( iFetchLogic );

    // Normally Comopser state has been already cleaned by now but in special
    // cases (like external view activation while in Composer) this may not be
    // the case. In those cases the message needs to be saved before the view
    // is deactivated.
    if ( !iAppUi.AppUiExitOngoing() )
        {
        SaveAndCleanPreviousMessage();
        }
    
    iChildActivationState = EChildActivationDeactivated ;
    
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DynInitMenuPaneL()
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DynInitMenuPaneL( TInt aResourceId,
                                        CEikMenuPane* aMenuPane )
    {
    FUNC_LOG;

    if ( !iViewReady )
        {
        User::Leave( KErrNcsComposeViewNotReady );
        }

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
    __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
    __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );

    //we are forbiding to change MSK label, because popup will be opened 
    iContainer->SwitchChangeMskOff( ETrue );
    
    if ( aResourceId == R_NCS_COMPOSE_MENU )
        {
	    if ( FeatureManager::FeatureSupported( 
	            KFeatureIdFfCmailIntegration ) )
		   {
		   // remove help support in pf5250
		   aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue);      
		   }     
        
    	// Disable send if there are no addresses in any of the AIF fields,
    	if ( iContainer->AreAddressFieldsEmpty() )
		    {
	    	aMenuPane->DeleteMenuItem( ENcsCmdSend );
		    }

	    // If no attachments, delete the remove attachments menu item
		CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
		attachmentControl = AttachmentsListControl();
		TInt count = attachmentControl->Model()->Count();

        // if mail has remote attachments then attachments can't be 
		// removed via options menu
		if ( count <= 0 || 
		     AttachmentsListControl()->Model()->HasReadOnlyAttachments() )
	    	{
    		aMenuPane->DeleteMenuItem( ENcsCmdRemoveAttachment );
    		aMenuPane->DeleteMenuItem( ENcsCmdRemoveAllAttachments );
	    	}
        else if ( count == 1 )
	     	{
    		aMenuPane->DeleteMenuItem( ENcsCmdRemoveAllAttachments );
	     	}
        else
	     	{
    		aMenuPane->DeleteMenuItem( ENcsCmdRemoveAttachment );
	     	}

        if ( iContainer->GetCcFieldLength() > 0 &&
             iContainer->GetBccFieldLength() > 0 )
        	{
            aMenuPane->DeleteMenuItem( ENcsCmdMore );
        	}

        if ( !TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) )
        	{
    		aMenuPane->DeleteMenuItem( ENcsCmdFlag );
        	}
        }

    if ( aResourceId == R_NCS_EXTRA_RECEPIENT_FIELDS_MENU )
        {
		// Select which View->CC menu items to show
		if ( iContainer->IsCcFieldVisible() )
            {
            aMenuPane->DeleteMenuItem( ENcsCmdShowCc );
            // if there is text in Cc field do not show "hide Cc" menu item
            if ( iContainer->GetCcFieldLength() > 0 )
            	{
            	aMenuPane->DeleteMenuItem( ENcsCmdHideCc );
            	}
            }
        else
            {
        	aMenuPane->DeleteMenuItem( ENcsCmdHideCc );
            }

		// Select which View->BCC menu items to show
        if ( iContainer->IsBccFieldVisible() )
            {
            aMenuPane->DeleteMenuItem( ENcsCmdShowBcc );
            // if there is text in Bcc field do not show "hide Bcc" menu item
            if ( iContainer->GetBccFieldLength() > 0 )
            	{
            	aMenuPane->DeleteMenuItem( ENcsCmdHideBcc );
            	}
            }
        else
            {
            aMenuPane->DeleteMenuItem( ENcsCmdHideBcc );
            }
        }

	if ( aResourceId == R_NCS_PRIORITY_MENU )
    	{

        if ( iNewMessage->IsFlagSet( EFSMsgFlag_Important ) )
            {
            aMenuPane->DeleteMenuItem( ENcsCmdPriorityHigh );
            }
        else if ( iNewMessage->IsFlagSet( EFSMsgFlag_Low ) )
            {
            aMenuPane->DeleteMenuItem( ENcsCmdPriorityLow );
            }
        else
            {
            aMenuPane->DeleteMenuItem( ENcsCmdPriorityNormal );
            }
    	}

    }

// -----------------------------------------------------------------------------
// CNcsComposeView::HandleCommandL()
// Takes care of Command handling.
// -----------------------------------------------------------------------------
//
void CNcsComposeView::HandleCommandL( TInt aCommand )
    {
    FUNC_LOG;

    // Attempt to handle commands only after view is fully activated and exit
    // has not yet been initiated.
    if ( iViewReady && !iAppUi.ViewSwitchingOngoing() )
        {
        __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );
        __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
        __ASSERT_DEBUG( iCrHandler, Panic( ENcsBasicUi ) );

        switch( aCommand )
            {
            case ENcsCmdSend:
                {
                // Set focus on body of message need for correct 
                // MSK setting for CAknConfirmationNote dialog. 
                iContainer->SetFocusToMessageFieldL();
                
                // Show query if the Subject field is empty
                if ( iContainer->IsSubjectFieldEmpty() )
                    {
                    TInt answer = TFsEmailUiUtility::ShowConfirmationQueryL(
                            R_FREESTYLE_EMAIL_QUERY_NO_SUBJECT );
                    if ( !answer )
                        {
                        // user didn't want to send yet
                        // -> go back to the message
                        return;
                        }
                    }

                TRAPD( error, DoSendL() );
                if ( !error )
                    {
                    // Sending successful
                    HBufC* confMessage = NULL;
                    if ( !TFsEmailUiUtility::IsOfflineModeL() || WLANConnectionActive() )
                        {
                        // when sync status is currently ONLINE
                        confMessage = StringLoader::LoadLC( 
                                R_FREESTYLE_EMAIL_CONFIRM_NOTE_SENDING_QUEUED );
                        }
                    else
                        {
                        // when sync status is currently OFFLINE
                        confMessage = StringLoader::LoadLC( 
                                R_FREESTYLE_EMAIL_CONFIRM_NOTE_QUEUED_UNTIL_ONLINE );
                        }
                    CAknConfirmationNote* note = 
                        new (ELeave) CAknConfirmationNote( ETrue ); //waiting
                    note->SetTimeout( CAknNoteDialog::ELongTimeout );
                    note->SetTone( CAknNoteDialog::ENoTone );
                    note->ExecuteLD( *confMessage );
                    CleanupStack::PopAndDestroy( confMessage );
                    DoSafeExit(); // Exit after successful sending
                    }
                else if ( error == KErrBadName )
                	{
                  	// sending failed because recipient address was invalid
                	TFsEmailUiUtility::ShowErrorNoteL( 
                        R_FREESTYLE_EMAIL_CONFIRM_NOTE_INVALID_EMAIL_ADDRESS,
                        ETrue );
                	}
                else
                	{
                	// sending failed for some other reason
                    TFsEmailUiUtility::ShowErrorNoteL( 
                        R_FREESTYLE_EMAIL_CONFIRM_NOTE_MESSAGE_NOT_SENT,
                        ETrue );
                    // Exit after sending failed for other reason for other
                    // reason than KErrBadName
                	DoSafeExit();
                	}
                }
                break;
            case ENcsCmdAddAttachment:
           	 	{
                if ( AknLayoutUtils::PenEnabled() )
                    {
                    // show the toolbar
                    UpdateToolbarL();
                    CAknToolbar* toolbar = Toolbar();
                    if ( toolbar )
                        {
                        CAknToolbarExtension* extension =
                            static_cast<CAknToolbarExtension*>(
                                toolbar->ControlOrNull( EFsEmailUiTbCmdExpandInsert ) );
                        if ( extension )
                            {
                            extension->SetShown( ETrue );
                            }
                        }
                    }
                else
                    {
                    iAttachmentAddType = MsgAttachmentUtils::EUnknown;
                    iAsyncAttachmentAdd->Cancel();
                    iAsyncAttachmentAdd->Set( 
                            TCallBack( AsyncAddAttachment, this ) );
                    iAsyncAttachmentAdd->CallBack();
                    iContainer->SetMskL();
                    }                
           	 	}
                break;
            case EFsEmailUiCmdOpenAttachment:
            case EFsEmailUiCmdOpenAttachmentList:
                {
                DoOpenAttachmentListL();
                }
                break;
            case ENcsCmdRemoveAttachment:
            case EFsEmailUiCmdRemoveAttachment:
                {
                TInt index( iContainer->FocusedAttachmentLabelIndex() );
                CFreestyleEmailUiSendAttachmentsListControl* ctrl =
                    AttachmentsListControl();
                if ( ctrl && KNoAttachmentLabelFocused != index )
                    {
                    ctrl->RemoveAttachmentFromListL( index );
                    }
                SetAttachmentLabelContentL();
                }
                break;
            case ENcsCmdRemoveAllAttachments:
           	 	{
           	 	CFreestyleEmailUiSendAttachmentsListControl* ctrl =
                    AttachmentsListControl();
           	 	if ( ctrl )
           	 	    {
           	 	    ctrl->RemoveAllAttachmentsL();
           	 	    }
           	 	SetAttachmentLabelContentL();
            	}
                break;
            case ENcsCmdPriorityHigh:
            	{
            	if ( iNewMessage )
            	    {
                    iNewMessage->ResetFlag( EFSMsgFlag_Low );
                    iNewMessage->SetFlag( EFSMsgFlag_Important );
                    iNewMessage->SaveMessageL();
                    iMessageModified = EFalse;
                    iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityHigh );
            	    }
            	}
                break;
        	case ENcsCmdPriorityNormal:
    	    	{
    	    	if ( iNewMessage )
    	    	    {
                    iNewMessage->ResetFlag( EFSMsgFlag_Low );
                    iNewMessage->ResetFlag( EFSMsgFlag_Important );
                    iNewMessage->SaveMessageL();
                    iMessageModified = EFalse;
                    iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityNormal );
    	    	    }
    	    	}
                break;
        	case ENcsCmdPriorityLow:
    	    	{
    	    	if ( iNewMessage )
    	    	    {
                    iNewMessage->ResetFlag( EFSMsgFlag_Important );
                    iNewMessage->SetFlag( EFSMsgFlag_Low );
                    iNewMessage->SaveMessageL();
                    iMessageModified = EFalse;
                    iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityLow );
    	    	    }
    	    	}
                break;
            case ENcsCmdShowCc:
                {
                iContainer->SetCcFieldVisibleL( ETrue );
                iCrHandler->SetEditorCCVisible( 1 );
                }
                break;
            case ENcsCmdHideCc:
                {
                iContainer->SetCcFieldVisibleL( EFalse );
                iCrHandler->SetEditorCCVisible( 0 );
                }
                break;
            case ENcsCmdShowBcc:
                {
                iContainer->SetBccFieldVisibleL( ETrue );
                iCrHandler->SetEditorBCVisible( 1 );
                }
                break;
            case ENcsCmdHideBcc:
                {
                iContainer->SetBccFieldVisibleL( EFalse );
                iCrHandler->SetEditorBCVisible( 0 );
                }
                break;
            case ENcsCmdFlag:
    	        {
    	        RunFollowUpFlagDlgL();
    	        }
                break;
            case ENcsCmdQuickText:
    	        {
    	        DoQuickTextL();
    	        }
                break;
            case ENcsCmdInsertContact:
            case ENcsInsertContact:
            	{
            	iContainer->AppendAddressesL();
            	}
                break;
            case ENcsCmdSaveDraft:
            	{

                iContainer->FixSemicolonL();


            	TRAPD( saveDraftError, DoSaveDraftL( EFalse ) );
                if ( saveDraftError == KErrNone )
                	{
                    // Saving successful
                	if( !iAppUi.AppUiExitOngoing() )
                	TFsEmailUiUtility::ShowInfoNoteL( 
                        R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS,
                        ETrue );
                    }
            	else
                    {
                    // error occured in saving -> show an error message
                    if( !iAppUi.AppUiExitOngoing() )
                        TFsEmailUiUtility::ShowErrorNoteL( 
                            R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
                            ETrue );
                    }

            	DoSafeExit( ENoSave );
            	}
                break;
            case EAknCmdHelp:
            	{
            	TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID );
    	        }
            	break;
            case EAknSoftkeySelect:
                {
                iContainer->DoPopupSelectL();
                }
                break;
       	    case EAknSoftkeyCancel:
        	    {
    	 		iContainer->ClosePopupContactListL();
                }
                break;
            case EAknSoftkeyClose:
                {
                if ( !iAddingAttachmentDialogOpened )
                    DoSafeExit();
                }
                break;
            case ENcsCmdExit:
                {
                TIMESTAMP( "Exit selected from editor" );
                iAppUi.Exit();
                }
                break;
            default:
                {
                // empty implementation
                // these commands are passed next to FEP for processing
                }
                break;
            }
        }

    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DoSendL()
// Send message
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DoSendL()
    {
    FUNC_LOG;

    // check that addresses exist
    if ( iContainer->AreAddressFieldsEmpty() )
        {
        User::Leave( KErrNotFound );
        }

    TRAPD( commitErr, CommitL( ETrue, EAllFields, ETrue ) );
    if ( KErrNone != commitErr )
        {
        iMailSendFailed = ETrue;
        User::Leave( commitErr );
        }

    TRAPD(r, iMailBox->SendMessageL( *iNewMessage ) );
    if ( KErrNone != r )
        {
        iMailSendFailed = ETrue;
        User::Leave( r );
        }

    // prevent sending failure if original message is
    // removed from server while replying/forwarding
	TRAPD( flagError, SetReplyForwardFlagL() );

    if ( KErrNone != flagError && KErrNotFound != flagError )
        {
        iMailSendFailed = ETrue;
        User::Leave( flagError );
        }

    iMailSent = ETrue;

    }


// -----------------------------------------------------------------------------
// CNcsComposeView::DoSaveDraftL()
// Saves message to Drafts
// Displays dialog asking user choice if preferred
// Pressing cancel in the query dialog causes Leave with code KErrCancel
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::DoSaveDraftL( TBool aAskUser )
    {
    FUNC_LOG;

    __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );

    TBool result( ETrue );

    if ( aAskUser )
        {
    	TInt selectedOption( -1 );
    	CDesCArrayFlat* array = new (ELeave) CDesCArrayFlat( 2 );
    	CleanupStack::PushL( array );

    	HBufC* saveItem = StringLoader::LoadLC( R_NCS_DRAFT_SAVE );
        array->AppendL( *saveItem );
		CleanupStack::PopAndDestroy( saveItem );

    	HBufC* deleteItem = StringLoader::LoadLC( R_NCS_DRAFT_DISCARD );
        array->AppendL( *deleteItem );
		CleanupStack::PopAndDestroy( deleteItem );

		iDlg = new (ELeave) CAknListQueryDialog( &selectedOption );
    	iDlg->PrepareLC( R_DRAFT_QUERY_DIALOG );
    	iDlg->SetItemTextArray( array );
    	iDlg->SetOwnershipType( ELbmDoesNotOwnItemArray );

        iCheckQuery = ETrue;
        //we are forbiding to change MSK label, cause popup will be opend 
        iContainer->SwitchChangeMskOff( ETrue );
        TInt ret = iDlg->RunLD();
        iDlg = NULL;

        iCheckQuery = EFalse; 
        iContainer->SwitchChangeMskOff( EFalse );

    	if ( !ret )
    	    {
    	    selectedOption = KErrCancel;
    	    }

    	switch ( selectedOption )
    		{
    		case 0:
    			{
				TRAPD( saveError, SaveToDraftsL( ETrue ) );

				if ( saveError == KErrNone )
				    {
				    // User wanted to save to Drafts and saving was successful
				    if( !iAppUi.AppUiExitOngoing() )
				        TFsEmailUiUtility::ShowInfoNoteL( 
                            R_FREESTYLE_EMAIL_CONFIRM_NOTE_SAVED_TO_DRAFTS, 
                            ETrue );
				    }
				else
				    {

				    // error occured in saving -> show an error message
				    if( !iAppUi.AppUiExitOngoing() )
				        TFsEmailUiUtility::ShowErrorNoteL( 
                            R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
                            ETrue );

				    // let's return EFalse so after completing this query
				    // so the focus would stay in compose view (same behaviour
				    // as if Cancel was pressed )
				    result = EFalse;
				    }
				}
                break;
    		case 1:
    			{
    			TIMESTAMP( "Delete draft message selected in editor" ); 
				TRAPD( error, SaveToDraftsL( ETrue ) );
    			if ( KErrNone != error )
    			    {
    			    }
    			// for delete messages fake sync calls
    	        iFakeSyncGoingOn = ETrue;
                error = NcsUtility::DeleteMessage( iMailClient,
            		iMailBox->GetId(),
            		iNewMessage->GetFolderId(),
            		iNewMessage->GetMessageId() );

    			if ( KErrNone == error && 
    			     iMailBox->HasCapability( 
    			             EFSMBoxCapaSupportsDeletedItemsFolder ) )
    			    {
                    error = NcsUtility::DeleteMessage( iMailClient,
                		iMailBox->GetId(),
                		iMailBox->GetStandardFolderId( EFSDeleted ),
                		iNewMessage->GetMessageId() );
    			    }
    		     iFakeSyncGoingOn = EFalse;

                if( !iAppUi.AppUiExitOngoing() )
                    {
                    if ( KErrNone != error )
                        {
                        // error occured in saving -> show an error message
                        TFsEmailUiUtility::ShowErrorNoteL( 
                            R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
                            ETrue );
                        }
                    else
                        {
                        // Simulate delete event so that drafts folder is
                        // updated correctly.
                        RArray<TFSMailMsgId> messageIds;
                        CleanupClosePushL( messageIds );
                        messageIds.AppendL( iNewMessage->GetMessageId() );
                        TFSMailMsgId folderId = iNewMessage->GetFolderId();
                        TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
                        iAppUi.EventL( TFSEventMailDeleted,
                            mailboxId, &messageIds, &folderId, NULL );
                        CleanupStack::PopAndDestroy( &messageIds );
                        }
                    }
                }
                break;
    		default:
    			{
    			result = EFalse;
    			}
                break;
    		}
    	CleanupStack::PopAndDestroy( array );
        }
    else  // no question from user
        {
        SaveToDraftsL( ETrue );
        }

    return result;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::NewMessage()
// Returns pointer to currently composed mail message
// -----------------------------------------------------------------------------
//
CFSMailMessage* CNcsComposeView::NewMessage()
    {
    FUNC_LOG;
	return iNewMessage;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::AsyncAddAttachmentL()
// Open file dialog and add selected file as an attachment
// -----------------------------------------------------------------------------
//
TInt CNcsComposeView::AsyncAddAttachment( TAny* aSelfPtr )
    {
    FUNC_LOG;

    CNcsComposeView* self = static_cast<CNcsComposeView*>( aSelfPtr );

    // get pointer to attachment list view
	CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
	attachmentControl = self->AttachmentsListControl();

    // show file dialog and get file name
    TBool ok = EFalse;
    TInt error = KErrNone;
    CAknToolbar* toolbar = self->Toolbar();
    if ( !toolbar->IsDimmed() )
        {
        toolbar->SetDimmed(ETrue); 
        }
    
    self->iAddingAttachmentDialogOpened = ETrue;
    self->iContainer->SwitchChangeMskOff( ETrue );
    TRAP( error, ok = attachmentControl->AppendAttachmentToListL(
                self->iAttachmentAddType) );

    if( error == KErrNoMemory )
    	{
        TRAP_IGNORE( TFsEmailUiUtility::ShowErrorNoteL( 
            R_FREESTYLE_EMAIL_ERROR_GENERAL_UNABLE_TO_COMPLETE,
            ETrue ) );
    	}
    self->iContainer->SwitchChangeMskOff( EFalse );
    self->iAddingAttachmentDialogOpened = EFalse;
    
    if ( ok && error == KErrNone )
        {
        TRAP( error, self->SetAttachmentLabelContentL() );
        }

    if ( !attachmentControl->IsAttachmentAddingLocked() )
        {
        toolbar->SetDimmed(EFalse);
        self->RefreshToolbar();
        toolbar->DrawDeferred();
        }
    return error;
    }

// -----------------------------------------------------------------------------
// RunFollowUpFlagDlgL()
// Query user for followup flag
// -----------------------------------------------------------------------------
//
void CNcsComposeView::RunFollowUpFlagDlgL()
    {
    FUNC_LOG;
    if ( iNewMessage && TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) )
        {
        TFollowUpNewState newState =
            TFsEmailUiUtility::SetMessageFollowupFlagL( 
                    *iNewMessage, EFalse );

        switch ( newState )
            {
            case EFollowUp:
                {
                iStatusPaneIndicators->SetFollowUpFlag( 
                        CCustomStatuspaneIndicators::EFollowUp );
                }
                break;
            case EFollowUpComplete:
                {
                iStatusPaneIndicators->SetFollowUpFlag( 
                        CCustomStatuspaneIndicators::EFollowUpComplete );
                }
                break;
            case EFollowUpClear:
                {
                iStatusPaneIndicators->SetFollowUpFlag( 
                        CCustomStatuspaneIndicators::EFollowUpNone );
                }
                break;
            default:
                {
                // do nothing.
                }
                break;
            }
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::SetAttachmentLabelContentL()
// Open file dialog and add selected file as an attachment
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SetAttachmentLabelContentL()
    {
    FUNC_LOG;
    if ( iFirstStartCompleted && iContainer )
        {
        CFreestyleEmailUiSendAttachmentsListControl* 
            attachmentControl = AttachmentsListControl();
        if ( !( attachmentControl && attachmentControl->Model() ) )
            {
            return;
            }
        
        // read number of attachments
        TInt count = attachmentControl->Model()->Count();
        if ( count > 0 )
            {
            // Fill in the name and size descriptor arrays
            CDesCArrayFlat* nameArray = new (ELeave) CDesCArrayFlat( count );
            CleanupStack::PushL( nameArray );
            CDesCArrayFlat* sizeArray = new (ELeave) CDesCArrayFlat( count );
            CleanupStack::PushL( sizeArray );

            for ( TInt i(0); i<count; ++i )
                {
                CFSEmailUiSendAttachmentsListModelItem* item =
                    static_cast<CFSEmailUiSendAttachmentsListModelItem*>
                    ( attachmentControl->Model()->Item( i ) );
                if ( item )
                    {
                    nameArray->AppendL( item->FileName() );
                    HBufC* sizeDesc = 
                        TFsEmailUiUtility::CreateSizeDescLC( 
                                item->FileSize() );
                    sizeArray->AppendL( *sizeDesc );
                    CleanupStack::PopAndDestroy( sizeDesc );
                    }
                }
            iContainer->SetAttachmentLabelTextsLD( nameArray, sizeArray );
            iContainer->SetFocusToAttachmentField();
            
            CleanupStack::Pop( sizeArray );
            CleanupStack::Pop( nameArray );
            }
        else
            {
            iContainer->SetAttachmentLabelTextsLD( NULL, NULL );
            iContainer->HideAttachmentLabel();
            }
        }
    }


// -----------------------------------------------------------------------------
// CNcsComposeView::AttachmentsListControl()
//
// -----------------------------------------------------------------------------
//
CFreestyleEmailUiSendAttachmentsListControl* 
CNcsComposeView::AttachmentsListControl()
	{
    FUNC_LOG;
    CFreestyleEmailUiSendAttachmentsListControl* attachmentControl( NULL );
    if ( iFirstStartCompleted ) // Safety
        {
        CFSEmailUiSendAttachmentsListVisualiser* attachmentView =
            static_cast<CFSEmailUiSendAttachmentsListVisualiser*>(
                iAvkonViewAppUi->View( SendAttachmentMngrViewId ) );
        if ( attachmentView )
            {
            attachmentControl = 
                static_cast<CFreestyleEmailUiSendAttachmentsListControl*>(
                    attachmentView->ViewerControl() );
            }
        }
	return attachmentControl;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::ProcessCommandL()
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ProcessCommandL( TInt aCommand )
    {
    FUNC_LOG;

    // Block all the commands while we are exiting
    if ( !iExecutingDoExitL )
        {
        CFsEmailUiViewBase::ProcessCommandL( aCommand );
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::HandleActivationCommandL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::HandleActivationCommandL( TUid aCustomMessageId )
    {
    FUNC_LOG;
    // Called from doactivate in which case first start is completed
    iMailFetchingErrCode = KErrNone;

    if ( aCustomMessageId == TUid::Uid( KEditorCmdCreateNew ) )
        {
        iOrigMessage = NULL;
        iFakeSyncGoingOn = ETrue;
        iNewMessage = iMailBox->CreateMessageToSend();
        iFakeSyncGoingOn = EFalse;
        if ( !iNewMessage )
            {
            User::Leave( KErrGeneral );
            }
        iFakeSyncGoingOn = ETrue;
        TFsEmailUiUtility::MoveMessageToDraftsL( *iMailBox, *iNewMessage );
        iFakeSyncGoingOn = EFalse;
        
        if ( iNewMessage->GetContentType() != 
             KFSMailContentTypeMultipartMixed )
            {
            iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
            iNewMessage->SaveMessageL();
            iMessageModified = EFalse;
            }
        
        TFsEmailUiUtility::CreatePlainTextPartL( 
                *iNewMessage, iNewMessageTextPart );
        IncludeMessageTextL( ETrue );
        AttachmentsListControl()->Model()->Clear();
        iContainer->SelectAllToFieldTextL();
        }
    else if ( aCustomMessageId == TUid::Uid( KEditorCmdReply ) ||
              aCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
        {

        iOrigMessage = iMailClient.GetMessageByUidL( 
                iLaunchParams.iMailboxId, iLaunchParams.iFolderId,
                iLaunchParams.iMsgId, EFSMsgDataStructure );
        if ( !iOrigMessage )
            {
            User::Leave( KErrNotFound );
            }

        SafeDelete( iFetchLogic );
        iFetchLogic = CFsComposerFetchLogic::NewL( 
                iMailClient, iLaunchParams.iMailboxId,
                iOrigMessage->GetFolderId(), iLaunchParams.iMsgId, 
                *this, iAppUi );
        ShowFetchingWaitNoteL();
        iFetchLogic->RunReplyLogicL();

        // now fetch logic object runs its tasks and gives callback
        // to CNcsComposeView::FetchLogicComplete when it is finished
        }
    else if ( aCustomMessageId == TUid::Uid( KEditorCmdForward ) )
        {

        iOrigMessage = iMailClient.GetMessageByUidL( 
                iLaunchParams.iMailboxId, iLaunchParams.iFolderId, 
                iLaunchParams.iMsgId, EFSMsgDataStructure );
        if ( !iOrigMessage )
            {
            User::Leave( KErrNotFound );
            }

        SafeDelete( iFetchLogic );
        iFetchLogic = CFsComposerFetchLogic::NewL( 
                iMailClient, iLaunchParams.iMailboxId,
                iOrigMessage->GetFolderId(), iLaunchParams.iMsgId, 
                *this, iAppUi );
        ShowFetchingWaitNoteL();
        iFetchLogic->RunForwardLogicL();

        // now fetch logic object runs its tasks and gives callback
        // to CNcsComposeView::FetchLogicComplete when it is finished
        }
    else if ( aCustomMessageId == TUid::Uid( KEditorCmdOpen ) ||
              aCustomMessageId == TUid::Uid( KEditorCmdReturnToPrevious ) )
        {
        // for now, we handle returning from attachments list just like 
        // any message opening
        iNewMessage = iMailClient.GetMessageByUidL( 
                iLaunchParams.iMailboxId, iLaunchParams.iFolderId, 
                iLaunchParams.iMsgId, EFSMsgDataStructure );
        if ( !iNewMessage )
            {
            User::Leave( KErrNotFound );
            }

        // Show "Opening" wait note if the message body is large
        TInt waitNoteId = KErrNotFound;
        if ( TFsEmailUiUtility::IsMessageBodyLargeL(iNewMessage) )
            {
            waitNoteId = TFsEmailUiUtility::ShowGlobalWaitNoteLC( 
                    R_FSE_WAIT_OPENING_TEXT );
            }

        iOrigMessage = NULL;
        iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
        iNewMessage->SaveMessageL();
        iMessageModified = EFalse;
        TFsEmailUiUtility::CreatePlainTextPartL( 
                *iNewMessage, iNewMessageTextPart );
        InitFieldsL();
        TBool spaceInBegin = ETrue;
        IncludeMessageTextL(spaceInBegin);
        AttachmentsListControl()->Model()->Clear();
        GetAttachmentsFromMailL();
        SetAttachmentLabelContentL();
        iAttachmentListSaveDraft = ETrue;

        // Close the "Opening" wait note if it was shown
        if ( waitNoteId != KErrNotFound )
            {
            CleanupStack::PopAndDestroy( (TAny*)waitNoteId );
            }
        }
    else if ( aCustomMessageId == TUid::Uid( KEditorCmdInternalMailto ) )
        {
        FUNC_LOG;

        iOrigMessage = NULL;
        iFakeSyncGoingOn = ETrue;
        iNewMessage = iMailBox->CreateMessageToSend();
        iFakeSyncGoingOn = EFalse;
        if ( !iNewMessage )
            {
            User::Leave( KErrGeneral );
            }
        iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
        iNewMessage->SaveMessageL();
        iMessageModified = EFalse;

        TFsEmailUiUtility::CreatePlainTextPartL( 
                *iNewMessage, iNewMessageTextPart );

        IncludeMessageTextL( ETrue );

        CFSMailAddress* toAddress = 
            static_cast<CFSMailAddress*>( iLaunchParams.iExtra ); // not owned
        RPointerArray<CNcsEmailAddressObject> toRecipients;
        CleanupResetAndDestroyClosePushL( toRecipients );
        CNcsEmailAddressObject* ncsToAddress = 
            NcsUtility::CreateNcsAddressL( *toAddress );
        CleanupStack::PushL( ncsToAddress );
        toRecipients.AppendL( ncsToAddress );
        CleanupStack::Pop( ncsToAddress ); // owned by toRecipients now
        iContainer->SetToFieldAddressesL( toRecipients );
        CleanupStack::PopAndDestroy( &toRecipients );

        iContainer->SetFocusToMessageFieldL();
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DoQuickTextL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DoQuickTextL()
    {
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

	HBufC* title = 
        iEikonEnv->AllocReadResourceLC( R_NCS_QUICK_TEXT_TITLE_TEXT );
	HBufC* buf( 0 );
	TRAPD( err, buf = CNotepadApi::FetchTemplateL( title ) );
	if ( err == KLeaveExit )
	    { 
		// If end key was pressed the dialog leaves with the above error code.
	    // In that case we must leave as well or the application will become
	    // stuck as the exit will be incomplete.
	    User::Leave( err );
	    }
		
	if ( buf && err == KErrNone ) // Safety check, 0 if user cancel
		{
		CleanupStack::PushL( buf );
		iContainer->AddQuickTextL( *buf );
		CleanupStack::PopAndDestroy( buf );
		}
	CleanupStack::PopAndDestroy( title );

    }

// -----------------------------------------------------------------------------
// CNcsComposeView::HandleDynamicVariantSwitchL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::HandleDynamicVariantSwitchL(
    CFsEmailUiViewBase::TDynamicSwitchType aType )
	{
    FUNC_LOG;

    if ( iFirstStartCompleted && iContainer && !iExecutingDoExitL )
        {
        if ( aType == CFsEmailUiViewBase::EScreenLayoutChanged )
            {
            iContainer->HandleLayoutChangeL();
            }
        else if ( aType == CFsEmailUiViewBase::ESkinChanged )
            {
            iContainer->HandleSkinChangeL();
            }
        else
            {
            }
        }

	}

// ---------------------------------------------------------------------------
// CNcsComposeView::FadeOut()
// enables hiding toolbar on different view -> DoActivate()  
// which is earlier than -> CFsEmailUiViewBase::DoDeactivate() 
// -----------------------------------------------------------------------------
//
void CNcsComposeView::FadeOut( TBool aDirectionOut )
    {
    if ( aDirectionOut && Toolbar()->IsShown() )
        {
        HideToolbar();
        }
    else if ( ! ( aDirectionOut || Toolbar()->IsShown() ) )
        {
        ShowToolbar();
        }
    }
// -----------------------------------------------------------------------------
// CNcsComposeView::InitReplyFieldsL()
// Initialises the reply fields from the reply message created by the plug-in.
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitReplyFieldsL( TBool /*aReplyAll*/ )
    {
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

    // Get TO recipients
    RPointerArray<CFSMailAddress>& toRecipients = 
        iNewMessage->GetToRecipients();
    RPointerArray<CNcsEmailAddressObject> recipients;
    CleanupResetAndDestroyClosePushL( recipients );
    NcsUtility::ConvertAddressArrayL( toRecipients, recipients );
    iContainer->SetToFieldAddressesL( recipients );
    CleanupStack::PopAndDestroy( &recipients );

    // Get CC recipients
    RPointerArray<CFSMailAddress>& ccRecipients = 
        iNewMessage->GetCCRecipients();
    NcsUtility::ConvertAddressArrayL( ccRecipients, recipients );
    iContainer->SetCcFieldAddressesL( recipients );
    recipients.ResetAndDestroy();

    // Get BCC recipients
    RPointerArray<CFSMailAddress>& bccRecipients = 
        iNewMessage->GetBCCRecipients();
    NcsUtility::ConvertAddressArrayL( bccRecipients, recipients );
    iContainer->SetBccFieldAddressesL( recipients );
    recipients.ResetAndDestroy();

    // Get subject line from original message
    HBufC* prefix = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_REPLY_PREFIX );
    HBufC* formattedSubject = NcsUtility::FormatSubjectLineL(
        iOrigMessage->GetSubject(), *prefix );
    CleanupStack::PushL( formattedSubject );
    iContainer->SetSubjectL( *formattedSubject );
    CleanupStack::PopAndDestroy( formattedSubject );
    CleanupStack::PopAndDestroy( prefix );

    // clear attachments
    AttachmentsListControl()->Model()->Clear();

    }

// -----------------------------------------------------------------------------
// CNcsComposeView::RemoveOwnAddress()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::RemoveOwnAddress( 
        RPointerArray<CNcsEmailAddressObject>& aAddressList )
    {
    FUNC_LOG;
    TInt index = 0;
    TDesC& ownAddress( iMailBox->OwnMailAddress().GetEmailAddress() );
	while ( index < aAddressList.Count() )
        {
        if ( !aAddressList[index]->EmailAddress().CompareC(ownAddress) )
            {
            // The entry will be removed from the arry.
            aAddressList.Remove(index);
            break;
            }
        index++;
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::IncludeMessageTextL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::IncludeMessageTextL( 
        TBool aEnsureSpaceInBegin /*= EFalse*/ )
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

    HBufC* body = NULL;
    HBufC* rawBody = GetMessageBodyL();
    CleanupStack::PushL( rawBody );

    // Ensure there's free space in the beginning of the message if required
    if ( aEnsureSpaceInBegin && rawBody->Length() )
        {
        TText firstChar = (*rawBody)[0];
        _LIT( KNewLines, "\r\n\x2028\x2029" );
        if ( KNewLines().Locate( firstChar ) == KErrNotFound )
            {
            // First character is not a new line character. Insert one.
            body = HBufC::NewL( rawBody->Length() + KIMSLineFeed().Length() );
            TPtr ptr = body->Des();
            ptr.Append( KIMSLineFeed );
            ptr.Append( *rawBody );
            CleanupStack::PopAndDestroy( rawBody );
            rawBody = NULL;
            CleanupStack::PushL( body );
            }
        }
    // If no modifications were needed, then just set body pointer to point
    // the rawBody
    if ( !body )
        {
        body = rawBody;
        rawBody = NULL;
        }
    // Now we have possibly decorated message text in body pointer and
    // in cleanup stack

    // Divide the contents into normal body and the read-only quote fields
    // Convert bytes length to words length
    TInt readOnlyLength = iNewMessageTextPart->ReadOnlyPartSize() / 2;
    if ( body )
    	{
		TInt modifiableLength = body->Length() - readOnlyLength;
	
		// Remove one newline from the end of the modifiable body if there's
		// read-only quote present. This is because the field boundary appears
		// as newline on the screen. This newline is added back when saving
		// the message.
		TInt lfLength = KIMSLineFeed().Length();
		if ( readOnlyLength && modifiableLength >= lfLength &&
			 body->Mid( modifiableLength-lfLength, lfLength ) == 
			 KIMSLineFeed )
			{
			modifiableLength -= lfLength;
			}
	
		iContainer->SetBodyContentL( body->Left( modifiableLength ),
			body->Right( readOnlyLength ) );
    	}

    CleanupStack::PopAndDestroy( body );
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::IncludeMessageTextAsyncL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::IncludeMessageTextAsyncL( TBool aEnsureSpaceInBegin /*= EFalse*/ )
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

    delete iBody;
    iBody = NULL;
    HBufC* rawBody = GetMessageBodyL();

    // Ensure there's free space in the beginning of the message if required
    if ( aEnsureSpaceInBegin && rawBody->Length() )
        {
        TText firstChar = (*rawBody)[0];
        _LIT( KNewLines, "\r\n\x2028\x2029" );
        if ( KNewLines().Locate( firstChar ) == KErrNotFound )
            {
			CleanupStack::PushL( rawBody );
            // First character is not a new line character. Insert one.
            iBody = HBufC::NewL( rawBody->Length() + KIMSLineFeed().Length() );
            TPtr ptr = iBody->Des();
            ptr.Append( KIMSLineFeed );
            ptr.Append( *rawBody );
            CleanupStack::PopAndDestroy( rawBody );
            rawBody = NULL;
            }
        }
    // If no modifications were needed, then just set body pointer to point
    // the rawBody
    if ( !iBody )
        {
        iBody = rawBody;
        rawBody = NULL;
        }
    // Now we have possibly decorated message text in body pointer and
    // in cleanup stack

    // Divide the contents into normal body and the read-only quote fields
    // Convert bytes length to words length
    TInt readOnlyLength = iNewMessageTextPart->ReadOnlyPartSize() / 2;
	//This check is unnecessary, but without that coverity complains
    if ( iBody )
    	{
		TInt modifiableLength = iBody->Length() - readOnlyLength;
	
		// Remove one newline from the end of the modifiable body if there's
		// read-only quote present. This is because the field boundary appears
		// as newline on the screen. This newline is added back when saving
		// the message.
		TInt lfLength = KIMSLineFeed().Length();
		if ( readOnlyLength && modifiableLength >= lfLength &&
			 iBody->Mid( modifiableLength-lfLength, lfLength ) == KIMSLineFeed )
			{
			modifiableLength -= lfLength;
			}
	
		iContainer->SetBodyContentAsyncL( iBody->Left( modifiableLength ),
			iBody->Right( readOnlyLength ) );
		
		// callback: SetBodyContentCompleteL
    	}
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::SetBodyContentComplete()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SetBodyContentComplete()
	{
	delete iBody;
	iBody = NULL;
	
    if ( iOpeningWaitDialog )
        {
        TRAP_IGNORE( iOpeningWaitDialog->ProcessFinishedL() );
        iOpeningWaitDialog = NULL;
        }
    
    iOpeningWaitNoteVisible = EFalse;
    iIncludeMessageTextAsync = EFalse;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::IsOpeningWaitNoteVisible()
//
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::IsOpeningWaitNoteVisible() 
    {
    return iOpeningWaitNoteVisible;
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::InitForwardFieldsL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitForwardFieldsL()
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

	// set subject
	HBufC* prefix = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_FORWARD_PREFIX );
	HBufC* formattedSubject = NcsUtility::FormatSubjectLineL( 
	        iOrigMessage->GetSubject(), *prefix );
	CleanupStack::PushL( formattedSubject );
	iContainer->SetSubjectL( *formattedSubject );
	CleanupStack::PopAndDestroy( formattedSubject );
	CleanupStack::PopAndDestroy( prefix );

    // attachments
	AttachmentsListControl()->Model()->Clear();
	// <cmail>
	TInt error = KErrNone;
	TRAP( error, GetAttachmentsFromMailL() );
	// </cmail>
	SetAttachmentLabelContentL();

	}

// -----------------------------------------------------------------------------
// CNcsComposeView::SetPriority()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SetPriority()
    {
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

    if ( iNewMessage && iNewMessage->IsFlagSet( EFSMsgFlag_Important ) )
        {
        iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityHigh );
        }
    else if ( iNewMessage && iNewMessage->IsFlagSet( EFSMsgFlag_Low ) )
        {
        iStatusPaneIndicators->SetPriorityFlag( EMsgPriorityLow );
        }
    }

// -----------------------------------------------------------------------------
// Sets follow-up flags to status pane indicators
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SetFollowUp()
    {
    if ( iNewMessage && iStatusPaneIndicators )
        {
        if ( iNewMessage->IsFlagSet( EFSMsgFlag_FollowUp ) )
            {
            iStatusPaneIndicators->SetFollowUpFlag(
                CCustomStatuspaneIndicators::EFollowUp );
            }
        else if ( iNewMessage->IsFlagSet( EFSMsgFlag_FollowUpComplete ) )
            {
            iStatusPaneIndicators->SetFollowUpFlag(
                CCustomStatuspaneIndicators::EFollowUpComplete );
            }
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::InitFieldsL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitFieldsL()
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iContainer, Panic( ENcsBasicUi ) );

	// to
 	RPointerArray<CFSMailAddress>& toRecipients = 
        iNewMessage->GetToRecipients();
	RPointerArray<CNcsEmailAddressObject> ncsToRecipients;
	CleanupResetAndDestroyClosePushL( ncsToRecipients );
	NcsUtility::ConvertAddressArrayL( toRecipients, ncsToRecipients );
 	iContainer->SetToFieldAddressesL( ncsToRecipients );
    CleanupStack::PopAndDestroy( &ncsToRecipients );

	// cc
 	RPointerArray<CFSMailAddress>& ccRecipients = 
        iNewMessage->GetCCRecipients();
	RPointerArray<CNcsEmailAddressObject> ncsCcRecipients;
    CleanupResetAndDestroyClosePushL( ncsCcRecipients );
	NcsUtility::ConvertAddressArrayL( ccRecipients, ncsCcRecipients );
 	iContainer->SetCcFieldAddressesL( ncsCcRecipients );
    CleanupStack::PopAndDestroy( &ncsCcRecipients );

	// bcc
 	RPointerArray<CFSMailAddress>& bccRecipients = 
        iNewMessage->GetBCCRecipients();
	RPointerArray<CNcsEmailAddressObject> ncsBccRecipients;
    CleanupResetAndDestroyClosePushL( ncsBccRecipients );
	NcsUtility::ConvertAddressArrayL( bccRecipients, ncsBccRecipients );
 	iContainer->SetBccFieldAddressesL( ncsBccRecipients );
    CleanupStack::PopAndDestroy( &ncsBccRecipients );

	// set subject line
	iContainer->SetSubjectL( iNewMessage->GetSubject() );

	}

// -----------------------------------------------------------------------------
// CNcsComposeView::GetMessageBodyL()
//
// -----------------------------------------------------------------------------
//
HBufC* CNcsComposeView::GetMessageBodyL()
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iNewMessageTextPart, Panic( ENcsBasicUi ) );

    TInt messageSize = iNewMessageTextPart->FetchedContentSize();

    HBufC* data = NULL;

    if ( messageSize > 0 )
        {
        // fetch message body if there is something to fetch
        data = HBufC::NewLC( messageSize );
        TPtr dataPtr = data->Des();
        iNewMessageTextPart->GetContentToBufferL( dataPtr, 0 );
        CleanupStack::Pop( data );
        }
    else
        {
        data = KNullDesC().AllocL();
        }

	return data;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::CommitL()
//
// -----------------------------------------------------------------------------
//
void CNcsComposeView::CommitL( TBool aParseAddresses,
    TFieldToCommit aFieldToCommit, TBool aSaveNow, TCommitType aType  )
    {
    FUNC_LOG;
    __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );
	__ASSERT_DEBUG( iNewMessageTextPart, Panic( ENcsBasicUi ) );

	TBool commitToField = EFalse;
	TBool commitCcField = EFalse;
	TBool commitBccField = EFalse;
	TBool commitSubjectField = EFalse;
	TBool commitBodyField = EFalse;

	switch ( aFieldToCommit )
	    {
	    case EAllFields:
	        commitToField = ETrue;
	        commitCcField = ETrue;
	        commitBccField = ETrue;
	        commitSubjectField = ETrue;
	        commitBodyField = ETrue;
	        break;
	    case EToField:
            commitToField = ETrue;
	        break;
	    case ECcField:
            commitCcField = ETrue;
	        break;
	    case EBccField:
            commitBccField = ETrue;
	        break;
        case EBodyField:
            commitBodyField = ETrue;
            break;
        case ESubjectField:
            commitSubjectField = ETrue;
            break;
        default:
            break;
        }

	if ( iNewMessage )
	    {
        if ( commitToField )
            {
            RPointerArray<CFSMailAddress>& recipients = 
                iNewMessage->GetToRecipients();
            recipients.ResetAndDestroy();
            NcsUtility::ConvertAddressArrayL(
                iContainer->GetToFieldAddressesL( aParseAddresses ), recipients );
            }
    
        if ( commitCcField )
            {
            RPointerArray<CFSMailAddress>& recipients = 
                iNewMessage->GetCCRecipients();
            recipients.ResetAndDestroy();
            NcsUtility::ConvertAddressArrayL( 
                iContainer->GetCcFieldAddressesL( aParseAddresses ), recipients );
            }
    
        if ( commitBccField )
            {
            RPointerArray<CFSMailAddress>& recipients = 
                iNewMessage->GetBCCRecipients();
            recipients.ResetAndDestroy();
            NcsUtility::ConvertAddressArrayL( 
                iContainer->GetBccFieldAddressesL( aParseAddresses ), recipients );
            }

        if ( commitSubjectField )
            {
            // get subject from UI to MSG object
            HBufC* subject = iContainer->GetSubjectLC();
            TPtr ptr = subject->Des();
            // replace new line characters with spaces as Subject is normally
            // one line only
            AknTextUtils::ReplaceCharacters( 
                    ptr, KLineSeparators, KReplacementChar );
            iNewMessage->SetSubject( *subject );
            CleanupStack::PopAndDestroy( subject );
            }
        }
    else // iNewMessage is still NULL
        {
        User::Leave( KErrNotFound );
        }
	
	if ( iNewMessageTextPart )
	    {
        if ( commitBodyField )
            {
            HBufC* body = iContainer->GetBodyContentLC();
            TPtr bodyPtr = body->Des(); // this TPtr is needed only because of
            // incorrect argument type in FW API, can be removed when API fixed
            iNewMessageTextPart->SetContent( bodyPtr );
            CleanupStack::PopAndDestroy( body );
            iMessageTextPartModified = ETrue;
            }
	    }
	else // iNewMessageTextPart is still NULL
	    {
        User::Leave( KErrNotFound );
	    }
        
    iMessageModified = ETrue;
    RefreshToolbar();

    if ( aSaveNow )
        {
        SaveMessageL();
        
        // If this is final commit, then inform it via extension
        if ( aType == EFinal )
            {
            CMailMessageExtension* messageExtension = 
                    static_cast<CMailMessageExtension*>
                        ( iNewMessage->ExtensionL( KEmailMessageExtensionUid ) );
            if ( messageExtension )
                {
                messageExtension->CommitL( *iNewMessage ) ;
                iNewMessage->ReleaseExtension( messageExtension );
                }
            }
        }
    }

TInt CNcsComposeView::SaveMessage()
    {
    FUNC_LOG;
    TInt error = KErrNone;
    TRAP( error, SaveMessageL() );
    return error;
    }

// -----------------------------------------------------------------------------
// Saves the new message if it has been modifed since the last save.
// -----------------------------------------------------------------------------
void CNcsComposeView::SaveMessageL()
    {
    FUNC_LOG;
    if ( iNewMessageTextPart && iMessageTextPartModified )
        {
        iNewMessageTextPart->SaveL();
        iMessageTextPartModified = EFalse;
        }

    if ( iNewMessage && iMessageModified )
        {
        iNewMessage->SaveMessageL();
        iMessageModified = EFalse;
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DoSafeExit
// -----------------------------------------------------------------------------
void CNcsComposeView::DoSafeExit( TExitMode aMode )
    {
    FUNC_LOG;
    if ( !iExecutingDoExitL )
        {
        iExecutingDoExitL = ETrue;
        TRAP_IGNORE( DoExitL( aMode ) );
        iExecutingDoExitL = EFalse;
        }
    }


// -----------------------------------------------------------------------------
// CNcsComposeView::DoExitL
// -----------------------------------------------------------------------------
void CNcsComposeView::DoExitL( TExitMode aMode )
    {
    FUNC_LOG;

    TBool emptyMessage = ETrue;

    if ( iAutoSaver && iContainer )
        {
        iAutoSaver->Enable( EFalse );

        // check for some user input in some header field or in message body
    	TInt attaCount = AttachmentsListControl()->Model()->Count();
        emptyMessage =  iContainer->AreAddressFieldsEmpty() &&
            iContainer->IsSubjectFieldEmpty() &&
            iContainer->GetMessageFieldLength() < 1 &&
            attaCount <= 0;
	    }

    // Consider saving the draft if the message is not completely empty
    if ( !emptyMessage )
        {
        if ( aMode == ESaveDraftQuery && !iMailSent && !iMailSendFailed )
            {
            TBool actionSucceeded = EFalse;

            // DoSaveDraftL returns EFalse if the user query was cancelled
            // or saving to Drafts failed
            TRAPD( saveDraftError, actionSucceeded = DoSaveDraftL( ETrue ) );
            if ( saveDraftError == KErrNone )
                {
                if ( !actionSucceeded )
                    {
                    // return to normal action 
                    // (cancel was pressed in the query)
                    iAutoSaver->Enable( ETrue );
                    return;
                    }
                }
            else
                {
                }
            }
        else if ( aMode == ESaveDraft )
            {
            DoSaveDraftL( EFalse );
            }
        }
    else if ( iNewMessage ) // message is empty 
        {
        // delete the draft if it has been already saved earlier
        TInt err = NcsUtility::DeleteMessage( iMailClient, iMailBox->GetId(),
            iNewMessage->GetFolderId(), iNewMessage->GetMessageId() );
        if ( !err && iMailBox->HasCapability( 
                EFSMBoxCapaSupportsDeletedItemsFolder ) )
            {
            err = NcsUtility::DeleteMessage( iMailClient, iMailBox->GetId(),
                iMailBox->GetStandardFolderId( EFSDeleted ),
                iNewMessage->GetMessageId() );
            }

        if ( !err && !iAppUi.AppUiExitOngoing() )
            {
            // Simulate delete event so that drafts folder is
            // updated correctly.
            RArray<TFSMailMsgId> messageIds;
            CleanupClosePushL( messageIds );
            messageIds.AppendL( iNewMessage->GetMessageId() );
            TFSMailMsgId folderId = iNewMessage->GetFolderId();
            TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
            iAppUi.EventL( TFSEventMailDeleted,
                mailboxId, &messageIds, &folderId, NULL );
            CleanupStack::PopAndDestroy( &messageIds );
            }
        }

    // Clear attachment control now that message has been sent
    // othewise this will kind of leak memory by leaving attachments
    // in the list, even if they have been sent.
    CFreestyleEmailUiSendAttachmentsListControl* attachmentControl;
    attachmentControl = AttachmentsListControl();
    if ( attachmentControl && attachmentControl->Model() )
        {
        attachmentControl->Model()->Clear();
        }
    ExitComposer();
    TIMESTAMP( "Editor exited" );
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DoOpenAttachmentList
// Opens the currently focused attachment
// -----------------------------------------------------------------------------
void CNcsComposeView::DoOpenAttachmentListL()
	{
    FUNC_LOG;

    CFreestyleEmailUiSendAttachmentsListControl* attachmentControl
   		= AttachmentsListControl();

    TInt index( iContainer ? iContainer->FocusedAttachmentLabelIndex() 
            : KNoAttachmentLabelFocused );
    if ( KNoAttachmentLabelFocused != index && 
         attachmentControl && attachmentControl->Model() )
        {
        CFSEmailUiSendAttachmentsListModelItem* item =
            static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
                    attachmentControl->Model()->Item( index ) );
            
        if ( item && !item->IsRemote() ) // cannot open remote attachments
            {
            CFSMailMessagePart* msgPart = 
                iNewMessage->ChildPartL( item->MailMsgPartId() );
            CleanupStack::PushL( msgPart );
            TFsEmailUiUtility::OpenAttachmentL( *msgPart );
            CleanupStack::PopAndDestroy( msgPart );
            }
        }
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::LaunchStylusPopupMenu
// Show stylus popup menu for the attachments line
// -----------------------------------------------------------------------------
//
void CNcsComposeView::LaunchStylusPopupMenu( const TPoint& aPenEventScreenLocation )
    {
    FUNC_LOG;
    
    CFSEmailUiSendAttachmentsListModel* attachmentModel =
        ( AttachmentsListControl() ? 
                AttachmentsListControl()->Model() : NULL ); 
    TInt count( attachmentModel ? attachmentModel->Count() : 0 );
    TBool attachmentsInModel( count > 0 );
    CFSEmailUiSendAttachmentsListModelItem* item( NULL );
   
    if ( attachmentsInModel )
        {
        item = static_cast<CFSEmailUiSendAttachmentsListModelItem*>( 
                attachmentModel->Item( 
                    iContainer->FocusedAttachmentLabelIndex() ) );
        // Only non-remote attachments can be opened
        TBool dimOpenMenuItem = !item || item->IsRemote(); 
        iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdOpenAttachment, dimOpenMenuItem );

        // Read-only attachments cannot be removed
        TBool dimRemoveMenuItem = !item || item->IsReadOnly();  
        iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdRemoveAttachment, dimRemoveMenuItem );
        }

    // Set the position for the popup
	iStylusPopUpMenu->SetPosition( aPenEventScreenLocation );

	// Display the popup.
	iStylusPopUpMenu->ShowMenu();
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::GetAttachmentsFromMail
// -----------------------------------------------------------------------------
void CNcsComposeView::GetAttachmentsFromMailL()
	{
    FUNC_LOG;

    TInt error( KErrNone );

	RPointerArray<CFSMailMessagePart> attachments;
    CleanupResetAndDestroyClosePushL( attachments );
	TRAP( error, iNewMessage->AttachmentListL( attachments ) );
	User::LeaveIfError( error );

	for ( TInt i=0; i<attachments.Count(); ++i )
		{
        TFileType fileType = TFsEmailUiUtility::GetFileType( 
                attachments[i]->AttachmentNameL(),
                attachments[i]->GetContentType() );

        TBool isReadOnly = ( attachments[i]->ReadOnlyPartSize() > 0 );
        TBool isRemote = EFalse;

		if ( attachments[i]->FetchedContentSize() < 
		     attachments[i]->ContentSize() )
			{
			if ( iMailBox->HasCapability( EFSMBoxCapaSmartForward ) )
			    {
			    isRemote = ETrue;
			    }
			else
			    {
	            __ASSERT_DEBUG( EFalse, Panic(EFSEmailUiUnexpectedValue) );
	            User::Leave( KErrNotFound );
	            continue;
			    }
			}

		AttachmentsListControl()->AppendFileToModelL(
		        attachments[i]->GetPartId(),
		        attachments[i]->AttachmentNameL(),
		        attachments[i]->ContentSize(),
		        fileType,
		        isReadOnly,
		        isRemote );
		}

	CleanupStack::PopAndDestroy( &attachments );

	}

// -----------------------------------------------------------------------------
// CNcsComposeView::FileExistsInModel
// -----------------------------------------------------------------------------
TBool CNcsComposeView::FileExistsInModel( TFSMailMsgId aAttachmentId )
	{
    FUNC_LOG;

	TInt count( AttachmentsListControl()->Model()->Count() );

	for ( TInt i=0; i < count; ++i )
		{
		CFSEmailUiSendAttachmentsListModelItem* item =
			static_cast<CFSEmailUiSendAttachmentsListModelItem*>(
                AttachmentsListControl()->Model()->Item(i) );
		if ( aAttachmentId.Id() == item->MailMsgPartId().Id() )
			{
			return ETrue;
			}
		}

	return EFalse;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::GenerateReplyHeaderLC
// -----------------------------------------------------------------------------
HBufC* CNcsComposeView::GenerateReplyHeaderLC()
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iOrigMessage, Panic( ENcsBasicUi ) );

	// separator line
	HBufC* separator = 
        StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_MESSAGE_LINE_SEPARATOR ); //1

	// from line
	RPointerArray<CNcsEmailAddressObject> senderArray;
	CleanupResetAndDestroyClosePushL( senderArray );
    CFSMailAddress* sender = iOrigMessage->GetSender();
    if ( sender )
        {
    	CNcsEmailAddressObject* ncsSender = 
            NcsUtility::CreateNcsAddressL( *sender );
    	CleanupStack::PushL( ncsSender );
	    senderArray.AppendL( ncsSender );
	    CleanupStack::Pop( ncsSender ); // now owned by senderArray
        }
	HBufC* fromLine = 
        NcsUtility::GenerateFromLineToMessageBodyL( senderArray );
	CleanupStack::PopAndDestroy( &senderArray );
	CleanupStack::PushL( fromLine ); //2

	// sent line
	HBufC* sentLine = 
        NcsUtility::GenerateSentLineToMessageBodyL( *iOrigMessage );
	CleanupStack::PushL( sentLine ); //3

	// to line
	RPointerArray<CNcsEmailAddressObject> ncsToRecipients;
	CleanupResetAndDestroyClosePushL( ncsToRecipients );
	RPointerArray<CFSMailAddress>& toRecipients = 
        iOrigMessage->GetToRecipients();
	NcsUtility::ConvertAddressArrayL( toRecipients, ncsToRecipients );
	HBufC* toLine = NcsUtility::GenerateAddressLineToMessageBodyL( 
                ncsToRecipients, NcsUtility::ERecipientTypeTo );
    CleanupStack::PopAndDestroy( &ncsToRecipients );
	CleanupStack::PushL( toLine ); //4

	// cc line
	RPointerArray<CFSMailAddress>& ccRecipients = 
        iOrigMessage->GetCCRecipients();
	TBool hasCcLine = ( ccRecipients.Count() > 0 );
    HBufC* ccLine = NULL;
	if ( hasCcLine )
		{
	    RPointerArray<CNcsEmailAddressObject> ncsCcRecipients;
	    CleanupResetAndDestroyClosePushL( ncsCcRecipients );
		NcsUtility::ConvertAddressArrayL( ccRecipients, ncsCcRecipients );
		ccLine = NcsUtility::GenerateAddressLineToMessageBodyL( 
		        ncsCcRecipients, NcsUtility::ERecipientTypeCc );
	    CleanupStack::PopAndDestroy( &ncsCcRecipients );
		CleanupStack::PushL( ccLine ); //5
		}

	// subject line
	HBufC* subjectLine = NcsUtility::GenerateSubjectLineToMessageBodyL( 
	        iOrigMessage->GetSubject() );
	CleanupStack::PushL( subjectLine ); //6

    // Body
    HBufC* body = NULL;
    TBool hasBody = EFalse;
    CFSMailMessagePart* textBodyPart = iOrigMessage->PlainTextBodyPartL();
    if ( textBodyPart )
        {
        // Plain text body part present, no need
        // to generate it from HTML body part
        delete textBodyPart;
        }
    else
        {
        // Generate body part for reply
        CFSMailMessagePart* htmlBodyPart = iOrigMessage->HtmlBodyPartL();
        if ( htmlBodyPart )
            {
            CleanupStack::PushL( htmlBodyPart );

            HBufC* htmlData = 
                HBufC::NewLC( htmlBodyPart->FetchedContentSize() );
            TPtr pointer = htmlData->Des();
            htmlBodyPart->GetContentToBufferL( pointer, 0 );

            body = TFsEmailUiUtility::ConvertHtmlToTxtL( *htmlData );

            CleanupStack::PopAndDestroy( htmlData );
            CleanupStack::PopAndDestroy( htmlBodyPart );

            CleanupStack::PushL( body ); //7

            hasBody = ETrue;
            }
        }
	// calculate total length
	TInt length = 0;
	length += separator->Length();
	length += KIMSLineFeed().Length();
	length += fromLine->Length();
	length += KIMSLineFeed().Length();
	length += sentLine->Length();
	length += KIMSLineFeed().Length();
	length += toLine->Length();
	if ( hasCcLine )
		{
		length += KIMSLineFeed().Length();
		length += ccLine->Length();
		}
	length += KIMSLineFeed().Length();
	length += subjectLine->Length();
	length += KIMSLineFeed().Length();
    if ( hasBody )
        {
        length += body->Length();
        }
	length += KIMSLineFeed().Length();
	length += KIMSLineFeed().Length();

	// create buffer and write contents
	HBufC* header = HBufC::NewL( length );
	TPtr ptr = header->Des();
	ptr.Append( *separator );
	ptr.Append( KIMSLineFeed );
	ptr.Append( *fromLine );
	ptr.Append( KIMSLineFeed );
	ptr.Append( *sentLine );
	ptr.Append( KIMSLineFeed );
	ptr.Append( *toLine );
	if ( hasCcLine )
		{
		ptr.Append( KIMSLineFeed );
		ptr.Append( *ccLine );
		}
	ptr.Append( KIMSLineFeed );
	ptr.Append( *subjectLine );
	ptr.Append( KIMSLineFeed );
    if ( hasBody )
        {
        ptr.Append( *body );
        }
	ptr.Append( KIMSLineFeed );
	ptr.Append( KIMSLineFeed );

	// leave header on the cleanup stack
    if ( hasBody )
        {
        CleanupStack::PopAndDestroy( body ); //-7
        }
	CleanupStack::PopAndDestroy( subjectLine ); //-6
	if ( hasCcLine )
		{
		CleanupStack::PopAndDestroy( ccLine ); //-5
		}
	CleanupStack::PopAndDestroy( toLine ); //-4
	CleanupStack::PopAndDestroy( sentLine ); //-3
	CleanupStack::PopAndDestroy( fromLine ); //-2
	CleanupStack::PopAndDestroy( separator ); //-1

	CleanupStack::PushL( header );

	return header;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::GenerateSmartTagLC
// -----------------------------------------------------------------------------
HBufC* CNcsComposeView::GenerateSmartTagLC()
	{
    FUNC_LOG;

	HBufC* tag = StringLoader::LoadLC( R_FSE_EDITOR_SMART_TAG );

	return tag;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::InitReplyOrForwardUiL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitReplyOrForwardUiL()
    {
    FUNC_LOG;
    // Show "Opening" wait note if the message body is large
    iOpeningWaitNoteVisible = EFalse;
    if ( TFsEmailUiUtility::IsMessageBodyLargeL(iOrigMessage) )
        {
        TFsEmailUiUtility::ShowWaitNoteL( iOpeningWaitDialog, 
                R_FSE_WAIT_OPENING_TEXT, EFalse, ETrue );
        iOpeningWaitNoteVisible = ETrue;
        }

    // disable this flag if "old style" sync mode is needed
    // for including body of text
    iIncludeMessageTextAsync = ETrue;
    
    if ( iCustomMessageId == TUid::Uid( KEditorCmdReply ) )
        {
        GenerateReplyMessageL( EFalse );
        InitReplyUiL( EFalse );
        }
    else if ( iCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
        {
        GenerateReplyMessageL( ETrue );
        InitReplyUiL( ETrue );
        }
    else if ( iCustomMessageId == TUid::Uid( KEditorCmdForward ) )
        {
        GenerateForwardMessageL();
        InitForwardUiL();
        }
    else
        {
        // This shouldn't ever happen. Panic in debug builds.
        ASSERT( EFalse );
        }
    
    // Close the "Opening" wait note if it was shown 
    // and include message text was done synchronously
    if ( !iIncludeMessageTextAsync && iOpeningWaitDialog )
        {
        iOpeningWaitDialog->ProcessFinishedL();
        iOpeningWaitDialog = NULL;
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::GenerateReplyMessageL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::GenerateReplyMessageL( TBool aReplyAll )
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );

	TReplyForwardParams params;
	params.iHeader = GenerateReplyHeaderLC();
	params.iSmartTag = GenerateSmartTagLC();
	TPckgBuf<TReplyForwardParams> buf( params );
	HBufC* temp = HBufC::NewLC( buf.Length() );
	temp->Des().Copy( buf );

	//<cmail> this is actually a waited async method
	iFakeSyncGoingOn = ETrue;
    iNewMessage = iMailBox->CreateReplyMessage( 
            iLaunchParams.iMsgId, aReplyAll, *temp );
    iFakeSyncGoingOn = EFalse;
    //</cmail>
   	// Compose screen does not send cal messages, make sure
	// that cal event flag is not left active by some protocol
	if ( iNewMessage )
		{
		iNewMessage->ResetFlag( EFSMsgFlag_CalendarMsg );
		}
    CleanupStack::PopAndDestroy( temp );
    CleanupStack::PopAndDestroy( params.iSmartTag );
    CleanupStack::PopAndDestroy( params.iHeader );
    if ( !iNewMessage )
    	{
    	User::Leave( KErrGeneral );
    	}
    iFakeSyncGoingOn = ETrue; //<cmail>
    TRAPD( error, TFsEmailUiUtility::MoveMessageToDraftsL( 
            *iMailBox, *iNewMessage ) );
    iFakeSyncGoingOn = EFalse; //</cmail>
    User::LeaveIfError( error );

    if ( iNewMessage->GetContentType() != KFSMailContentTypeMultipartMixed )
        {
        iNewMessage->SetContentType( KFSMailContentTypeMultipartMixed );
        iNewMessage->SaveMessageL();
        iMessageModified = EFalse;
        }

    TFsEmailUiUtility::CreatePlainTextPartL( *iNewMessage, iNewMessageTextPart );
    if (NULL == iNewMessageTextPart) // problems with creating 
        {
        User::Leave( KErrUnknown );
        }
    }

// -----------------------------------------------------------------------------
// 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 );
    if (NULL == iNewMessageTextPart) // problems with creating 
        {
        User::Leave( KErrUnknown );
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::InitReplyUiL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitReplyUiL( TBool aReplyAll )
	{
    FUNC_LOG;
    if ( iFirstStartCompleted ) // Safety check
        {
        InitReplyFieldsL( aReplyAll );
        // if flag is set -
        // message text will be included asynchronously by calling method
		// IncludeMessageTextAsyncL() at the end of view activation or when 
		// all attachments are downloaded - this is done because formatting 
		// text in CTextView with method FormatTextL() causes phone 
		// irresponsive.
        if ( !iIncludeMessageTextAsync )
        	{
			IncludeMessageTextL( ETrue );
        	}
        iContainer->SetFocusToMessageFieldL();
        }
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::InitUiGeneralL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitUiGeneralL()
	{
    FUNC_LOG;
    if ( iFirstStartCompleted ) // Safety check
        {
        AppUi()->AddToStackL( iContainer );
        iContainer->SetMenuBar( Cba() );
        iContainer->UpdateScrollBar();

        // Set title pane text
        const TDesC& mbName = iMailBox->GetName();
        iAppUi.SetTitlePaneTextL( mbName );

        // Set priority flag
        SetPriority();

        // Set follow-up flag
        SetFollowUp();
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::InitForwardUiL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::InitForwardUiL()
	{
    FUNC_LOG;
    if ( iFirstStartCompleted ) // Safety check
        {
        InitForwardFieldsL();
        // if flag is set - 
        // message text will be included asynchronously by calling method
		// IncludeMessageTextAsyncL() at the end of view activation or when 
		// all attachments are downloaded - this is done because formatting 
        // text in CTextView with method FormatTextL() causes phone 
        // irresponsive.
        if ( !iIncludeMessageTextAsync )
        	{
			IncludeMessageTextL( ETrue );
        	}
        iContainer->SetFocusToToField();
        iContainer->SelectAllToFieldTextL();
        }
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::SetReplyForwardFlag
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SetReplyForwardFlagL()
	{
    FUNC_LOG;

	if ( iFirstStartCompleted && iOrigMessage )
		{
		if ( iCustomMessageId == TUid::Uid( KEditorCmdReply ) ||
             iCustomMessageId == TUid::Uid( KEditorCmdReplyAll ) )
			{
			iOrigMessage->SetFlag( EFSMsgFlag_Answered );
			iOrigMessage->SaveMessageL();
			}
		else if ( iCustomMessageId == TUid::Uid( KEditorCmdForward ) )
			{
			iOrigMessage->SetFlag( EFSMsgFlag_Forwarded );
			iOrigMessage->SaveMessageL();
			}
		}

	}

// -----------------------------------------------------------------------------
// CNcsComposeView::MailBoxSupportsSmartReply
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::MailBoxSupportsSmartReply()
	{
    FUNC_LOG;

    __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );

	return iMailBox->HasCapability( EFSMBoxCapaSmartReply );
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::MailBoxSupportsSmartForward
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::MailBoxSupportsSmartForward()
	{
    FUNC_LOG;
    __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );

	return iMailBox->HasCapability( EFSMBoxCapaSmartForward );
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::HasUnfetchedAttachmentsL
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::HasUnfetchedAttachmentsL( CFSMailMessage& aMsg )
	{
    FUNC_LOG;

    __ASSERT_DEBUG( &aMsg, Panic( ENcsBasicUi ) );

    TBool ret = EFalse;

	RPointerArray<CFSMailMessagePart> attachments;
	CleanupResetAndDestroyClosePushL( attachments );
	aMsg.AttachmentListL( attachments );
	for ( TInt i=0; i<attachments.Count(); i++ )
		{
		if ( EFSFull != attachments[i]->FetchLoadState() )
			{
			ret = ETrue;
			break;
			}
		}
	CleanupStack::PopAndDestroy( &attachments );

	return ret;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::HandleActionL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::HandleActionL( const TAlfActionCommand& aActionCommand )
    {
    FUNC_LOG;
    if ( iFirstStartCompleted && iNewMessage && iMailBox 
         && aActionCommand.Id() == KCmdEditorAutoSave )
        {
        CommitL( EFalse, EAllFields, ETrue );
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::SaveToDraftsL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::SaveToDraftsL( TBool aParseAddresses )
	{
    FUNC_LOG;
    if ( iFirstStartCompleted ) // Safety
        {
        __ASSERT_DEBUG( iMailBox, Panic( ENcsBasicUi ) );
        __ASSERT_DEBUG( iNewMessage, Panic( ENcsBasicUi ) );

        iFakeSyncGoingOn = ETrue;
        TRAPD( error, CommitL( aParseAddresses, EAllFields, ETrue, EFinal ) );
        iFakeSyncGoingOn = EFalse;
        User::LeaveIfError( error );

        iFakeSyncGoingOn = ETrue;
        TRAP( error, TFsEmailUiUtility::MoveMessageToDraftsL(
            *iMailBox, *iNewMessage ) );
        iFakeSyncGoingOn = EFalse;
        User::LeaveIfError( error );

        if ( !iAppUi.AppUiExitOngoing() )
            {
            // Simulate a new mail event to ensure that saved message becomes
            // visible in the mail list. 
            // All protocols do not send event automatically in this case.
            RArray<TFSMailMsgId> messageIdArray;
            CleanupClosePushL( messageIdArray );
            messageIdArray.Append( iNewMessage->GetMessageId() );
            TFSMailMsgId folderId = iNewMessage->GetFolderId();
            TFSMailMsgId mailboxId = iNewMessage->GetMailBoxId();
            iAppUi.EventL(
                TFSEventNewMail, mailboxId, &messageIdArray, &folderId, NULL );
            // Update displayed mail info if the mail was created previously
            iAppUi.EventL(
                TFSEventMailChanged, mailboxId, &messageIdArray, 
                &folderId, NULL );
            CleanupStack::PopAndDestroy( &messageIdArray );
            }
        }
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::FetchLogicComplete
// -----------------------------------------------------------------------------
//
TBool CNcsComposeView::FetchLogicComplete( 
        TComposerFetchState /*aState*/, TInt aError )
	{
    FUNC_LOG;
    TBool result = EFalse;
    if ( iFirstStartCompleted ) // Safety
        {
        if ( !aError )
            {
            // may leave if unable to create new message part
            TRAP( aError, InitReplyOrForwardUiL() );
            }
        if ( !aError )
            {
            iAutoSaver->Enable( ETrue );
            }
        else
            {
            // something went wrong
            DoSafeExit( ENoSave );
            iMailFetchingErrCode = aError;
            result = ETrue;
            }
        }
    if ( iFetchWaitDialog && !iFetchDialogCancelled )
        {
        TRAP_IGNORE( iFetchWaitDialog->ProcessFinishedL() );
        iFetchWaitDialog = NULL;
        }
    
    if ( iMailFetchingErrCode == KErrNone )
        {
        if ( iIncludeMessageTextAsync )
            {
            // in case the "Opening" wait note was closed by 
            // wait note "Retrieving"
            if ( !iOpeningWaitDialog && iOpeningWaitNoteVisible )
                {
                TRAP_IGNORE( TFsEmailUiUtility::ShowWaitNoteL( iOpeningWaitDialog, 
                        R_FSE_WAIT_OPENING_TEXT, EFalse, ETrue ) );
                }
            }
        
        if ( iViewFullyActivated && iIncludeMessageTextAsync )
            {
            // include message body in async way.
            // it is done here only if view was already activated
            // this mean that attachments were added in async way
            // and we couldn't start async including body text 
            TRAP_IGNORE( IncludeMessageTextAsyncL( ETrue ) );
            }
        }
    return result;
	}

// -----------------------------------------------------------------------------
// CNcsComposeView::ExitComposer
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ExitComposer()
    {
    FUNC_LOG;

    // dont exit while in child activation 
    if ( EChildActivationStarted == iChildActivationState )
        {
        iChildActivationState = EChildActivationError;
        }
    if ( EChildActivationError == iChildActivationState )
        {
        return; 
        }
    
    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;
        }
    iIncludeMessageTextAsync = EFalse;
    }

// -----------------------------------------------------------------------------
// 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 ( EChildActivationExitRequired == iChildActivationState )
        {
        ExitComposer();
        }
    else if ( iFakeSyncGoingOn || iExecutingDoExitL )
        {
        // if some sync method is still going on, we continue waiting
        iActiveHelper->Cancel();
        iActiveHelper->Start();
        }
    else
        {
        ExitComposer();
        // for some strange reason composer view is stuck and only option 
        // was to call ProcessCommandL with EAknCmdExit
        ProcessCommandL( EAknCmdExit );
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::HandleContainerChangeRequiringToolbarRefresh
// -----------------------------------------------------------------------------
//
void CNcsComposeView::HandleContainerChangeRequiringToolbarRefresh()
    {
    RefreshToolbar();
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::ShowFetchingWaitNoteL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::ShowFetchingWaitNoteL()
    {
    FUNC_LOG;
    if ( !iAppUi.AppUiExitOngoing() )
        {
        if ( !iFetchWaitDialog )
            {
            iFetchWaitDialog = new (ELeave) CAknWaitDialog(
                reinterpret_cast<CEikDialog**>( &iFetchWaitDialog ), EFalse);
            iFetchWaitDialog->SetCallback( this );
            iFetchDialogCancelled = EFalse;
            iFetchWaitDialog->ExecuteLD( R_FSE_FETCHING_WAIT_DIALOG );
            }
        }
    }

// -----------------------------------------------------------------------------
// CNcsComposeView::DialogDismissedL
// -----------------------------------------------------------------------------
//
void CNcsComposeView::DialogDismissedL( TInt aButtonId )
    {
    FUNC_LOG;
    if ( aButtonId == EAknSoftkeyCancel && iFetchLogic )
        {
        iFetchDialogCancelled = ETrue;
        iFetchLogic->CancelFetchings();
        }
    }

TBool CNcsComposeView::IsPreparedForExit()
    {
    return !( iFakeSyncGoingOn ||iExecutingDoExitL );
    }

// ---------------------------------------------------------------------------
// Returns the speficied button from the toolbar extension, or NULL, 
// if the button is not found.
// ---------------------------------------------------------------------------
//
CAknButton* CNcsComposeView::Button( TInt aCmdId, 
    CAknToolbarExtension* aExtension )
    {
    CAknButton* button = NULL;

    // Get toolbar extension.
    CAknToolbarExtension* extension = aExtension;
    if ( !aExtension )
        {
        CAknToolbar* toolbar = Toolbar();
        if ( toolbar )
            {
            extension = toolbar->ToolbarExtension();
            }
        }

    // Get specified button from the extension.
    if ( extension )
        {
        button = static_cast<CAknButton*>( extension->ControlOrNull( aCmdId ) );
        }

    return button;
    }

// ---------------------------------------------------------------------------
// Returns ETrue if WLAN connection is active.
// ---------------------------------------------------------------------------
//
TBool CNcsComposeView::WLANConnectionActive()    
    {
    TBool ret = EFalse;
    
    TInt wlanState;
    TInt err = RProperty::Get( KPSUidWlan, KPSWlanIndicator, wlanState );

    if ( err == KErrNone )
        {
        if ( wlanState == EPSWlanIndicatorActive ||
             wlanState == EPSWlanIndicatorActiveSecure )
            {
            ret = ETrue;
            }
        }
    
    return ret;    
    }


// ---------------------------------------------------------------------------
// CActiveHelper::NewL()
// ---------------------------------------------------------------------------
//
CActiveHelper* CActiveHelper::NewL( CNcsComposeView* aSession )
    {
    CActiveHelper* self = new(ELeave) CActiveHelper( aSession );
    CleanupStack::PushL( self );
    self->ConstructL( );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// CActiveHelper::~CActiveHelper()
// ---------------------------------------------------------------------------
//
CActiveHelper::~CActiveHelper( )
    {
    Cancel();
    }

// ---------------------------------------------------------------------------
// CActiveHelper::Start()
// ---------------------------------------------------------------------------
//
void CActiveHelper::Start()
    {
    TRequestStatus* status = &iStatus;
    User::RequestComplete( status, KErrNone );
    SetActive();
    }

// ---------------------------------------------------------------------------
// CActiveHelper::CActiveHelper()
// ---------------------------------------------------------------------------
//
CActiveHelper::CActiveHelper( CNcsComposeView* aSession ) 
    : CActive( EPriorityLow )
    {
    iComposeView = aSession;
    }

// ---------------------------------------------------------------------------
// CActiveHelper::RunL()
// ---------------------------------------------------------------------------
//
void CActiveHelper::RunL()
    {
    if( iComposeView )
        {
        iComposeView->AsyncExitL();
        }
    }

// ---------------------------------------------------------------------------
// CActiveHelper::DoCancel()
// ---------------------------------------------------------------------------
//
void CActiveHelper::DoCancel()
    {
    // Empty
    }

// ---------------------------------------------------------------------------
// CActiveHelper::ConstructL()
// ---------------------------------------------------------------------------
//
void CActiveHelper::ConstructL()
    {
    CActiveScheduler::Add( this );
    }

