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