meetingrequest/mrgui/src/cmrlistpane.cpp
branchRCL_3
changeset 12 4ce476e64c59
parent 0 8466d47a6819
child 13 8592a65ad3fb
--- a/meetingrequest/mrgui/src/cmrlistpane.cpp	Mon Mar 15 12:39:10 2010 +0200
+++ b/meetingrequest/mrgui/src/cmrlistpane.cpp	Wed Mar 31 21:08:33 2010 +0300
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* 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"
@@ -15,61 +15,64 @@
 *
 */
 #include "cmrlistpane.h"
+#include "mesmrfieldstorage.h"
+#include "mmrscrollbarobserver.h"
+#include "esmrdef.h"
+#include "cesmrfield.h"
+#include "cmrfieldcontainer.h"
+#include "cmrlistpanephysics.h"
 
 #include <eikscrlb.h>
-#include <AknUtils.h>
-#include <touchfeedback.h>
+#include <aknutils.h>
 
-#include "mesmrfieldstorage.h"
-#include "cesmrfield.h"
-
+//DEBUG
 #include "emailtrace.h"
 
-namespace // codescanner::namespace
-    {
-    /**
-     * Vertical scroll margin
-     */
-    const TInt KVerticalScrollMargin = 3;
+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 )
+// ----------------
+// IndexByFieldId
+// ----------------
+//
+TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
+                     TESMREntryFieldId aFieldId )
+    {
+    TInt index( KErrNotFound );
+    TInt count( aFactory.Count() );
+
+    for ( TInt i = 0; i < count; ++i )
         {
-        TInt index( KErrNotFound );
-        TInt count( aFactory.Count() );
-        
-        for ( TInt i = 0; i < count; ++i )
+        if ( aFactory.Field( i )->FieldId() == aFieldId )
             {
-            if ( aFactory.Field( i )->FieldId() == aFieldId )
-                {
-                index = i;
-                break;
-                }
+            index = i;
+            break;
             }
-        
-        return index;
         }
+
+    return index;
     }
 
+}
+
 //----- MEMBER FUNCTIONS ----
 
 // ---------------------------------------------------------------------------
-// CMRListPane::NewL
+// CMRListPane::CMRListPane
 // ---------------------------------------------------------------------------
 //
-CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
-                                MESMRFieldStorage& aFactory,
-                                TAknDoubleSpanScrollBarModel& aScrollModel )
+CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
+                          TAknDoubleSpanScrollBarModel& aScrollModel, 
+                          CAknDoubleSpanScrollBar& aScroll,
+                          MMRScrollBarObserver& aScrollBarObserver )
+    : iFactory( aFactory ),
+      iScrollModel( aScrollModel ),
+      iScroll( aScroll ),
+      iScrollBarObserver( aScrollBarObserver )
     {
-    CMRListPane* self = new (ELeave) CMRListPane( aFactory, aScrollModel );
-    CleanupStack::PushL( self );
-    self->ConstructL( aParent );
-    CleanupStack::Pop( self );
-    return self;
+    FUNC_LOG;
     }
 
 // ---------------------------------------------------------------------------
@@ -78,17 +81,32 @@
 //
 CMRListPane::~CMRListPane()
     {
+    FUNC_LOG;
+    delete iLongtapDetector;
+    delete iPhysics;
+    delete iFieldContainer;
     }
 
 // ---------------------------------------------------------------------------
-// CMRListPane::CMRListPane
+// CMRListPane::NewL
 // ---------------------------------------------------------------------------
 //
-CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
-                          TAknDoubleSpanScrollBarModel& aScrollModel )
-    : iFactory( aFactory ),
-      iScrollModel( aScrollModel )
+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;
     }
 
 // ---------------------------------------------------------------------------
@@ -97,64 +115,173 @@
 //
 void CMRListPane::ConstructL( const CCoeControl& aParent )
     {
+    FUNC_LOG;
+    CCoeControl::SetComponentsToInheritVisibility( ETrue );
     SetContainerWindowL( aParent );
-    TBool focusSet = EFalse;
+
+    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)->SetContainerWindowL( *this );
+        iFactory.Field(i)->InitializeL();
         }
+    iClickedField = NULL;
+    }
+
 
-    for ( TInt i = 0; i < count; i++ )
-        {
-        CESMRField* field = iFactory.Field( i );
-        
-        // Initialize field
-        field->InitializeL();
-        User::LeaveIfError( field->SetParent( this ) );
+// ---------------------------------------------------------------------------
+// CMRListPane::InternalizeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InternalizeL( MESMRCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    iFactory.InternalizeL( aEntry );
+    
+    // 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 ( !focusSet
-             && field->IsVisible()
-             && !field->IsNonFocusing())
+    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
             {
-            field->SetOutlineFocusL( ETrue );
-            focusSet = ETrue;
-            iFocus = i;
+            // 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;
+    // TODO: Fix or remove! L-Function called in non-leaving function!
+    // Suggestion: Move functionality to viewerdialog and use existing
+    // functions in listpane to do the required actions.
+    
+    // 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::FocusedItem() const
+CESMRField* CMRListPane::FocusedField() const
+    {
+    FUNC_LOG;
+    return iFieldContainer->FocusedField();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetControlFocusedL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SetControlFocusedL( TESMREntryFieldId aFieldId )
     {
     FUNC_LOG;
-    CESMRField* field = NULL;
-    if ( iFactory.Count() > 0 )
-        {
-        field = iFactory.Field( iFocus );
-        }
-    return field;
+    iFieldContainer->SetControlFocusedL( aFieldId );
     }
-        
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ClickedItem
+// ---------------------------------------------------------------------------
+//
+CESMRField* CMRListPane::ClickedField() const
+    {
+    return iClickedField;
+    }
+
 // ---------------------------------------------------------------------------
 // CMRListPane::CountComponentControls
 // ---------------------------------------------------------------------------
 //
 TInt CMRListPane::CountComponentControls() const
     {
-    return iFactory.Count();
+    FUNC_LOG;
+    return 1; // iFieldContainer
+    
     }
 
 // ---------------------------------------------------------------------------
 // CMRListPane::ComponentControl
 // ---------------------------------------------------------------------------
 //
-CCoeControl* CMRListPane::ComponentControl( TInt aIndex ) const
+CCoeControl* CMRListPane::ComponentControl( TInt /*aIndex*/ ) const
     {
-    return iFactory.Field( aIndex );
+    FUNC_LOG;
+    return iFieldContainer;
     }
 
 // ---------------------------------------------------------------------------
@@ -163,35 +290,19 @@
 //
 void CMRListPane::SizeChanged()
     {
-    TPoint tl( Position() );
-    TInt scrollSpan = 0;
-    // Loop all the visible fields and set size and position in the list
-    TBool topVisibleFound( EFalse );
-    
-    const TInt count( iFactory.Count() );
-    for ( TInt i = 0; i < count; i++ )
+    FUNC_LOG;
+    if ( iDisableSizeChanged || Rect() == TRect( 0, 0, 0, 0 ) )
         {
-        CESMRField* field = iFactory.Field( i );
-
-        if ( field->IsVisible() )
-            {
-            LayoutField( *field, tl );
-            
-            if ( !topVisibleFound )
-                {
-                iTopVisibleIndex = i;
-                topVisibleFound = ETrue;
-                }
-
-            TInt height = field->Size().iHeight;
-            tl.iY += height;
-            scrollSpan += height;
-            }
+        return;
         }
+   
+    TSize containerSize( iFieldContainer->MinimumSize() );
+    iFieldContainer->SetSize( containerSize );
     
-    iScrollModel.SetScrollSpan( scrollSpan );
-    iScrollModel.SetWindowSize( iSize.iHeight );
-    UpdateFocusPosition();
+    // Physics:
+    iPhysics->InitPhysics();
+    
+    DoUpdateScrollBar();
     }
 
 // ---------------------------------------------------------------------------
@@ -201,737 +312,111 @@
 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 we have at least one item in the list
-    if ( iFocus < iFactory.Count() )
+    if ( aType == EEventKey
+            && response == EKeyWasNotConsumed )
         {
-        CESMRField* field = iFactory.Field( iFocus );
-        // First check if the focused item needs the key event
-        response = field->OfferKeyEventL( aKeyEvent, aType );
-
-        if ( aType == EEventKey
-             && response == EKeyWasNotConsumed )
+        // Check if the focus should be changed
+        switch ( aKeyEvent.iScanCode )
             {
-            // Check if the focus should be changed
-            switch ( aKeyEvent.iScanCode )
+            case EStdKeyUpArrow:
                 {
-                case EStdKeyUpArrow:
-                    {
-                    response = MoveFocusUpL();
-                    break;
-                    }
-                case EStdKeyDownArrow:
-                    {
-                    response = MoveFocusDownL();
-                    break;
-                    }
-                default:
-                    {
-                    break;
-                    }
+                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;
+                }
+            default:
+                {
+                break;
                 }
             }
         }
+    
     return response;
     }
 
 // ---------------------------------------------------------------------------
-// CMRListPane::ControlSizeChanged
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::ControlSizeChanged( CESMRField* aCtrl )
-    {
-    if ( !aCtrl )
-        {
-        SizeChanged();
-        }
-    else
-        {
-        TPoint tl( aCtrl->Position() );
-        TInt index = IndexByFieldId( iFactory, aCtrl->FieldId() );
-        
-        // Relayout aCtrl
-        TSize old( aCtrl->Size() );
-        TSize size( aCtrl->MinimumSize() );
-        if ( aCtrl->IsExpandable() )
-            {
-            size.iHeight = aCtrl->ExpandedHeight();
-            }
-        aCtrl->SetSize( size );
-        iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
-                                    + size.iHeight - old.iHeight );
-        
-        // Move other fields
-        ++index;
-        tl.iY += size.iHeight;
-        MoveFields( index, tl );
-        UpdateFocusPosition();
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::InsertControl
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::InsertControl( TESMREntryFieldId aField )
-    {
-    CESMRField* field = iFactory.FieldById( aField );
-    
-    if ( field && !field->IsVisible() )
-        {
-        // Make field visible 
-        field->MakeVisible( ETrue );
-        TInt index = IndexByFieldId( iFactory, aField );
-        if ( index < iTopVisibleIndex )
-            {
-            iTopVisibleIndex = index;
-            }
-        
-        TPoint tl( Rect().iTl );
-        TInt prevIndex = index - 1;
-        
-        // Get previous visible field position
-        if ( prevIndex >= 0 )
-            {
-            CESMRField* previous = NULL;
-            do
-                {
-                previous = iFactory.Field( prevIndex-- );
-                }
-            while ( prevIndex >= 0 && !previous->IsVisible() );
-            
-            tl.iY = previous->Rect().iBr.iY;
-            }
-        
-        // Layout field
-        LayoutField( *field, tl );
-        iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
-                                    + field->Size().iHeight );
-        
-        // Move following fields
-        tl.iY += field->Size().iHeight;
-        MoveFields( ++index, tl );
-        UpdateFocusPosition();
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::InsertControl
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::RemoveControl( TESMREntryFieldId aField )
-    {
-    CESMRField* field = iFactory.FieldById( aField );
-        
-    if ( field && field->IsVisible() )
-        {
-        field->MakeVisible( EFalse );
-        iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan() - field->Size().iHeight );
-        TInt index = IndexByFieldId( iFactory, aField );
-        TBool focused = ( index == iFocus )? ETrue : EFalse;
-        
-        if ( index == iTopVisibleIndex )
-            {
-            // Find next
-            TInt count( iFactory.Count() );
-            while ( index < count )
-                {
-                if ( iFactory.Field( ++index )->IsVisible() )
-                    {
-                    iTopVisibleIndex = index;
-                    break;
-                    }
-                }
-            }
-        else
-            {
-            ++index;
-            }
-        TPoint pos( field->Position() );
-        MoveFields( index, pos );
-        if ( focused && !field->IsNonFocusing() )
-            {
-            TRAP_IGNORE( DoSetFocusL( index ) )
-            }
-        UpdateFocusPosition();
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::IsControlVisible
-// ---------------------------------------------------------------------------
-//
-TBool CMRListPane::IsControlVisible( TESMREntryFieldId aField )
-    {
-    TBool visible( EFalse );
-    CESMRField* field = iFactory.FieldById( aField );
-    
-    if ( field )
-        {
-        visible = field->IsVisible();
-        }
-    
-    return visible;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::SetControlFocusedL
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::SetControlFocusedL( TESMREntryFieldId aField )
-    {
-    TInt count = iFactory.Count();
-    for ( TInt i(0); i < count; i++ )
-        {
-        CESMRField* field = iFactory.Field(i);
-        
-        if ( field->FieldId() == aField )
-            {
-            if( field->IsVisible() && !field->IsNonFocusing() )
-                {
-                // Remove current focus before setting new one
-                CESMRField* focusedField = FocusedItem();
-                ASSERT( focusedField );
-                focusedField->SetOutlineFocusL( EFalse );
-
-                // Set new focus
-                field->SetOutlineFocusL( ETrue );
-                iFocus = i;
-                break;
-                }
-            else
-                {
-                // Not possible to set focus to non-visible control
-                User::Leave( KErrGeneral );
-                }
-            }
-        }
-    }
-
-// SCROLLING_MOD: These two methods are for CESMRRichTextViewer to 
-// be able to control view area
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveListAreaDownL
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::MoveListAreaDownL( TInt aAmount )
-    {
-    FUNC_LOG;
-    // Method for CESMRRichTextViewer for moving view area down if the text in
-    // text field does not fit on the screen.
-
-    // Fetch the position info about the first visible field in field set:
-    CESMRField* field;
-    if( iTopVisibleIndex != KErrNotFound )
-        {
-        field = iFactory.Field( iTopVisibleIndex );
-        }
-    else
-        {
-        field = iFactory.Field( iFactory.Count() - 1 );
-        }
-    TRect rect( field->Rect() );
-
-    // check whether the first field is visible, if not, let's
-    // check should we scroll less than needed to get the first
-    // field shown.
-    if ( rect.iTl.iY + aAmount > Rect().iTl.iY )
-        {
-        aAmount = Rect().iTl.iY - rect.iTl.iY + KVerticalScrollMargin;
-        }
-    else if ( rect.iTl.iY == Rect().iTl.iY )
-        {
-        // field already visible, do not scroll.
-        aAmount = 0;
-        }
-
-    // Do the view scrolling if needed:
-    if ( aAmount )
-        {
-        ScrollItemsDown( aAmount );
-        UpdateFocusPosition();
-        //UpdateScrollBar();
-        DrawDeferred();
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveListAreaUpL
+// CMRListPane::HandleLongTapEventL
 // ---------------------------------------------------------------------------
 //
-void CMRListPane::MoveListAreaUpL( TInt aAmount )
-    {
-    FUNC_LOG;
-    // Fetch the position information about currently focused field:
-    CESMRField* field = iFactory.Field( iFocus );
-    TRect rect( field->Rect() );
-
-    // check whether the scroll pixels should be less than normal
-    // scroll sequence to let the field bottom to be placed at
-    // the bottom of view rect.
-    if ( rect.iBr.iY - aAmount < Rect().iBr.iY )
-        {
-        aAmount = rect.iBr.iY - Rect().iBr.iY + KVerticalScrollMargin;
-        }
-    else if ( rect.iBr.iY + aAmount == Rect().iBr.iY )
-        {
-        // field already visible, do not scroll.
-        aAmount = 0;
-        }
-
-    // do the scrolling if needed:
-    if ( aAmount > 0 )
-        {
-        // if the focus is on last
-        ScrollItemsUp( aAmount );
-        UpdateFocusPosition();
-        //UpdateScrollBar();
-        DrawDeferred();
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::ListHeight
-// ---------------------------------------------------------------------------
-//
-TInt CMRListPane::ListHeight()
+void CMRListPane::HandleLongTapEventL(
+        const TPoint& aPenEventLocation,
+        const TPoint& /* aPenEventScreenLocation */ )
     {
     FUNC_LOG;
-    return iSize.iHeight;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::IsFieldBottomVisible
-// ---------------------------------------------------------------------------
-//
-TBool CMRListPane::IsFieldBottomVisible()
-    {
-    // Fetch the position information about currently focused field:
-    CESMRField* field = iFactory.Field( iFocus );
-    TBool ret( EFalse );
-    if ( field->Rect().iBr.iY <= Rect().iBr.iY )
-       {
-       ret = ETrue;
-       }
-
-    return ret;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveFocusUpL
-// ---------------------------------------------------------------------------
-//
-TKeyResponse CMRListPane::MoveFocusUpL()
-    {
-    TInt ind( iFocus );
-    
-    // search next visible focus item
-    while ( ind > 0 )
-        {
-        CESMRField* field = iFactory.Field( --ind );
-
-        if ( !field->IsNonFocusing() )
-            {
-            field = iFactory.Field( ind );
-
-            CESMRField* focusedField = iFactory.Field( iFocus );
-            if ( field->IsVisible() )
-                {
-                TBool canLoseFocus( 
-                        focusedField->OkToLoseFocusL( field->FieldId() ) );
-
-                if ( canLoseFocus )
-                    {
-                    iFocus = ind;
-                                        
-                    // update focus index and scroll the item visible
-                    focusedField->SetOutlineFocusL( EFalse );
-                    // This call changes the text color of previously 
-                    // focused field
-                    focusedField->SetFocus( EFalse );
-                    field->SetOutlineFocusL( ETrue );
-                    // This call changes the text color of focused field
-                    field->SetFocus( ETrue );
-
-                    ScrollItemVisible( iFocus );
-                    }
-                return EKeyWasConsumed;
-                }
-            }
-        }
-    return EKeyWasNotConsumed;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveFocusDownL
-// ---------------------------------------------------------------------------
-//
-TKeyResponse CMRListPane::MoveFocusDownL()
-    {
-    TInt ind( iFocus );
-
-    // start searching next possible focus item
-    TInt maxItemIndex = iFactory.Count() - 1;
-    
-    while ( ind < maxItemIndex )
-        {
-        // only visible and focusable items can be focused
-        CESMRField* field = iFactory.Field( ++ind );
-
-        if ( field->IsVisible() && !field->IsNonFocusing() )
-            {
-            CESMRField* focusedField = iFactory.Field( iFocus );
-                    
-            TBool canLoseFocus( 
-                    focusedField->OkToLoseFocusL( field->FieldId() ) );
+    iLongTapEventConsumed = EFalse;
+    // Long tap functionality may vary between fields
+    // ==> Command field to execute action related to long tap
+    TInt count( iFactory.Count() );
 
-            // check it its ok for the old focus item to lose focus
-            if ( canLoseFocus )
-                {
-                iFocus = ind;
-                                
-                // update focus index and scroll the item visible
-                focusedField->SetOutlineFocusL( EFalse );
-                // This call changes the text color of previously 
-                // focused field
-                focusedField->SetFocus( EFalse );
-                field->SetOutlineFocusL( ETrue );
-                // This call changes the text color of focused field
-                field->SetFocus( ETrue );
-
-                ScrollItemVisible( iFocus );
-                }
-            return EKeyWasConsumed;
-            }
-        }
-    return EKeyWasNotConsumed;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveFocusL
-// ---------------------------------------------------------------------------
-//
-TBool CMRListPane::MoveFocusL(TInt aNextFieldIndex)
-    {
-    // start searching next possible focus item
-    TInt maxItemIndex = iFactory.Count() - 1;
-
-    CESMRField* focusedField = iFactory.Field( iFocus );
-    
-    // only visible and focusable items can be focused
-    CESMRField* field = iFactory.Field( aNextFieldIndex );
-
-    if ( field->IsVisible() && !field->IsNonFocusing() )
-        {
-        TBool canLoseFocus( 
-                focusedField->OkToLoseFocusL( field->FieldId() ) );
-
-        // check it its ok for the old focus item to lose focus
-        if ( canLoseFocus )
-            {
-            // tactile feedback if touch 
-            if ( AknLayoutUtils::PenEnabled() )
-                {
-                MTouchFeedback* feedback = MTouchFeedback::Instance();
-                if ( feedback )
-                    {
-                    feedback->InstantFeedback( this, ETouchFeedbackBasic );
-                    }
-                }
-            
-            iFocus = aNextFieldIndex;
-                            
-            // update focus index and scroll the item visible
-            focusedField->SetOutlineFocusL( EFalse );
-            // This call changes the text color of previously 
-            // focused field
-            focusedField->SetFocus( EFalse );
-            field->SetOutlineFocusL( ETrue );
-            // This call changes the text color of focused field
-            field->SetFocus( ETrue );
-            DrawDeferred();
-            }
-        return ETrue; // operation succeed
-        }
-    return EFalse;
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::LayoutField
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::LayoutField( CESMRField& aField,
-                               const TPoint& aTl )
-    {
-    TSize size( aField.MinimumSize() );
-    if ( aField.IsExpandable() )
-        {
-        size.iHeight = aField.ExpandedHeight();
-        }
-    aField.SetPosition( aTl );
-    aField.SetSize( size );
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::MoveFields
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::MoveFields( TInt aIndex,
-                              TPoint& aTl )
-    {
-    const TInt count( iFactory.Count() );
-    
-    for ( TInt i = aIndex; i < count; ++i )
+    for ( TInt i = 0; i < count; ++i )
         {
         CESMRField* field = iFactory.Field( i );
 
-        if ( field->IsVisible() )
+        if ( field->IsVisible()
+             && field->Rect().Contains( aPenEventLocation ) )
             {
-            field->SetPosition( aTl );
-            
-            aTl.iY += field->Size().iHeight;
+            field->LongtapDetectedL( aPenEventLocation );
+            iLongTapEventConsumed = ETrue;
+            break;
             }
         }
     }
 
 // ---------------------------------------------------------------------------
-// CMRListPane::DoSetFocusL
+// CMRListPane::DoUpdateScrollBar
 // ---------------------------------------------------------------------------
 //
-void CMRListPane::DoSetFocusL( TInt aFocus )
-    {
-    TInt count( iFactory.Count() );
-    aFocus = Max( 0, Min( aFocus, count - 1 ) );
-    
-    if ( aFocus != iFocus )
-        {
-        // Get current focused field
-        CESMRField* old = iFactory.Field( iFocus );
-        
-        // Get next focused field
-        CESMRField* field = iFactory.Field( aFocus );
-        while ( aFocus < count && !field->IsVisible() )
-            {
-            field = iFactory.Field( aFocus++ );
-            }
-        
-        if ( !field->IsVisible() )
-            {
-            aFocus = iFocus - 1;
-            while ( aFocus > 0 && !field->IsVisible() )
-                {
-                field = iFactory.Field( aFocus-- );
-                }
-            }
-        
-        ASSERT( field->IsVisible() );
-        
-        // Remove focus from old
-        iFocus = aFocus;
-        // update focus index and scroll the item visible
-        old->SetOutlineFocusL( EFalse );
-        // Change the text color of previously focused field
-        old->SetFocus( EFalse );
-        field->SetOutlineFocusL( ETrue );
-        // This call changes the text color of focused field
-        field->SetFocus( ETrue );
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::ScrollItemVisible
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::ScrollItemVisible( TInt aInd )
+void CMRListPane::DoUpdateScrollBar( TInt aFocusPosition )
     {
     FUNC_LOG;
-    CESMRField* field = NULL;
-    if ( aInd == KErrNotFound )
+    // 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 )
         {
-        field = FocusedItem();
+        iScrollModel.SetFocusPosition( iPhysics->VerticalScrollIndex() );
         }
     else
         {
-        field = iFactory.Field( aInd );
+        iScrollModel.SetFocusPosition( aFocusPosition );
         }
 
-    ASSERT( field );
-
-    TRect rect( field->Rect() );
-
-    // move all items upwards
-    TInt bottomRightY = Rect().iBr.iY;
-
-
-    TInt fieldUpper(0);
-    TInt fieldLower(0);
-    field->GetMinimumVisibleVerticalArea( fieldUpper, fieldLower );
-
-    // desired position below view rect:
-    if ( rect.iTl.iY + fieldLower > Rect().iBr.iY )
-        {
-        // field rect Y position related to view rect:
-        TInt fieldRelYPos = rect.iTl.iY - Size().iHeight;
-        TInt px = fieldRelYPos + fieldLower;
+    iScroll.SetModel( &iScrollModel );
 
-        // if focus on first or last field: add margin height to
-        // scroll amount.
-        if ( iFocus == 0 || iFocus == iFactory.Count()-1 )
-            {
-            px += 2 * KVerticalScrollMargin;
-            }
-
-        ScrollItemsUp( px );
-        }
-
-    // move all items downwards.
-    TInt topLeftY = Rect().iTl.iY;
-
-    if ( rect.iBr.iY - (rect.Height() - fieldUpper ) < topLeftY )
-        {
-        TInt fieldRelYPos = topLeftY - rect.iBr.iY;
-        TInt px = fieldRelYPos + ( rect.Height() - fieldUpper);
-
-        // if focus on first or last field: add margin height to
-        // scroll amount.
-        if ( iFocus == 0 ||  iFocus == iFactory.Count()-1 )
-            {
-            px += KVerticalScrollMargin;
-            }
-
-        ScrollItemsDown( px );
-        }
-
-    UpdateFocusPosition();//UpdateScrollBar();
-    DrawDeferred();
+    // finally update the new thumb position to view's
+    // iScrollBarThumbPosition member.
+    iScrollBarObserver.ScrollBarPositionChanged( 
+            iScroll.ThumbPosition() );
     }
 
 // ---------------------------------------------------------------------------
-// CMRListPane::UpdateScrollBar
+// CMRListPane::UpdatedFocusPosition
 // ---------------------------------------------------------------------------
 //
-void CMRListPane::UpdateScrollBar()
-    {
-    FUNC_LOG;
-    // Scroll span is the size of the scrolled list,
-    // including the items that doesn't fit in the screen
-    TInt spanSize( 0 );
-    TInt hidden( 0 );
-    const TInt count(iFactory.Count());
-    for ( TInt i(0); i < count; i++ )
-        {
-        CESMRField* field = iFactory.Field( i );
-        if ( field->IsVisible() )
-            {
-            TRect rect( field->Rect() );
-            spanSize += rect.Height();
-            // Check if the field's top Y-position is hidden.
-            if ( rect.iTl.iY  < 0 )
-                {
-                // whole field is hidden
-                if ( rect.iBr.iY < 0 )
-                    {
-                    hidden += rect.Height();
-                    }
-                // partly hidden:
-                else
-                    {
-                    hidden += Abs( rect.iTl.iY );
-                    }
-                }
-            }
-        }
-
-    iScrollModel.SetScrollSpan( spanSize );
-    iScrollModel.SetWindowSize( iSize.iHeight );
-    iScrollModel.SetFocusPosition( hidden );
-
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::ScrollItemsUp
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::ScrollItemsUp( TInt aPx )
+TInt CMRListPane::UpdatedFocusPosition()
     {
     FUNC_LOG;
-    TInt count( iFactory.Count() );
-    for ( TInt i = 0; i < count; ++i )
-        {
-        CESMRField* field = iFactory.Field(i);
-        if ( field->IsVisible() )
-            {
-            TPoint pos( field->Position() );
-            pos.iY -= aPx;
-            if ( i == iTopVisibleIndex && pos.iY < 0 )
-                {
-                iTopVisibleIndex = KErrNotFound;
-                }
-            else if ( iTopVisibleIndex == KErrNotFound && pos.iY >= 0 )
-                {
-                iTopVisibleIndex = i;
-                }
-            field->SetPosition( pos );
-            }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::ScrollItemsDown
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::ScrollItemsDown( TInt aPx )
-    {
-    FUNC_LOG;
-    TInt count( iFactory.Count() );
-    for ( TInt i = 0; i < count; ++i )
-        {
-        CESMRField* field = iFactory.Field( i );
-        if ( field->IsVisible() )
-            {
-            TPoint pos( field->Position() );
-            pos.iY += aPx;
-            if ( pos.iY >= 0 && ( i < iTopVisibleIndex || iTopVisibleIndex == KErrNotFound ) )
-                {
-                iTopVisibleIndex = i;
-                }
-            field->SetPosition( pos );
-            }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CMRListPane::ScrollView
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::ScrollView( TInt aAmount )
-    {
-    FUNC_LOG;
-    
-    if ( aAmount > 0 )
-        {
-        // move list up
-        ScrollItemsUp( aAmount );
-        UpdateFocusPosition();
-        DrawDeferred();
-        }
-    else if ( aAmount < 0 )
-        {
-        // move list down
-        ScrollItemsDown( -aAmount );
-        UpdateFocusPosition();
-        DrawDeferred();
-        }
-    }
-
-
-// ---------------------------------------------------------------------------
-// CMRListPane::UpdateFocusPosition
-// ---------------------------------------------------------------------------
-//
-void CMRListPane::UpdateFocusPosition()
-    {
     TInt focusPos = 0;
     TInt count = iFactory.Count();
     for ( TInt i = 0; i < count; ++i )
@@ -961,62 +446,300 @@
                 }
             }
         }
+
+    return focusPos;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsUp
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsUp( TInt aPx )
+    {
+    FUNC_LOG;
+    TPoint point = iFieldContainer->Position();
+    point.iY -= aPx;
     
-    iScrollModel.SetFocusPosition( focusPos );
+    // This initializes Draw also
+    iFieldContainer->SetPosition( point );
+    
+    // Non-kinetic scrolling executed. Update
+    // new position to physics.
+    iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
+
+    DoUpdateScrollBar( UpdatedFocusPosition() );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsDown
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsDown( TInt aPx )
+    {
+    FUNC_LOG;
+    TPoint point = iFieldContainer->Position();
+    point.iY += aPx;
+    
+    // This initializes Draw also
+    iFieldContainer->SetPosition( point );
+    // Non-kinetic scrolling executed. Update
+    // new position to physics.
+    iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
+
+    DoUpdateScrollBar( UpdatedFocusPosition() );
     }
 
 
-// -----------------------------------------------------------------------------
-// CMRListPane::GetViewCenterPosition
-// -----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateScrollBarAndPhysics
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateScrollBarAndPhysics()
+    {
+    // Update physics world size
+    iPhysics->InitPhysics();
+    
+    // Update scrollbar
+    DoUpdateScrollBar();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ShowControl( TESMREntryFieldId aFieldId )
+    {
+    iFieldContainer->ShowControl( aFieldId );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
 //
-TPoint CMRListPane::GetViewCenterPosition() const
+TBool CMRListPane::IsControlVisible( TESMREntryFieldId aFieldId )
+    {
+    return iFieldContainer->IsControlVisible( aFieldId );
+    }
+// ---------------------------------------------------------------------------
+// CMRListPane::GetResponseFieldsFieldId
+// ---------------------------------------------------------------------------
+//
+TESMREntryFieldId CMRListPane::GetResponseFieldsFieldId()
     {
-    const TInt count( iFactory.Count() );
-    TInt topFieldYPos( 0 );
-    for ( TInt i = 0; i < count; i++ )
+    // TODO: Should be removed. This shouldn't be even a public function!
+    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->IsVisible() )
+        if ( !field->IsFieldActivated() )
             {
-            topFieldYPos = field->Position().iY;    
-            break;
+            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();
             }
         }
-    TInt centerX = iSize.iWidth / 2;
-    TInt visibleHeight = iSize.iHeight;
+    }
 
-    TInt centerY = visibleHeight / 2 - topFieldYPos;
+// ---------------------------------------------------------------------------
+// CMRListPane::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::HandlePointerEventL( const TPointerEvent &aPointerEvent )
+    {
+    // Check if touch is enabled or not
+    if( !AknLayoutUtils::PenEnabled() )
+        {
+        return;
+        }
+   
+    // 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();
+        	}
+        }
     
-    
-    return TPoint( centerX, centerY );
+    if( !iPhysicsActionOngoing )
+    	{    
+		// Offer pointer event to long tap detector
+		iLongtapDetector->PointerEventL( aPointerEvent );
+	
+		SetFocusAfterPointerEventL( aPointerEvent );
+		
+        // If longtap event has been handled, then do not handle signal event anymore.
+        if( !iLongTapEventConsumed )
+            {
+            CCoeControl::HandlePointerEventL( aPointerEvent );
+            }
+        else
+            {
+            iLongTapEventConsumed = EFalse;
+            }
+        
+		UpdateClickedField( aPointerEvent );
+    	}
     }
 
+// ---------------------------------------------------------------------------
+// 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::HandlePointerEventL
-// -----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// CMRListPane::PhysicsEmulationEnded
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::PhysicsEmulationEnded()
+    {
+    FUNC_LOG;
+    DoUpdateScrollBar();
+    iPhysicsActionOngoing = EFalse;
+    Parent()->DrawDeferred();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetFocusAfterPointerEventL
+// ---------------------------------------------------------------------------
 //
-void CMRListPane::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+void CMRListPane::SetFocusAfterPointerEventL( 
+        const TPointerEvent &aPointerEvent )
     {
-    if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+    FUNC_LOG;
+
+    if( aPointerEvent.iType == TPointerEvent::EButton1Down )
+    	{
+		TInt count( iFactory.Count() );
+		for( TInt i = 0; i < count; ++i )
+			{
+			CESMRField* field = iFactory.Field( i );
+			if ( field->IsVisible() &&
+					field->Rect().Contains( aPointerEvent.iPosition ) )
+				{
+				CESMRField* focusedField = iFieldContainer->FocusedField();
+	
+				if ( field != focusedField )
+					{
+					TBool canLoseFocus(
+							focusedField->OkToLoseFocusL( field->FieldId() ) );
+	
+					if ( canLoseFocus )
+						{
+						iFieldContainer->SetControlFocusedL( field->FieldId() );
+						}
+					}
+	
+				break;
+				}
+			}
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateClickedField
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateClickedField( const TPointerEvent &aPointerEvent )
+    {
+    FUNC_LOG;
+    TInt fieldCount( iFactory.Count() );
+
+    for( TInt i = 0; i < fieldCount; ++i )
         {
-        TInt count = iFactory.Count();
-        for ( TInt i = 0; i < count; ++i )
+        if( iFactory.Field( i )->Rect().Contains( 
+                aPointerEvent.iPosition ) )
             {
-            CESMRField* field = static_cast<CESMRField*>(iFactory.Field( i ) );
-            TRect r = field->Rect();
-            TBool tapped = field->Rect().Contains( aPointerEvent.iPosition );
-            if (tapped && field->IsVisible() && !field->IsFocused() )
+            if( aPointerEvent.iType == TPointerEvent::EButton1Down )
                 {
-                MoveFocusL( i );
-                break;
+                iClickedField = iFactory.Field( i );
                 }
             }
         }
-    // here some fields can further adjust their state (for example, CESMRResponseField has sub-fields) 
-    CCoeControl::HandlePointerEventL(aPointerEvent);
     }
+
+// ---------------------------------------------------------------------------
+// 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;
+    }
+
 // End of file
-