emailuis/emailui/src/ncscomposeviewcontainer.cpp
branchRCL_3
changeset 25 3533d4323edc
child 26 968773a0b6ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncscomposeviewcontainer.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,2148 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  compose view container
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "emailtrace.h"
+#include <s32mem.h>
+#include <txtrich.h>
+#include <AknIconUtils.h>
+#include <StringLoader.h>
+#include <avkon.hrh>
+#include <AknsDrawUtils.h>
+#include <aknview.h>
+#include <AknUtils.h>
+#include <FreestyleEmailUi.rsg>
+#include <eikclbd.h>
+#include <aknViewAppUi.h>
+#include <aknnotewrappers.h> //CAknInformationNote
+#include <txtetext.h>
+#include <aknphysics.h>
+
+#include "ncscomposeviewcontainer.h"
+#include "ncsheadercontainer.h"
+#include "ncsaddressinputfield.h"
+#include "ncssubjectfield.h"
+#include "ncsconstants.h"
+#include "ncseditor.h"
+#include "ncspopuplistbox.h"
+#include "ncscomposeview.h"
+#include "ncsutility.h"
+#include "ncsemailaddressobject.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "FreestyleEmailUiConstants.h"
+#include "FreestyleEmailUiSendAttachmentsListControl.h"
+#include "FreestyleEmailUiSendAttachmentsListVisualiser.h"
+#include "FreestyleEmailUiSendAttachmentsListModel.h"
+#include "FreestyleEmailUi.hrh"
+#include "FSAutoSaver.h"
+#include "FreestyleEmailUiCLSItem.h"
+#include "FSAsyncTextFormatter.h"
+
+const TInt KHeaderVisibilityThreshold = -100;
+
+// ========================= MEMBER FUNCTIONS ==================================
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CNcsComposeViewContainer::CNcsComposeViewContainer(
+    CNcsComposeView& aView,
+    CFsAutoSaver& aAutoSaver,
+	CFSMailBox& aMailBox ):
+	iView( aView ), iAmountMesFieldMovedUp( 0 ),
+	iAutoSaver( aAutoSaver ), iMailBox( aMailBox )
+    {
+    FUNC_LOG;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CNcsComposeViewContainer* CNcsComposeViewContainer::NewL( 
+    CNcsComposeView& aView, const TRect& aRect, CFSMailBox& aMailBox, 
+    CFsAutoSaver& aAutoSaver, TInt aFlags )
+    {
+    FUNC_LOG;
+
+    CNcsComposeViewContainer* self = new ( ELeave ) CNcsComposeViewContainer(
+        aView, aAutoSaver, aMailBox );
+    CleanupStack::PushL( self );
+    self->ConstructL( aRect, aFlags );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::ConstructL( const TRect& aRect, TInt aFlags )
+    {
+    FUNC_LOG;
+
+    SetMopParent( &iView );
+    CreateWindowL();
+
+    if ( CAknPhysics::FeatureEnabled() )
+        {
+        iPhysics = CAknPhysics::NewL( *this, this );
+        }
+
+    // Setup the control array
+    InitComponentArrayL();
+    CCoeControlArray& controls = Components();
+    controls.SetControlsOwnedExternally( ETrue );
+
+    // Create the header field
+    iHeader = CNcsHeaderContainer::NewL( *this, iMailBox, aFlags, iPhysics );
+    controls.AppendLC( iHeader );
+    CleanupStack::Pop( iHeader );
+
+    // Create 'message body' field, default text is empty for that field
+    iMessageField = new ( ELeave ) CNcsEditor( this, EFalse, ENcsEditorBody );
+    iMessageField->SetContainerWindowL( *this );
+    iMessageField->ConstructL( this, 0, 0 );
+    iMessageField->SetAlignment( EAknEditorAlignBidi );
+    iMessageField->SetAknEditorInputMode( EAknEditorTextInputMode );
+    iMessageField->EnableKineticScrollingL( iPhysics );
+    controls.AppendLC( iMessageField );
+    CleanupStack::Pop( iMessageField );
+
+    iMessageField->SetNcsFontType( NcsUtility::ENcsBodytextFont );
+
+    // Listen edwin events and size events from message body field
+    iMessageField->AddEdwinObserverL( this );
+    iMessageField->SetEdwinSizeObserver( this );
+
+    // Create read-only field to be used for original message quote when
+    // protocol doesn't allow editing the original message
+    iReadOnlyQuoteField = new( ELeave ) CNcsEditor( this, EFalse );
+    iReadOnlyQuoteField->SetContainerWindowL( *this );
+    iReadOnlyQuoteField->ConstructL( this, 0, 0 );
+    iReadOnlyQuoteField->SetAlignment( EAknEditorAlignBidi );
+    iReadOnlyQuoteField->SetReadOnly( ETrue );
+    controls.AppendLC( iReadOnlyQuoteField );
+    CleanupStack::Pop( iReadOnlyQuoteField );
+
+    // Listen edwin events and size events from smart quote field
+    iReadOnlyQuoteField->AddEdwinObserverL( this );
+    iReadOnlyQuoteField->SetEdwinSizeObserver( this );
+   iReadOnlyQuoteField->EnableKineticScrollingL( iPhysics );
+
+    // Create the scroll bar
+    iScrollBar = new( ELeave ) CAknDoubleSpanScrollBar( this );
+    iScrollBar->ConstructL( ETrue, this, this, CEikScrollBar::EVertical,
+        aRect.Height() );
+    iScrollBar->MakeVisible( EFalse );
+    iScrollBar->SetModelL( &iScrollBarModel );
+    controls.AppendLC( iScrollBar );
+    CleanupStack::Pop( iScrollBar );
+
+    iMessageField->SetupEditorL();
+    iReadOnlyQuoteField->SetupEditorL();
+
+    iBgContext = CAknsBasicBackgroundControlContext::NewL(
+        KAknsIIDQsnBgAreaMain, Rect(), EFalse );
+
+    SetRect( aRect );
+
+    iLongTapDetector = CAknLongTapDetector::NewL( this );
+
+    // activate auto save functionality
+    iAutoSaver.Enable( ETrue );
+    }
+
+// ---------------------------------------------------------------------------
+// CNcsComposeViewContainer::StopAsyncTextFormatter
+// ---------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::StopAsyncTextFormatter()
+    {
+    if ( iAsyncTextFormatter )
+        {
+        iAsyncTextFormatter->Cancel();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CNcsComposeViewContainer::~CNcsComposeViewContainer
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CNcsComposeViewContainer::~CNcsComposeViewContainer()
+    {
+    FUNC_LOG;
+    
+    if ( iAsyncTextFormatter )
+        {
+        iAsyncTextFormatter->Cancel();
+        delete iAsyncTextFormatter;
+        }
+    
+    if ( iContactHandler )
+        {
+        iContactHandler->ClearObservers();
+        }
+	delete iHeader;
+    delete iScrollBar;
+    delete iMessageField;
+    delete iBgContext;
+	delete iLongTapDetector;
+    delete iReadOnlyQuoteField;
+    delete iReadOnlyQuote;
+
+    delete iPhysics;
+    iPhysics = NULL;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::FocusChanged
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::FocusChanged( TDrawNow aDrawNow )
+    {
+    FUNC_LOG;
+
+	if ( iFocused != iHeader &&
+	     iFocused != iMessageField &&
+	     iFocused != iReadOnlyQuoteField )
+        {
+		iFocused = iHeader;
+        }
+    if ( iFocused == iHeader )
+        {
+        iHeader->ShowCursor( IsFocused() );
+        iFocused->SetFocus( ETrue, aDrawNow );
+        }
+    else if ( iFocused == iMessageField )
+        {
+        iFocused->SetFocus( IsFocused(), aDrawNow );
+        }
+    else 
+        {
+        iFocused->SetFocus( ETrue, aDrawNow );
+        }
+
+    iView.HandleContainerChangeRequiringToolbarRefresh();
+
+	if ( aDrawNow )
+	    {
+		DrawNow();
+	    }
+
+    }
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetMskL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetMskL()
+    {
+    FUNC_LOG;
+    iHeader->SetMskL();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandlePointerEventL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandlePointerEventL( 
+        const TPointerEvent& aPointerEvent )
+    {
+    FUNC_LOG;
+	TBool clearSelection(EFalse);
+    if ( aPointerEvent.iType != TPointerEvent::EButton1Down &&
+         iHeader->NeedsLongTapL( aPointerEvent.iPosition ) )
+        {
+    	iLongTapDetector->PointerEventL( aPointerEvent );
+        }
+	   
+    switch( aPointerEvent.iType )
+    	{
+    	case TPointerEvent::EButton1Down:
+    		{
+            // Save current and original position so that those can be used in
+            // drag/scrolling calculations
+            iPreviousPosition = iOriginalPosition = 
+                aPointerEvent.iPosition;
+            iIsDragging = EFalse;
+            iIsFlicking = EFalse;
+
+            if( iPhysics )
+                {
+                iPhysics->StopPhysics();
+                iPhysics->ResetFriction();
+                iStartTime.HomeTime();
+                UpdatePhysicsL();
+                }            
+
+            if ( iHeader->Rect().Contains( aPointerEvent.iPosition ) )
+                {
+                if ( iFocused == iMessageField )
+                    {
+					if( iMessageField->SelectionLength() )
+						{
+						iMessageField->ClearSelectionL();
+						}
+                    iMessageField->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iHeader;
+                    iHeader->SetFocus( ETrue,ENoDrawNow );
+                    }
+                else if ( iFocused == iReadOnlyQuoteField )
+                    {
+                    iReadOnlyQuoteField->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iHeader;
+                    iHeader->SetFocus( ETrue, ENoDrawNow );
+                    }
+                }
+            else if ( iReadOnlyQuoteField->Rect().Contains( 
+                        aPointerEvent.iPosition ) )
+                {
+                if ( iFocused == iMessageField )
+                    {
+                    iMessageField->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iReadOnlyQuoteField;
+                    iReadOnlyQuoteField->SetFocus( ETrue, ENoDrawNow );
+                    iReadOnlyQuoteField->SetCursorPosL( 0, EFalse );
+                    }
+                else if ( iFocused == iHeader )
+                    {
+                    iHeader->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iReadOnlyQuoteField;
+                    iReadOnlyQuoteField->SetFocus( ETrue, ENoDrawNow );
+                    iReadOnlyQuoteField->SetCursorPosL( 0, EFalse );
+                    }
+                }
+            else 
+                {
+                if ( iFocused == iHeader )
+                    {
+                    iHeader->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iMessageField;
+                    iMessageField->SetFocus( ETrue, ENoDrawNow );
+                    }
+                else if ( iFocused == iReadOnlyQuoteField )
+                    {
+                    iReadOnlyQuoteField->SetFocus( EFalse, ENoDrawNow );
+                    iFocused = iMessageField;
+                    iMessageField->SetFocus( ETrue, ENoDrawNow );
+                    }
+                else
+                    {
+				    // Changes made in predictive input mode can be approved
+					// only if ClearSelection is called AFTER
+					// CCoeControl::HandlePointerEventL,
+					// so iMessageField->ClearSelection() has been moved
+					clearSelection = ETrue;
+                    }
+                }
+
+			break;
+    		}
+    	
+    	case TPointerEvent::EButton1Up:    		
+    		{
+            if( iIsDragging && iPhysics )
+                {
+                TPoint drag( iOriginalPosition - aPointerEvent.iPosition );
+                iPhysics->StartPhysics( drag, iStartTime );
+                iIsFlicking = ETrue;
+                iIsDragging = EFalse;
+                }
+    		break;
+    		}
+    	
+    	case TPointerEvent::EDrag:
+    		{
+            if ( !iIsDragging )
+                {
+                TInt drag( iOriginalPosition.iY - aPointerEvent.iPosition.iY );
+                if ( Abs( drag ) > iPhysics->DragThreshold() )
+                    {
+					// If user started dragging, cancel hotspot actions
+					iIsDragging = ETrue;
+					iMessageField->SetPhysicsEmulationOngoing( ETrue );
+					iReadOnlyQuoteField->SetPhysicsEmulationOngoing( ETrue );
+					iHeader->SetPhysicsEmulationOngoing( ETrue );
+                    }
+                }
+
+            // Get current pointer position
+            TPoint position = aPointerEvent.iPosition;
+
+
+           if( iPhysics )
+               {
+			   if ( iIsDragging )
+				   {
+                    TPoint delta( 0, iPreviousPosition.iY - position.iY );
+                    if ( !iMessageField->SelectionLength() )
+                    		iPhysics->RegisterPanningPosition( delta );
+				   }
+                }
+            else
+                {
+    			TInt topPosition( -iHeader->Position().iY );
+    						
+    			TInt totalHeight( ContentTotalHeight() );
+
+    			TInt areaHeight( Rect().Size().iHeight );
+    			TInt scrollOffset( 0 );
+    			
+				if( totalHeight > areaHeight )
+					{
+					// Calculate new scroll offset based on current and
+					// previous Y-positions
+					scrollOffset = topPosition + 
+                        ( iPreviousPosition.iY - position.iY );
+					// Ensure that thumb position is in correct range
+					scrollOffset = Max( scrollOffset, 0 );
+					scrollOffset = Min( scrollOffset, 
+                                        totalHeight - areaHeight );
+					}
+
+				Scroll( scrollOffset );
+				}
+           
+			// Save current position as previous pos for future calculations
+			iPreviousPosition = position;  
+			
+			break;
+    		}
+    		
+    	default:
+    		{
+    		// unknown event, ignored
+    		break;
+    		}
+    	}
+    	
+    if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
+         iHeader->NeedsLongTapL( aPointerEvent.iPosition ) )
+        {
+        iLongTapDetector->PointerEventL( aPointerEvent );
+        }
+
+    CCoeControl::HandlePointerEventL( aPointerEvent );
+	if (clearSelection)
+		{
+		iMessageField->ClearSelectionL();
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::OfferKeyEventL()
+// Handles key events
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CNcsComposeViewContainer::OfferKeyEventL( 
+        const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    FUNC_LOG;
+
+    if( iPhysics )
+        {
+        iPhysics->StopPhysics();
+        iPhysics->ResetFriction();
+        }
+
+    TKeyResponse ret( EKeyWasNotConsumed );
+
+    //we are allowing to change MSK label 
+    SwitchChangeMskOff( EFalse );
+    
+    if ( aKeyEvent.iCode == EKeyYes )
+        {
+        // check that at least one of the address fields has an address
+        if ( !iHeader->AreAddressFieldsEmpty() )
+            {
+            iView.HandleCommandL( ENcsCmdSend );
+            }
+        else
+            {
+            AppendAddressesL();
+            }
+        ret = EKeyWasConsumed;
+        }
+    else if ( aKeyEvent.iCode == EKeyOK )
+    	{
+        if ( iHeader->IsPopupActive() )
+            {
+            DoPopupSelectL();
+            ret = EKeyWasConsumed;
+            }
+        else if ( AppendAddressesL() )
+            {
+            ret = EKeyWasConsumed;
+            }
+        }
+    else if ( aKeyEvent.iScanCode == 'S' &&
+              aKeyEvent.iModifiers & EModifierCtrl &&
+              aType == EEventKey )
+        {
+        iView.HandleCommandL( ENcsCmdSaveDraft );
+        ret = EKeyWasConsumed;
+        }
+    else if ( aKeyEvent.iCode == EKeyUpArrow || 
+              aKeyEvent.iCode == EKeyDownArrow )
+        {
+        ret = iFocused->OfferKeyEventL( aKeyEvent, aType );
+
+        if ( ret == EKeyWasNotConsumed )
+            {
+            ret = ChangeFocusL( aKeyEvent );
+            }
+
+        if ( ret != EKeyWasConsumed )
+            {
+            DrawDeferred();
+            }
+        }
+
+    if ( ret == EKeyWasNotConsumed )
+        {
+        if ( iFocused )
+            ret = iFocused->OfferKeyEventL( aKeyEvent, aType );
+
+        iView.HandleContainerChangeRequiringToolbarRefresh();
+        
+        // Report user activity to auto saver if editor field handled the
+        // event. In case of message field (body text), EKeyWasConsumed
+        // condition does not come true because AknFep consumes EKeyEvent
+        // and calls HandleEdwinEventL. This OfferKeyEventL gets only
+        // EEventKeyUp and EEventKeyDown events. Thus, when typing body text,
+        // autosaver is notified in HandleEdwinEventL()
+        if ( ( ret == EKeyWasConsumed ) && ( iFocused != iMessageField ) )
+            {
+            iAutoSaver.ReportActivity();
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::UpdateScreenPositionL()
+// If the user scrolled down in the message field
+// we want to scroll up the header and grow the message field.
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::UpdateScreenPositionL( 
+        const TUint& /*aKeyCode*/ )
+    {
+    FUNC_LOG;
+
+    // get screen rectangle
+    const TRect screenRect( Rect() );
+
+    TPoint msgPos( iMessageField->Position() );
+    TPoint quotePos( iReadOnlyQuoteField->Position() );
+
+    // find out cursor position in absolute coordinates
+    TRect lineRect;
+    if ( iFocused == iMessageField )
+        {
+        iMessageField->GetLineRectL( lineRect );
+        lineRect.Move( msgPos );
+        }
+    else if ( iFocused == iReadOnlyQuoteField )
+        {
+        iReadOnlyQuoteField->GetLineRectL( lineRect );
+        lineRect.Move( quotePos );
+        }
+    else
+        {
+        // This function should be used only when focus is in body or
+        // read-only quote
+        return;
+        }
+    TPoint linePos = lineRect.iTl;
+
+    TInt minTargetY = lineRect.Height();
+    TInt maxTargetY = screenRect.Height() - lineRect.Height() * 2;
+
+    TInt moveY = 0;
+    // if cursor goes out of screen then move the controls
+    if ( linePos.iY > maxTargetY )
+        {
+        moveY = maxTargetY - linePos.iY;
+        }
+    else if ( linePos.iY < minTargetY )
+        {
+        moveY = minTargetY - linePos.iY;
+        }
+
+    // Check we don't scroll too low
+    if ( quotePos.iY + moveY + iReadOnlyQuoteField->Size().iHeight < 
+         screenRect.Height() )
+        {
+        moveY = screenRect.Height() - quotePos.iY - 
+            iReadOnlyQuoteField->Size().iHeight;
+        }
+
+    // Check we don't scroll too high
+    TPoint headerPos = iHeader->Position();
+    if ( headerPos.iY + moveY > 0 )
+        {
+        moveY = -headerPos.iY;
+        }
+
+    if ( moveY )
+        {
+        headerPos.iY += moveY;
+        iHeader->SetPosition( headerPos );
+
+        msgPos.iY += moveY;
+        iMessageField->SetPosition( msgPos );
+
+        quotePos.iY += moveY;
+        iReadOnlyQuoteField->SetPosition( quotePos );
+
+        iSeparatorLineYPos += moveY;
+        UpdateScrollBar();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::UpdateFieldPosition
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::UpdateFieldPosition( CCoeControl* aAnchor )
+    {
+    FUNC_LOG;
+
+    // We may not be completely constructed
+    if ( iHeader && iMessageField && iReadOnlyQuoteField )
+        {
+        // First, move all the controls in the header
+        iHeader->UpdateFieldPosition( aAnchor );
+
+        // Then, move the body field below the header
+        TRect headerRect = iHeader->Rect();
+
+        const TSize separatorSize( 
+            NcsUtility::SeparatorSizeInThisResolution() );
+        iSeparatorLineYPos = headerRect.iBr.iY;
+
+        TPoint bodyPos( iMessageField->Position() );
+        bodyPos.iY = iSeparatorLineYPos + separatorSize.iHeight;
+        iMessageField->SetPosition( bodyPos );
+
+        TPoint quotePos( iReadOnlyQuoteField->Position() );
+        quotePos.iY = iMessageField->Rect().iBr.iY;
+        iReadOnlyQuoteField->SetPosition( quotePos );
+
+        UpdateScrollBar();
+        DrawDeferred();
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ChangeFocusL()
+// Handles key events
+// -----------------------------------------------------------------------------
+//
+
+TKeyResponse CNcsComposeViewContainer::ChangeFocusL( 
+        const TKeyEvent& aKeyEvent )
+    {
+    FUNC_LOG;
+
+    TKeyResponse ret( EKeyWasNotConsumed );
+
+    if ( iFocused == iReadOnlyQuoteField && aKeyEvent.iCode == EKeyUpArrow )
+        {
+        iFocused = iMessageField;
+        iReadOnlyQuoteField->SetFocus( EFalse, ENoDrawNow );
+        iMessageField->SetFocus( ETrue, ENoDrawNow );
+        ret = EKeyWasConsumed;
+        }
+    else if ( iFocused == iMessageField )
+        {
+        if ( aKeyEvent.iCode == EKeyUpArrow )
+            {
+            iFocused = iHeader;
+            iHeader->SetFocus( ETrue, ENoDrawNow );
+            iMessageField->SetFocus( EFalse, ENoDrawNow );
+            iHeader->MakeVisible( ETrue );
+            iHeader->ShowCursor( ETrue );
+            CommitL( EBodyField );
+            ret = EKeyWasConsumed;
+            }
+        else if ( aKeyEvent.iCode == EKeyDownArrow && 
+                  iReadOnlyQuoteField->TextLength() )
+            {
+            // Focus move to read-only quote only if there is some text in it.
+            iFocused = iReadOnlyQuoteField;
+            iReadOnlyQuoteField->SetFocus( ETrue, ENoDrawNow );
+            iMessageField->SetFocus( EFalse, ENoDrawNow );
+            iReadOnlyQuoteField->SetCursorPosL( 0, EFalse );
+            ret = EKeyWasConsumed;
+            }
+        }
+    else if ( iFocused == iHeader && aKeyEvent.iCode == EKeyDownArrow )
+        {
+        iFocused = iMessageField;
+        iHeader->SetFocus( EFalse, ENoDrawNow );
+        iMessageField->SetFocus( ETrue, ENoDrawNow );
+        iMessageField->SetCursorPosL( 0, EFalse );
+        ret = EKeyWasConsumed;
+        }
+
+    if ( ret == EKeyWasConsumed )
+        {
+        UpdateScreenPositionL( aKeyEvent.iCode );
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::UpdateFieldSizeL()
+// This is called through MNcsFieldSizeObserver when the rects have changed
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::UpdateFieldSizeL( TBool aDoScroll )
+    {
+    FUNC_LOG;
+
+    // We may not have finished construction
+    if ( iHeader && iMessageField && iReadOnlyQuoteField && !aDoScroll )
+        {
+        SizeChanged();
+        }
+    if ( iHeader && aDoScroll )
+        {
+        iHeader->DoScroll();
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SizeChanged()
+// set size
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SizeChanged()
+    {
+    FUNC_LOG;
+
+    const TRect rect( Rect() );
+    iScrollBar->SetRect( NcsUtility::ListCmailScrollbarRect( rect ) );
+    TRect cmailPaneRect( NcsUtility::ListCmailPaneRect( rect ) );
+
+    const TInt headerLineCount( iHeader->LayoutLineCount() );
+    const TPoint headerPos( 
+            NcsUtility::HeaderControlPosition( cmailPaneRect, 0 ) );
+    cmailPaneRect.Move( 0, iHeader->Position().iY - headerPos.iY );
+    iCmailPaneRect = cmailPaneRect;
+
+    NcsUtility::LayoutHeaderControl( 
+            iHeader, cmailPaneRect, 0, headerLineCount );
+
+    // do not used stored headerLineCount, because relayout above may grow or
+    // shrink edit fields
+    NcsUtility::LayoutBodyEdwin( 
+            iMessageField, cmailPaneRect, iHeader->LayoutLineCount(), 
+            iMessageField->LineCount(), iSeparatorLineYPos );
+    iMessageField->SetAlignment( EAknEditorAlignBidi );
+    
+    // we don't need format again when format was already done
+    // during creation of forward/reply message
+    if ( !iSwitchOffFormattingText )
+        {
+        TRAP_IGNORE( iMessageField->FormatAllTextNowL() );
+        }
+
+    iMessageField->UpdateFontSize();
+
+    TInt readOnlyQuoteFieldHeight( 0 );
+    if ( iReadOnlyQuoteField->TextLength() )
+        {
+        TInt dummySeparatorPos;
+        NcsUtility::LayoutBodyEdwin(
+                iReadOnlyQuoteField, cmailPaneRect, 
+                iHeader->LayoutLineCount() + iMessageField->LineCount(), 
+                iReadOnlyQuoteField->LineCount(), dummySeparatorPos );
+        iReadOnlyQuoteField->SetAlignment( EAknEditorAlignBidi );
+        // we don't need format again when format was already done
+		// during creation of forward/reply message
+        if ( !iSwitchOffFormattingText )
+            {
+            TRAP_IGNORE( iReadOnlyQuoteField->FormatAllTextNowL() );
+            }
+        iReadOnlyQuoteField->UpdateFontSize();
+        readOnlyQuoteFieldHeight = iReadOnlyQuoteField->Rect().Height();
+        }
+
+    iBgContext->SetRect( Rect() );
+    iMessageField->SetRealRect( Rect() );
+    iReadOnlyQuoteField->SetRealRect( Rect() );
+
+    TInt messageLineHeigth = 
+        NcsUtility::HeaderCaptionPaneRect( cmailPaneRect ).Height();
+    iSeparatorHeight = NcsUtility::SeparatorSizeInThisResolution().iHeight;
+    iMessageEditorMinHeigth = 
+        cmailPaneRect.Height() - iHeader->Size().iHeight -
+        iSeparatorHeight -
+        readOnlyQuoteFieldHeight;
+    
+    iMessageEditorMinHeigth -= iMessageEditorMinHeigth % messageLineHeigth;
+    if ( iMessageEditorMinHeigth > messageLineHeigth )
+        {
+        TSize newSize( iMessageField->Size().iWidth,
+                       Max( iMessageField->Size().iHeight, 
+                            iMessageEditorMinHeigth ) );
+
+        if ( !iSwitchOffFormattingText ) 
+            {
+            iMessageField->SetSize( newSize );
+            }
+        }
+    else
+        {
+        iMessageEditorMinHeigth = messageLineHeigth;
+        }
+
+	// update some layout variables
+    iHeaderHeight = iHeader->Rect().Height();
+    TRect bodyRect = iMessageField->Rect();
+    TRect quoteRect = iReadOnlyQuoteField->Rect();
+
+    iTotalComposerHeight = iHeaderHeight + iSeparatorHeight * 2 + 
+							   bodyRect.Height() + quoteRect.Height();
+    
+    iVisibleAreaHeight = Rect().Height();
+        
+    UpdateScrollBar();
+
+    iScrollBarModel.SetScrollSpan( iTotalComposerHeight );
+    iScrollBarModel.SetWindowSize( iVisibleAreaHeight );
+    DrawDeferred();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::Draw() const
+// Draws the display
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::Draw( const TRect& aRect ) const
+    {
+    FUNC_LOG;
+
+    CWindowGc& gc = SystemGc();
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    if ( skin )
+        {
+        AknsDrawUtils::Background( skin, iBgContext, this, gc, aRect );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetBodyContentL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetBodyContentL( const TDesC& aMessage,
+    const TDesC& aReadOnlyQuote )
+    {
+    FUNC_LOG;
+    delete iReadOnlyQuote;
+    iReadOnlyQuote = NULL;
+    if ( aReadOnlyQuote.Length() )
+        {
+        iReadOnlyQuote = aReadOnlyQuote.AllocL();
+        }
+
+    RMemReadStream inputStream( aMessage.Ptr(), aMessage.Size() );
+    CleanupClosePushL( inputStream );
+    iMessageField->RichText()->ImportTextL( 0, inputStream,
+        CPlainText::EOrganiseByParagraph );
+    CleanupStack::PopAndDestroy( &inputStream );
+
+    // Activating the field will set the control to the end of the text
+    iMessageField->ActivateL();
+    iMessageField->SetCursorPosL( 0, EFalse );
+	iMessageField->FormatAllTextNowL();
+
+    inputStream.Open( aReadOnlyQuote.Ptr(), aReadOnlyQuote.Size() );
+    CleanupClosePushL( inputStream );
+    iReadOnlyQuoteField->RichText()->ImportTextL( 0, inputStream,
+        CPlainText::EOrganiseByParagraph );
+    CleanupStack::PopAndDestroy( &inputStream );
+
+    // Activating the field will set the control to the end of the text
+    iReadOnlyQuoteField->ActivateL();
+    iReadOnlyQuoteField->SetCursorPosL( 0, EFalse );
+
+    // Recalculate the size of the body field
+    SizeChanged();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetBodyContentAsyncL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetBodyContentAsyncL( const TDesC& aMessage,
+    const TDesC& aReadOnlyQuote )
+    {
+    FUNC_LOG;
+    delete iReadOnlyQuote;
+    iReadOnlyQuote = NULL;
+    if ( aReadOnlyQuote.Length() )
+        {
+        iReadOnlyQuote = aReadOnlyQuote.AllocL();
+        }
+
+    RMemReadStream inputStream( aMessage.Ptr(), aMessage.Size() );
+    CleanupClosePushL( inputStream );
+    iMessageField->RichText()->ImportTextL( 0, inputStream,
+        CPlainText::EOrganiseByParagraph );
+    CleanupStack::PopAndDestroy( &inputStream );
+    
+
+    // Activating the field will set the control to the end of the text
+    iMessageField->ActivateL();
+    iMessageField->SetCursorPosL( 0, EFalse );
+    
+    iProcessedField = iMessageField;
+    
+	iAsyncTextFormatter = CFSAsyncTextFormatter::NewL();
+    iAsyncTextFormatter->StartFormatting( iMessageField->TextLayout(), this );
+        
+    // callback from AO: FormatAllTextCompleteL
+}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::FormatAllTextCancelled()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::FormatAllTextCancelled()
+	{
+	iView.SetBodyContentComplete();
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::FormatAllTextComplete()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::FormatAllTextComplete()
+	{
+    if ( iReadOnlyQuote && iProcessedField == iMessageField )
+        {
+        iProcessedField = iReadOnlyQuoteField;
+        if ( iReadOnlyQuote )
+            {
+			TInt dummySeparatorPos;
+			NcsUtility::LayoutBodyEdwin( iReadOnlyQuoteField, iCmailPaneRect, 
+					iHeader->LayoutLineCount() + iMessageField->LineCount(),
+					iReadOnlyQuoteField->LineCount(), dummySeparatorPos );
+            iReadOnlyQuoteField->SetAlignment( EAknEditorAlignBidi );
+            
+			RMemReadStream inputStream;
+            inputStream.Open( iReadOnlyQuote->Ptr(), iReadOnlyQuote->Size() );
+            TRAP_IGNORE( iReadOnlyQuoteField->RichText()->ImportTextL( 0, inputStream,
+                    CPlainText::EOrganiseByParagraph ) );
+            inputStream.Close();
+            
+            // Activating the field will set the control to the end of the text
+            TRAP_IGNORE( iReadOnlyQuoteField->ActivateL() );
+            TRAP_IGNORE( iReadOnlyQuoteField->SetCursorPosL( 0, EFalse ) );
+            
+            if ( !iAsyncTextFormatter )
+                {
+                TRAP_IGNORE( iAsyncTextFormatter = CFSAsyncTextFormatter::NewL() );
+                }
+            iAsyncTextFormatter->StartFormatting( 
+                    iReadOnlyQuoteField->TextLayout(), this );
+            }
+        }
+    else
+        {
+        // Recalculate the size of the body field
+        iSwitchOffFormattingText = ETrue;
+        SizeChanged();
+        iSwitchOffFormattingText = EFalse;
+        
+        iView.SetBodyContentComplete();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetBodyContentLC()
+// -----------------------------------------------------------------------------
+//
+HBufC* CNcsComposeViewContainer::GetBodyContentLC()
+    {
+    FUNC_LOG;
+    HBufC* body = NULL;
+
+    TInt messageLength = iMessageField->TextLength();
+    HBufC* message = HBufC::NewLC( messageLength );
+    TPtr messagePtr = message->Des();
+    iMessageField->GetText( messagePtr );
+
+    CleanupStack::Pop();
+    CleanupStack::PushL( message );
+    messageLength = message->Length();
+
+    // Append read-only quote if present
+    if ( iReadOnlyQuote )
+        {
+        TInt quoteLength = iReadOnlyQuote->Length();
+        TInt length = messageLength + KIMSLineFeed().Length() + quoteLength;
+        body = message->ReAllocL( length );
+        CleanupStack::Pop( message );
+        CleanupStack::PushL( body );
+
+        TPtr bodyPtr = body->Des();
+        bodyPtr.Append( KIMSLineFeed() );
+        bodyPtr.Append( *iReadOnlyQuote );
+        }
+    else
+        {
+        body = message;
+        }
+
+    return body;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::BodyText()
+// -----------------------------------------------------------------------------
+//
+CRichText& CNcsComposeViewContainer::BodyText()
+    {
+    FUNC_LOG;
+    return *iMessageField->RichText();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleScrollEventL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandleScrollEventL( 
+        CEikScrollBar* aScrollBar, TEikScrollEvent /*aEventType*/ )
+    {
+    FUNC_LOG;
+    
+    if( iPhysics )
+        {
+        iPhysics->StopPhysics();
+        iPhysics->ResetFriction();
+        }
+        
+    ClosePopupContactListL();
+
+    Scroll( aScrollBar->ThumbPosition() );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::OperationCompleteL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::OperationCompleteL( TContactHandlerCmd /*aCmd*/,
+    const RPointerArray<CFSEmailUiClsItem>& aContacts )
+	{
+    FUNC_LOG;
+	if ( aContacts.Count() )
+		{
+		RPointerArray<CNcsEmailAddressObject> ncsObjects;
+		CleanupResetAndDestroyClosePushL( ncsObjects );
+
+		for ( TInt i = 0 ; i < aContacts.Count() ; i++ )
+			{
+			CNcsEmailAddressObject* object = 
+                CNcsEmailAddressObject::NewL( aContacts[i]->DisplayName(),
+					aContacts[i]->EmailAddress() );
+			if ( aContacts[i]->MultipleEmails() )
+				{
+
+				object->SetDisplayFull( ETrue );
+				}
+			CleanupStack::PushL( object );
+			ncsObjects.AppendL( object );
+			CleanupStack::Pop( object );
+			}
+
+		if ( iAppendAddresses == EAppendTo )
+			{
+			AppendToFieldAddressesL( ncsObjects );
+			}
+		// if Cc field is focused insert addresses in there
+		else if ( iAppendAddresses == EAppendCc )
+			{
+			AppendCcFieldAddressesL( ncsObjects );
+			}
+		// if Bcc field is focused insert addresses in there
+		else if ( iAppendAddresses == EAppendBcc )
+			{
+			AppendBccFieldAddressesL( ncsObjects );
+			}
+
+		CleanupStack::PopAndDestroy( &ncsObjects );
+		}
+	iView.HandleContainerChangeRequiringToolbarRefresh();
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::OperationErrorL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::OperationErrorL( 
+        TContactHandlerCmd, TInt /*aError*/ )
+	{
+    FUNC_LOG;
+	//Nothing to do
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleEdwinEventL
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandleEdwinEventL( CEikEdwin* aEdwin,
+    TEdwinEvent aEventType )
+    {
+    FUNC_LOG;
+    if (( aEdwin == iMessageField || aEdwin == iReadOnlyQuoteField ) && 
+         ( !iPhysics || iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionNone ))
+        {
+        if ( aEventType == MEikEdwinObserver::EEventTextUpdate ||
+             aEventType == MEikEdwinObserver::EEventNavigation )
+            {
+            iAutoSaver.ReportActivity();
+
+            // Update screen position and scroll bar when text changed
+            // or cursor moved
+            UpdateScreenPositionL();
+            UpdateScrollBar();
+            DrawDeferred();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleEdwinSizeEventL
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::HandleEdwinSizeEventL( CEikEdwin* aEdwin,
+        TEdwinSizeEvent /*aEventType*/, TSize aDesirableEdwinSize )
+    {
+    FUNC_LOG;
+    TBool ret = ETrue;
+    
+    const TRect rect( Rect() );
+    TRect cmailPaneRect( NcsUtility::ListCmailPaneRect( rect ) );
+
+    if ( aDesirableEdwinSize.iHeight < iPrevDesiredHeigth )
+        {
+        if ( aDesirableEdwinSize.iHeight < iMessageEditorMinHeigth )
+            {
+            Scroll( 0 );
+            }
+        }
+
+    if ( aEdwin == iMessageField ) 
+        {
+        if ( aDesirableEdwinSize.iHeight >= iMessageEditorMinHeigth )
+            {
+            if ( !iSwitchOffFormattingText )
+                {
+                aEdwin->SetSize( aDesirableEdwinSize );
+                }
+            }        
+        }
+    else
+        {
+        if ( !iSwitchOffFormattingText )
+            {
+            aEdwin->SetSize( aDesirableEdwinSize );
+            }
+        }
+    if ( aEdwin == iMessageField )
+        {
+        // move the quote field below the body field
+        TPoint quotePos = iMessageField->Position();
+        quotePos.iY += iMessageField->Size().iHeight;
+        iReadOnlyQuoteField->SetPosition( quotePos );
+		UpdateScreenPositionL(); 
+        }
+
+    iPrevDesiredHeigth = aDesirableEdwinSize.iHeight;
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::MopSupplyObject
+// From CCoeControl.
+// -----------------------------------------------------------------------------
+//
+TTypeUid::Ptr CNcsComposeViewContainer::MopSupplyObject( TTypeUid aId )
+    {
+    FUNC_LOG;
+    if ( aId.iUid == MAknsControlContext::ETypeId )
+        {
+        return MAknsControlContext::SupplyMopObject( aId, iBgContext );
+        }
+    return CCoeControl::MopSupplyObject( aId );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::UpdateScrollBar()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::UpdateScrollBar()
+    {
+    FUNC_LOG;
+
+    TRect headerRect = iHeader->Rect();
+    TInt visiblePosition = -headerRect.iTl.iY;
+
+    iScrollBarModel.SetFocusPosition( visiblePosition );
+
+    iScrollBar->SetModel( &iScrollBarModel );
+    iScrollBar->MakeVisible( IsVisible() );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetFocusToMessageFieldL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetFocusToMessageFieldL()
+    {
+    FUNC_LOG;
+
+    if( iFocused != iMessageField )
+        {
+        iHeader->SetFocus( EFalse, ENoDrawNow );
+        iMessageField->SetCursorPosL( 0, EFalse );
+        iMessageField->SetFocus( ETrue, ENoDrawNow );
+        iFocused = iMessageField;
+        UpdateScreenPositionL();
+        DrawDeferred();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AddQuickTextL()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::AddQuickTextL( const TDesC& aText )
+    {
+    FUNC_LOG;
+
+    // If in 'To' field, go to msg. field
+    if( !iMessageField->IsFocused() )
+    	{
+    	SetFocusToMessageFieldL();
+    	}
+	TInt pos = iMessageField->CursorPos();
+	TCursorSelection selIns( pos, pos );
+	iMessageField->InsertDeleteCharsL( pos, aText, selIns );
+	// Fix for error EFTG-7Y63XG, moving cursor to the end of inserted text
+	pos += aText.Length();
+	iMessageField->SetCursorPosL( pos, EFalse );
+	DrawDeferred();
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SelectAllToFieldTextL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SelectAllToFieldTextL()
+	{
+    FUNC_LOG;
+
+	iHeader->SelectAllToFieldTextL();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SelectAllCcFieldTextL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SelectAllCcFieldTextL()
+	{
+    FUNC_LOG;
+
+	iHeader->SelectAllCcFieldTextL();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SelectAllBccFieldTextL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SelectAllBccFieldTextL()
+	{
+    FUNC_LOG;
+
+	iHeader->SelectAllBccFieldTextL();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SelectAllSubjectFieldTextL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SelectAllSubjectFieldTextL()
+	{
+    FUNC_LOG;
+
+	iHeader->SelectAllSubjectFieldTextL();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsSubjectFieldEmpty
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsSubjectFieldEmpty()
+    {
+    FUNC_LOG;
+    return iHeader->IsSubjectFieldEmpty();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AppendAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::AppendAddressesL()
+	{
+    FUNC_LOG;
+
+    iContactHandler = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
+    if ( iContactHandler )
+        {
+        iContactHandler->GetAddressesFromPhonebookL( this );
+        }
+    
+	if ( IsFocusCc() )
+		{
+		iAppendAddresses = EAppendCc;
+		}
+	else if ( IsFocusBcc() )
+		{
+		iAppendAddresses = EAppendBcc;
+		}
+	else
+		{
+		iAppendAddresses = EAppendTo;
+		}
+
+    return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleAttachmentsOpenCommand
+// If attachment header field is focused and open key is pressed
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandleAttachmentsOpenCommandL()
+	{
+    FUNC_LOG;
+
+	iView.HandleCommandL( EFsEmailUiCmdOpenAttachment );
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::LaunchStylusPopupMenu
+// Called when long tap happens in the attachments field
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::LaunchStylusPopupMenu( const TPoint& aPenEventScreenLocation )
+    {
+    FUNC_LOG;
+    iView.LaunchStylusPopupMenu( aPenEventScreenLocation );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetToFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CNcsEmailAddressObject>& 
+CNcsComposeViewContainer::GetToFieldAddressesL( TBool aParseNow )
+    {
+    return iHeader->GetToFieldAddressesL( aParseNow );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetCcFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CNcsEmailAddressObject>& 
+CNcsComposeViewContainer::GetCcFieldAddressesL( TBool aParseNow )
+    {
+    return iHeader->GetCcFieldAddressesL( aParseNow );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetBccFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CNcsEmailAddressObject>& 
+CNcsComposeViewContainer::GetBccFieldAddressesL( TBool aParseNow )
+    {
+    return iHeader->GetBccFieldAddressesL( aParseNow );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetSubjectLC
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* CNcsComposeViewContainer::GetSubjectLC() const
+    {
+    FUNC_LOG;
+	return iHeader->GetSubjectLC();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsBccFieldVisible
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsBccFieldVisible() const
+    {
+    FUNC_LOG;
+    return iHeader->IsBccFieldVisible();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsCcFieldVisible
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsCcFieldVisible() const
+    {
+    FUNC_LOG;
+    return iHeader->IsCcFieldVisible();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsFocusAttachments
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsFocusAttachments() const
+    {
+    FUNC_LOG;
+    return iHeader->IsFocusAttachments();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsFocusTo
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsFocusTo() const
+    {
+    FUNC_LOG;
+    return iHeader->IsFocusTo();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsFocusCc
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsFocusCc() const
+    {
+    FUNC_LOG;
+    return iHeader->IsFocusCc();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsFocusBcc
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsFocusBcc() const
+    {
+    FUNC_LOG;
+    return iHeader->IsFocusBcc();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetCcFieldLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetCcFieldLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetCcFieldLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetBccFieldLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetBccFieldLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetBccFieldLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetToFieldLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetToFieldLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetToFieldLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetSubjectFieldLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetSubjectFieldLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetSubjectFieldLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetMessageFieldLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetMessageFieldLength() const
+    {
+    FUNC_LOG;
+	return iMessageField->TextLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetAttachmentCount
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetAttachmentCount() const
+    {
+    FUNC_LOG;
+    TInt count = iView.AttachmentsListControl()->Model()->Count();
+	return count;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HasRemoteAttachments
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::HasRemoteAttachments() const
+    {
+    FUNC_LOG;
+    TBool ret = iView.AttachmentsListControl()->Model()->HasRemoteAttachments();
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetLookupTextLC
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* CNcsComposeViewContainer::GetLookupTextLC() const
+    {
+    FUNC_LOG;
+	return iHeader->GetLookupTextLC();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetToFieldSelectionLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetToFieldSelectionLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetToFieldSelectionLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetCcFieldSelectionLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetCcFieldSelectionLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetCcFieldSelectionLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::GetBccFieldSelectionLength
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::GetBccFieldSelectionLength() const
+    {
+    FUNC_LOG;
+	return iHeader->GetBccFieldSelectionLength();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetMenuBar
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetMenuBar( CEikButtonGroupContainer* aMenuBar )
+    {
+    FUNC_LOG;
+
+	iHeader->SetMenuBar(aMenuBar);
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetToFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetToFieldAddressesL( 
+        RPointerArray<CNcsEmailAddressObject>& aAddress )
+    {
+    FUNC_LOG;
+
+    iHeader->SetToFieldAddressesL(aAddress);
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetCcFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetCcFieldAddressesL( 
+        RPointerArray<CNcsEmailAddressObject>& aAddress )
+    {
+    FUNC_LOG;
+
+    iHeader->SetCcFieldAddressesL( aAddress );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetBccFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetBccFieldAddressesL( 
+        RPointerArray<CNcsEmailAddressObject>& aAddress )
+    {
+    FUNC_LOG;
+
+    iHeader->SetBccFieldAddressesL( aAddress );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AppendToFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::AppendToFieldAddressesL( RPointerArray<CNcsEmailAddressObject>& aAddresses )
+    {
+    FUNC_LOG;
+    FixSemicolonL();
+    iHeader->AppendToFieldAddressesL(aAddresses);
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AppendCcFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::AppendCcFieldAddressesL( RPointerArray<CNcsEmailAddressObject>& aAddress )
+    {
+    FUNC_LOG;
+    FixSemicolonL();
+    iHeader->AppendCcFieldAddressesL( aAddress );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AppendBccFieldAddressesL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::AppendBccFieldAddressesL( RPointerArray<CNcsEmailAddressObject>& aAddress )
+    {
+    FUNC_LOG;
+    FixSemicolonL();
+    iHeader->AppendBccFieldAddressesL( aAddress );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetSubjectL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetSubjectL( const TDesC& aSubject )
+    {
+    FUNC_LOG;
+
+    iHeader->SetSubjectL( aSubject );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetAttachmentLabelTextsLD
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetAttachmentLabelTextsLD( 
+    CDesCArray* aAttachmentNames, CDesCArray* aAttachmentSizes )
+    {
+    FUNC_LOG;   
+    iHeader->SetAttachmentLabelTextsLD( aAttachmentNames, aAttachmentSizes );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::FocusedAttachmentLabelIndex
+//
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::FocusedAttachmentLabelIndex()
+    {
+    FUNC_LOG;   
+    return iHeader->FocusedAttachmentLabelIndex();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HideAttachmentLabel
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HideAttachmentLabel()
+    {
+    FUNC_LOG;
+
+	iHeader->HideAttachmentLabel();
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetCcFieldVisibleL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetCcFieldVisibleL( TBool aVisible, TBool aFocus )
+	{
+    FUNC_LOG;
+
+	if ( aFocus )
+		{
+		iMessageField->SetCursorPosL( 0,EFalse );
+		iMessageField->SetFocus( EFalse );
+		iHeader->MakeVisible( ETrue );
+		iHeader->SetFocus( ETrue );
+		iFocused = iHeader;
+		}
+	iHeader->SetCcFieldVisibleL( aVisible, EDrawNow, aFocus );
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetBccFieldVisibleL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetBccFieldVisibleL( TBool aVisible, TBool aFocus )
+	{
+    FUNC_LOG;
+
+	if ( aFocus )
+		{
+		iMessageField->SetCursorPosL( 0, EFalse );
+		iMessageField->SetFocus( EFalse );
+		iHeader->MakeVisible( ETrue );
+		iHeader->SetFocus( ETrue );
+		iFocused = iHeader;
+		}
+	iHeader->SetBccFieldVisibleL( aVisible, EDrawNow, aFocus );
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IncludeAddressL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::IncludeAddressL(const CNcsEmailAddressObject& eml)
+    {
+    FUNC_LOG;
+
+	iHeader->IncludeAddressL(eml);
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IncludeAddressL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::IncludeAddressL()
+    {
+    FUNC_LOG;
+
+	iHeader->IncludeAddressL();
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ClosePopupContactListL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::ClosePopupContactListL()
+    {
+    FUNC_LOG;
+
+	iHeader->ClosePopupContactListL();
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::DeleteSelectionL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::DeleteSelectionL()
+    {
+    FUNC_LOG;
+
+	iHeader->DeleteSelectionL();
+
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetFocusToToField
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetFocusToToField()
+	{
+    FUNC_LOG;
+
+	iHeader->FocusToField();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SetFocusToAttachmentField
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::SetFocusToAttachmentField()
+	{
+    FUNC_LOG;
+
+	if ( iFocused == iMessageField )
+    	{
+		iFocused = iHeader;
+		iHeader->SetFocus( ETrue, EDrawNow );
+		iMessageField->SetFocus( EFalse, EDrawNow );
+		iHeader->MakeVisible( ETrue );
+    	}
+	iHeader->FocusAttachmentField();
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::AreAddressFieldsEmpty
+//
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::AreAddressFieldsEmpty()
+	{
+    FUNC_LOG;
+	return iHeader->AreAddressFieldsEmpty();
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::DoPopupSelectL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::DoPopupSelectL()
+	{
+    FUNC_LOG;
+
+	iHeader->DoPopupSelectL();
+
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleLayoutChangeL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandleLayoutChangeL()
+    {
+    FUNC_LOG;
+    SetRect( iView.ClientRect() );
+    if ( iHeader )
+        {
+        iHeader->HandleDynamicVariantSwitchL();
+        }
+    // force recalculation of the position of every component
+    UpdateFieldPosition( NULL );
+    UpdateScrollBar();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::HandleSkinChangeL
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::HandleSkinChangeL()
+    {
+    FUNC_LOG;
+    if ( iHeader )
+        {
+        iHeader->HandleSkinChangeL();
+        }
+
+    if ( iMessageField )
+        {
+        iMessageField->UpdateFontSize();
+        }
+
+    if ( iScrollBar )
+        {
+        iScrollBar->HandleResourceChange( KAknsMessageSkinChange );
+        iScrollBar->DrawNow();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ContentTotalHeight
+// Return the total height of the components shown in the view
+// -----------------------------------------------------------------------------
+//
+TInt CNcsComposeViewContainer::ContentTotalHeight()
+    {
+    FUNC_LOG;	
+	TInt totalHeight( iHeader->Size().iHeight + 
+	                  iSeparatorHeight * 2 + 
+					  iMessageField->Size().iHeight );
+
+	if( iReadOnlyQuoteField->IsVisible() )
+		{
+		totalHeight += iReadOnlyQuoteField->Size().iHeight;
+		}	
+	
+	return totalHeight;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::CommitL()
+//
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::CommitL( TFieldToCommit aFieldToCommit )
+    {
+    FUNC_LOG;
+    iView.CommitL( ETrue, aFieldToCommit );
+    iView.HandleContainerChangeRequiringToolbarRefresh();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::SwitchChangeMskOff
+// sets up iSwitchChangeMskOff falg, which disables changes of MSK label if
+// any popup dialog is open
+// -----------------------------------------------------------------------------
+void CNcsComposeViewContainer::SwitchChangeMskOff(TBool aTag)
+    {
+    FUNC_LOG;
+    iHeader->SwitchChangeMskOff( aTag );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsHeaderContainer::HandleLongTapEventL()
+// Handles key events
+// -----------------------------------------------------------------------------
+void CNcsComposeViewContainer::HandleLongTapEventL( 
+        const TPoint& aPenEventLocation, 
+        const TPoint& aPenEventScreenLocation )
+    {
+    FUNC_LOG;
+    iHeader->HandleLongTap( aPenEventLocation, aPenEventScreenLocation );
+    }
+
+
+void CNcsComposeViewContainer::FixSemicolonL()
+	{
+    FUNC_LOG;
+	iHeader->FixSemicolonInAddressFieldsL();
+	}
+
+// ---------------------------------------------------------------------------
+// CNcsComposeViewContainer::UpdatePhysicsL()
+// ---------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::UpdatePhysicsL()
+    {
+    FUNC_LOG;
+    if ( iPhysics )
+        {
+        const TSize viewSize( Rect().Size() );
+        // We must ensure that world size is at least the size of the view
+        const TSize worldSize( viewSize.iWidth, 
+                Max( ContentTotalHeight(), viewSize.iHeight ) );
+        iPhysics->InitPhysicsL( worldSize, viewSize, EFalse );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::Scroll()
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::Scroll( TInt aTargetPos, TBool aDrawNow )
+    {
+    FUNC_LOG;
+	TPoint headerPos( iHeader->Position() );
+	TInt moveY = -headerPos.iY - aTargetPos;
+	
+    if ( aDrawNow )
+    	{
+		moveY = iTotalMoveY + moveY;
+		iTotalMoveY = 0;
+		if ( moveY )
+			{
+			headerPos.iY += moveY;
+			iHeader->SetPosition( headerPos );
+
+			// set header invisible if it is not in visible area
+			// this is done to prevent drawing of header when it is not necessary
+            if ( headerPos.iY + iHeaderHeight <= KHeaderVisibilityThreshold && iHeader->IsVisible() )
+                {            
+                iHeader->MakeVisible( EFalse );
+                }
+            // set header visible if it is in visible area
+            else if ( headerPos.iY + iHeaderHeight > KHeaderVisibilityThreshold && !iHeader->IsVisible() ) 
+                {
+                iHeader->MakeVisible( ETrue );
+                }
+    
+			TPoint msgPos( iMessageField->Position() );
+			msgPos.iY += moveY;
+			iMessageField->SetPosition( msgPos );
+	
+			if( iReadOnlyQuoteField->IsVisible() )
+				{
+				TPoint readOnlyPos( iReadOnlyQuoteField->Position() );
+				readOnlyPos.iY += moveY;
+				iReadOnlyQuoteField->SetPosition( readOnlyPos );
+				}
+	
+			iSeparatorLineYPos += moveY;
+
+			UpdateScrollBar();
+			DrawDeferred();
+			}
+    	}
+    else
+    	{
+		iTotalMoveY += moveY;
+    	}    	
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ViewPositionChanged
+// From MAknPhysicsObserver
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::ViewPositionChanged(
+    const TPoint& aNewPosition, TBool aDrawNow, TUint /*aFlags*/ )
+    {
+    FUNC_LOG;
+    TInt scrollOffset = aNewPosition.iY - iVisibleAreaHeight / 2;
+
+    // when the composer view is overlapped by other view for instance task switcher or screensaver
+    // physics sends a faulty event to move the composer view down. 
+    // This action is ignored here.	
+    if (aNewPosition.iY != 0)
+        {
+        Scroll( scrollOffset, aDrawNow );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::PhysicEmulationEnded
+// From MAknPhysicsObserver
+// -----------------------------------------------------------------------------
+//
+void CNcsComposeViewContainer::PhysicEmulationEnded()
+    {
+    FUNC_LOG;
+    iIsFlicking = EFalse;
+    iMessageField->SetPhysicsEmulationOngoing( EFalse );
+    iReadOnlyQuoteField->SetPhysicsEmulationOngoing( EFalse );
+    iHeader->SetPhysicsEmulationOngoing( EFalse );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::ViewPosition
+// From MAknPhysicsObserver
+// -----------------------------------------------------------------------------
+//
+TPoint CNcsComposeViewContainer::ViewPosition() const
+    {
+    FUNC_LOG;
+    return TPoint(0, -iHeader->Position().iY  + iVisibleAreaHeight / 2 );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CNcsComposeViewContainer::IsRemoteSearchInprogress
+// -----------------------------------------------------------------------------
+//
+TBool CNcsComposeViewContainer::IsRemoteSearchInprogress() const
+    {
+    FUNC_LOG;
+    return iHeader->IsRemoteSearchInprogress();
+    }