uifw/AvKon/aknhlist/src/akntreelistview.cpp
branchRCL_3
changeset 56 d48ab3b357f1
parent 55 aecbbf00d063
child 64 85902f042028
--- a/uifw/AvKon/aknhlist/src/akntreelistview.cpp	Tue Aug 31 15:28:30 2010 +0300
+++ b/uifw/AvKon/aknhlist/src/akntreelistview.cpp	Wed Sep 01 12:16:19 2010 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2006, 2007 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2006-2010 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"
@@ -26,13 +26,17 @@
 #include <aknitemactionmenu.h>
 #include <AknTasHook.h> // for testability hooks
 #include <AknPriv.hrh>
+#include <AknIconArray.h>
+#include <avkon.mbg>
+#include <gulicon.h>
+#include <aknmarkingmodeobserver.h>
 #include "akntreelistview.h"
 #include "akntree.h"
 #include "akntreelist.h"
 #include "akntreeiterator.h"
 #include "akntreelistphysicshandler.h"
 
-
+#include "akntrace.h"
 
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
 
@@ -49,6 +53,8 @@
 // Number of additional items to draw
 const TInt KAdditionalItems = 2;
 
+// Number of icons in marking mode icon array
+const TInt KMarkingModeIconArraySize = 2;
 
 // Tree list view flag definitions.
 enum TAknTreeListViewFlags
@@ -58,7 +64,7 @@
     EFlagLooping,
     EFlagUpdateBackground,
     EFlagMarkingEnabled, // Marking of list items is enabled.
-    EFlagMarkingMode, // List in marking mode (MSK controlled by list). 
+    EFlagMarkingState, // List in marking state (MSK controlled by list).
     EFlagMark, // List items are being marked.
     EFlagUnmark, // List items are being unmarked.
     EFlagSimultaneousMarking, // Simultaneous marking ongoing.
@@ -68,7 +74,11 @@
     EFlagSaveFocusAfterSorting,
     EFlagSingleClickEnabled,
     EFlagHighlightEnabled, // Is highlight drawing enabled
-    EFlagIgnoreButtonUpEvent // Up event ignored (when styluspopup menu open)
+    EFlagIsPressedDownState,
+    EFlagIsDragged,
+    EFlagScrollPhysicsTop, // Physics view adjusted according to top item
+    EFlagMirroredLayoutInUse, // Mirrored layout in use
+    EFlagMarkingMode // Marking mode activated    
     };
 
 
@@ -112,6 +122,13 @@
         }
     delete iLongTapDetector;
 
+    if ( iMarkingIconArray )
+        {
+        iMarkingIconArray->ResetAndDestroy();
+        }
+
+    delete iMarkingIconArray;
+
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
     if ( CAknListLoader::TfxApiInternal( iGc ) )
         {
@@ -163,7 +180,8 @@
         {
         Window().Invalidate( Rect() );
         }
-    UpdateScrollbars();
+
+    UpdateScrollbars( ETrue );
     }
 
 
@@ -213,7 +231,7 @@
     // Draw always
     Window().Invalidate( Rect() );
         
-    UpdateScrollbars();
+    UpdateScrollbars( ETrue );
     }
 
 
@@ -422,6 +440,7 @@
     delete iEmptyListText;
     iEmptyListText = NULL;
     iEmptyListText = aText.AllocL();
+    UpdateScrollbars( ETrue ); 
     }
 
 
@@ -468,7 +487,21 @@
 //     
 void CAknTreeListView::SelectItem( CAknTreeItem* aSelectedItem )
     {
-    SelectItem( aSelectedItem, EFalse );
+    if ( iFlags.IsSet( EFlagMarkingMode ) )
+        {
+        if ( aSelectedItem->IsMarkable() )
+            {
+            MarkItem( aSelectedItem, !aSelectedItem->IsMarked(), ETrue );
+            }
+        else if ( aSelectedItem->IsNode() )
+            {
+            SelectItem( aSelectedItem, EFalse );
+            }
+        }
+    else 
+        {
+        SelectItem( aSelectedItem, EFalse );
+        }
     }
 
 
@@ -490,7 +523,14 @@
 //     
 void CAknTreeListView::SetPressedDownState( const TBool& aPressedDown )
     {
-    iIsPressedDownState = aPressedDown;
+    if ( aPressedDown )
+        {
+        iFlags.Set( EFlagIsPressedDownState );
+        }
+    else
+        {
+        iFlags.Clear( EFlagIsPressedDownState );
+        }
     }
     
 
@@ -503,7 +543,7 @@
     {
     CAknTreeItem* first = iTree.VisibleItem( aFirstItem );
     UpdateVisibleItems( 0, first );
-    UpdateScrollbars();
+    UpdateScrollbars( ETrue );
     UpdateAnimation();
     
     if ( aDrawNow )
@@ -741,11 +781,7 @@
 void CAknTreeListView::MakeVisible( TBool aVisible )
     {
     CAknControl::MakeVisible( aVisible );
-
-    if ( aVisible )
-        {
-        UpdateScrollbars();
-        }
+    UpdateScrollbars( aVisible );
     }
 
 
@@ -770,6 +806,11 @@
 
     iScrollbarFrame = new ( ELeave ) CEikScrollBarFrame( this, this );
     iScrollbarFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse );
+    if ( CAknEnv::Static()->TransparencyEnabled() && iPhysicsHandler )
+        {
+        // disable background drawing of scrollbar 
+        iScrollbarFrame->DrawBackground( EFalse, EFalse );
+        }
     }
 
 
@@ -781,62 +822,127 @@
 void CAknTreeListView::HandleResourceChange( TInt aType )
     {
     CAknControl::HandleResourceChange( aType );
-    if ( aType == KAknsMessageSkinChange )
-        {
-        TRAPD( error, CreateAnimationL() )
-        if ( error )
-            {
-            delete iAnimation;
-            iAnimation = NULL;
-            }
-        }
-    else if ( aType == KEikDynamicLayoutVariantSwitch && FocusedItem() )
+    
+    switch ( aType )
         {
-        if ( !FocusedItemVisible() )
+        case KEikMessageWindowsFadeChange:
+             {
+             ReportCollectionChangedEvent();
+             }        
+
+        case KAknsMessageSkinChange:
             {
-            TInt firstItemIndex = 0;
-            if ( iItems.Count() && iItems[0].Item() )
+            TRAPD( error, CreateAnimationL() )
+            if ( error )
                 {
-                firstItemIndex = iTree.VisibleItemIndex( iItems[0].Item() );
+                delete iAnimation;
+                iAnimation = NULL;
                 }
 
-            TInt index = 0;
-            if ( firstItemIndex < iTree.VisibleItemIndex( FocusedItem() ) )
+            TRAP_IGNORE( LoadMarkingIconsL() );
+            break;
+            }
+
+        case KEikDynamicLayoutVariantSwitch:
+            {
+            if ( AknLayoutUtils::LayoutMirrored() )
                 {
-                index = iItems.Count() - 1;
+                iFlags.Set( EFlagMirroredLayoutInUse );
+                }
+            else
+                {
+                iFlags.Clear( EFlagMirroredLayoutInUse );
                 }
 
-            SetFocusedItem( FocusedItem(), index, ETrue );
-            }
-        else
-            {
-            SetFocusedItem( FocusedItem(), FocusIndex(), ETrue );
-            
-            
-            // This block moves visible view after layout switch
-            // if there are not enough items to fill whole screen
-            TInt visibleItemIndex = iTree.VisibleItemIndex( FocusedItem() );
-            if ( visibleItemIndex != KErrNotFound)
+            CAknTreeItem* focusedItem( FocusedItem() );
+            if ( focusedItem )
                 {
-                TInt focusedItemIndex = FocusedItemIndex();
-                if (focusedItemIndex != -1)
+                if ( !FocusedItemVisible() )
                     {
-                    TInt height =  iTree.VisibleItemCount() - visibleItemIndex + focusedItemIndex;
-                    TInt itemCountLimit = iItems.Count();
-                    
-                    if ( height < itemCountLimit && height < iTree.VisibleItemCount() )
+                    TInt firstItemIndex = 0;
+                    if ( iItems.Count() && iItems[0].Item() )
+                        {
+                        firstItemIndex =
+                            iTree.VisibleItemIndex( iItems[0].Item() );
+                        }
+    
+                    TInt index = 0;
+                    if ( firstItemIndex < iTree.VisibleItemIndex( focusedItem ) )
+                        {
+                        index = iItems.Count() - 1;
+                        }
+
+                    if( HighlightEnabled() )
+                        {
+                        SetFocusedItem( focusedItem, index, ETrue );
+                        }
+                    else
                         {
-                        TInt move = itemCountLimit - height;                
-                        UpdateVisibleItems( focusedItemIndex + move, FocusedItem() );
+                        // This block moves visible view after layout switch
+                        // if there are not enough items to fill whole screen
+                        TInt visibleItemIndex = iTree.VisibleItemIndex( focusedItem );
+                        if ( visibleItemIndex != KErrNotFound )
+                            {
+                            TInt visibleItemCount( iTree.VisibleItemCount() );
+                            TInt itemCountLimit = iItems.Count();
+                            if ( visibleItemCount <= itemCountLimit - KAdditionalItems )
+                                {
+                                UpdateVisibleItems( visibleItemIndex, focusedItem );
+                                }
+                            }
                         }
+
+                    }
+                else
+                    {
+                    SetFocusedItem( focusedItem, FocusIndex(), ETrue );
+
+                    // This block moves visible view after layout switch
+                    // if there are not enough items to fill whole screen
+                    TInt visibleItemIndex =
+                        iTree.VisibleItemIndex( focusedItem );
+                    if ( visibleItemIndex != KErrNotFound )
+                        {
+                        TInt focusedItemIndex = FocusedItemIndex();
+                        if ( focusedItemIndex != -1 )
+                            {
+                            TInt visibleItemCount( iTree.VisibleItemCount() );
+                        
+                            TInt height =
+                                visibleItemCount - visibleItemIndex + focusedItemIndex;
+                            TInt itemCountLimit = iItems.Count();
+                            
+                            if ( height < itemCountLimit &&
+                                 height < visibleItemCount )
+                                {
+                                TInt move = itemCountLimit - height;
+                                UpdateVisibleItems( focusedItemIndex + move, focusedItem );
+                                }
+                            }
+                        }
+                    // end of block
                     }
                 }
-            // end of block
+            break;
             }
-        }
-    else if ( aType == KAknMessageFocusLost && HighlightEnabled() )
-        {
-        EnableHighlight( EFalse );
+            
+        case KAknMessageFocusLost:
+            {
+            if ( SingleClickEnabled() && HighlightEnabled() &&
+                 ( iOldWinPos == KErrNotFound || 
+                   iOldWinPos == DrawableWindow()->OrdinalPosition() ) )
+                {
+                EnableHighlight( EFalse );
+                // Redraw item
+                SetFocusedItem( FocusedItem(), FocusIndex(), ETrue );
+                }
+            break;
+            }
+            
+        default:
+            {
+            break;
+            }
         }
     }
 
@@ -851,13 +957,7 @@
 //
 void CAknTreeListView::HandlePointerEventL( const TPointerEvent& aPointerEvent )
     {
-    if ( iFlags.IsSet( EFlagIgnoreButtonUpEvent ) 
-         && aPointerEvent.iType == TPointerEvent::EButton1Up )
-        {
-        return;
-        }
-    
-    if ( GrabbingComponent() != NULL )
+    if ( GrabbingComponent() )
         {
         iPhysicsHandler->ResetEventBlockingStatus();
         }
@@ -912,7 +1012,7 @@
         }
 
     TInt thumbPosition = aScrollBar->ThumbPosition();
-    if ( AknLayoutUtils::LayoutMirrored() &&
+    if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) &&
          aScrollBar != iScrollbarFrame->VerticalScrollBar() )
         {
         const TEikScrollBarModel* model = aScrollBar->Model();
@@ -931,7 +1031,7 @@
         case EEikScrollPageLeft:
         case EEikScrollPageRight:
             iViewLevel = thumbPosition;
-            UpdateScrollbars();
+            UpdateScrollbars( ETrue );
             UpdateAnimation();
             Window().Invalidate( Rect() );
             break;
@@ -943,15 +1043,15 @@
             break;
 
         case EEikScrollThumbReleaseHoriz:
-            UpdateScrollbars();
+            UpdateScrollbars( ETrue );
             break;
 
         case EEikScrollHome:
-            // Not in use!
+            // Not in use
             break;
 
        case EEikScrollEnd:
-           // Not in use!
+           // Not in use
            break;
 
         default:
@@ -1050,7 +1150,8 @@
 
     if ( aDrawNow )
         {
-        Window().Invalidate( Rect() );
+		// DrawNow must be used here.
+        DrawNow();
         }
     }
 
@@ -1134,7 +1235,9 @@
         }
     else if ( IsFocused() && FocusedItemVisible() )
         {
-        TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel, Indention(), IndentionWidth() );
+        TRect rect = iItems[FocusIndex()].HighlightRect( iViewLevel,
+                                                         Indention(),
+                                                         IndentionWidth() );
         Window().Invalidate( rect );
         }
         
@@ -1154,11 +1257,9 @@
     LayoutView();
 
     // Update scrollbars.
-    UpdateScrollbars();
-
-#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    UpdateScrollbars( ETrue );
+
     UpdateIndexes();
-#endif
     AknsUtils::RegisterControlPosition( this, PositionRelativeToScreen() );
     
     TRAP_IGNORE( InitPhysicsL() );
@@ -1200,13 +1301,13 @@
       iStylusDownItemIndex( -1 ),
       iAnimationIID( KAknsIIDQsnAnimList ),
       iIndentionWidth( -1 ),
-      iPhysicsHandler( NULL ),
-      iScrollPhysicsTop( ETrue )
+      iPhysicsHandler( NULL )
       #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       ,iGc(NULL)
       #endif //RD_UI_TRANSITION_EFFECTS_LIST
       ,iItemActionMenu( NULL ),
-      iLongTapDetector( NULL )       
+      iLongTapDetector( NULL ),
+      iOldWinPos( KErrNotFound )
     {
     if ( static_cast<CAknAppUi*>( 
             iCoeEnv->AppUi() )->IsSingleClickCompatible() )
@@ -1216,6 +1317,7 @@
   
     iFlags.Set( EFlagStructureLines );
     iFlags.Set( EFlagIndention );
+    iFlags.Set( EFlagScrollPhysicsTop );
     }
 
 
@@ -1253,9 +1355,10 @@
                                                             &iItems );
         }
 
-    iIsPressedDownState = EFalse;
-    iIsDragged = EFalse;
-    iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this );
+    iFlags.Clear( EFlagIsPressedDownState );   
+    iFlags.Clear( EFlagIsDragged );
+    iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this, this );
+
     if ( iItemActionMenu )
         {
         iLongTapDetector = CAknLongTapDetector::NewL( this );
@@ -1269,6 +1372,15 @@
         {
         EnableHighlight( ETrue );
         }
+    if ( AknLayoutUtils::LayoutMirrored() )
+        {
+        iFlags.Set( EFlagMirroredLayoutInUse );
+        }
+    else
+        {
+        iFlags.Clear( EFlagMirroredLayoutInUse );
+        }
+    LoadMarkingIconsL();
     }
 
 
@@ -1281,10 +1393,7 @@
 void CAknTreeListView::HandleItemAddedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow )
     {
     UpdateVisibleItems();
-    if (aDrawNow)
-        {
-        UpdateScrollbars();
-        }
+    UpdateScrollbars( aDrawNow );
     }
 
 
@@ -1299,7 +1408,7 @@
     // been changed, unless the it receives information from where the
     // specified item was moved.
     UpdateVisibleItems();
-    UpdateScrollbars();
+    UpdateScrollbars( ETrue );
     }
 
 
@@ -1354,10 +1463,7 @@
 void CAknTreeListView::HandleItemRemovedEvent( CAknTreeItem* /*aItem*/, TBool aDrawNow )
     {
     UpdateVisibleItems();
-    if (aDrawNow)
-        {
-        UpdateScrollbars();
-        }
+    UpdateScrollbars( aDrawNow );
     }
 
 
@@ -1380,7 +1486,8 @@
         {
         UpdateVisibleItems();
         }
-    UpdateScrollbars();
+
+    UpdateScrollbars( ETrue );
     }
 
 
@@ -1420,7 +1527,7 @@
         }
 
     UpdateVisibleItems();
-    UpdateScrollbars();
+    UpdateScrollbars( ETrue );
     }
 
 
@@ -1472,10 +1579,8 @@
                 }
             }
         }
-    if ( aDrawNow )
-        {
-        UpdateScrollbars();
-        }
+
+    UpdateScrollbars( aDrawNow );
     }
 
 
@@ -1490,9 +1595,7 @@
     SetFocusIndex( KMinTInt );
     if ( !iItems.Count() )
         {
-#ifdef RD_UI_TRANSITION_EFFECTS_LIST
         UpdateIndexes();
-#endif
         return;
         }
 
@@ -1530,9 +1633,7 @@
             SetFocusIndex( ii );
             }
         }
-#ifdef RD_UI_TRANSITION_EFFECTS_LIST
     UpdateIndexes();
-#endif
     }
 
 
@@ -1578,9 +1679,7 @@
                 item = iterator.Next();
                 }
             }
-#ifdef RD_UI_TRANSITION_EFFECTS_LIST
         UpdateIndexes();
-#endif
         }
     else if ( itemCount && iItems.Count() )
         {
@@ -1613,13 +1712,16 @@
     CAknTreeItem* item = FocusedItem();
     if ( item )
         {
-        if ( MarkingOngoing() )
+        if ( iFlags.IsSet( EFlagMarkingMode ) )
             {
-            MarkItem( item, !item->IsMarked(), ETrue );
+            if ( item->IsMarkable() )
+                {
+                MarkItem( item, !item->IsMarked(), ETrue );
+                }
             }
         else
             {
-            SelectItem( item, true );
+            SelectItem( item, EFalse );
             }
         }
     }
@@ -1631,7 +1733,7 @@
 //
 void CAknTreeListView::HandleRightArrowKeyEvent()
     {
-    if ( AknLayoutUtils::LayoutMirrored() )
+    if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) )
         {
         AscendFocus();
         }
@@ -1648,7 +1750,7 @@
 //
 void CAknTreeListView::HandleLeftArrowKeyEvent()
     {
-    if ( AknLayoutUtils::LayoutMirrored() )
+    if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) )
         {
         DescendFocus();
         }
@@ -1949,7 +2051,10 @@
             // This should not fail, if enough space was reserved for the
             // array, and if it fails, it results only fewer items being
             // shown in the list.
-            iItems.Append( TAknTreeListViewItem() );
+			if ( KErrNone != iItems.Append( TAknTreeListViewItem() ) )
+				{
+				return;
+				}
             }
         }
 
@@ -1962,6 +2067,21 @@
         iterator.SetCurrent( first );
         iterator.Previous();
         }
+    if ( iFlags.IsSet( EFlagMarkingMode ) )    
+        {
+        if ( iFlags.IsSet( EFlagMirroredLayoutInUse ))
+            {
+            itemRect.iBr.iX -= 
+                    AknLayoutScalable_Avkon::list_double_graphic_pane_t1( 
+                            0 ).LayoutLine().ir;        
+            }
+        else
+            {
+            itemRect.iBr.iX -= 
+                    AknLayoutScalable_Avkon::list_double_graphic_pane_t1( 
+                            0 ).LayoutLine().il;
+            }
+        }
 
     // Update items and their rectangles.
     for ( TInt ii = 0; ii < iItems.Count(); ++ii )
@@ -1986,7 +2106,8 @@
     // Fill whole control area with list items when physics enabled
     // and threre is no horizontal scrollbar.  
     if ( iScrollbarFrame &&
-         iScrollbarFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOn && 
+         iScrollbarFrame->ScrollBarVisibility(
+             CEikScrollBar::EHorizontal ) != CEikScrollBarFrame::EOn && 
          viewRect.Height() < Rect().Height() )
         {
         viewRect.iTl.iY = Rect().iTl.iY;
@@ -2004,12 +2125,27 @@
 // scrollbars changes.
 // ---------------------------------------------------------------------------
 //
-void CAknTreeListView::UpdateScrollbars()
+void CAknTreeListView::UpdateScrollbars( TBool aDrawNow )
     {
     if ( iScrollbarFrame )
         {
-        iPhysicsHandler->UpdateScrollIndex( iScrollPhysicsTop );
-        iScrollPhysicsTop = ETrue;
+        TBool drawHorizontal;
+        TBool drawVertical;
+        if ( !aDrawNow )
+            {
+            // Backup the old values.
+            iScrollbarFrame->DrawBackgroundState( drawHorizontal,
+                                                  drawVertical );
+        
+            // Disable the scrollbar background drawing for the duration
+            // of this call.
+            iScrollbarFrame->DrawBackground( EFalse, EFalse );
+            }
+            
+        iPhysicsHandler->UpdateScrollIndex( 
+                iFlags.IsSet( EFlagScrollPhysicsTop ) );
+        iFlags.Set( EFlagScrollPhysicsTop );
+    
         
         // Get values for horizontal scrollbar.
         TInt hThumbPos = iViewLevel;
@@ -2025,8 +2161,8 @@
             hThumbSpan = a/b;
             hScrollSpan = Max( hThumbPos + hThumbSpan, c/b );
             }
-
-        if ( AknLayoutUtils::LayoutMirrored() )
+        if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) )
+
             {
             hThumbPos = hScrollSpan - ( hThumbPos + hThumbSpan );
             }
@@ -2073,7 +2209,7 @@
             iScrollbarFrame->Tile( &hModel, &vModel );
 
             LayoutView();
-            UpdateScrollbars(); // Recursion
+            UpdateScrollbars( aDrawNow ); // Recursion
             
             // Update animation in case that scrollbar visibility change
             // has affected the highlight size of focused item.
@@ -2083,7 +2219,13 @@
             {
             // Set new model for scrollbars.
             iScrollbarFrame->Tile( &hModel, &vModel );  
-            }        
+            }
+        
+        if ( !aDrawNow )
+            {
+            // Restore the previous draw background state values.
+            iScrollbarFrame->DrawBackground( drawHorizontal, drawVertical );
+            }
         }
        
     }
@@ -2534,9 +2676,9 @@
         }
 
     // Exits marking mode.
-    if ( iFlags.IsSet( EFlagMarkingMode ) )
+    if ( iFlags.IsSet( EFlagMarkingState ) )
         {
-        ExitMarkingMode();
+        ExitMarking();
         }
 
     // Remove MSK observer.
@@ -2597,18 +2739,18 @@
 //
 void CAknTreeListView::DoHandleLongPressL()
     {
-    if ( iFlags.IsClear( EFlagMarkingMode ) )
+    if ( iFlags.IsClear( EFlagMarkingState ) )
         {
-        EnterMarkingMode();
+        EnterMarking();
         }
     }
 
 
 // ---------------------------------------------------------------------------
-// Enters marking mode.
+// Enters marking state.
 // ---------------------------------------------------------------------------
 //
-void CAknTreeListView::EnterMarkingMode()
+void CAknTreeListView::EnterMarking()
     {
     CEikButtonGroupContainer* bgc;
     CCoeControl* MSK = NULL;
@@ -2642,7 +2784,7 @@
             {
             ReportTreeListEvent( MAknTreeListObserver::EMarkingModeEnabled,
                 iTree.Id( FocusedItem() ) );
-            iFlags.Set( EFlagMarkingMode );
+            iFlags.Set( EFlagMarkingState );
             bgc->DrawNow();
             }
         }
@@ -2650,12 +2792,12 @@
 
 
 // ---------------------------------------------------------------------------
-// Exits marking mode.
+// Exits marking state.
 // ---------------------------------------------------------------------------
 //
-void CAknTreeListView::ExitMarkingMode()
+void CAknTreeListView::ExitMarking()
     {
-    if ( iFlags.IsSet( EFlagMarkingMode ) )
+    if ( iFlags.IsSet( EFlagMarkingState ) )
         {
         CEikButtonGroupContainer* bgc = NULL;
         CCoeControl* MSK = NULL;
@@ -2675,7 +2817,7 @@
             }
         ReportTreeListEvent( MAknTreeListObserver::EMarkingModeDisabled,
             iTree.Id( FocusedItem() ) );
-        iFlags.Clear( EFlagMarkingMode );
+        iFlags.Clear( EFlagMarkingState );
         }
     }
 
@@ -2721,14 +2863,29 @@
 void CAknTreeListView::DrawItemsWithPhysics( const TRect& aRect ) const
     {
     TBool empty = IsEmpty();
-
+    TInt offset = Offset();
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST    
     CWindowGc& gc = iGc && !empty ? *iGc : SystemGc();
-    TInt offset = Offset();
 #else
     CWindowGc& gc = SystemGc();
 #endif
 
+    TInt checkBoxOffset ( 0 );
+    if ( iFlags.IsSet( EFlagMarkingMode ) )
+        {
+        if ( iFlags.IsSet( EFlagMirroredLayoutInUse ) )
+            {   
+            checkBoxOffset = 
+                    AknLayoutScalable_Avkon::list_double_graphic_pane_t1( 
+                            0 ).LayoutLine().ir;                                         
+            }
+        else
+            {
+            checkBoxOffset =           
+                    AknLayoutScalable_Avkon::list_double_graphic_pane_t1( 
+                            0 ).LayoutLine().il;                                         
+            }
+        }
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &gc );
     if ( !empty && transApi )
@@ -2773,13 +2930,57 @@
             }
 #endif // RD_UI_TRANSITION_EFFECTS_LIST
 
+        // text color, used to draw the separator line between list items
+        TRgb textColor( KRgbBlack );
+        AknsUtils::GetCachedColor( skin,
+                                   textColor, 
+                                   KAknsIIDQsnTextColors,
+                                   EAknsCIQsnTextColorsCG6 );
+        if ( iFlags.IsSet( EFlagMarkingMode ) 
+                && iMarkingIconArray 
+                && iMarkingIconArray->Count() == KMarkingModeIconArraySize  )
+
+            {
+            // Set sizes for marking icon bitmaps
+            TRect drawRect; 
+            drawRect = iItems[0].Rect();
+
+            // Rect for the marking icon
+            TRect iconRect = RectFromLayout( drawRect,
+                    AknLayoutScalable_Avkon::list_single_graphic_pane_g1( 0 ) );
+            
+            for ( TInt ii = 0; ii < iMarkingIconArray->Count(); ++ii )
+                {
+                CGulIcon* icon = ( *iMarkingIconArray )[ii];            
+                CFbsBitmap* bitmap = icon->Bitmap();
+
+                if ( bitmap )
+                    {
+                    TSize size( bitmap->SizeInPixels() ); // set size if not already
+                    TSize targetSize( iconRect.Size() );
+
+                    if ( size.iWidth != targetSize.iWidth && size.iHeight
+                            != targetSize.iHeight )
+                        {
+                        AknIconUtils::SetSize( bitmap, targetSize,
+                                EAspectRatioPreservedAndUnusedSpaceRemoved );
+                        }
+                    }
+                }
+            }
         const TInt itemCount = iItems.Count();
         for ( TInt ii = 0; ii < itemCount; ++ii )
             {
             TRect drawRect( iItems[ii].Rect() );
 
+            if ( iFlags.IsSet( EFlagMarkingMode ) )
+                {
+                drawRect.iBr.iX += checkBoxOffset;                    
+                }
+
             if ( iItems[ii].Item() )
                 {
+
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                 TRect tfxDrawRect( drawRect );
                 tfxDrawRect.Move( 0, -offset );
@@ -2789,7 +2990,6 @@
                     transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
                     }
 
-  
                 TRect clippingRect( tfxDrawRect );
                 
                 // If horizontal scrollbar on, reduce clipping rect
@@ -2803,17 +3003,32 @@
                         clippingRect.iBr.iY = viewRect.iBr.iY;
                         }
                     }
+                // Set clipping rect.    
+                if ( clippingRect.Intersects( aRect ) )
+                    {
+                    clippingRect.Intersection( aRect );
+                    gc.SetClippingRect( clippingRect );
+                    }
+                else
+                    {
+                    //Draw nothing if no overlap between item rectangel and given rect.
+                    continue;
+                    }
                 
-                // Set clipping rect.    
-                gc.SetClippingRect( clippingRect );
-
-
                 if ( transApi )
                     {
                     transApi->StopDrawing();
                     }
 #endif
-                TBool focused = ( IsFocused() && FocusedItem() &&
+
+                if ( iItems[ii].Item() != iBottomItem )
+                    {
+                    TRect offsetRect( drawRect );
+                    offsetRect.Move( 0, -offset );
+                    AknListUtils::DrawSeparator( gc, offsetRect, textColor, skin );
+                    }
+                
+                TBool focused = ( FocusedItem() &&
                     iItems[ii].Item() == FocusedItem() );
 
                 if ( SingleClickEnabled() && !HighlightEnabled() )
@@ -2826,24 +3041,33 @@
                     // Draw highlight for focused item.
                     TRect highlightRect( iItems[ii].HighlightRect(
                         iViewLevel, Indention(), IndentionWidth() ) );
+                     
+                    if ( iFlags.IsSet( EFlagMarkingMode ) )
+                        {
+                        highlightRect.iBr.iX = drawRect.iBr.iX;
+                        highlightRect.iTl.iX = drawRect.iTl.iX;
+                        }
 
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                         TRect tfxHighlightRect( highlightRect );
                         tfxHighlightRect.Move( 0, -offset );
 #endif //RD_UI_TRANSITION_EFFECTS_LIST
 
-                    if ( iIsPressedDownState || !DrawAnimation( gc, highlightRect ) )
+                    if ( iFlags.IsSet( EFlagIsPressedDownState ) 
+                            || !DrawAnimation( gc, highlightRect ) )
                         {
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                         if ( transApi )
                             {
                             transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight );
-                            transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, tfxHighlightRect );
+                            transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight,
+                                                   tfxHighlightRect );
                             transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
                             }
 #endif //RD_UI_TRANSITION_EFFECTS_LIST
-
-                        DrawHighlight( gc, highlightRect, iIsPressedDownState );
+                        DrawHighlight( gc, highlightRect, 
+                                iFlags.IsSet( EFlagIsPressedDownState ) );
+
 
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                         if ( transApi )
@@ -2861,29 +3085,91 @@
 #endif //RD_UI_TRANSITION_EFFECTS_LIST
                     }
 
+                if ( iFlags.IsSet( EFlagMarkingMode ) && iMarkingIconArray
+                        && iMarkingIconArray->Count() == 
+                                KMarkingModeIconArraySize )
+                    {
+                    // Rect for the marking icon
+                    TRect iconRect = RectFromLayout( drawRect,
+                        AknLayoutScalable_Avkon::list_single_graphic_pane_g1( 0 ) );
+            
+                    iconRect.Move( 0, -offset );
+                    // unchecked icon
+                    CGulIcon* icon = ( *iMarkingIconArray )[1];                    
+
+                    TBool marked = ( iItems[ii].Item()->IsMarked() );
+                    if ( marked )
+                        {
+                        icon = (*iMarkingIconArray)[0];
+                        }
+
+                    CFbsBitmap* bitmap = icon->Bitmap();
+
+                    if ( bitmap )
+                        {
+                        gc.BitBltMasked( iconRect.iTl, bitmap, 
+                            iconRect.Size(), icon->Mask(), EFalse );
+                       }
+                    }
+                
+                if ( iFlags.IsSet( EFlagMarkingMode ) )
+                    {
+                    drawRect.iBr.iX -= checkBoxOffset;
+                    if ( iFlags.IsClear( EFlagMirroredLayoutInUse ) )
+                        {
+                        gc.SetOrigin( TPoint( checkBoxOffset, 0 ) );
+                        }
+                    }
+
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                 if (iItems[ii].Item()) 
                 {
                 if ( transApi )
                     {
-                    transApi->BeginRedraw(MAknListBoxTfxInternal::EListItem, tfxDrawRect, iTree.VisibleItemIndex(iItems[ii].Item()));
+                    transApi->BeginRedraw(
+                        MAknListBoxTfxInternal::EListItem,
+                        tfxDrawRect,
+                        iTree.VisibleItemIndex( iItems[ii].Item() ) );
                     transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
                     }
 #endif //RD_UI_TRANSITION_EFFECTS_LIST
 
-                // Draw item.
-                iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel,
-                    StructureLines(), Indention(), IndentionWidth() );
+                if ( iFlags.IsSet( EFlagMarkingMode ) )
+                    {
+                    TBool marked = iItems[ii].Item()->IsMarked();
+                    if ( marked )
+                        {
+                        iItems[ii].Item()->SetMarked( EFalse );
+                        }           
+                    iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel,
+                        StructureLines(), Indention(), IndentionWidth() );
+
+                    if ( marked )
+                        {
+                        iItems[ii].Item()->SetMarked( ETrue );
+                        }
+                    }
+                else
+                    {
+                    iItems[ii].Draw( gc, iTree, drawRect, focused, iViewLevel,
+                            StructureLines(), Indention(), IndentionWidth() );                
+                    }
 
 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
                 if ( transApi )
                     {
                     transApi->StopDrawing();
-                    transApi->EndRedraw(MAknListBoxTfxInternal::EListItem, iTree.VisibleItemIndex(iItems[ii].Item()));
+                    transApi->EndRedraw(
+                        MAknListBoxTfxInternal::EListItem,
+                        iTree.VisibleItemIndex( iItems[ii].Item() ) );
                     }
                 }
 #endif //RD_UI_TRANSITION_EFFECTS_LIST
 
+                if ( iFlags.IsSet( EFlagMarkingMode ) )
+                    {
+                    gc.SetOrigin( TPoint( 0, 0 ) );
+                    }
                 }
             }
         }
@@ -2974,7 +3260,7 @@
                 item = iterator.Previous();
                 }
             }
-        iScrollPhysicsTop = EFalse;
+        iFlags.Clear( EFlagScrollPhysicsTop );
         }
         
     }
@@ -2995,8 +3281,11 @@
 // Enables or disables the highlight drawing
 // ---------------------------------------------------------------------------
 //
-void CAknTreeListView::EnableHighlight( TBool aEnabled )
+void CAknTreeListView::EnableHighlight( TBool aEnabled, 
+                                        TBool aPointerEnabled )
     {
+    TBool wasEnabled = iFlags.IsSet( EFlagHighlightEnabled );
+
     if ( aEnabled )
         {
         iFlags.Set( EFlagHighlightEnabled );
@@ -3005,6 +3294,13 @@
         {
         iFlags.Clear( EFlagHighlightEnabled );
         }
+
+    if ( !aPointerEnabled
+            && ( ( wasEnabled && !aEnabled )
+                    || ( !wasEnabled && aEnabled ) ) )
+        {
+        ReportCollectionChangedEvent();
+        }
     }
 
 // ---------------------------------------------------------------------------
@@ -3036,7 +3332,7 @@
 TUint CAknTreeListView::CollectionState() const
     {
     TUint state( 0 );
-    if ( IsVisible() )
+    if ( IsVisible() && ( !DrawableWindow() || !DrawableWindow()->IsFaded() ) )
         {
         state |= MAknCollection::EStateCollectionVisible;
         }
@@ -3044,6 +3340,17 @@
         {
         state |= MAknCollection::EStateHighlightVisible;
         }
+
+    if ( iList.Flags() & KAknTreeListMarkable )
+        {
+        state |= MAknCollection::EStateMultipleSelection;        
+        }
+    TBool markedItems( EFalse );
+    TRAP_IGNORE( markedItems = HasMarkedItemsL() );
+    if ( markedItems )
+        {
+        state |= MAknCollection::EStateMarkedItems; 
+        }
     return state;
     }
 
@@ -3053,7 +3360,7 @@
 //
 void CAknTreeListView::ItemActionMenuClosed()
     {
-    iFlags.Clear( EFlagIgnoreButtonUpEvent );
+    iOldWinPos = KErrNotFound;
     EnableHighlight( EFalse );
     DrawDeferred();
     }
@@ -3062,12 +3369,187 @@
 // CAknTreeListView::CollectionExtension
 // -----------------------------------------------------------------------------
 //
-TInt CAknTreeListView::CollectionExtension( TUint /*aExtensionId*/,
-        TAny*& /*a0*/, TAny* /*a1*/ )
+TInt CAknTreeListView::CollectionExtension(
+        TUint aExtensionId, TAny*& a0, TAny* /*a1*/ )
     {
+    if ( aExtensionId == MAknMarkingCollection::TYPE )
+        {
+        a0 = static_cast<MAknMarkingCollection*>( this );
+        }
+
     return KErrNone;
     }
 
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::SetMultipleMarkingState
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::SetMultipleMarkingState( TBool aActive )
+    {
+    if ( iFlags.IsSet( EFlagMarkingMode ) != aActive )
+        {
+        if ( !aActive )
+            {
+            TBool markedItems( EFalse );
+            TRAP_IGNORE( markedItems = HasMarkedItemsL() );
+            if ( markedItems )
+                {
+                UnmarkAll();
+                }
+            }
+        
+        EnableMarking( aActive );
+        if ( aActive )
+            {
+            iFlags.Set( EFlagMarkingMode );
+            }
+        else
+            {
+            iFlags.Clear( EFlagMarkingMode );
+            }
+        if ( aActive )
+            {
+            // Expand all items when entering marking mode
+            iTree.Expand(); 
+            }
+        LayoutView();
+        DrawDeferred();
+
+        if ( iList.MarkingModeObserver() )
+            {
+            iList.MarkingModeObserver()->MarkingModeStatusChanged( aActive );
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::MarkingState
+// -----------------------------------------------------------------------------
+//
+TUint CAknTreeListView::MarkingState() const
+    {
+    TUint state( 0 );
+
+    if ( iFlags.IsSet( EFlagMarkingMode ) )
+        {
+        state |= MAknMarkingCollection::EStateMarkingMode;
+
+        TBool markedItems ( EFalse );
+        TRAP_IGNORE( markedItems = HasMarkedItemsL() );
+        if ( markedItems )
+            {
+            state |= MAknMarkingCollection::EStateMarkedItems;
+            }
+        if ( iItems.Count() == 0 )
+            {
+            state |= MAknMarkingCollection::EStateCollectionEmpty;
+            }
+        }
+    return state;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::MarkCurrentItemL
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::MarkCurrentItemL()
+    {
+    if ( iFlags.IsSet( EFlagMarkingMode ) && FocusedItem() && 
+            FocusedItem()->IsMarkable() )    
+        {
+        MarkItem( FocusedItem(), ETrue, ETrue );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::MarkAllL
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::MarkAllL()
+    {
+    if ( iFlags.IsSet( EFlagMarkingMode ) )
+        {
+        TAknTreeIterator iterator = iTree.Iterator();
+        CAknTreeItem* item = NULL;
+        item = iterator.First(); 
+        while ( item && iterator.HasNext() )
+            {
+            if ( item->IsMarkable() )
+                {
+                MarkItem( item, ETrue, EFalse );
+                }
+            item = iterator.Next();
+            }
+        DrawDeferred(); 
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::UnmarkAll
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::UnmarkAll()
+    {
+    if ( iFlags.IsSet( EFlagMarkingMode ) )
+        {
+        TAknTreeIterator iterator = iTree.Iterator();
+        CAknTreeItem* item = NULL;
+        item = iterator.First(); 
+        while ( item && iterator.HasNext() )
+            {
+            MarkItem( item, EFalse, EFalse );
+            item = iterator.Next();
+            }
+        DrawDeferred(); 
+        }
+    }
+
+
+ // -----------------------------------------------------------------------------
+// CAknTreeListView::CurrentItemMarkable
+// -----------------------------------------------------------------------------
+//
+TBool CAknTreeListView::CurrentItemMarkable()
+    {
+    if ( FocusedItem() && !FocusedItem()->IsMarkable() ) 
+        {
+        return EFalse;
+        }
+    return ETrue; 
+    }
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::ExitMarkingMode
+// -----------------------------------------------------------------------------
+//
+TBool CAknTreeListView::ExitMarkingMode()
+    {
+    if ( iList.MarkingModeObserver() )
+        {
+        return iList.MarkingModeObserver()->ExitMarkingMode();
+        }
+    return ETrue; 
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::ReportCollectionChangedEvent
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::ReportCollectionChangedEvent()
+    {
+    if ( iItemActionMenu )
+        {
+        iItemActionMenu->CollectionChanged( *this );
+        }
+    }
+
+
 // ---------------------------------------------------------------------------
 // CAknTreeListView::HandleLongTapEventL
 // ---------------------------------------------------------------------------
@@ -3076,8 +3558,9 @@
         const TPoint& /*aPenEventLocation*/,
         const TPoint& aPenEventScreenLocation)
     {
-    iFlags.Set( EFlagIgnoreButtonUpEvent );
     iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 );
+    iOldWinPos = DrawableWindow()->OrdinalPosition();
+    IgnoreEventsUntilNextPointerUp();
     }
 
 // ---------------------------------------------------------------------------
@@ -3087,7 +3570,9 @@
 void CAknTreeListView::LongTapPointerEventL(
         const TPointerEvent& aPointerEvent)
     {
-    if ( iLongTapDetector && iItemActionMenu && iItemActionMenu->InitMenuL() )
+    if ( iLongTapDetector && iItemActionMenu 
+            && !( HasMarkedItemsL() && FocusedItem() 
+            && !FocusedItem()->IsMarked() ) && iItemActionMenu->InitMenuL() )
         {
         iLongTapDetector->PointerEventL( aPointerEvent );
         }
@@ -3109,18 +3594,14 @@
 // CAknTreeListView::HasMarkedItemsL
 // ---------------------------------------------------------------------------
 //
-TBool CAknTreeListView::HasMarkedItemsL()
+TBool CAknTreeListView::HasMarkedItemsL() const
     {
     RArray<TInt> selection;
     CleanupClosePushL( selection );
     iList.GetMarkedItemsL( selection );
     TInt count( selection.Count() );
     CleanupStack::PopAndDestroy( &selection );
-    if ( count > 0 )
-         {
-         return ETrue;
-         }
-    return EFalse;
+    return ( count > 0 );
     }
 
 
@@ -3155,10 +3636,19 @@
     {
     return iBottomIndex;
     }
-    
+
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+// ---------------------------------------------------------------------------
+// CAknTreeListView::UpdateIndexes
+// ---------------------------------------------------------------------------
+//
 void CAknTreeListView::UpdateIndexes()
     {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
     iTopIndex = iBottomIndex = iHighlightIndex = 0;
+#else 
+    iBottomIndex = 0;
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
     
     if ( iItems.Count() )
         {
@@ -3166,14 +3656,57 @@
             {
             if (iItems[i].Item())   
                 {
-                iBottomIndex = iTree.VisibleItemIndex(iItems[i].Item());
+                iBottomItem = iItems[i].Item();
+                iBottomIndex = iTree.VisibleItemIndex( iBottomItem );
                 break;
                 }
             }
     
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
         iTopIndex = iTree.VisibleItemIndex(iItems[0].Item());
         iHighlightIndex = iTree.VisibleItemIndex(FocusedItem());
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
         } 
     }
 
-#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+// -----------------------------------------------------------------------------
+// CAknTreeListView::LoadMarkingIconsL
+// -----------------------------------------------------------------------------
+//
+void CAknTreeListView::LoadMarkingIconsL()
+    {
+    if ( !iMarkingIconArray )
+        {
+        iMarkingIconArray = new ( ELeave ) 
+            CAknIconArray( KMarkingModeIconArraySize ); 
+        }
+    else
+        {
+        iMarkingIconArray->ResetAndDestroy();
+        }
+
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    const TDesC& avkonIconFile = AknIconUtils::AvkonIconFileName();
+
+    CGulIcon* icon = AknsUtils::CreateGulIconL( skin, 
+            KAknsIIDQgnPropCheckboxOn, 
+            avkonIconFile, 
+            EMbmAvkonQgn_prop_checkbox_on, 
+            EMbmAvkonQgn_prop_checkbox_on_mask );
+    
+    CleanupStack::PushL( icon );
+    iMarkingIconArray->AppendL( icon );
+    CleanupStack::Pop( icon );
+
+    icon = AknsUtils::CreateGulIconL( skin, 
+            KAknsIIDQgnPropCheckboxOff, 
+            avkonIconFile, 
+            EMbmAvkonQgn_prop_checkbox_off, 
+            EMbmAvkonQgn_prop_checkbox_off_mask );
+
+    CleanupStack::PushL( icon );
+    iMarkingIconArray->AppendL( icon );
+    CleanupStack::Pop( icon );
+    }
+