meetingrequest/mrgui/src/cmrlistpane.cpp
branchRCL_3
changeset 25 3533d4323edc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/src/cmrlistpane.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,936 @@
+/*
+* Copyright (c) 2009 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:  List pane component for UI fields
+*
+*/
+#include "cmrlistpane.h"
+#include "mesmrfieldstorage.h"
+#include "mmrscrollbarobserver.h"
+#include "esmrdef.h"
+#include "cesmrfield.h"
+#include "cmrfieldcontainer.h"
+#include "cmrlistpanephysics.h"
+#include "nmrlayoutmanager.h"
+
+#include <eikscrlb.h>
+#include <AknUtils.h>
+#include <touchfeedback.h>
+
+//DEBUG
+#include "emailtrace.h"
+
+namespace { // codescanner::namespace
+
+const TInt KLongTapDelay( 700000 ); // 0,7 sec
+const TInt KLongTapAnimationDelay( 300000 ); // 0,3 sec
+
+// ----------------
+// IndexByFieldId
+// ----------------
+//
+TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
+                     TESMREntryFieldId aFieldId )
+    {
+    TInt index( KErrNotFound );
+    TInt count( aFactory.Count() );
+
+    for ( TInt i = 0; i < count; ++i )
+        {
+        if ( aFactory.Field( i )->FieldId() == aFieldId )
+            {
+            index = i;
+            break;
+            }
+        }
+
+    return index;
+    }
+}
+
+//----- MEMBER FUNCTIONS ----
+
+// ---------------------------------------------------------------------------
+// CMRListPane::CMRListPane
+// ---------------------------------------------------------------------------
+//
+CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
+                          TAknDoubleSpanScrollBarModel& aScrollModel,
+                          CAknDoubleSpanScrollBar& aScroll,
+                          MMRScrollBarObserver& aScrollBarObserver )
+    : iFactory( aFactory ),
+      iScrollModel( aScrollModel ),
+      iScroll( aScroll ),
+      iScrollBarObserver( aScrollBarObserver )
+    {
+    FUNC_LOG;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::~CMRListPane
+// ---------------------------------------------------------------------------
+//
+CMRListPane::~CMRListPane()
+    {
+    FUNC_LOG;
+    delete iLongtapDetector;
+    delete iPhysics;
+    delete iFieldContainer;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::NewL
+// ---------------------------------------------------------------------------
+//
+CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
+                                MESMRFieldStorage& aFactory,
+                                TAknDoubleSpanScrollBarModel& aScrollModel,
+                                CAknDoubleSpanScrollBar& aScroll,
+                                MMRScrollBarObserver& aScrollBarObserver )
+    {
+    FUNC_LOG;
+    CMRListPane* self = new( ELeave )CMRListPane(
+            aFactory,
+            aScrollModel,
+            aScroll,
+            aScrollBarObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL( aParent );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ConstructL( const CCoeControl& aParent )
+    {
+    FUNC_LOG;
+    CCoeControl::SetComponentsToInheritVisibility( ETrue );
+    SetContainerWindowL( aParent );
+
+    iLongtapDetector = CAknLongTapDetector::NewL( this );
+    iLongtapDetector->SetLongTapDelay( KLongTapDelay );
+    iLongtapDetector->SetTimeDelayBeforeAnimation( KLongTapAnimationDelay );
+
+    iFieldContainer = CMRFieldContainer::NewL( iFactory, *this );
+    iFieldContainer->SetFieldContainerObserver( this );
+
+    // Physics: Create physics
+    // Give pointer to control that should be able to flick/drag
+    iPhysics = CMRListPanePhysics::NewL( *this, *iFieldContainer, *this );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InitializeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InitializeL()
+    {
+    FUNC_LOG;
+    const TInt count( iFactory.Count() );
+    for ( TInt i = 0; i < count; i++ )
+        {
+        iFactory.Field(i)->InitializeL();
+        }
+    iClickedField = NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InternalizeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InternalizeL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+
+    iFactory.InternalizeL( aEntry );
+
+    // Record visible fields
+    RecordFields();
+
+    // This is called to make sure everything is drawn correctly
+    DrawDeferred();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ExternalizeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ExternalizeL(
+        MESMRCalEntry& aEntry,
+        TBool aForceValidation )
+    {
+    FUNC_LOG;
+    CESMRField* currentFocus = FocusedField();
+    ASSERT( currentFocus );
+    TESMREntryFieldId id = currentFocus->FieldId();
+
+    if ( aForceValidation )
+        {
+        // force validate the values:
+        TInt err = iFactory.Validate( id, aForceValidation );
+        // fill the calendar entry with data in fields.
+        iFactory.ExternalizeL( aEntry );
+        }
+    else
+        {
+        TInt err = iFactory.Validate( id );
+        if ( err )
+            {
+            //SetControlFocusedL( id ); Why would we set this focused here?
+            User::Leave( err );
+            }
+        else
+            {
+            // fill the calendar entry with data in fields.
+            iFactory.ExternalizeL( aEntry );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::DisableSizeChange()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::DisableSizeChange(TBool aDisable )
+    {
+    FUNC_LOG;
+    iDisableSizeChanged = aDisable;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InitialScroll
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InitialScrollL()
+    {
+    FUNC_LOG;
+
+    // Check if the ResponseArea exist
+    TESMREntryFieldId id = GetResponseFieldsFieldId();
+
+    if( id == EESMRFieldResponseArea )
+        {
+        // Set the focus on the ResponseArea
+        iFieldContainer->SetControlFocusedL( id );
+        //iFactory.FieldById(id)->SetFocus( ETrue );
+
+        // Scroll the list to put the ResponseArea on the top
+        CESMRField* focusField = FocusedField();
+        TPoint pos( focusField->Position() );
+        ScrollFieldsUp(pos.iY);
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::FocusedItem
+// ---------------------------------------------------------------------------
+//
+CESMRField* CMRListPane::FocusedField() const
+    {
+    FUNC_LOG;
+    return iFieldContainer->FocusedField();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetControlFocusedL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SetControlFocusedL( TESMREntryFieldId aFieldId )
+    {
+    FUNC_LOG;
+    iFieldContainer->SetControlFocusedL( aFieldId );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ClickedItem
+// ---------------------------------------------------------------------------
+//
+CESMRField* CMRListPane::ClickedField() const
+    {
+    return iClickedField;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::CountComponentControls
+// ---------------------------------------------------------------------------
+//
+TInt CMRListPane::CountComponentControls() const
+    {
+    FUNC_LOG;
+    return 1; // iFieldContainer
+
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ComponentControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CMRListPane::ComponentControl( TInt /*aIndex*/ ) const
+    {
+    FUNC_LOG;
+    return iFieldContainer;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SizeChanged
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SizeChanged()
+    {
+    FUNC_LOG;
+    if ( iDisableSizeChanged || Rect() == TRect( 0, 0, 0, 0 ) )
+        {
+        return;
+        }
+
+    TSize containerSize( iFieldContainer->MinimumSize() );
+    iFieldContainer->SetSize( containerSize );
+
+    // Physics:
+    iPhysics->InitPhysics();
+
+    DoUpdateScrollBar();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMRListPane::OfferKeyEventL( const TKeyEvent &aKeyEvent,
+                                          TEventCode aType )
+    {
+    FUNC_LOG;
+    TKeyResponse response( EKeyWasNotConsumed );
+
+    // First check if the focused item needs the key event
+    response = FocusedField()->OfferKeyEventL( aKeyEvent, aType );
+
+    if ( aType == EEventKey
+         && response == EKeyWasNotConsumed )
+        {
+        // Check if the focus should be changed
+        switch ( aKeyEvent.iScanCode )
+            {
+            case EStdKeyUpArrow:
+                {
+                response = iFieldContainer->MoveFocusUpL( HiddenFocus() );
+
+                // Focus changed via keyboard, iClickedItem is no
+                // longer valid
+                iClickedField = NULL;
+                break;
+                }
+            case EStdKeyDownArrow:
+                {
+                response = iFieldContainer->MoveFocusDownL( HiddenFocus() );
+
+                // Focus changed via keyboard, iClickedItem is no
+                // longer valid
+                iClickedField = NULL;
+                break;
+                }
+            case EStdKeyEnter:
+                {
+                FocusedField()->ExecuteGenericCommandL( EAknCmdOpen );
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+        }
+
+    return response;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::HandleLongTapEventL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::HandleLongTapEventL(
+        const TPoint& aPenEventLocation,
+        const TPoint& /* aPenEventScreenLocation */ )
+    {
+    FUNC_LOG;
+    iLongTapEventInProgess = EFalse;
+    // Long tap functionality may vary between fields
+    // ==> Command field to execute action related to long tap
+    TInt count( iFactory.Count() );
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+
+        if ( field->IsVisible()
+             && field->Rect().Contains( aPenEventLocation ) )
+            {
+            field->LongtapDetectedL( aPenEventLocation );
+            iLongTapEventInProgess = ETrue;
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::DoUpdateScrollBar
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::DoUpdateScrollBar( TInt aFocusPosition )
+    {
+    FUNC_LOG;
+    // Set this lispane's size as scroll bar's window size
+    iScrollModel.SetWindowSize( iSize.iHeight );
+    // Set fieldcontainer's height as scrolbar's scroll span
+    iScrollModel.SetScrollSpan( iFieldContainer->MinimumSize().iHeight );
+
+    // Update scrollbar focus position.
+    if( aFocusPosition == KErrNotFound )
+        {
+        iScrollModel.SetFocusPosition( iPhysics->VerticalScrollIndex() );
+        }
+    else
+        {
+        iScrollModel.SetFocusPosition( aFocusPosition );
+        }
+
+    iScroll.SetModel( &iScrollModel );
+
+    // finally update the new thumb position to view's
+    // iScrollBarThumbPosition member.
+    iScrollBarObserver.ScrollBarPositionChanged(
+            iScroll.ThumbPosition() );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdatedFocusPosition
+// ---------------------------------------------------------------------------
+//
+TInt CMRListPane::UpdatedFocusPosition()
+    {
+    FUNC_LOG;
+    TInt focusPos = 0;
+    TInt count = iFactory.Count();
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+        if ( field->IsVisible() )
+            {
+            TRect rect( field->Rect() );
+            // Check if the field's top is above scroll area origo.
+            if ( rect.iTl.iY  < 0 )
+                {
+                // Whole field is above origo
+                if ( rect.iBr.iY < 0 )
+                    {
+                    focusPos += rect.Height();
+                    }
+                // Part of the field is above origo
+                else
+                    {
+                    focusPos += Abs( rect.iTl.iY );
+                    }
+                }
+            else
+                {
+                // Rest of the fields are below scroll area origo
+                break;
+                }
+            }
+        }
+
+    return focusPos;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsUp
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsUp( TInt aPx )
+    {
+    FUNC_LOG;
+    iPositionChanged = ETrue;
+
+    iUpdatedPanePoint = iFieldContainer->Position();
+    iUpdatedPanePoint.iY -= aPx;
+
+    if ( !iPointerEventInProgress )
+        {
+        // We can updace view only if pointer event processing
+        // is not ongoing.
+        // If pointer event processing is ongoing, view is updated
+        // in CMRListPane::HandlePointerEventL method.
+        UpdatePosition();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsDown
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsDown( TInt aPx )
+    {
+    FUNC_LOG;
+
+    iPositionChanged = ETrue;
+
+    iUpdatedPanePoint = iFieldContainer->Position();
+    iUpdatedPanePoint.iY += aPx;
+
+    if ( !iPointerEventInProgress )
+        {
+        // We can updace view only if pointer event processing
+        // is not ongoing.
+        // If pointer event processing is ongoing, view is updated
+        // in CMRListPane::HandlePointerEventL method.
+        UpdatePosition();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateScrollBarAndPhysics
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateScrollBarAndPhysics()
+    {
+    FUNC_LOG;
+    // Update physics world size
+    iPhysics->InitPhysics();
+
+    // Update scrollbar
+    DoUpdateScrollBar();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ShowControl( TESMREntryFieldId aFieldId )
+    {
+    FUNC_LOG;
+    iFieldContainer->ShowControl( aFieldId );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::IsControlVisible( TESMREntryFieldId aFieldId )
+    {
+    FUNC_LOG;
+    return iFieldContainer->IsControlVisible( aFieldId );
+    }
+// ---------------------------------------------------------------------------
+// CMRListPane::GetResponseFieldsFieldId
+// ---------------------------------------------------------------------------
+//
+TESMREntryFieldId CMRListPane::GetResponseFieldsFieldId()
+    {
+    FUNC_LOG;
+    CESMRField* rfield = iFactory.FieldById( EESMRFieldResponseArea );
+
+    if ( rfield && rfield->IsVisible() && !rfield->IsNonFocusing() )
+        {
+        return EESMRFieldResponseArea;
+        }
+    else
+        {
+        return iFactory.Field(0)->FieldId();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ReActivateL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ReActivateL()
+    {
+    FUNC_LOG;
+    TInt count = iFactory.Count();
+
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+
+        if ( !field->IsFieldActivated() )
+            {
+            field->SetContainerWindowL( *iFieldContainer );
+            field->SetListObserver( iFieldContainer );
+            }
+        }
+
+    // This "for" circle can not be mixed with the above one, since the
+    // field->ActivateL() will call some functions which will traverse
+    // all the fields, but that time, not all the fields have set the
+    // container window.
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+        if ( !field->IsFieldActivated() )
+            {
+            field->ActivateL();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::RecordFields
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::RecordFields()
+    {
+    FUNC_LOG;
+
+    // Loop all visible fields and record them
+    TInt count( iFactory.Count() );
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+        if ( field->IsVisible() )
+            {
+            field->RecordField();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::HandlePointerEventL( const TPointerEvent &aPointerEvent )
+    {
+    // Check if touch is enabled or not
+    if( !AknLayoutUtils::PenEnabled() )
+        {
+        return;
+        }
+
+    iPointerEventInProgress = ETrue;
+
+    // If new down event is received, and
+    // iLongTapEventInProgess flag is still ETrue, we need to
+    // set it back to EFalse -> Long tap event cannot be in progress
+    // in this case anymore.
+    if( aPointerEvent.iType == TPointerEvent::EButton1Down &&
+    		iLongTapEventInProgess )
+    	{
+		iLongTapEventInProgess = EFalse;
+    	}
+
+    // Forward all listpane related events to physics api first.
+    if ( iPhysics->HandlePointerEventL( aPointerEvent, iPhysicsActionOngoing ) )
+        {
+        DoUpdateScrollBar();
+        // Physics in action. If long tap detection is active,
+        // it should be cancelled.
+        if( iLongtapDetector->IsActive() )
+        	{
+			iLongtapDetector->Cancel();
+        	}
+        }
+
+    if( !iPhysicsActionOngoing && TPointerEvent::EDrag != aPointerEvent.iType )
+    	{
+		UpdateClickedField( aPointerEvent );
+
+		// Offer pointer event to long tap detector if field supports long tap
+		// functionality
+		if( ClickedField()->SupportsLongTapFunctionalityL( aPointerEvent ) )
+			{
+			iLongtapDetector->PointerEventL( aPointerEvent );
+			}
+
+		SetFocusAfterPointerEventL( aPointerEvent );
+
+        // If longtap event is in progress, do not pass events to coecontrol
+        if( !iLongTapEventInProgess )
+            {
+            CCoeControl::HandlePointerEventL( aPointerEvent );
+            }
+        // Longtap event executed after up event ->
+        // Let's set iLongTapEventInProgess to EFalse
+        else if( aPointerEvent.iType == TPointerEvent::EButton1Up )
+            {
+			iLongTapEventInProgess = EFalse;
+            }
+    	}
+
+    if ( iPositionChanged )
+        {
+        // Position has changed during pointer event processing
+        // ==> adjusting UI to correct position.
+        UpdatePosition();
+        }
+
+    iPointerEventInProgress = EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ActivateL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ActivateL()
+    {
+    FUNC_LOG;
+    // This ActiveteL is required only for setting the initial position
+    // of the field container. After setting the position, physics is
+    // initialized with new values also.
+
+    CCoeControl::ActivateL();
+    iFieldContainer->SetPosition( Position() );
+
+    // Physics:
+    iPhysics->InitPhysics();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::PhysicsEmulationEnded
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::PhysicsEmulationEnded()
+    {
+    FUNC_LOG;
+    DoUpdateScrollBar();
+    iPhysicsActionOngoing = EFalse;
+    Parent()->DrawDeferred();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateScrollBarDuringOngoingPhysics
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateScrollBarDuringOngoingPhysics()
+    {
+    FUNC_LOG;
+    TInt verticalScrollIndex( iPhysics->VerticalScrollIndex() );
+    iScrollModel.SetFocusPosition( verticalScrollIndex );
+
+	iScroll.SetModel( &iScrollModel );
+
+	// Update the new thumb position to view's
+	// iScrollBarThumbPosition member.
+	iScrollBarObserver.ScrollBarPositionChanged(
+			iScroll.ThumbPosition() );
+
+	iScroll.DrawDeferred();
+
+	if( FeedbackScrollMarginExceeded(
+			Abs( verticalScrollIndex - iPreviousVerticalScrollIndex ) ) )
+		{
+		HandleTactileFeedback( ETouchFeedbackSensitiveList );
+
+		iPreviousVerticalScrollIndex = verticalScrollIndex;
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRField::HandleTactileFeedback
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::HandleTactileFeedback(
+		const TTouchLogicalFeedback& aType )
+	{
+	FUNC_LOG;
+
+	if( !iTactileFeedback )
+		{
+		// Aquire tactile feedback pointer from TLS
+		iTactileFeedback = MTouchFeedback::Instance();
+		}
+
+	if ( iTactileFeedback && iTactileFeedback->FeedbackEnabledForThisApp() )
+		{
+		iTactileFeedback->InstantFeedback( aType );
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetFocusAfterPointerEventL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SetFocusAfterPointerEventL(
+        const TPointerEvent &aPointerEvent )
+    {
+    FUNC_LOG;
+
+    if( aPointerEvent.iType == TPointerEvent::EButton1Down )
+    	{
+		TInt count( iFactory.Count() );
+		for( TInt i = 0; i < count; ++i )
+			{
+			CESMRField* field = iFactory.Field( i );
+
+            // Calculate actual screen rect for field.
+            // If field does not have focus, it is layouted off screen
+            TPoint pos( field->Position() );
+            if ( !field->HasOutlineFocus() )
+                {
+                pos.iX = field->Parent()->Position().iX;
+                }
+            TRect rect( pos, field->Size() );
+
+            if ( field->IsVisible()
+                 && rect.Contains( aPointerEvent.iPosition ) )
+				{
+				CESMRField* focusedField = iFieldContainer->FocusedField();
+
+				if ( field != focusedField )
+					{
+					TBool canLoseFocus(
+							focusedField->OkToLoseFocusL( field->FieldId() ) );
+
+					if ( canLoseFocus )
+						{
+						iFieldContainer->SetControlFocusedL( field->FieldId() );
+						}
+					}
+                else
+                    {
+                    // If field is not focused from coecontrol's point of view
+                    // due to focus strategy, we have to set the field
+                    // focused again.
+                    if( !field->IsFocused() )
+                        {
+                        field->SetOutlineFocusL( ETrue );
+                        field->SetFocus( ETrue );
+                        DrawDeferred();
+                        }
+                    }
+				break;
+				}
+			}
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateClickedField
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateClickedField( const TPointerEvent &aPointerEvent )
+    {
+    FUNC_LOG;
+    TInt fieldCount( iFactory.Count() );
+
+    for( TInt i = 0; i < fieldCount; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+
+        // Calculate actual screen rect for field.
+        // If field does not have focus, it is layouted off screen
+        TPoint pos( field->Position() );
+        if ( !field->HasOutlineFocus() )
+            {
+            pos.iX = field->Parent()->Position().iX;
+            }
+        TRect rect( pos, field->Size() );
+
+        if( rect.Contains( aPointerEvent.iPosition )
+            && field->IsVisible() )
+            {
+            if( aPointerEvent.iType == TPointerEvent::EButton1Down )
+                {
+                iClickedField = field;
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::HiddenFocus
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::HiddenFocus()
+    {
+    FUNC_LOG;
+    TBool hiddenFocus( EFalse );
+
+    CESMRField* focusedField( iFieldContainer->FocusedField() );
+    TInt focusedFieldIndex( IndexByFieldId(
+            iFactory, focusedField->FieldId() ) );
+
+    if ( focusedFieldIndex < iFactory.Count() )
+        {
+        TRect focusedFieldRect( focusedField->Rect() );
+        TRect listPaneRect( Rect() );
+
+        TInt fieldTopY( focusedFieldRect.iTl.iY );
+        TInt fieldBottomY( focusedFieldRect.iBr.iY );
+
+        TInt listTopY( listPaneRect.iTl.iY );
+        TInt listBottomY( listPaneRect.iBr.iY );
+
+        if ( ( fieldBottomY > listBottomY ||
+                fieldTopY < listTopY ) &&
+                    focusedFieldRect.Height() < listPaneRect.Height() )
+            {
+            hiddenFocus = ETrue;
+            }
+        }
+    return hiddenFocus;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::FeedbackScrollMarginExceeded
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::FeedbackScrollMarginExceeded( TInt aMargin )
+    {
+    FUNC_LOG;
+	/*
+	 * This compares given margin to default one row
+	 * field height, and returns ETrue if margin is exceeded.
+	 * Otherwise EFalse.
+	 */
+	TBool ret( EFalse );
+
+	if( !iDefaultFieldHeight )
+		{
+		TAknLayoutRect fieldLayoutRect(
+			NMRLayoutManager::GetFieldLayoutRect(
+					iFieldContainer->Rect(), 1 ) );
+
+		iDefaultFieldHeight = fieldLayoutRect.Rect().Height();
+		}
+
+	if( aMargin > iDefaultFieldHeight )
+		{
+		ret = ETrue;
+		}
+
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdatePosition
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdatePosition()
+    {
+    // This initializes Draw also
+    iFieldContainer->SetPosition( iUpdatedPanePoint );
+
+    // Non-kinetic scrolling executed. Update
+    // new position to physics.
+    iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
+    DoUpdateScrollBar( UpdatedFocusPosition() );
+
+    iPositionChanged = EFalse;
+    }
+
+// End of file