email/mail/EditorSrc/MsgMailEditorAppUi.cpp
branchRCL_3
changeset 27 7fdbb852d323
parent 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/mail/EditorSrc/MsgMailEditorAppUi.cpp	Wed Sep 01 12:31:54 2010 +0100
@@ -0,0 +1,2788 @@
+/*
+* Copyright (c) 2002 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:  Implements UI class for Mail application
+*
+*/
+
+
+// Mail includes
+#include "MsgMailEditorAppUi.h"
+#include "MsgMailEditorDocument.h"
+#include "msgmaileditor.hrh"
+#include "cmsgmailsendop.h"
+#include "cmsgmaillaunchop.h"
+#include "cmsgmailfetchfileop.h"
+#include <MsgMailUIDs.h>            // Application UIDs
+#include "MsgMailViewAttachmentsDlg.h"
+#include <MsgEditorAppUi.rsg>       // resource identifiers
+#include <MsgMailEditor.rsg>
+#include "MailLog.h"
+#include "MailUtils.h"
+#include "cmsgmaileditorheader.h"
+#include "cmsgmailnavipaneutils.h"
+#include <hlplch.h>
+#include <csxhelp/mail.hlp.hrh>
+#include <bldvariant.hrh>
+
+// ui includes
+#include <avkon.hrh>
+#include <eikmop.h> // for SupplyMopObject
+#include <eikrted.h>
+#include <aknenv.h>         // AppShutter
+#include <barsread.h>       // TResourceReader
+#include <aknnotewrappers.h>
+#include <AknWaitDialog.h>
+#include <akntitle.h>
+#include <akntoolbar.h>
+#include <akntoolbarextension.h>
+#include <aknclearer.h>     // CAknLocalScreenClearer
+// Editor base classes:
+#include <MsgAttachmentInfo.h>
+#include <MsgAttachmentModel.h>
+#include <MsgEditorView.h>
+#include <MsgBodyControl.h>
+#include <MsgExpandableControl.h>
+#include <MsgAddressControl.h>
+#include <MsgCheckNames.h>
+
+#include <Muiumsginfo.hrh>
+#include <mtmuibas.h>                   // CBaseMtmUi
+#include <MuiuMsvUiServiceUtilities.h>  // MUIU MTM utils
+#include <MtmExtendedCapabilities.hrh>
+#include <cemailaccounts.h>				// CEmailAccounts
+#include <StringLoader.h>               // for StringLoader
+#include "MsgMailOptionsDlg.h"
+#include "CMsgAddMailHeadersDlg.h"      // Additional headers dialog
+
+#include <fepbase.h>
+#include <aknedsts.h>
+#include <akninputblock.h>              // CAknInputBlock
+
+// mail central repository handler
+#include "CMailCRHandler.h"
+#include <MailInternalCRKeys.h>
+#include <ImumInHealthServices.h>
+#include <ImumInMailboxServices.h>
+
+#include <SendUiConsts.h>
+
+#include <MsgEditorAppUiExtension.h>// for iMsgEditorAppUiExtension
+#include <MsgEditorSettingCacheUpdatePlugin.h>
+
+// LOCAL CONSTANTS
+const TInt KMessageSizeMaxLength(15);
+const TInt KMSKControlID(3);
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::CMsgMailEditorAppUi()
+// A default constructor
+// -----------------------------------------------------------------------------
+//
+CMsgMailEditorAppUi::CMsgMailEditorAppUi()
+    {
+    }
+
+//
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::ConstructL()
+// Constructs new mail editor and calls PrepareToLaunchL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::ConstructL()
+    {
+    LOG( "ConstructL" );
+    CMsgMailAppUi::ConstructL();
+    
+    // Screen is cleared so that user can't press softkeys before the view is
+    // properly constructed. Softkeys become visible again in 
+    // DelegateFinalizeLaunch() after the editor is properly constructed. 
+    iScreenClearer = CAknLocalScreenClearer::NewLC( EFalse );
+    CleanupStack::Pop( iScreenClearer ); 
+    
+#ifdef RD_SCALABLE_UI_V2    
+        if ( AknLayoutUtils::PenEnabled() )
+        	{
+    		//Set us as an observer for the toolbar
+    		if ( PopupToolbar() )
+    			{
+    			PopupToolbar()->SetToolbarObserver( this );
+    			PopupToolbar()->SetToolbarVisibility( ETrue, EFalse );
+    			}
+        	}        	
+#endif // RD_SCALABLE_UI_V2
+
+    // Disable task swapper from options menu during launch
+    MenuBar()->SetMenuType( CEikMenuBar::EMenuOptionsNoTaskSwapper );
+    
+    MenuBar()->SetContextMenuTitleResourceId(R_MSGMAILEDITOR_CONTEXT_MENUBAR);           
+    
+    iNaviPaneUtils = CMsgMailNaviPaneUtils::NewL();
+    
+    iSendOp = CMsgMailSendOp::NewL( *Document(), *this );
+                                    
+    iLaunchOp = CMsgMailLaunchOp::NewL( *Document(), *this );
+
+    // Dialer is always disabled in editor
+    SetDialerEnabled( EFalse );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::~CMsgMailEditorAppUi()
+// -----------------------------------------------------------------------------
+//
+CMsgMailEditorAppUi::~CMsgMailEditorAppUi()
+    {
+    delete iCheckNames;
+    delete iWaitNote;
+    delete iMailEditorHeader;
+    delete iFetchFileOp;
+    delete iSendOp;
+    delete iLaunchOp;
+    delete iNaviPaneUtils;
+    delete iScreenClearer;
+    }
+
+// -----------------------------------------------------------------------------
+//  void CMsgMailEditorAppUi::LaunchViewL
+//  Opens a message, either a new or an old one.
+//  Sets send options in CMsgMailPreferences object.
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::LaunchViewL()
+    {
+    LOG( "LaunchViewL" );
+    
+    if ( !Document()->HasModel() )
+        {
+        // Format restarts editor without proper context
+        // and this extra check is needed with.
+        // Leave with KErrGeneral.
+        User::Leave( KErrGeneral );
+        }    
+
+    CMsgEditorAppUi::SetCloseWithEndKey( EFalse );
+     
+    iLaunchOp->StartOp( *this );
+
+    LOG( "LaunchViewL end" );
+    }
+
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::DelegateInitLaunchL()
+//  Called from CMsgMailLaunchOp
+// ----------------------------------------------------------------------------
+//
+CMsgBodyControl& CMsgMailEditorAppUi::DelegateInitLaunchL()
+    {
+    LOG("CMsgMailEditorAppUi::DelegateInitLaunchL()");
+    CMsgMailEditorDocument& doc = *Document();
+    
+    iMessageID = doc.Entry().Id();
+
+    DoCreateControlsL();
+    doc.SetConfirmation( ETrue );
+    doc.ReadSendOptionsL();
+    
+    // Checks which kind of the message is.
+    if( doc.IsForwardMessage() || doc.IsReplyMessage() )
+    	{
+    	HandleSubjectL();
+    	}
+    else
+    	{
+    	SetSubjectL( doc.HeaderL().Subject() );
+    	}
+    
+    LOG("CMsgMailEditorAppUi::DelegateInitLaunchL() end");
+    return *( BodyControl() );  
+    }
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::HandleSubjectL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::HandleSubjectL()
+	{
+	CMsgMailEditorDocument& doc = *Document();
+	// base editor provides a service which removes unneeded prefixes
+	HBufC* newSubject = CreateSubjectPrefixStringL( 
+			doc.HeaderL().Subject(), doc.IsReplyMessage() );
+	CleanupStack::PushL( newSubject );
+	SetSubjectL( *newSubject );
+	CleanupStack::PopAndDestroy( newSubject );
+	}
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::DelegateExecuteViewL()
+//  Called from CMsgMailLaunchOp
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DelegateExecuteViewL()
+    {
+    LOG("CMsgMailEditorAppUi::DelegateExecuteViewL ");
+    DoGetRecipientsL();
+    LockEntryL();    
+    UpdateMessageSizeL();    
+    iView->ExecuteL( ClientRect(), EMsgComponentIdNull );    
+    LOG("CMsgMailEditorAppUi::DelegateExecuteViewL end");
+    }    
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::DelegateFinalizeLaunchL()
+//  Called from CMsgMailLaunchOp
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DelegateFinalizeLaunchL()
+    {
+    LOG("CMsgMailEditorAppUi::DelegateFinalizeLaunchL");
+    CMsgMailEditorDocument& doc = *Document();
+        
+    UpdatePriorityIndicatorL();
+
+    // Check recipients' addresses    
+    TBool highlight(EFalse);
+
+    if ( doc.IsNewMessage() && !CheckRecipientsL( highlight ) )
+        {
+        // Wrong address via Send As, CheckRecipientsL shows error note
+        // so don't ShowSelectedMailboxL
+        }
+    else
+        {
+        SetFocusToFirstFreeFieldL();
+        ShowSelectedMailboxL();
+        }
+
+        
+	CImHeader& header = doc.HeaderL();
+	
+	//Check if there is old reply to value saved.
+	//We don't want to write over local reply-to setting if there is one.
+	//If the reply-to is empty it must be replaced by the value
+	//in global smtp settings.
+	if(header.ReplyTo().Length() == 0)
+		{
+		TBool retVal = CheckGlobalReplyToSettingL();        
+		LOG1("CheckGlobalReplyToSettingL retVal=%d", retVal);
+		}
+        
+	
+	// Enable task swapper to options menu after launch has been completed.
+    MenuBar()->SetMenuType( CEikMenuBar::EMenuOptions );
+
+    doc.SetChanged( EFalse );   
+    
+    // Make softkeys visible again.
+    delete iScreenClearer;
+    iScreenClearer = NULL;
+    
+    LOG("CMsgMailEditorAppUi::DelegateFinalizeLaunchL end");
+    }
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::SetTitlePaneL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::SetTitlePaneL( TInt aResourceId )    
+    {
+    CAknTitlePane* titlePane =
+        static_cast<CAknTitlePane *>(StatusPane()->ControlL(
+        TUid::Uid(EEikStatusPaneUidTitle)));
+
+    TResourceReader reader;
+    iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
+    titlePane->SetFromResourceL( reader );
+    CleanupStack::PopAndDestroy(); // CSI: 12 # CreateResourceReaderLC
+    }
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::::DynInitMenuPaneL()
+//  This function is called by the framework just before it displays
+//  a menu pane.
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DynInitMenuPaneL(
+	TInt aResourceId, CEikMenuPane* aMenuPane)
+    {
+    ASSERT( aMenuPane );
+    // Confirm app is running properly (needed atleast now)
+    if ( !Document()->IsLaunched() )
+        {
+        // If not, hide everything and return
+        TInt amountOfItems = aMenuPane->NumberOfItemsInPane();
+        if ( amountOfItems )
+            {
+            aMenuPane->DeleteBetweenMenuItems( 0, amountOfItems-1 );
+            }
+        return;
+        }
+    switch (aResourceId)
+        {
+        case R_MSGMAILEDITOR_OPTIONS_MENU1:
+            // FALLTHROUGH
+        case R_MSGMAILEDITOR_CONTEXT_MENUPANE:
+
+            if ( Document()->MailCRHandler()->MailInsertToolBar() )
+                {
+                aMenuPane->SetItemDimmed(
+                    EMsgMailEditorCmdInsertMenu, EFalse );
+                }
+            else
+                {
+                aMenuPane->SetItemDimmed(
+                    EMsgMailEditorCmdInsertSubMenu, EFalse );
+                }
+            break;
+        case R_MSGMAILEDITOR_OPTIONS_MENU2:
+            // Remove attachment option if no attachments
+	        aMenuPane->SetItemDimmed(
+	        	EMsgMailEditorCmdAttachments,
+	        	(Document()->AttachmentModel().NumberOfItems() <= 0));
+            break;
+        case R_SEND_OPTIONS_MENU:
+            // FALLTHROUGH
+        case R_MSGMAILEDITOR_OPTIONS_MENU3:
+            if (!(iCommonFlags & EHelpSupported))
+                {
+                aMenuPane->DeleteMenuItem(EAknCmdHelp);
+                }
+            break;
+        case R_MSGMAILEDITOR_INSERT_MENU:
+        	aMenuPane->SetItemDimmed(
+        		EMsgMailEditorCmdInsertTemplate,
+        		EFalse );
+        	break;
+        case R_MSGMAILEDITOR_ZOOM_SUBMENU:
+            {
+            TInt zoomLevel = KErrGeneral;
+            iMsgEditorAppUiExtension->
+                iSettingCachePlugin.GetValue( KAknLocalZoomLayoutSwitch, zoomLevel );
+            switch ( zoomLevel )
+                {
+                case EAknUiZoomAutomatic:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeAutomatic,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomNormal:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeNormal,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomSmall:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeSmall,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomLarge:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeLarge,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                default:
+                    ASSERT(0);
+                    break;
+                }
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::::EditorObserver
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::EditorObserver(
+            TMsgEditorObserverFunc aFunc,
+            TAny* aArg1,
+            TAny* aArg2,
+            TAny* aArg3 )
+	{
+	TRAP_IGNORE( EditorObserverL(aFunc, aArg1, aArg2, aArg3) );
+	}
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleKeyEventL()
+// Handles received key events
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CMsgMailEditorAppUi::HandleKeyEventL(
+    const TKeyEvent& aKeyEvent,TEventCode aType)
+    {
+    // still launching application
+    if (!Document()->IsLaunched())
+        {
+        return EKeyWasConsumed;
+        }
+    TKeyResponse keyResp = CMsgEditorAppUi::HandleKeyEventL(
+            aKeyEvent, aType);
+    if (iView)
+        {
+        // By befault the send key is not functional when dialogs or menus
+        // are displaying.
+        if (!IsDisplayingMenuOrDialog())
+        	{
+        	if (aKeyEvent.iCode == EKeyPhoneSend)
+        		{
+        		if ( AreAddressFieldsEmptyL() )
+        			{
+        			DoAddRecipientL();
+        			}
+        		else
+        			{
+        			DoSendMessageL();
+        			}
+        		keyResp = EKeyWasConsumed;
+        		}
+        	}
+        if ( aKeyEvent.iCode == EKeyEnter )
+			{
+			HandleEnterKeyL();
+			keyResp = EKeyWasConsumed;
+			}
+        
+    	switch (aKeyEvent.iScanCode)
+    		{
+    		case EStdKeyUpArrow:
+    		case EStdKeyDownArrow:
+    			{
+    			if( aType == EEventKeyUp &&
+    					SpecialScrolling( aKeyEvent.iScanCode ) )
+    				{
+    				keyResp = EKeyWasConsumed;
+    				break;
+    				}
+    			// FALLTHROUGH
+    			}
+    		case EStdKeyLeftArrow:
+    		case EStdKeyRightArrow:
+    		case EStdKeyDevice0:        // Options menu
+    		case EStdKeyDevice1:        // Done key
+    		case EStdKeyDevice2:        // Ok
+    		case EStdKeyDevice3:        // Ok
+    		case EStdKeyRightShift:     // Shift
+    		case EStdKeyApplication0:   // Task switching
+    			break;
+    		default:
+    			{
+    			//something is written to header or to body
+    			if (aType == EEventKeyUp)
+    				{
+    				Document()->SetChanged(ETrue);
+    				UpdateMessageSizeL();
+    				}
+    			break;
+    			}
+    		}
+        }
+    return keyResp;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleCommandL(TInt aCommand)
+// Processes menu selections
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::HandleCommandL(TInt aCommand)
+    {
+    MAIL_ALLOC_TEST( DoHandleCommandL( aCommand ) );
+    } 
+
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoMsgSaveExitL()
+// Because this method is inherited from MsgEditor method signature is leaving,
+// but leaves are really trapped to ensure that exiting succeeds always.
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoMsgSaveExitL()
+	{    
+    LOG( "CMsgMailEditorAppUi::DoMsgSaveExit" );
+    
+#ifdef _DEBUG
+    TRAPD( err, PrepereToExitL() );
+    LOG1( "CMsgMailEditorAppUi::DoMsgSaveExit @ err:%d", err );
+#else
+    TRAP_IGNORE( PrepereToExitL() );
+#endif
+    
+    Exit();    
+    }
+    
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::PrepereToExitL()
+// Called by DoMsgSaveExit
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::PrepereToExitL()
+    {
+    LOG( "CMsgMailEditorAppUi::PrepereToExitL" );
+    CMsgMailEditorDocument* doc = Document();    
+    
+    // Make sure that possibly running asynchronous operations are canceled.
+    // If their progress note isn't closed before actual destruction, then it
+    // will cause an access violation.
+    iLaunchOp->Cancel();
+    iSendOp->Cancel();
+    if ( iFetchFileOp )
+        {
+        iFetchFileOp->Cancel();
+        }
+        
+    LOG( "PrepereToExitL, operations cancelled" );
+
+    // check that document is launched and view has been created
+    if (doc->IsLaunched() && iView )
+    	{
+    	LOG( "PrepereToExitL, has been fully launched" );
+	    if (IsEmptyL())
+	        {
+	        LOG( "PrepereToExitL, calling DeleteCurrentEntryL" );
+	        DeleteCurrentEntryL();
+	        LOG( "PrepereToExitL, DeleteCurrentEntryL returned" );
+	        return;
+	        }
+
+	    // save the document if it has been changed or if it is a new message
+	    if (doc->HasChanged() || !doc->CurrentEntry().Entry().Visible() ||
+	        iView->IsAnyControlModified())
+	        {
+	        LOG( "PrepereToExitL, check app shutter" );
+	        // Do this some time before starting the active sheduler
+	        // Restarting the active scheduler will stop the app shutter,
+	        // so record if an app is running a shutter
+	        CAknAppUi* shuttingApp = CAknEnv::AppWithShutterRunning();
+
+	        TBool isVisible(Document()->CurrentEntry().Entry().Visible());
+	        LOG( "PrepereToExitL, start wait note" );
+	        StartWaitNoteLC( isVisible ?
+                R_WAIT_SAVE_NOTE :
+                R_WAIT_SAVE_NEW_NOTE,
+                !isVisible );
+
+            LOG( "PrepereToExitL, saving message" );
+	        MsgSaveL( EFalse );
+            LOG( "PrepereToExitL, saving finished" );	        
+			CleanupStack::PopAndDestroy(); // CSI: 12 # StartWaitNoteLC
+
+	        if (shuttingApp)
+	            {
+	            shuttingApp->RunAppShutter();
+	            }
+	        }
+    	}        	
+    }
+
+// -----------------------------------------------------------------------------
+// Checks addresses of all recipients
+// -----------------------------------------------------------------------------
+TBool CMsgMailEditorAppUi::CheckRecipientsL(TBool aHighlight)
+    {
+    TBool result(ETrue);
+    CMsgAddressControl* addressField = AddressControl(EMsgComponentIdTo);
+    if (addressField)
+        {
+        CheckRecipientsInFieldL(addressField, aHighlight, result);
+        }
+
+    if ( result )
+        {
+        addressField = AddressControl(EMsgComponentIdCc);
+        if (addressField)
+            {
+            CheckRecipientsInFieldL(addressField, aHighlight, result);
+            }
+        }
+
+    if ( result )
+        {
+        addressField = AddressControl(EMsgComponentIdBcc);
+        if (addressField)
+            {
+            CheckRecipientsInFieldL(addressField, aHighlight, result);
+            }
+        }
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// Checks addresses of all recipients in given field
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::CheckRecipientsInFieldL(
+    CMsgAddressControl* aAddressField, TBool& aHighLight, TBool& aResult)
+    {
+    ASSERT( aAddressField );
+    CAknInputBlock::NewLC(); // block key events
+    aResult = ETrue;
+
+    CMsgRecipientArray& recs = *aAddressField->GetRecipientsL();
+    TInt count(recs.Count());
+
+    for (TInt i = 0; i < count; i++)
+        {
+        if (aResult)
+            {
+            HBufC* address = recs.At(i)->Address();
+
+            if ( IsValidAddress(*address) )
+                {
+                recs.At(i)->SetValidated(ETrue);
+                }
+
+            else // Not valid email address , Search from Phonebook
+                {
+                InitPhoneBookL();
+                //approx 3 recipients
+                CMsgRecipientArray* rcptArray =
+                    new (ELeave) CArrayPtrFlat<CMsgRecipientItem>(3);		// CSI: 47 # See a comment above.
+                CleanupStack::PushL( rcptArray );
+		        if ( iCheckNames->FindAndCheckByNameL(
+		                *address, CMsgCheckNames::EMsgTypeMail, *rcptArray, -1 ) ) //-1 add
+                    {
+                    LOG( "CMsgMailEditorAppUi::CheckRecipientsInFieldL" );
+                    }
+
+                const TInt contacts(rcptArray->Count());
+
+                if ( contacts > 0)
+                    {
+                    // Validate addresses found from phonebook
+                    TInt index;
+                    for (index = 0; index < contacts; ++index)
+                        {
+                        HBufC* rcptAddress = rcptArray->At(index)->Address();
+                        if ( !IsValidAddress(*rcptAddress) )
+                            {
+                            aResult = EFalse;
+                            ShowIncorrectAddressErrorL(
+                                *(rcptArray->At(index)->Name()),
+                                *rcptAddress);
+
+                            // highlight only first invalid address
+                            if (!aHighLight)
+                                {
+                                SearchUnverifiedStringL(
+                                    *address, aAddressField);
+                                aAddressField->HighlightUnverifiedStringL();
+                                aHighLight = ETrue;
+                                }
+
+                            }
+                        else
+                            {
+                            // Valid address from phonebook
+                            rcptArray->At(index)->SetValidated(ETrue);
+                            rcptArray->At(index)->SetVerified(ETrue);
+                            }
+                        }
+
+                    // replace array only if all addresses were valid
+                    if ( aResult && contacts > 0)
+                        {
+                        // Replace alias text and set flags
+                        recs.At(i)->SetNameL( *rcptArray->At(0)->Name() );
+                        recs.At(i)->SetAddressL(
+                            *rcptArray->At(0)->Address() );
+                        recs.At(i)->SetValidated(ETrue);
+                        recs.At(i)->SetVerified(ETrue);
+
+                        // ownership not changed so delete
+                        delete rcptArray->At( 0 );
+                        rcptArray->Delete( 0 );
+
+                        while ( rcptArray->Count() )
+                            {
+                            //Add the selected address items
+                            i++;
+                            count++;
+                            // takes ownership
+                            recs.InsertL( i, rcptArray->At( 0 ));
+                            rcptArray->Delete( 0 );
+                            }
+                        }
+
+                    }
+                else // incorrect address
+                    {
+                    aResult = EFalse;
+                    ShowIncorrectAddressErrorL(*(recs.At(i)->Name()),
+                        *address);
+                    if (!aHighLight) // highlight only first invalid address
+                        {
+                        SearchUnverifiedStringL( *address, aAddressField);
+                        aAddressField->HighlightUnverifiedStringL();
+                        aHighLight = ETrue;
+                        }
+
+                    }
+                CleanupStack::PopAndDestroy( rcptArray );
+                }
+            }
+        }
+
+    if (aResult)
+        {
+        // refresh addresscontrol
+        User::LeaveIfError( aAddressField->RefreshL( recs ));
+        }
+    CleanupStack::PopAndDestroy(); // CSI: 12 # CAknInputBlocker
+    }
+
+// -----------------------------------------------------------------------------
+// Show invalid address error note
+// -----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::ShowIncorrectAddressErrorL(const TDesC& aTitle,
+    const TDesC& aAddress) const
+    {
+    HBufC* stringholder = NULL;
+
+    if (aTitle.Length())
+        {
+        // 2 for title & address
+        CDesCArrayFlat* strings = new(ELeave) CDesCArrayFlat(2);		// CSI: 47 # See a comment above.
+        CleanupStack::PushL( strings );
+        strings->AppendL(aAddress);
+        strings->AppendL(aTitle);
+        stringholder = StringLoader::LoadL(
+            R_MAIL_EDITOR_INCORRECT_ADDRESS, *strings, iEikonEnv);
+        CleanupStack::PopAndDestroy( strings ); // strings
+        CleanupStack::PushL(stringholder);
+        }
+    else
+        {
+        stringholder = StringLoader::LoadLC(
+            R_MAIL_EDITOR_INCORRECT_ADDRESS_NO_ALIAS,
+            aAddress, iEikonEnv );
+        }
+
+    // This is a waiting dialog
+    CAknInformationNote* note = new(ELeave) CAknInformationNote(ETrue);
+    note->ExecuteLD(*stringholder);
+    CleanupStack::PopAndDestroy( stringholder ); // stringholder
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoSendMessageL()
+// Saves message to outbox and tries to send it immediately,
+// if Sending schedule in Send options is
+// CMsgMailPreferences::EMsgMailSchedulingNow.
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::DoSendMessageL()
+    {
+    CMsgMailEditorDocument* doc = Document();    
+    UnlockEntry();
+
+    // Force FEP commit the current word
+    BodyControl()->SetFocus( EFalse );
+    iCoeEnv->SyncNotifyFocusObserversOfChangeInFocus();
+
+    // check that recipients are valid
+    TBool highlight( EFalse );
+    if ( CheckRecipientsL( highlight ) )
+        {
+        DoRemoveDuplicatesL();
+        
+        iSendOp->StartOp( *this );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DelegateSaveMsgL()
+// called from send operation
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::DelegateSaveMsgL()
+    {
+    MsgSaveL( EFalse );
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DelegateMoveMsgToOutboxL()
+// called from send operation
+// ----------------------------------------------------------------------------
+TMsvId CMsgMailEditorAppUi::DelegateMoveMsgToOutboxL()
+    {    
+    return MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );
+    }    
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleOpCompleted()
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::HandleOpCompleted(
+    const CMsgMailBaseOp& aOp,
+    TInt aResult )
+    {
+    LOG( "CMsgMailEditorAppUi::HandleOpCompleted" );
+    if ( &aOp == iSendOp )
+        {
+        LOG1( "HandleOpCompleted, send op @ aResult:%d", aResult );
+        if ( aResult == KErrNone || aResult == KErrNoMemory )
+            {
+            Exit( EAknSoftkeyBack );
+            }
+        // this is a special error case -  mailbox wasn't found
+        else if ( aResult == KErrNotFound )
+            {
+            //Try to step back
+            //Trapped to avoid possible problems in operation side
+            //and to keep function as non-leaving.
+            TRAPD(err, DoBackstepL() );
+            
+            //DoBackStep can leave with KLeaveExit and since it call is trapped
+            //mail editor isn't closed like it should. That is why we have to make additional
+            //call to Exit().
+            
+            if(err == KLeaveExit)
+                {
+                Exit( EAknSoftkeyBack );    
+                }
+            
+            
+            }
+        }
+    if ( &aOp == iFetchFileOp )
+        {
+        LOG1( "HandleOpCompleted, fetch file op @ aResult:%d", aResult );
+        // try to update message size and lock the entry
+        TRAP_IGNORE( LockEntryL() );
+        if ( aResult == KErrNone )
+            {
+            TRAP_IGNORE( HandleAttaAddedL() );
+            }                     
+        }    
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleAttaAddedL()
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::HandleAttaAddedL()
+    {
+    if ( iAttachmentDlg )
+        {
+        iAttachmentDlg->ItemAddedL();
+        }
+    else
+        {
+        UpdateMessageSizeL();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::UpdateHeaderVisibilityL()
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::UpdateHeaderVisibilityL(
+        	RPointerArray<TAdditionalHeaderStatus>& aHeaders)
+	{
+	ASSERT( iMailEditorHeader );
+	iMailEditorHeader->UpdateHeaderVisibilityL( aHeaders );
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::UpdatePriorityIndicatorL()
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::UpdatePriorityIndicatorL()
+	{
+    TMsvId service;
+    TMsvEntry entry;
+    User::LeaveIfError(
+        Document()->Session().GetEntry( iMessageID, service, entry ) );
+    iNaviPaneUtils->SetPriorityIndicator( entry.Priority() );
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoSendOptionsL()
+// ----------------------------------------------------------------------------
+void CMsgMailEditorAppUi::DoSendOptionsL()
+    {
+    // Enable dialer
+    SetDialerEnabled( ETrue );
+    UnlockEntry();
+    CMsgMailOptionsDlg* sendOptionsDlg
+        = CMsgMailOptionsDlg::NewL(
+            Document(), (iCommonFlags & EHelpSupported) );
+    sendOptionsDlg->SetMopParent(this);
+
+#ifdef RD_SCALABLE_UI_V2    
+    //Hide toolbar
+    if ( PopupToolbar() )
+        {
+		CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+    	extension->SetShown( EFalse );
+    	DoHideToolbar( ETrue );
+        }
+    
+#endif // RD_SCALABLE_UI_V2
+    
+    if (sendOptionsDlg->ExecuteLD(R_MAIL_EDITOR_SEND_OPTIONS))
+        {
+        // exit was chosen in dialog
+        CAknAppUi::ProcessCommandL( EAknCmdExit );
+        }
+
+#ifdef RD_SCALABLE_UI_V2    
+    //Show toolbar
+    if ( PopupToolbar() )
+        {
+        DoHideToolbar( EFalse );
+         }
+#endif // RD_SCALABLE_UI_V2
+
+	ASSERT( iMailEditorHeader );
+    iMailEditorHeader->UpdateReplyToControlL();
+
+    if ( Document()->MailCRHandler()->MailEncodingSetting() )
+        {
+        DoCheckEncodingL();
+        }
+
+    LockEntryL();
+    UpdatePriorityIndicatorL();
+    // Disable dialer
+    SetDialerEnabled( EFalse );
+    }
+
+// ----------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::SetSubjectL()
+//  Sets subject text from CImHeader.
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::SetSubjectL
+    (const TDesC& aText) const    //in: subject from CImHeader
+    {
+    CMsgExpandableControl* subjectControl = SubjectControl();
+    if (subjectControl)
+    	{
+	    CEikRichTextEditor& subject = subjectControl->Editor();
+	    subject.SetTextL(&aText);
+	    subject.SetCursorPosL(subject.TextLength(), EFalse);
+    	}
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoHidetoolbar( const TBool aHide )
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoHideToolbar( const TBool aHide )
+	{
+    if ( PopupToolbar() )
+        {
+#ifdef RD_SCALABLE_UI_V2    
+        if ( AknLayoutUtils::PenEnabled() )
+        	{
+    		PopupToolbar()->HideItemsAndDrawOnlyBackground( aHide );
+        	}        	
+#endif // RD_SCALABLE_UI_V2
+		}
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoShowSelectionListL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoShowSelectionListL()
+	{
+	TInt selection( 0 );
+	
+	CAknListQueryDialog* dlg = new ( ELeave ) CAknListQueryDialog( &selection );
+	dlg->PrepareLC( R_MAILEDITOR_INSERT_SELECTIONLIST );
+	
+	if ( dlg->RunLD() )
+		{
+		TInt commandId( EMsgMailFirstFreeCmdId );
+		switch( selection )
+			{
+			case 0:
+				commandId = EMsgMailEditorCmdInsertImage;
+				break;
+			case 1:
+				commandId = EMsgMailEditorCmdInsertVideo;
+				break;
+			case 2:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertAudio;
+				break;
+			case 3:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertNote;
+				break;
+			case 4:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertTemplate;
+				break;
+#ifdef EMAIL_PRESENTATION_SUPPORT
+			case 5:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertPresentation;
+				break;
+			case 6:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertOther;
+				break;
+#else
+			case 5:	// CSI: 47 # switch case
+				commandId = EMsgMailEditorCmdInsertOther;
+				break;
+#endif //EMAIL_PRESENTATION_SUPPORT
+			}
+		
+		HandleCommandL( commandId );
+		}
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoShowExtensionToolBar()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoShowExtensionToolBar()
+	{
+    if ( PopupToolbar() )
+        {
+#ifdef RD_SCALABLE_UI_V2    
+        if ( AknLayoutUtils::PenEnabled() )
+        	{
+        	CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+        	extension->SetShown( ETrue );
+        	}        	
+#endif // RD_SCALABLE_UI_V2
+		}
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoShowToolBarOtherL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoShowToolBarOtherL()
+	{
+    TInt selection( 0 );
+    
+    CAknListQueryDialog* dlg =
+        new ( ELeave ) CAknListQueryDialog( &selection );
+    
+    if(!AknLayoutUtils::PenEnabled())
+        { //For non-touch devices
+        dlg->PrepareLC(R_MAILEDITOR_TOOLBAR_CHOICELIST);
+        
+        if ( dlg->RunLD() )
+            {
+            TInt command;
+            // See r_maileditor_toolbar_choicelist_items
+            command = ( selection == 0 ) ?
+                EMsgMailEditorCmdInsertNote :
+                EMsgMailEditorCmdInsertOther;
+            
+            DoFetchFileL(command);
+            }
+        }
+#ifdef RD_SCALABLE_UI_V2
+    //For touch devices toolbar and submenus are different.
+    else 
+        {
+        dlg->PrepareLC( R_MAILEDITOR_TOOLBAR_TOUCH_CHOICELIST );
+        
+        if ( dlg->RunLD() )
+            {
+            // See r_maileditor_toolbar_choicelist_touch_items.
+            //Order of this switch-case is based on 
+            //that resource array.
+            switch(selection)
+                {
+                case 0: 
+                    HandleCommandL( EMsgMailEditorCmdInsertTemplate );
+                    break;
+                case 1:
+                    HandleCommandL( EMsgMailEditorCmdInsertTemplateNote );
+                    break;
+                case 2:														// CSI: 47 # See a comment above.
+                    DoFetchFileL(EMsgMailEditorCmdInsertNote);
+                    break;
+#ifdef EMAIL_PRESENTATION_SUPPORT
+                case 3:														// CSI: 47 # See a comment above.
+                    HandleCommandL( EMsgMailEditorCmdInsertPresentation );
+                    break;
+                case 4:														// CSI: 47 # See a comment above.
+                    DoFetchFileL(EMsgMailEditorCmdInsertOther);
+                    break;
+#else
+                case 3:														// CSI: 47 # See a comment above.
+                    DoFetchFileL(EMsgMailEditorCmdInsertOther);
+                    break;
+                    
+#endif //EMAIL_PRESENTATION_SUPPORT
+                default:
+                    //unknown selection
+                    ASSERT( 0 );
+                    return;
+                }
+            }
+        }
+#endif  //RD_SCALABLE_UI_V2
+   	}
+	
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoShowToolBarTextL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoShowToolBarTextL()
+    {
+    TInt selection( 0 );
+    CAknListQueryDialog* dlg =
+        new ( ELeave ) CAknListQueryDialog( &selection );
+    dlg->PrepareLC( R_MAILEDITOR_TOOLBAR_TEXT_CHOICELIST );
+    if ( dlg->RunLD() )
+        {
+        TInt command;
+        // See r_maileditor_toolbar_choicelist_items
+        command = ( selection == 0 ) ?
+            EMsgMailEditorCmdInsertTemplate :
+            EMsgMailEditorCmdInsertTemplateNote;
+        HandleCommandL( command );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::DoFetchFileL()
+// Fetch from other application.
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoFetchFileL( TInt aCommand )
+    {
+    MsgAttachmentUtils::TMsgAttachmentFetchType fetchType;
+    switch( aCommand )
+    	{
+        case EMsgMailEditorCmdInsertImage:
+            fetchType = MsgAttachmentUtils::EImage;
+            break;
+        case EMsgMailEditorCmdInsertAudio:
+            fetchType = MsgAttachmentUtils::EAudio;
+            break;
+        case EMsgMailEditorCmdInsertVideo:
+            fetchType = MsgAttachmentUtils::EVideo;
+            break;
+        case EMsgMailEditorCmdInsertNote:
+        	fetchType = MsgAttachmentUtils::ENote;
+        	break;
+    	case EMsgMailEditorCmdInsertPresentation:
+    		fetchType = MsgAttachmentUtils::ESVG;
+    		break;
+    		
+    		// Falltrough
+        case EMsgMailEditorCmdInsertOther:
+            // unknown
+            fetchType = MsgAttachmentUtils::EUnknown;
+            break;
+        default:
+        	// not our command, just return
+    		return;
+    	}
+    	
+    UnlockEntry();
+    
+    delete iFetchFileOp; // re-instantiate each time with proper fetch type
+    iFetchFileOp = NULL;
+    iFetchFileOp = CMsgMailFetchFileOp::NewL( fetchType, *Document() );        
+
+    iFetchFileOp->StartOp( *this );
+    }
+
+// ----------------------------------------------------------------------------
+// TBool CMsgMailEditorAppUi::IsEmptyL()
+// Returns ETrue if document contains no data, EFalse otherwise
+// ----------------------------------------------------------------------------
+//
+TBool CMsgMailEditorAppUi::IsEmptyL() const
+    {
+    if (!AreAddressFieldsEmptyL())
+        {
+        return EFalse;
+        }
+
+    if ( (SubjectControl() && SubjectControl()->TextContent().DocumentLength() > 0) ||
+        BodyControl()->TextContent().DocumentLength() > 0 ||
+        Document()->AttachmentModel().NumberOfItems())
+        {
+        return EFalse;
+        }
+
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgEditorAppUi::HelpContextL
+// ----------------------------------------------------------------------------
+//
+CArrayFix<TCoeHelpContext>* CMsgMailEditorAppUi::HelpContextL( ) const
+    {
+    CArrayFix<TCoeHelpContext>* help =
+                    new( ELeave ) CArrayFixFlat<TCoeHelpContext>( 1 );
+    CleanupStack::PushL( help );
+    help->AppendL( TCoeHelpContext( TUid::Uid( KUidMsgMailEditor ),
+        KMAIL_HLP_MAIL_EDITOR() ) );
+    CleanupStack::Pop( help );
+    return help;
+    }
+    
+// ----------------------------------------------------------------------------
+// CMsgEditorAppUi::DynInitToolbarL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DynInitToolbarL( TInt aResourceId, CAknToolbar* aToolbar )
+	{
+    if ( aResourceId == R_MAILEDITOR_TOOLBAR )
+        {
+        //Attachment dialog might have hided this so make sure it is visible
+	    aToolbar->HideItem( EMsgMailEditorCmdInsertText, EFalse, EFalse );
+	    aToolbar->SetInitialFocusedItem( EMsgMailEditorCmdInsertImage );
+	    
+#ifdef RD_SCALABLE_UI_V2
+	    if(AknLayoutUtils::PenEnabled())
+	        {
+	        //Less items shown if touch device.
+#ifdef RD_SVGT_IN_MESSAGING
+	        aToolbar->HideItem( EMsgMailEditorCmdInsertPresentation, ETrue, EFalse );
+#endif //RD_SVGT_IN_MESSAGING
+	        aToolbar->HideItem( EMsgMailEditorCmdInsertText, ETrue, EFalse );
+	        }
+#endif //RD_SCALABLE_UI_V2
+
+        }		
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgEditorAppUi::OfferToolbarEventL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::OfferToolbarEventL( TInt aCommand )
+	{
+    if ( PopupToolbar() )
+        {
+#ifdef RD_SCALABLE_UI_V2    
+        // These commands create the list over the toolbar
+        // and reason of that list the toolbar must be hidden.
+    	if ( aCommand == EMsgMailEditorCmdInsertTemplate ||
+    		 aCommand == EMsgMailEditorCmdInsertOther )
+    		{
+    		CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+    		extension->SetShown( EFalse );
+    		}        
+
+    	PopupToolbar()->SetToolbarVisibility( ETrue, EFalse );
+
+#else  // RD_SCALABLE_UI_V2
+	PopupToolbar()->SetToolbarVisibility( EFalse );    	
+#endif // RD_SCALABLE_UI_V2
+        }
+		
+	if ( aCommand == EMsgMailEditorCmdInsertOther )
+	    {
+	    // If user chooses Cancel while selecting template text or note
+        // DoShowToolBarTextL leaves. This is ok so leave is catched here.
+        TRAPD(err, DoShowToolBarOtherL() );
+	    if( err != KErrCancel )
+            {
+            User::LeaveIfError( err );
+            }
+	    
+	    }
+    else if ( aCommand == EMsgMailEditorCmdInsertText )
+        {
+    	// If user chooses Cancel while selecting template text or note
+        // DoShowToolBarTextL leaves. This is ok so leave is catched here.
+        TRAPD( err, DoShowToolBarTextL() );
+        if( err != KErrCancel )
+            {
+            User::LeaveIfError( err );
+            }
+        }
+    else
+        {
+	    HandleCommandL( aCommand );
+	    
+        }
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgEditorAppUi::DoCreateControlsL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoCreateControlsL()
+	{
+	// Create Base view
+	iView = CMsgEditorView::NewL(*this, CMsgEditorView::EMsgEditorModeNormal);
+	ASSERT( iView );
+	iMailEditorHeader = CMsgMailEditorHeader::NewL( *Document(), *iView );
+	}
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoAttachmentL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoAttachmentL()
+    {
+    HBufC* title = iCoeEnv->AllocReadResourceLC(R_TITLE_ATTACHMENTS);
+
+    CMsgAttachmentModel& attmodel = Document()->AttachmentModel();
+
+    iAttachmentDlg = CMsgMailViewAttachmentsDlg::NewL(*title,
+        attmodel, *this, (iCommonFlags & EHelpSupported));
+    iAttachmentDlg->SetMopParent(this);
+
+
+#ifdef RD_SCALABLE_UI_V2    
+    //Hide toolbar
+    if ( PopupToolbar() )
+        {
+		CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+    	extension->SetShown( EFalse );
+        DoHideToolbar( ETrue );
+        }
+#endif // RD_SCALABLE_UI_V2
+    
+    // safe to call LD even as a member variable, since
+    // framework always takes care of deleting the dialog
+    if (iAttachmentDlg->ExecuteLD(R_MEB_VIEW_ATTACHMENT_DIALOG)) // CSI: 50 # see comment above
+        {
+        iAttachmentDlg = NULL;
+        // exit was chosen in dialog
+        CAknAppUi::ProcessCommandL( EAknCmdExit );
+        }
+    else
+        {
+        //Attachment dialog has exited. Make sure we are the observers for toolbar
+        if ( PopupToolbar() )
+	        {
+			PopupToolbar()->SetToolbarObserver( this );
+#ifdef RD_SCALABLE_UI_V2    
+			CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+        	extension->SetShown( EFalse );
+        	DoHideToolbar( EFalse );
+#endif // RD_SCALABLE_UI_V2
+			}
+	        
+        iAttachmentDlg = NULL;
+        UpdateMessageSizeL();
+        }
+
+    CleanupStack::PopAndDestroy( title ); // title
+    }
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoCheckEncodingL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoCheckEncodingL()
+	{
+	CMsgMailPreferences& prefs = Document()->SendOptions();
+    TUint charsetId = prefs.SendingCharacterSet().iUid;
+    LOG1( "CMsgMailEditorAppUi::DoCheckEncodingL CharsetId:%08x", charsetId );
+	if (charsetId)
+		{
+	    CCnvCharacterSetConverter* charConv =
+	        CCnvCharacterSetConverter::NewLC();
+
+	    TInt error = charConv->PrepareToConvertToOrFromL(
+	    	charsetId, iEikonEnv->FsSession());
+		TInt unconverted(0);
+		if (error == CCnvCharacterSetConverter::EAvailable)
+			{
+			// Try to convert body text
+		    CRichText& rtf = BodyControl()->TextContent();
+		    HBufC* buf = HBufC::NewLC(rtf.DocumentLength());
+		    TPtr bufPtr = buf->Des();
+		    rtf.Extract(bufPtr);
+
+		    HBufC8* foreing = HBufC8::NewLC(rtf.DocumentLength());
+		    TPtr8 ptr = foreing->Des();
+		    error = charConv->ConvertFromUnicode(ptr, *buf, unconverted);
+		    CleanupStack::PopAndDestroy(2, buf);							// CSI: 47,12 #  buf, foreing
+			}
+	    // Show note if can't convert to selected character set.
+	    if (error != KErrNone || unconverted > 0)
+	    	{
+	    	MailUtils::ConfirmationNoteL(R_MAIL_SETTINGS_ENCODE_FALSE_NOTE);
+	    	}
+
+	    CleanupStack::PopAndDestroy( charConv );
+		}
+	}
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoBackstepL()
+// Implements backstep functionality
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoBackstepL()
+    {
+    CMsgMailEditorDocument* doc = Document();
+
+    // if document contains no data, message and entry is deleted
+    if ( IsEmptyL() )
+        {
+        if (doc->CurrentEntry().Entry().Visible())
+            {
+            HBufC* text = iEikonEnv->AllocReadResourceLC(
+                R_MAIL_EDITOR_MESSAGE_DELETED_TEXT);
+            // waiting dialog, so it is not left into screen when
+            // application is exited
+            CAknInformationNote* note = new(ELeave) CAknInformationNote(ETrue);
+            note->ExecuteLD(*text);
+            CleanupStack::PopAndDestroy( text ); // text
+            }
+        DeleteAndExitL();
+        return;
+        }
+
+    switch ( ShowCloseQueryL() )
+        {
+        case EMsgCloseDelete:
+            {
+            DeleteAndExitL();
+            }
+        case EMsgCloseCancel:
+            {
+            return;
+            }
+        default:
+            {
+            // Normal save
+            if ( !doc->CurrentEntry().Entry().Visible() ||
+                doc->HasChanged() ||
+                iView->IsAnyControlModified() )
+                {
+                const TBool newMessage(
+                    !doc->CurrentEntry().Entry().Visible() );
+                StartWaitNoteLC( newMessage ?
+                    R_WAIT_SAVE_NEW_NOTE :
+                    R_WAIT_SAVE_NOTE,
+                    newMessage );
+
+			    TRAPD( err, MsgSaveL( EFalse ) );
+
+			    CleanupStack::PopAndDestroy(); // CSI: 12 # StartWaitNoteLC
+				User::LeaveIfError(err);
+                }
+            }
+        }
+    Exit( EAknSoftkeyBack );
+    }
+
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoAddRecipientL()
+// Fetch an address from phonebook
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoAddRecipientL()
+    {
+    TMsgControlId uiCompId =
+    	(TMsgControlId)iView->FocusedControl()->ControlId();
+
+	//Remember original focused control
+	TMsgControlId uiOriginalCompId = uiCompId;
+	
+    // Add recipient into To field if focus is not in address field
+    if ( !(uiCompId == EMsgComponentIdTo ||
+    	uiCompId == EMsgComponentIdCc ||
+    	uiCompId == EMsgComponentIdBcc) )
+    	{
+    	uiCompId = EMsgComponentIdTo;
+    	}
+
+    InitPhoneBookL();
+    CMsgRecipientList* recipientList = CMsgRecipientList::NewL();
+    CleanupStack::PushL( recipientList );
+
+    CMsgRecipientArray* recipients =
+        new (ELeave) CArrayPtrFlat<CMsgRecipientItem>(3);			// CSI: 47 # approx 3
+    CleanupStack::PushL( recipients );
+
+#ifdef RD_SCALABLE_UI_V2    
+    //Hide toolbar
+    if ( PopupToolbar() )
+        {
+		CAknToolbarExtension* extension = PopupToolbar()->ToolbarExtension();
+    	extension->SetShown( EFalse );
+    	DoHideToolbar( ETrue );
+        }    
+#endif // RD_SCALABLE_UI_V2
+
+    //multiple entry fetch to get the contact
+    iCheckNames->FetchRecipientsL( *recipients, CMsgCheckNames::EMsgTypeMail );
+
+#ifdef RD_SCALABLE_UI_V2    
+    DoHideToolbar( EFalse );
+#endif // RD_SCALABLE_UI_V2
+    
+    //contacts now fetched, verify each contact
+    for ( TInt i(0); i < recipients->Count(); i++ )
+        {
+        CMsgRecipientItem* recipient = (*recipients)[ i ];
+        HBufC* name = recipient->Name();
+        HBufC* address = recipient->Address();
+
+        // Don't parse away chars here so this is consistent with
+        // addresses that user writes "-()" are saved to draft
+        // but removed when sending
+        if ( IsValidAddress( *address ) )
+            {
+            //  add it to the list of valid addresses
+            recipient->SetVerified( ( name->Length() > 0 ? ETrue : EFalse ) );
+            recipientList->AppendL( recipient );
+            }
+        else
+            {
+            ShowIncorrectAddressErrorL( *address, *name );
+            }
+        }
+    // if valid recipients were selected, add them to control
+    // and set focus to right component
+    if ( recipientList->Count() )
+        {
+        //Add to control
+        AddressControl(uiCompId)->AddRecipientsL( *recipientList );
+        
+        //Set focus
+    	SetFocusAfterAddRecipientL( uiOriginalCompId );
+        }
+
+    // recipientList, recipients
+    CleanupStack::PopAndDestroy( 2, recipientList );				// CSI: 47,12 # See a comment above.
+    }
+// -----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::AreAddressFieldsEmptyL()
+// -----------------------------------------------------------------------------
+//
+TBool CMsgMailEditorAppUi::AreAddressFieldsEmptyL() const
+    {
+    TBool result( ETrue );
+
+    CMsgAddressControl* addressField = AddressControl(EMsgComponentIdTo);
+    if (addressField)
+        {
+        CMsgRecipientArray& recs = *addressField->GetRecipientsL();
+        if( recs.Count() > 0 )
+            {
+            result = EFalse;
+            }
+        }
+
+    addressField = AddressControl(EMsgComponentIdCc);
+    if (addressField)
+        {
+        CMsgRecipientArray& recs = *addressField->GetRecipientsL();
+        if( recs.Count() > 0 )
+            {
+            result = EFalse;
+            }
+        }
+
+    addressField = AddressControl(EMsgComponentIdBcc);
+    if (addressField)
+        {
+        CMsgRecipientArray& recs = *addressField->GetRecipientsL();
+        if( recs.Count() > 0 )
+            {
+            result = EFalse;
+            }
+        }
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::UpdateMessageSizeL()
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::UpdateMessageSizeL()
+    {
+    //If attachment dialog is visible we don't want to update navipane,
+    //because dialogs navi pane should be empty.
+    if(!iAttachmentDlg)
+        {
+        TInt docSize = MessageSizeL( ETrue ); // Count also attachments
+        LOG1( "CMsgMailEditorAppUi::UpdateMessageSizeL:%d", docSize );
+        iNaviPaneUtils->SetMessageSizeIndicatorL( docSize );
+            
+        // attachment indicator may be shown in navi pane only if local variation
+        // flag is enabled (by default disabled in common code). Remove this
+        // code and SetAttachmentIndicator() method when CR key gets obsolete.
+        if ( !Document()->MailCRHandler()->MailAttachmentField() )
+            {
+            CMsgAttachmentModel& attModel = Document()->AttachmentModel();
+            const TInt attCount( attModel.NumberOfItems() );    
+            iNaviPaneUtils->SetAttachmentIndicator( attCount > 0 );
+            }    
+        }
+                
+    }
+
+// -----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoMessageInfoL()
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoMessageInfoL()
+    {
+    CMsgMailDocument* doc = Document();
+    CMsvEntrySelection* sel = new (ELeave) CMsvEntrySelection;
+    CleanupStack::PushL(sel);
+    TMsvId id(doc->Entry().Id());
+    sel->AppendL(id);
+
+    // save the message so the fields in message info dialog will be up to date
+    // this is a "hidden" save, so we preserve values of
+    // preparation and visible flags
+    const TBool visible(doc->CurrentEntry().Entry().Visible());
+    CAknWaitDialog* dlg = new(ELeave) CAknWaitDialog(NULL);
+    CleanupStack::PushL(dlg);
+    dlg->PrepareLC(R_MEB_WAIT_NOTE);
+    HBufC* text = StringLoaderLoadLC( R_WAIT_OPENING );
+    dlg->SetTextL(*text);
+    CleanupStack::PopAndDestroy( text ); // text
+    dlg->RunLD();
+    UnlockEntry();
+    MsgSaveL(!visible);
+    CleanupStack::Pop( dlg ); // dlg
+    dlg->ProcessFinishedL();
+
+    TBuf8<KMessageSizeMaxLength> infoParams(KMessageInfoEditor);
+    CMsvSingleOpWatcher* watch=CMsvSingleOpWatcher::NewLC(*doc);
+    CMsvOperation* op= doc->MtmUi().InvokeAsyncFunctionL(
+        KMtmUiFunctionMessageInfo,
+        *sel,
+        watch->iStatus,
+        infoParams
+        );
+    // watch owns op before leave can occur
+    doc->AddSingleOperationL(op, watch);
+    CleanupStack::Pop( watch ); // watch
+    LockEntryL();
+
+    CleanupStack::PopAndDestroy( sel ); // sel
+
+    // this is done, so message will be saved visible,
+    // when editor is exited
+    if (!visible)
+        {
+        doc->SetChanged(ETrue);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoAdditionalHeadersL()
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoAdditionalHeadersL()
+    {
+	// Cc field
+    TAdditionalHeaderStatus header_status_cc(EMsgComponentIdCc);
+    CMsgAddressControl* ccControl =  AddressControl(EMsgComponentIdCc);
+    if (ccControl)
+    	{
+    	header_status_cc.iHasContent = ccControl->Editor().TextLength() > 0;
+    	header_status_cc.iStatus = EHeaderVisible;
+    	}
+    // Bcc field
+    TAdditionalHeaderStatus header_status_bcc(EMsgComponentIdBcc);
+    // Check if bcc field is allowed
+    if ( Document()->MailCRHandler()->MailAdditionalHeaders() )
+        {
+        CMsgAddressControl* bccControl =  AddressControl(EMsgComponentIdBcc);
+        if (bccControl)
+        	{
+        	header_status_bcc.iHasContent =
+        	    bccControl->Editor().TextLength() > 0;
+        	header_status_bcc.iStatus = EHeaderVisible;
+        	}
+        }
+	// Subject
+    TAdditionalHeaderStatus header_status_subject(EMsgComponentIdSubject);
+    CMsgExpandableControl* subjectControl = SubjectControl();
+    if (subjectControl)
+    	{
+    	header_status_subject.iHasContent =
+    		subjectControl->Editor().TextLength() > 0;
+    	header_status_subject.iStatus = EHeaderVisible;
+    	}
+
+    RPointerArray<TAdditionalHeaderStatus> headers;
+    CleanupClosePushL(headers);
+
+    headers.Append(&header_status_cc);
+    // Check if bcc field is allowed
+    if ( Document()->MailCRHandler()->MailAdditionalHeaders() )
+        {
+        headers.Append(&header_status_bcc);
+        }
+    headers.Append(&header_status_subject);
+
+    CMsgAddMailHeadersDlg* addHeadersDlg =
+    	CMsgAddMailHeadersDlg::NewLC(headers);
+
+    if( addHeadersDlg->ExecuteDialogL() )
+        {
+        TUint headersvalue(0);
+        for (TInt index(0); index < headers.Count(); ++index)
+            {
+            switch( headers[index]->iHeaderValue )
+                {
+                case EMsgComponentIdCc:
+                    if ( headers[index]->iStatus == EHeaderVisible )
+                        {
+                        headersvalue += KBit0;
+                        }
+                    break;
+                case EMsgComponentIdBcc:
+                    if ( headers[index]->iStatus == EHeaderVisible )
+                        {
+                        headersvalue += KBit1;
+                        }
+                    break;
+                case EMsgComponentIdSubject:
+                    if ( headers[index]->iStatus == EHeaderVisible )
+                        {
+                        headersvalue += KBit2;
+                        }
+                    break;
+                default:
+                    // Unknown header field
+                    ASSERT( 0 );
+                }
+            }
+		// remember user selection
+        Document()->MailCRHandler()->SetCRInt(
+        	KCRUidMail,KMailAdditionalHeaderSettings,headersvalue);
+
+        // set headers
+        UpdateHeaderVisibilityL(headers);
+        }
+    CleanupStack::PopAndDestroy(2);				// CSI: 47,12 # headers, addHeadersDlg
+    }
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoGetRecipientsL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoGetRecipientsL()
+	{
+    CImHeader& header = Document()->HeaderL();
+    CMsgAddressControl* addressField = NULL;
+
+    addressField = AddressControl(EMsgComponentIdTo);
+    AddRecipientArrayL(addressField,
+    	header.ToRecipients());
+
+    addressField = AddressControl(EMsgComponentIdCc);
+        AddRecipientArrayL(addressField,
+            header.CcRecipients());
+
+    addressField = AddressControl(EMsgComponentIdBcc);
+    	AddRecipientArrayL(addressField,
+            header.BccRecipients());
+	}
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoRemoveDuplicatesL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoRemoveDuplicatesL()
+	{
+    // Remove duplicate addresses
+    CMsgAddressControl* addressField(NULL);
+    addressField = AddressControl(EMsgComponentIdTo);
+    RemoveDuplicatesL(addressField);
+
+    addressField = AddressControl(EMsgComponentIdCc);
+    RemoveDuplicatesL(addressField);
+
+    addressField = AddressControl(EMsgComponentIdBcc);
+    RemoveDuplicatesL(addressField);
+    
+    //After each control is cleaned remove rest duplicates by comparing different controls
+    RemoveDuplicatesL(AddressControl(EMsgComponentIdTo), AddressControl(EMsgComponentIdCc));
+    RemoveDuplicatesL(AddressControl(EMsgComponentIdTo), AddressControl(EMsgComponentIdBcc));
+    RemoveDuplicatesL(AddressControl(EMsgComponentIdCc), AddressControl(EMsgComponentIdBcc));
+	}
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::RemoveDuplicatesL
+//
+// Compares two address controls and removes duplicate
+// address from later one.
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::RemoveDuplicatesL(CMsgAddressControl* aAddressField, 
+		CMsgAddressControl* aLaterAddressField)
+    {
+    
+    //Symbian also removes duplicate addresses (CImHeader::IsRecipientPresent), 
+    //but it ignores BCC field for some reason.
+    
+    if(aAddressField && aLaterAddressField)
+        {
+        CMsgRecipientArray& recs = *aAddressField->GetRecipientsL();
+        CMsgRecipientArray& laterRecs = *aLaterAddressField->GetRecipientsL();
+    	    
+    	TInt laterCount(laterRecs.Count());
+    	TInt count(recs.Count());
+
+    	for(TInt i=0; i<count; i++)
+    	    {
+    	  
+        	for(TInt j=0; j<laterCount; j++)
+        	    {
+    	        if( recs[i]->Address()->FindF(*(laterRecs[j]->Address())) >= 0 )
+                    {
+                    //Remove duplicate from later control 
+                    //and update count of that
+                    delete laterRecs.At(j);
+                    laterRecs.Delete(j);    
+                    
+                    laterCount = laterRecs.Count();
+                    
+                    //Now we can break and move to next item in aAddressField.
+                    //Duplicates in the same row should have been removed earlier.
+                    break;
+                    }
+                }
+	        }
+	
+	    aLaterAddressField->RefreshL(laterRecs);    
+        }
+    
+    
+    }
+
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::DoHandleCommandL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::DoHandleCommandL( TInt aCommand )
+    {
+    //Still launching application.
+    //IsLaunched() can be true even if iView
+    //isn't created yet.
+    if( !Document()->IsLaunched() || !iView )
+    	{
+		if ( aCommand != EEikCmdExit )
+			{
+			return;
+			}
+    	}
+    
+	DoFetchFileL( aCommand );
+    switch ( aCommand )
+        {
+        case EEikCmdExit:
+            if( iForceDeleteDocument )
+                {
+                DeleteAndExitL();
+                }
+            else
+                {
+                DoMsgSaveExitL();
+                }
+            break;
+        case EMsgMailEditorCmdSend:
+            if (AreAddressFieldsEmptyL())
+                {
+                DoAddRecipientL();
+                }
+            else
+                {
+                DoSendMessageL();
+                }
+            break;
+        case EMsgMailEditorCmdSendingOptions:
+            DoSendOptionsL();
+            break;
+        case EAknSoftkeyClose:
+            TRAPD(error, DoBackstepL());
+            if ( error == KErrDiskFull )
+                {
+                // No memory to save changes
+                if ( MailUtils::ConfirmationQueryL(
+                    R_QTN_MAIL_CLOSE_NOSAVE, R_MAIL_EDITOR_DELETE_MESSAGE) )
+                    {
+                    Exit();
+                    }
+                }
+            else
+                {
+                User::LeaveIfError( error );
+                }
+            break;
+        case EMsgMailEditorCmdMskAddRecipient:
+            if(!AreAddressFieldsEmptyL() && !AllAddressValidL())
+                {
+                CheckRecipientsL(EFalse);
+                }
+            else
+                {
+                DoAddRecipientL();    
+                }
+             break;
+        case EMsgMailEditorCmdAddRecipient:
+            DoAddRecipientL();
+            break;
+        case EMsgMailEditorCmdAttachments:
+            DoAttachmentL();
+            break;
+        case EMsgMailEditorCmdInsertMenu:
+        	DoShowSelectionListL();
+           	break;
+        case EMsgMailEditorCmdInsertTemplate:
+	    // If user chooses Cancel while selecting template text
+        // DoShowToolBarTextL leaves. This is ok so leave is catched here.
+        	TRAPD(err, InsertTemplateL() );
+		    if( err != KErrCancel )
+	            {
+	            User::LeaveIfError( err );
+	            }
+            UpdateMessageSizeL();
+            break;
+        case EMsgMailEditorCmdInsertTemplateNote:
+            User::LeaveIfError( InsertTextMemoL() );
+            UpdateMessageSizeL();
+            break;
+        case EMsgMailEditorCmdMessageInfo:
+            DoMessageInfoL();
+            break;
+        case EMsgMailEditorCmdAddHeaders:
+            DoAdditionalHeadersL();
+            break;
+        // general options:
+        case EEikCmdEditCut:
+            iView->FocusedControl()->ClipboardL(EMsgCut);
+            UpdateMessageSizeL();
+            break;
+        case EEikCmdEditCopy:
+            iView->FocusedControl()->ClipboardL(EMsgCopy);
+            break;
+        case EEikCmdEditPaste:
+            iView->FocusedControl()->ClipboardL(EMsgPaste);
+            UpdateMessageSizeL();
+            break;
+        case EMsgMailEditorCmdExpandInsert:
+			break;
+        case EAknCmdHelp:
+            {
+            if ((iCommonFlags & EHelpSupported))
+                {
+                // Launch help
+                HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(),
+                    iEikonEnv->EikAppUi()->AppHelpContextL() );
+                }
+            break;
+            }
+        case EMsgDispSizeAutomatic:
+        // FALLTHROUGH
+        case EMsgDispSizeLarge:
+        // FALLTHROUGH
+        case EMsgDispSizeNormal:
+        // FALLTHROUGH
+        case EMsgDispSizeSmall:
+            HandleLocalZoomChangeL( (TMsgCommonCommands)aCommand );
+            break;
+        default:
+            CMsgMailAppUi::HandleCommandL(aCommand);
+            break;
+        }                       
+    }
+
+// ----------------------------------------------------------------------------
+// void CMsgMailEditorAppUi::EditorObserverL()
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::EditorObserverL(
+    TMsgEditorObserverFunc aFunc,
+    TAny* aArg1,
+    TAny* aArg2,
+    TAny* /*aArg3*/ )
+	{
+	if ( aFunc == MMsgEditorObserver::EMsgHandleFocusChange )
+		{
+		ASSERT( aArg1 );
+		ASSERT( aArg2 );
+
+		TMsgFocusEvent event = *(static_cast<TMsgFocusEvent*>( aArg1 ) );    		
+		TInt controlId = *(static_cast<TInt*>( aArg2 ) );
+    		                  
+        switch( event )
+            {
+            case EMsgFocusMovingFrom:
+                {
+                if ( controlId == EMsgComponentIdAttachment )
+                    {                        
+                    iNaviPaneUtils->EnableOwnNaviPaneL( EFalse );
+                    }
+                     
+                // Set input mode (e.g. number mode)to other address fields too
+				CMsgAddressControl* ctrl = AddressControl( controlId );
+                if ( ctrl )
+                	{
+                	TInt mode( ctrl->Editor().AknEditorCurrentInputMode() );
+                    SetInputModeToAddressFields( mode );
+                	}
+                }// EMsgFocusMovingFrom
+                break;
+            case EMsgFocusMovedTo:
+                {
+                CheckFocusForMskL( controlId );
+                if ( controlId == EMsgComponentIdAttachment )
+                    {     
+                    iNaviPaneUtils->EnableOwnNaviPaneL( ETrue );
+                    }
+                } // EMsgFocusMovingTo
+                break;
+            } // switch
+		}
+#ifdef RD_SCALABLE_UI_V2
+	else if( aFunc == MMsgEditorObserver::EMsgButtonEvent )
+		{
+		ASSERT( aArg1 );
+		
+		//Get the parameter
+		CMsgBaseControl* control = static_cast<CMsgBaseControl*>( aArg1 );
+        
+        //Attachment handling is mostly done in pointer event branch.
+		//Here we tackle situation where focus is not in attachment row
+		//and the button is pressed. 
+		//Also other button events go this way, but attachment handling
+		//is a special case.
+		if ( control && ( control->ControlId() != EMsgComponentIdAttachment ||
+		        iFocusedControl != control ) )
+			{
+			//Summon touch functionality
+			ControlTouchedL( *control );	
+        	}
+		}
+	else if( aFunc == MMsgEditorObserver::EMsgControlPointerEvent )
+		{
+		if( aArg1 && aArg2 )
+			{
+            TPointerEvent* event = static_cast<TPointerEvent*>( aArg2 );
+            CMsgBaseControl* control = static_cast<CMsgBaseControl*>( aArg1 );
+
+            if ( event->iType == TPointerEvent::EButton1Down )
+                {
+                //This is done to check if control is already focused.
+                //When attachment row is clicked and it has focus
+                //attachment dialog is opened. Otherwise row just gains focus.                
+                iFocusedControl = control && control->IsFocused() ? control : NULL;
+                }
+            else if ( event->iType == TPointerEvent::EButton1Up )
+                {
+				if( control && iFocusedControl == control && 
+					control->ControlId() == EMsgComponentIdAttachment )        
+					{			
+					//Summon touch functionality
+					ControlTouchedL( *control );
+					}
+                }
+			}
+		}
+#endif
+	}
+
+// ---------------------------------------------------------------------------
+// CMsgMailEditorAppUi::CheckFocusForMSK
+// ---------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::CheckFocusForMskL(TInt aControl)
+    {
+
+    RemoveMSKCommands();
+    switch(aControl)
+        {
+        case EMsgComponentIdTo:
+        // FALLTHROUGH
+        case EMsgComponentIdCc:
+        // FALLTHROUGH
+        case EMsgComponentIdBcc:
+             SetMiddleSoftKeyLabelL(R_QTN_MSK_ADD,
+                EMsgMailEditorCmdMskAddRecipient);
+             break;
+
+        case EMsgComponentIdAttachment:
+            SetMiddleSoftKeyLabelL(R_QTN_MSK_ATTACHMENT,
+                EMsgMailEditorCmdAttachments);
+            break;
+
+        default:
+            //Change msk label back to normal (context sensitive menu icon)
+            SetMiddleSoftKeyLabelL(R_TEXT_SOFTKEY_OPTION,
+                EAknSoftkeyContextOptions);
+        }
+
+    }
+
+// ---------------------------------------------------------------------------
+// CMsgMailEditorAppUi::SetMiddleSoftKeyLabelL
+// ---------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::SetMiddleSoftKeyLabelL(
+    const TInt aResourceId, const TInt aCommandId )
+    {
+    CEikButtonGroupContainer* cbaGroup = Cba();
+    if ( cbaGroup )
+        {
+        HBufC* middleSKText = StringLoader::LoadLC( aResourceId );
+        TPtr mskPtr = middleSKText->Des();
+        cbaGroup->AddCommandToStackL(
+            KMSKControlID,
+            aCommandId,
+            mskPtr );
+        CleanupStack::PopAndDestroy( middleSKText );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::RemoveMSKCommands
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::RemoveMSKCommands()
+    {
+    if ( Cba() )
+        {
+        Cba()->RemoveCommandFromStack( KMSKControlID,
+            EMsgMailEditorCmdMskAddRecipient);
+        Cba()->RemoveCommandFromStack( KMSKControlID,
+            EMsgMailEditorCmdAttachments );
+        Cba()->RemoveCommandFromStack( KMSKControlID,
+            EAknSoftkeyContextOptions );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::InitPhoneBookL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::InitPhoneBookL()
+    {
+    // initialize pb
+    if ( !iCheckNames )
+        {
+        TRAP_IGNORE( iCheckNames = CMsgCheckNames::NewL() );
+        }
+    ASSERT( iCheckNames );
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::SearchUnverifiedStringL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::SearchUnverifiedStringL(
+    const TDesC& aText, CMsgAddressControl* aControl )
+    {
+    ASSERT( aControl );
+    HBufC* buf = NULL;
+    iView->SetFocus(aControl->ControlId());
+    aControl->GetFirstUnverifiedStringL(buf);
+    while (buf && buf->Compare(aText) != 0)
+        {
+        delete buf;
+        buf = NULL;
+        aControl->GetNextUnverifiedStringL(buf);
+        }
+    delete buf;
+    buf = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::AllAddressValidL
+// -----------------------------------------------------------------------------
+//
+TBool CMsgMailEditorAppUi::AllAddressValidL()
+    {
+    TInt i(0);
+    TBool ret(ETrue);
+
+    CMsgAddressControl* addressField = AddressControl(EMsgComponentIdTo);
+    CMsgRecipientArray* rcpt = addressField->GetRecipientsL();
+
+    while (i < rcpt->Count() && ret)
+        {
+        ret = IsValidAddress (*rcpt->At(i)->Address());
+        i++;
+        }
+
+    if (ret)
+        {
+        addressField = AddressControl(EMsgComponentIdCc);
+        if(addressField)
+            {
+            rcpt = addressField->GetRecipientsL();
+            i=0;
+            while (i < rcpt->Count() && ret)
+                {
+                ret = IsValidAddress (*rcpt->At(i)->Address());
+                i++;
+                }
+            }
+        }
+
+    if (ret)
+        {
+        addressField = AddressControl(EMsgComponentIdBcc);
+
+        if(addressField)
+            {
+            rcpt = addressField->GetRecipientsL();
+            i=0;
+            while (i < rcpt->Count() && ret)
+                {
+                ret = IsValidAddress (*rcpt->At(i)->Address());
+                i++;
+                }
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::SetFocusToFirstFreeFieldL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::SetFocusToFirstFreeFieldL()
+    {
+    // Set focus at begining of the message when replying
+    if ( Document()->IsReplyMessage() )
+        {
+        iView->SetFocus(EMsgComponentIdBody);
+        }
+    // set focus at first free field
+    else
+        {
+        if(AddressControl(EMsgComponentIdTo))
+            {
+            if (!AddressControl(EMsgComponentIdTo)->Editor().TextLength())
+                {
+                iView->SetFocus(EMsgComponentIdTo);
+                return;
+                }
+            }
+        if (AddressControl(EMsgComponentIdCc))
+            {
+            if (!AddressControl(EMsgComponentIdCc)->Editor().TextLength())
+                {
+                iView->SetFocus(EMsgComponentIdCc);
+                return;
+                }
+            }
+        if (AddressControl(EMsgComponentIdBcc))
+            {
+            if (!AddressControl(EMsgComponentIdBcc)->Editor().TextLength())
+                {
+                iView->SetFocus(EMsgComponentIdBcc);
+                return;
+                }
+            }
+        if (SubjectControl())
+            {
+            if (!SubjectControl()->Editor().TextLength())
+                {
+                iView->SetFocus(EMsgComponentIdSubject);
+                return;
+                }
+            }
+        iView->SetFocus(EMsgComponentIdBody);
+        CEikRichTextEditor& editor = BodyControl()->Editor();
+        editor.SetCursorPosL(editor.TextLength(), EFalse);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::ShowSelectedMailboxL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::ShowSelectedMailboxL()
+    {
+    const CMsgMailEditorDocument* doc = Document();
+    CMsvEntry* rootEntry = doc->Session().GetEntryL(KMsvRootIndexEntryId);
+    CleanupStack::PushL(rootEntry);
+
+    TInt noteResource(0);
+    TInt64 flags = MImumInHealthServices::EFlagSetHealthyReceiving;
+    
+	noteResource = R_MAIL_EDITOR_MAILBOX_IN_USE_TEXT;
+        
+
+    // if more than one box defined, show its name
+    if ( Document()->GetHealthyMailboxListL( flags ).Count() > 1 )
+        {
+        const TMsvId service(doc->SendOptions().ServiceId());
+        TMsvSelectionOrdering ordering(rootEntry->SortType());
+        ordering.SetShowInvisibleEntries(ETrue);
+        rootEntry->SetSortTypeL(ordering);
+        const TMsvEntry child = rootEntry->ChildDataL(service);
+        HBufC* stringholder = StringLoader::LoadLC(
+            noteResource, child.iDetails, iEikonEnv );
+
+        CAknInformationNote* note = new(ELeave) CAknInformationNote(ETrue);
+        note->ExecuteLD(*stringholder);
+        CleanupStack::PopAndDestroy( stringholder ); // stringholder
+        }
+    CleanupStack::PopAndDestroy( rootEntry ); // rootEntry
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgEditorAppUi::RemoveDuplicatesL
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::RemoveDuplicatesL(CMsgAddressControl* aAddressField)
+    {
+    if ( aAddressField )
+    	{
+	    CMsgRecipientArray& recs = *aAddressField->GetRecipientsL();
+	    TInt count(recs.Count());
+	    for (TInt i=0; i < count; i++)
+	        {
+	        for (TInt j = i + 1; j < count; )
+	            {
+	            if (recs[i]->Address()->Compare(*(recs[j]->Address())) == 0)
+	                {
+	                if (recs[i]->Name()->Length())
+	                    {
+	                    delete recs.At(j);
+	                    recs.Delete(j);
+	                    }
+	                else
+	                    {
+	                    delete recs.At(i);
+	                    recs.Delete(i);
+	                    }
+	                count = recs.Count();
+	                }
+	            else
+	                {
+	                // increase j if something wasn't deleted. if j is
+	                // increased when nothing is deleted, elements are skipped
+	                j++;
+	                }
+	            }
+	        }
+	    aAddressField->RefreshL(recs);
+    	}
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::MopSupplyObject(TTypeUid aId)
+// Returns a pointer to popup menu.
+// ----------------------------------------------------------------------------
+//
+TTypeUid::Ptr CMsgMailEditorAppUi::MopSupplyObject(TTypeUid aId)
+    {
+    return SupplyMopObject(aId);
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::StopWaitNote
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::StopWaitNote()
+	{
+    delete iWaitNote;
+    iWaitNote = NULL;
+	}
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::StartWaitNoteLC
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::StartWaitNoteLC(
+    TInt aStringResourceId, TBool aDelayOff )
+    {
+    StartWaitNoteLC( aStringResourceId, aDelayOff, R_MEB_WAIT_NOTE );
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::StartWaitNoteLC
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::StartWaitNoteLC(
+    TInt aStringResourceId, TBool aDelayOff, TInt aResouceID )
+    {
+    StopWaitNote();
+    iWaitNote = new(ELeave) CAknWaitDialog(
+            reinterpret_cast <CEikDialog**>(&iWaitNote), aDelayOff );
+    CleanupStack::PushL(TCleanupItem(CleanupWaitDialog, (TAny**)&iWaitNote));
+    iWaitNote->PrepareLC( aResouceID );
+    HBufC* text = StringLoaderLoadLC( aStringResourceId );
+    iWaitNote->SetTextL(*text);
+    CleanupStack::PopAndDestroy( text ); // text
+    
+	// safe to call LD even as a member variable, since sets itself to NULL when deleting
+    iWaitNote->RunLD(); // CSI: 50 # see comment above
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::StringLoaderLoadLC
+// ----------------------------------------------------------------------------
+//
+HBufC* CMsgMailEditorAppUi::StringLoaderLoadLC( TInt aTextResource )
+    {
+    return StringLoader::LoadLC( aTextResource, iEikonEnv );
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::SpecialScrolling
+// -----------------------------------------------------------------------------
+//
+TBool CMsgMailEditorAppUi::SpecialScrolling( TUint aKeyCode )
+    {
+    TBool keyConsumed( EFalse );
+    if ( aKeyCode == EStdKeyUpArrow || aKeyCode == EStdKeyDownArrow )
+        {
+        CMsgBaseControl* focusedControl = iView->FocusedControl();
+        if ( focusedControl )
+            {
+            TInt focused( focusedControl->ControlId() );
+            if ( aKeyCode == EStdKeyDownArrow )
+                {
+                // Focus on Reply-to field??
+                if (  focused == EMailEditorControlReplyTo )
+                    {
+                    // jump directly to atta control
+                    LOG( "CMsgMailEditorAppUi::SpecialScrolling - Down" );
+                    RotateFocus( ETrue, EMailEditorControlReplyTo );
+                    keyConsumed = ETrue;
+                    }
+                }
+            else
+                {
+                // scroll up, and focus is top of the body part
+                if ( focused == EMailEditorControlReplyTo )
+                        {
+                        LOG( "CMsgMailEditorAppUi::SpecialScrolling - Up" );
+                        RotateFocus( EFalse, EMailEditorControlReplyTo );
+                        keyConsumed = ETrue;
+                        }
+                }
+            }
+        }
+
+    return keyConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::RotateFocus
+// -----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::RotateFocus( TBool aDirection, TInt aCurrentFocus )
+    {
+    // Mail editor control order
+    const TInt TControls[] =
+        {
+        EMsgComponentIdTo,
+        EMsgComponentIdCc,
+        EMsgComponentIdBcc,
+        EMailEditorControlReplyTo,
+        EMsgComponentIdSubject,
+        EMsgComponentIdAttachment,
+        EMsgComponentIdBody
+        };
+
+    const TInt count( sizeof(TControls) / sizeof(TInt) );
+    TInt index(0); // index starts from 0
+	for(; index<count; ++index)
+	    {
+	    __ASSERT_DEBUG( index >= 0 && index < count, User::Invariant() );
+	    
+	    if ( aCurrentFocus == TControls[ index ] )	// CSI: 2 # This is checked above in the assert macro.
+	        {
+	        // locate currently focused item
+	        break;
+	        }
+	    }
+    CMsgBaseControl* control(NULL);
+	while ( !control )
+	    {
+        // Then find next control for current position
+        aDirection ? ++index : --index;
+        ASSERT( index >= 0 && index < count );
+        control = iView->ControlById( TControls[ index ] );	// CSI: 2 # This is checked above in the assert macro.
+	    }
+
+	LOG( "CMsgMailEditorAppUi::RotateFocus" );
+    iView->SetFocus( control->ControlId() );
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgMailEditorAppUi::AddRecipientArrayL
+// ----------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::AddRecipientArrayL(CMsgAddressControl* aControl,
+    const CDesCArray& aArray)
+    {
+    const TInt count(aArray.Count());
+    if ( aControl && count>0 )
+    	{
+    	CMsgRecipientList* recipientList = CMsgRecipientList::NewL();
+    	CleanupStack::PushL(recipientList);
+
+	    for ( TInt index=0; index<count; ++index )
+	    	{
+	    	TBool aliasFound( EFalse );
+	    	TImMessageField msgField;
+		    HBufC* address = msgField.GetValidInternetEmailAddressFromString(
+		        aArray[index]).AllocLC();
+			address->Des().Trim();
+
+            TInt found(KErrNone);
+            TPtrC16 aliasPtr = msgField.GetValidAlias(
+		        aArray[index], found );
+		    HBufC* alias;
+		    if ( found  == KErrNone )
+		        {
+		        alias = aliasPtr.AllocLC();
+		        aliasFound = ETrue;
+		        }
+		    else
+		        {
+		        alias = KNullDesC().AllocLC();
+		        }
+
+		    CMsgRecipientItem* reci =
+		    	CMsgRecipientItem::NewLC(*alias, *address);
+		    	
+			//verified is set according to alias found status
+			//as editorbase uses the alias only if verified == ETrue
+		    reci->SetVerified( aliasFound );
+			
+		    recipientList->AppendL(reci);
+		    // Ownership transferred just pop
+		    CleanupStack::Pop( reci );  // reci
+		    CleanupStack::PopAndDestroy( 2, address ); 			// CSI: 47,12 # alias, address
+	    	}
+
+        if ( recipientList->Count() )
+            {
+            aControl->AddRecipientsL(*recipientList);
+            }
+	    CleanupStack::PopAndDestroy( recipientList ); // recipientList
+    	}
+    }
+
+//---------------------------------------------------------------------------
+//  CMsgMailEditorAppUi::CheckGlobalReplyToSettingL()
+//  Gets mailbox reply to address from smtp settings
+//  and adds it to mail header if address is different
+//  than address of mailbox. Returns ETrue if new value is
+//  set.
+//---------------------------------------------------------------------------
+TBool CMsgMailEditorAppUi::CheckGlobalReplyToSettingL()
+    {
+    TBool retVal = EFalse;
+
+    CMsgMailEditorDocument& doc = *Document();
+
+    //Get smtp account and load smtp settings
+	CEmailAccounts* smtpAccount = CEmailAccounts::NewLC();
+    CImSmtpSettings* smtpSet=new(ELeave)CImSmtpSettings();
+    CleanupStack::PushL(smtpSet);
+    const TMsvId smtpSetId = doc.CurrentEntry().Entry().iServiceId;
+
+    TSmtpAccount accountParams;
+    smtpAccount->GetSmtpAccountL( smtpSetId, accountParams );
+	smtpAccount->LoadSmtpSettingsL(accountParams, *smtpSet);
+
+    //Check that if reply to address is same as mailbox address
+    //do not add "reply to" field for header. Otherwise "reply to" field
+    //would be always visible.
+    if(smtpSet->ReplyToAddress().Compare(smtpSet->EmailAddress() ) != 0)
+        {
+        CImHeader& header = doc.HeaderL();
+        
+        header.SetReplyToL( smtpSet->ReplyToAddress() );
+
+        ASSERT( iMailEditorHeader );
+        iMailEditorHeader->UpdateReplyToControlL();
+
+        retVal = ETrue;
+        }
+    else
+        {
+        retVal = EFalse;
+        }
+
+    CleanupStack::PopAndDestroy(2, smtpAccount);			// CSI: 47,12 # smtpSet
+
+    return retVal;
+    }
+
+// ---------------------------------------------------------
+// CMsgMailEditorAppUi::SetInputModeToAddressFields
+// ---------------------------------------------------------
+void CMsgMailEditorAppUi::SetInputModeToAddressFields( TInt aInputMode )
+    {
+    CMsgAddressControl* ctrl( NULL );
+    for ( TInt ctrlId( EMsgComponentIdTo );
+          ctrlId <= EMsgComponentIdBcc; ctrlId++ )
+        {
+        ctrl = AddressControl( ctrlId );
+        if ( ctrl )
+            {
+            ctrl->Editor().SetAknEditorCurrentInputMode( aInputMode );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgMailEditorAppUi::SetFocusAfterAddRecipientL
+// ---------------------------------------------------------
+void CMsgMailEditorAppUi::SetFocusAfterAddRecipientL( TMsgControlId aFocusBeforeAdd )
+    {    
+	//If the  cursor is in some other place than the address fields when "Add recipient"
+	//is selected the cursor remains in this same address field (do nothing). 
+     if ( aFocusBeforeAdd == EMsgComponentIdTo ||
+    	aFocusBeforeAdd == EMsgComponentIdCc ||
+    	aFocusBeforeAdd == EMsgComponentIdBcc )
+    	{
+    	//Set the cursor to the next empty address field if there is one. 
+    	
+    	//From "To" to "CC" if available
+        if( aFocusBeforeAdd < EMsgComponentIdCc && 
+        	AddressControl(EMsgComponentIdCc) &&
+        	!AddressControl(EMsgComponentIdCc)->Editor().TextLength() )
+            {
+            iView->SetFocus(EMsgComponentIdCc);
+            }
+
+    	//From "To" or "CC" to "BCC" if available
+        else if( aFocusBeforeAdd < EMsgComponentIdBcc && 
+        	AddressControl(EMsgComponentIdBcc) &&
+        	!AddressControl(EMsgComponentIdBcc)->Editor().TextLength() )
+            {
+            iView->SetFocus(EMsgComponentIdBcc);
+            }
+            
+    	//To "Subject" if CC and BCC have not been available           
+        else if( SubjectControl() && !SubjectControl()->Editor().TextLength() )
+            {
+			iView->SetFocus(EMsgComponentIdSubject);
+            }            
+            
+	    //In other case cursor is placed into the text body
+	    //1) the beginning of the text body if it is empty, or 
+	    //2) the end of text body if there is text already.
+	    else
+	    	{
+			iView->SetFocus(EMsgComponentIdBody);
+			CEikRichTextEditor& editor = BodyControl()->Editor();
+			editor.SetCursorPosL(editor.TextLength(), EFalse);  	    		
+	    	}	
+    	}
+    }
+    
+// ---------------------------------------------------------------------------
+// CMsgMailEditorAppUi::ControlTouchedL
+//
+// Control has been touched. Invoke appopriate actions
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CMsgMailEditorAppUi::ControlTouchedL( const CMsgBaseControl& aControl )
+	{
+    //Check the control id
+    TInt touchedControlId = aControl.ControlId();
+	switch( touchedControlId )
+		{
+		//Touch in address fields
+		case EMsgComponentIdTo:
+		case EMsgComponentIdCc:
+		case EMsgComponentIdBcc:
+		    {
+			//Set focus to touched control (if needed)
+			TInt focusedControlId = iView->FocusedControl()->ControlId(); 
+			
+			if ( focusedControlId != touchedControlId )
+				{
+				iView->SetFocus( touchedControlId );	
+				}
+
+            if(!AreAddressFieldsEmptyL() && !AllAddressValidL())
+                {
+                CheckRecipientsL(EFalse);
+                }
+            else
+                {
+                DoAddRecipientL();    
+                }
+			break;
+		    }
+		//Touch in attachment button
+		case EMsgComponentIdAttachment:
+		    {
+		    //Open attachment view
+			DoAttachmentL();
+			break;
+		    }
+		default:
+			{
+			LOG1( "CMsgMailEditorAppUi::ControlTouchedL - Unhandled control! id %d",  touchedControlId );	
+			}
+		} // switch   		
+	}
+#endif
+
+// --------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleEnterKeyL
+// Handles enter key events.
+// --------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::HandleEnterKeyL()
+    {
+    if( iView )
+        {
+        CMsgBaseControl* focusedCtrl = iView->FocusedControl();
+        if( focusedCtrl )
+            {
+            switch( focusedCtrl->ControlId() )
+                {
+                case EMsgComponentIdAttachment:
+                    {
+                    // Open attachment view
+                    DoAttachmentL();
+                    break;
+                    }
+                default:
+                    {
+                    // event ignored for other controls.
+                    break;
+                    }
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CMsgMailEditorAppUi::HandleSystemEventL
+// Handles system events
+// --------------------------------------------------------------------------
+//
+void CMsgMailEditorAppUi::HandleSystemEventL( const TWsEvent& aEvent )
+    {
+    TApaSystemEvent* event = ( TApaSystemEvent* )aEvent.EventData();
+    if( *event == EApaSystemEventSecureShutdown )
+        {
+        // When the user is writing a mail while the used memory drive is 
+        // removed from the phone, the mail editor is closed and the mail is
+        // not saved.
+        iForceDeleteDocument = ETrue;
+        }
+
+    CMsgMailAppUi::HandleSystemEventL( aEvent );
+    }
+
+// End of File