uifw/AvKon/src/akngridview.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/akngridview.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,2040 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  CAknGridView handles the drawing, the mapping
+*                of the grid data index to the underlying listbox index (and
+*                vice versa) as well as the movement around the grid.
+*
+*/
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefmacros.h>
+#endif
+#include <AknGridView.h>
+#include <AknGridM.h>
+#include <AknUtils.h>
+
+#include <eikenv.h>
+#include <gulutil.h>
+#include <eiklbv.h>
+#include <eiklbi.h>
+#include <eiklbm.h>
+#include <eiklbx.h>
+#include <eiklbx.pan>
+#include <eikpanic.h>
+#include <eikfrlb.h>
+#include <gulutil.h>
+#include <eikfrlbd.h>
+
+#include <AknsDrawUtils.h>
+#include <AknsControlContext.h>
+#include <aknphysics.h>
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+#include <aknlistloadertfx.h>
+#include <aknlistboxtfxinternal.h>
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+#include "akntrace.h"
+
+/**
+ * Local Panic Function and Panic Codes
+ */
+enum TAknGridViewPanicCodes
+    {
+    EAknPanicGridViewGeneralPanic,
+    EAknPanicGridViewInvalidRowIndex,
+    EAknPanicGridViewInvalidColumnIndex,
+    EAknPanicGridViewNoGraphicsContext,
+    EAknPanicGridViewNoModel,
+    EAknPanicGridViewInvalidNumberOfRows,
+    EAknPanicGridViewInvalidNumberOfColumns,
+    EAknPanicGridViewInvalidItemWidth,
+    EAknPanicGridViewInvalidItemHeight
+    };
+
+GLDEF_C void Panic(TAknGridViewPanicCodes aPanic)
+    {
+    _LIT(KPanicCat,"AknGridView");
+    User::Panic(KPanicCat, aPanic);
+    }
+
+
+/**
+ * Constructor
+ */
+EXPORT_C CAknGridView::CAknGridView()
+    {
+    iScrollingType = EScrollFollowsItemsAndLoops;
+    iScrollInSecondaryDimension = EScrollFollowsItemsAndLoops;
+    iGridDetails.iGridDimensions = TSize(1,1);
+    }
+
+/**
+ * Destructor
+ */
+EXPORT_C CAknGridView::~CAknGridView()
+    {
+    }
+
+// data index <-> row/column calculation
+
+/**
+ * Converts a logical position on the grid, where the coordinates are with respect to
+ * the top left hand corner of the grid, to an index for the cell with respect to the
+ * ordering of the cells in the grid.
+ */
+EXPORT_C void CAknGridView::DataIndexFromLogicalPos(
+    TInt& aItemIndex,
+    TInt aRowIndex,
+    TInt aColIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    // row and column orientated from  top left corner which is (0,0)
+
+    // check minimums
+    __ASSERT_ALWAYS((aRowIndex >= 0), Panic(EAknPanicGridViewInvalidRowIndex));
+    __ASSERT_ALWAYS((aColIndex >= 0), Panic(EAknPanicGridViewInvalidColumnIndex));
+
+    _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+    		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+    // calculate number of cells from lowest index corner
+    if (IsPrimaryVertical())
+        {
+        // work out how many complete columns from lowest index
+        // to required position
+        TInt numOfCols = aColIndex;
+        if (!(iGridDetails.iGridFlags & ELeftToRight))
+            numOfCols = (iGridDetails.iGridDimensions.iWidth - 1) - numOfCols;
+
+        // process the row to calculate final index value depending
+        // on orientation of lowest index with respect to the top to
+        // bottom numbering of the rows.
+        TInt adjustment = aRowIndex;
+        if (!(iGridDetails.iGridFlags & ETopToBottom))
+            {
+            adjustment = -(adjustment + 1);
+            numOfCols++;
+            }
+
+        aItemIndex = numOfCols * NumberOfRowsInView();
+        aItemIndex += adjustment;
+        }
+    else
+        {
+        TInt numOfRows = aRowIndex;
+        if (!(iGridDetails.iGridFlags & ETopToBottom))
+            numOfRows = (iGridDetails.iGridDimensions.iHeight - 1) - numOfRows;
+
+        TInt numOfCols  = aColIndex;
+        if (!(iGridDetails.iGridFlags & ELeftToRight))
+            {
+            numOfCols = (NumberOfColsInView() - 1) - numOfCols;
+            }
+
+        aItemIndex = numOfRows * NumberOfColsInView();
+        aItemIndex += numOfCols;
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+/**
+ * Converts an index for a cell in the grid, given with respect to the ordering
+ * of the cells in the grid, to a logical position on the grid, where the coordinates
+ * are with respect to the top left hand corner of the grid.
+ */
+EXPORT_C void CAknGridView::LogicalPosFromDataIndex(
+    TInt aItemIndex,
+    TInt& aRowIndex,
+    TInt& aColIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+    		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+    // refer to DataIndexFromLogicalPos above for explanation of mapping of data indexes
+    if (aItemIndex > 0)
+        {
+        if (IsPrimaryVertical())
+            {
+            aColIndex = aItemIndex / NumberOfRowsInView();
+            aRowIndex = aItemIndex % NumberOfRowsInView();
+            }
+        else
+            {
+            aRowIndex = aItemIndex / NumberOfColsInView();
+            aColIndex = aItemIndex % NumberOfColsInView();
+            }
+        }
+    else
+        {
+        aRowIndex = 0;
+        aColIndex = 0;
+        }
+
+    if (!(iGridDetails.iGridFlags & ELeftToRight))
+        aColIndex = (iGridDetails.iGridDimensions.iWidth - 1) - aColIndex;
+
+    if (!(iGridDetails.iGridFlags & ETopToBottom))
+        aRowIndex = (iGridDetails.iGridDimensions.iHeight - 1) - aRowIndex;
+
+    if (aColIndex < 0)
+        aColIndex = 0;
+    if (aRowIndex < 0)
+        aRowIndex = 0;
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+/**
+ * Converts a CEikListBox index for a cell in the grid, given with respect to the
+ * snaking listbox top down, left to right structure underlying the grid
+ * structure, to a logical position on the grid, where the coordinates are with
+ * respect to the top left hand corner of the grid.
+ */
+EXPORT_C void CAknGridView::ListBoxIndexFromLogicalPos(
+    TInt& aItemIndex,
+    TInt aRowIndex,
+    TInt aColIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+    		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+    // check minimums
+    __ASSERT_DEBUG((aRowIndex >= 0), Panic(EAknPanicGridViewInvalidRowIndex));
+    __ASSERT_DEBUG((aColIndex >= 0), Panic(EAknPanicGridViewInvalidColumnIndex));
+
+    if(IsPrimaryVertical())
+        {
+        aItemIndex = aColIndex * NumberOfRowsInView();
+        aItemIndex += aRowIndex;
+        }
+    else
+        {
+        aItemIndex = aRowIndex * NumberOfColsInView();
+        aItemIndex += aColIndex;
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+/**
+ * Converts a logical position on the grid, where the coordinates are with respect to
+ * the top left hand corner of the grid, to a CEikListBox index for the cell with
+ * respect to the snaking listbox top down, left to right structure underlying the
+ * grid structure.
+ */
+EXPORT_C void CAknGridView::LogicalPosFromListBoxIndex(TInt aItemIndex, TInt& aRowIndex, TInt& aColIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+    		   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+    aColIndex = 0;
+    aRowIndex = 0;
+
+    if (aItemIndex)
+        {
+        if(IsPrimaryVertical())
+            {
+            aColIndex = aItemIndex / NumberOfRowsInView();
+            aRowIndex = aItemIndex % NumberOfRowsInView();
+            }
+        else
+            {
+            aColIndex = aItemIndex % NumberOfColsInView();
+            aRowIndex = aItemIndex / NumberOfColsInView();
+            }
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+// data index <-> listbox index conversion routines
+
+/**
+ * Converts an underlying CEikListBox index into the equivalent grid
+ * cell index given with respect to the ordering of the cells in the grid.
+ */
+EXPORT_C TInt CAknGridView::ActualDataIndex(TInt aListBoxIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aListBoxIndex = %d", 
+    		   __FUNCTION__, aListBoxIndex );
+    TInt logicalRow = 0;
+    TInt logicalCol = 0;
+    LogicalPosFromListBoxIndex(aListBoxIndex, logicalRow, logicalCol);
+
+    TInt dataIndex = 0;
+    DataIndexFromLogicalPos(dataIndex, logicalRow, logicalCol);
+
+    _AKNTRACE_FUNC_EXIT;
+    return dataIndex;
+    }
+
+/**
+ * Converts a grid cell index into the equivalent CEikListBox index for
+ * the underlying snaking listbox top down, left to right structure.
+ */
+EXPORT_C TInt CAknGridView::ListBoxIndex(TInt aDataIndex) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aDataIndex = %d", 
+    		   __FUNCTION__, aDataIndex );
+    TInt logicalRow = 0;
+    TInt logicalCol = 0;
+    LogicalPosFromDataIndex(aDataIndex, logicalRow, logicalCol);
+
+    TInt listBoxIndex = 0;
+    ListBoxIndexFromLogicalPos(listBoxIndex, logicalRow, logicalCol);
+
+    _AKNTRACE_FUNC_EXIT;
+    return listBoxIndex;
+    }
+
+// the current data item
+/**
+ * Returns the current data index with respect to the ordering of the cells in
+ * the grid.
+ */
+EXPORT_C TInt CAknGridView::CurrentDataIndex() const
+    {
+    return ActualDataIndex(iCurrentItemIndex);
+    }
+
+/**
+ * Sets the current data index with a value given with respect to the ordering of
+ * the cells in the grid.
+ */
+EXPORT_C void CAknGridView::SetCurrentDataIndex(TInt aDataIndex)
+    {
+    _AKNTRACE( "[%s] aDataIndex = %d", 
+    		   __FUNCTION__, aDataIndex );
+    TRAP_IGNORE(MoveToItemIndexL(ListBoxIndex(aDataIndex),ENoSelection));
+    }
+
+// grid functions
+
+/**
+ * Checks that number of cells in the grid is always enough to fill the
+ * current grid dimensions. This method should be called after any
+ * method that may alter the amount of data within the grid.
+ *
+ */
+EXPORT_C void CAknGridView::SetGridCellDimensions(TSize aGridDimensions)
+    {
+    // set the new grid size
+    iGridDetails.iGridDimensions = aGridDimensions;
+    }
+
+/**
+ * Returns the current grid dimensions.
+ */
+EXPORT_C TSize CAknGridView::GridCellDimensions() const
+    {
+    return iGridDetails.iGridDimensions;
+    }
+
+/**
+ * Sets the size of the spaces between items.
+ */
+EXPORT_C void CAknGridView::SetSpacesBetweenItems(TSize aSizeOfSpaceBetweenItems)
+    {
+    iGridDetails.iSizeBetweenItems = TSize(0,0);
+    if (aSizeOfSpaceBetweenItems.iWidth > 0)
+        {
+        iGridDetails.iSizeBetweenItems.iWidth=aSizeOfSpaceBetweenItems.iWidth;
+        }
+    if (aSizeOfSpaceBetweenItems.iHeight > 0)
+        {
+        iGridDetails.iSizeBetweenItems.iHeight=aSizeOfSpaceBetweenItems.iHeight;
+        }
+    }
+
+/**
+ * Sets the form of scroll to activate upon reaching the limit when moving in
+ * the primary direction of grid, primary meaning whether the items are
+ * organised vertically or horizontally.
+ */
+EXPORT_C void CAknGridView::SetPrimaryScrollingType(TScrollingType aScrollingType)
+    {
+    iScrollingType = aScrollingType;
+    }
+
+/**
+ * Sets the form of scroll to activate upon reaching the limit when moving in
+ * the secondary direction of grid.
+ */
+EXPORT_C void CAknGridView::SetSecondaryScrollingType(TScrollingType aSecondaryScrolling)
+    {
+    iScrollInSecondaryDimension = aSecondaryScrolling;
+    }
+
+
+/**
+ * Returns true if the primary dimension of the grid is
+ * vertical.
+ */
+EXPORT_C TBool CAknGridView::IsPrimaryVertical() const
+    {
+    return (iGridDetails.iGridFlags & EPrimaryIsVertical);
+    }
+
+/**
+ * Returns ETrue if the CEikListBox index given exists.
+ */
+EXPORT_C TBool CAknGridView::ItemExists(TInt aListBoxIndex) const
+    {
+    TInt totalpossibleitems = iGridDetails.iGridDimensions.iHeight * iGridDetails.iGridDimensions.iWidth;
+
+    return ((aListBoxIndex > -1) && (aListBoxIndex < totalpossibleitems));
+    }
+
+
+/**
+ * This has been overloaded to ensure that only valid cells are drawn
+ * and not the empty cells.
+ */
+EXPORT_C void CAknGridView::DrawItem( TInt aItemIndex ) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d", 
+    		   __FUNCTION__, aItemIndex );
+    if ( RedrawDisabled() || !IsVisible() )
+        {
+        _AKNTRACE_FUNC_EXIT;
+        return;
+        }
+
+    if ( ItemExists( aItemIndex ) )
+        {
+        TBool transparencyEnabled( CAknEnv::Static()->TransparencyEnabled() );
+        TBool drawingInitiated = ETrue;
+        TPoint itemPosition( ItemPos( aItemIndex ) );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+        MAknListBoxTfxInternal* transApi =
+            CAknListLoader::TfxApiInternal( iGc );
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+        if ( transparencyEnabled )
+            {
+            if ( iWin && iWin->GetDrawRect() == TRect::EUninitialized )
+                {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+                drawingInitiated = transApi && !transApi->EffectsDisabled();
+#else
+                drawingInitiated = EFalse;
+#endif
+                }
+
+            if ( !drawingInitiated )
+                {
+                TRect itemRect( itemPosition, ItemSize( aItemIndex ) );
+                itemRect.Intersection( iViewRect );
+                iWin->Invalidate( itemRect );
+                iWin->BeginRedraw( itemRect );
+                }
+            }
+
+        // convert to actual data index
+        TInt dataIndex = ActualDataIndex( aItemIndex );
+
+        __ASSERT_DEBUG( (iGc), Panic( EAknPanicGridViewNoGraphicsContext ) );
+
+        if ( GridModel()->IndexContainsData( dataIndex ) )
+            {
+            // It must be ensured here that an item isn't drawn outside
+            // the view rectangle.
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
+                }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+            iGc->SetClippingRect( iViewRect );
+            
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StopDrawing();
+                }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+            iItemDrawer->DrawItem(
+                dataIndex,
+                itemPosition,
+                ItemIsSelected( aItemIndex ),
+                aItemIndex == iCurrentItemIndex,
+                ( iFlags & EEmphasized ) == EEmphasized,
+                ( iFlags & EDimmed ) == EDimmed );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
+                }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+            iGc->CancelClippingRect();
+            
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StopDrawing();
+                }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+            }
+        else
+            {
+            static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer )->
+                DrawEmptyItem( dataIndex,
+                               ItemPos( aItemIndex ),
+                               ( iFlags & EDimmed ) == EDimmed );
+            }
+
+        if ( transparencyEnabled && !drawingInitiated )
+            {
+            iWin->EndRedraw();
+            }
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+
+/**
+ * This has been overloaded to ensure that if no cells exist in the
+ * grid then an empty grid is displayed. And also to correct drawing.
+ */
+EXPORT_C void CAknGridView::Draw( const TRect* aClipRect ) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "The rect of grid are ( %d, %d ) ( %d, %d )", 
+    		   aClipRect->iTl.iX, aClipRect->iTl.iY, 
+    		   aClipRect->iBr.iX, aClipRect->iBr.iY );
+    if ( RedrawDisabled() || iItemHeight == 0 || ColumnWidth() == 0 )
+        {
+        _AKNTRACE_FUNC_EXIT;
+        return;
+        }
+
+    if ( GridModel()->NumberOfData() == 0 )
+        {
+        DrawEmptyList();
+        }
+    else
+        {
+        if (RedrawDisabled())
+        	{
+        	_AKNTRACE_FUNC_EXIT;
+            return;
+        	}
+        __ASSERT_DEBUG(iModel, Panic(EAknPanicGridViewNoModel));
+        if (iItemHeight == 0)
+        	{
+        	_AKNTRACE_FUNC_EXIT;
+            return;
+        	}
+        if ( !aClipRect )
+            {
+            aClipRect = &iViewRect;
+            }
+        
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+        MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
+        if ( transApi )
+            {
+            aClipRect = &iViewRect;
+            transApi->SetListType( MAknListBoxTfxInternal::EListBoxTypeGrid );    
+            transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
+            }
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+        iGc->SetClippingRect( *aClipRect );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( transApi )
+        {
+        transApi->StopDrawing();
+        }
+#endif
+
+        TInt numberOfItems( iModel->NumberOfItems() );
+        TInt numberOfCols( NumberOfColsInView() );
+        TInt numberOfCells( numberOfItems );
+        TInt emptyCellsAtEnd( numberOfItems % numberOfCols );
+        if ( emptyCellsAtEnd )
+            {
+            // Add empty cells to the last row if it's not full so
+            // that the whole row gets it's background drawn.
+            numberOfCells += ( numberOfCols - emptyCellsAtEnd );
+            }
+        TInt numberOfRows( numberOfCells / numberOfCols );
+        TInt firstPotentialItemIndex = iTopItemIndex >= numberOfCols ? iTopItemIndex - numberOfCols : iTopItemIndex;
+        TInt lastPotentialItemIndex = iTopItemIndex + 
+            ( NumberOfItemsThatFitInRect(iViewRect) * numberOfCols - 1 ) + numberOfCols;
+
+        if ( lastPotentialItemIndex / numberOfCols > numberOfRows )
+            {
+            // Check that there isn't an empty row at the bottom.
+            lastPotentialItemIndex -= numberOfCols;
+            }
+
+        // Clear the unused portion of the viewing area.
+        DrawUnusedViewPortion();
+
+        for ( TInt i = firstPotentialItemIndex; i <= lastPotentialItemIndex; i++ )
+            {
+            if ( ItemExists( i ) )
+                {
+                DrawItem( i );
+                }
+            else
+                {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+                if ( transApi )
+                    {
+                    transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+                    }
+#endif
+
+                iGc->SetClippingRect( *aClipRect );
+                ClearUnusedItemSpace( i, lastPotentialItemIndex );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+                if ( transApi )
+                    {
+                    transApi->StopDrawing();
+                    }
+#endif
+                break;
+                }
+            }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+        if ( transApi )
+            {
+            transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+            }
+#endif
+
+
+        iGc->CancelClippingRect();
+        
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+	    if ( transApi )
+	        {
+            transApi->StopDrawing();
+            }
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+
+// ---------------------------------------------------------------------------
+// This function has been overloaded to draw items correctly.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TPoint CAknGridView::ItemPos( TInt aItemIndex ) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d", 
+    		   __FUNCTION__, aItemIndex );
+    TInt rowIndex = 0;
+    TInt colIndex = 0;
+    CalcRowAndColIndexesFromItemIndex( aItemIndex, rowIndex, colIndex );
+    
+    TPoint itemPos(
+        iViewRect.iTl.iX + colIndex *
+            ( ColumnWidth() + iGridDetails.iSizeBetweenItems.iWidth ),
+        iViewRect.iTl.iY + rowIndex *
+            ( iItemHeight + iGridDetails.iSizeBetweenItems.iHeight ) + iVerticalOffset );
+    
+    _AKNTRACE_FUNC_EXIT;
+    return itemPos;
+    }
+
+
+// ---------------------------------------------------------------------------
+// This function has been overloaded to draw items correctly.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknGridView::CalcBottomItemIndex()
+    {
+    _AKNTRACE_FUNC_ENTER;
+    TInt numberOfItems( iModel->NumberOfItems() );
+    iBottomItemIndex =
+        iTopItemIndex + iGridDetails.iPageSize - 1 + iGridDetails.iColsInView;
+    if ( iBottomItemIndex - iGridDetails.iColsInView >= numberOfItems - 1 )
+        {
+        iBottomItemIndex -= iGridDetails.iColsInView;
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+
+// ---------------------------------------------------------------------------
+// This function has been overloaded to draw items correctly.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknGridView::CalcNewTopItemIndexSoItemIsVisible(
+    TInt aItemIndex ) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aItemIndex = %d", 
+    		   __FUNCTION__, aItemIndex );
+    TInt newTopItemIndex = iTopItemIndex;
+
+    if ( aItemIndex != iTopItemIndex )
+        {
+        if ( IsPrimaryVertical() )
+            {
+            TInt numOfRowsInView = NumberOfRowsInView();
+            TInt colIndexOfTargetItem = aItemIndex / numOfRowsInView;
+            TInt numOfColsInView = NumberOfColsInView();
+            if ( aItemIndex < iTopItemIndex )
+                {
+                newTopItemIndex = colIndexOfTargetItem * numOfRowsInView;
+                }
+            else if ( aItemIndex > iBottomItemIndex )
+                {
+                TInt colIndexOfNewBottomItem = colIndexOfTargetItem;
+                TInt colIndexOfNewTopItem =
+                    colIndexOfNewBottomItem - ( numOfColsInView - 1 );
+                newTopItemIndex = colIndexOfNewTopItem * numOfRowsInView;
+                }
+            }
+        else
+            {
+            TInt numOfColsInView = NumberOfColsInView();
+            TInt rowIndexOfTargetItem = aItemIndex / numOfColsInView;
+            TInt numOfRowsInView = NumberOfRowsInView();
+            
+			if ( aItemIndex < iTopItemIndex )
+                {
+                newTopItemIndex = rowIndexOfTargetItem * numOfColsInView;
+                }
+            else if ( aItemIndex > iBottomItemIndex - numOfColsInView )
+                {
+                TInt rowIndexOfNewBottomItem = rowIndexOfTargetItem;
+                TInt rowIndexOfNewTopItem =
+                    rowIndexOfNewBottomItem - ( numOfRowsInView - 1 );
+                newTopItemIndex = rowIndexOfNewTopItem * numOfColsInView;
+                }
+            }
+        }
+
+    _AKNTRACE_FUNC_EXIT;
+    return newTopItemIndex;
+    }
+
+
+/**
+ * This function has been overloaded to draw items correctly.
+ */
+EXPORT_C void CAknGridView::DrawItemRange( TInt aStartItemIndex,
+                                           TInt aEndItemIndex ) const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    _AKNTRACE( "[%s] aStartItemIndex = %d aEndItemIndex = %d", 
+    		   __FUNCTION__, aStartItemIndex, aEndItemIndex );
+    if ( RedrawDisabled() || iItemHeight == 0 )
+        {
+        _AKNTRACE_FUNC_EXIT;
+        return;
+        }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
+#endif
+    // Clear the unused portion of the viewing area.
+    DrawUnusedViewPortion();
+
+    for ( TInt i = aStartItemIndex; i <= aEndItemIndex; i++ )
+        {
+        if ( ItemExists( i ) )
+            {
+            DrawItem( i );
+            }
+        else
+            {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+                }
+#endif
+            ClearUnusedItemSpace( i, aEndItemIndex );
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            if ( transApi )
+                {
+                transApi->StopDrawing();
+                }
+#endif
+            break;
+            }
+        }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( transApi )
+        {
+        transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+        }
+#endif
+
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( transApi )
+        {
+        transApi->StopDrawing();
+        }
+#endif
+    _AKNTRACE_FUNC_EXIT;
+	}
+
+/**
+ * This function may be overloaded to detail an empty grid as required.
+ */
+EXPORT_C void CAknGridView::DrawEmptyList() const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	iGc->SetClippingRect(iViewRect);
+	iItemDrawer->ClearRect(iViewRect);
+
+	if (EmptyListText())
+		{
+		// display empty grid message
+		CFormattedCellListBoxItemDrawer *id = (CFormattedCellListBoxItemDrawer*)ItemDrawer();
+		AknDrawWithSkins::DrawEmptyList(iViewRect, *iGc, *EmptyListText(), id->FormattedCellData()->Control());
+		}
+	iGc->CancelClippingRect();
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+/**
+ * Grid initialisation function. Should only be called by SetLayoutL of
+ * grid box.
+ */
+EXPORT_C void CAknGridView::SetGridDetails(SGrid aGridDetails)
+	{
+	SGrid details = aGridDetails;
+
+	if (details.iSizeBetweenItems.iHeight < 0)
+		{
+		details.iSizeBetweenItems.iHeight = 0;
+		}
+	if (details.iSizeBetweenItems.iWidth < 0)
+		{
+		details.iSizeBetweenItems.iWidth = 0;
+		}
+
+	iGridDetails = details;
+	}
+
+
+// ---------------------------------------------------------------------------
+// This set the current item index and moves the highlight to the specified
+// item index and and scrolls the grid if necessary.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknGridView::MoveToItemIndexL( TInt aItemIndex,
+                                              TSelectionMode aSelectionMode )
+	{
+	_AKNTRACE_FUNC_ENTER;
+	if ( !ItemExists( aItemIndex ) )
+	    {
+	    _AKNTRACE_FUNC_EXIT;
+		return; // nothing to do
+	    }
+	_AKNTRACE( "[%s] aItemIndex = %d TSelectionMode = %d", 
+			   __FUNCTION__, aItemIndex, aSelectionMode );
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
+    if ( transApi )
+        {
+        transApi->SetMoveType( MAknListBoxTfxInternal::EListStartUnknownMove );
+        }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+    
+    TInt oldItemIndex = iCurrentItemIndex;
+    
+    if ( !ScrollToMakeItemVisible( aItemIndex ) )
+        {
+        if ( ItemIsPartiallyVisible( aItemIndex ) )
+            {
+            // ScrollToMakeItemVisible doesn't scroll the view for
+            // partial items, so for key events the scrolling is done here.
+            
+            TInt amountToScroll =
+                CalculateHScrollOffsetSoItemIsVisible( aItemIndex );
+        
+            iHScrollOffset += amountToScroll;        
+            iCurrentItemIndex = aItemIndex;
+            
+            if ( iExtension && !iExtension->iScrollingDisabled )
+                {
+                CFormattedCellListBoxItemDrawer* itemDrawer =
+                    static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
+                CEikListBox* listBox =
+                    static_cast<CEikListBox*>(
+                        itemDrawer->FormattedCellData()->Control() );
+                listBox->HandlePhysicsScrollEventL(
+                    amountToScroll * iItemHeight + ItemOffsetInPixels() );
+                }
+            else
+                {
+                // Do normal scrolling if physics are not enabled.
+                VScrollTo( CalcNewTopItemIndexSoItemIsVisible( aItemIndex ) );
+                }
+            }
+        else
+            {
+            // View was not scrolled, so item is already visible.
+            iCurrentItemIndex = aItemIndex;
+            DrawItem( oldItemIndex );
+            }
+        }
+
+	UpdateSelectionL( aSelectionMode ); // this draws iCurrentItemIndex
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    if ( transApi )
+        {
+        transApi->SetMoveType( MAknListBoxTfxInternal::EListStopUnknownMove );
+        }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+    _AKNTRACE_FUNC_EXIT;
+	}
+
+
+// ---------------------------------------------------------------------------
+// Returns the number of visible columns.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknGridView::NumberOfColsInView() const
+	{
+	__ASSERT_ALWAYS( ( iGridDetails.iColsInView > 0 ),
+	                 Panic( EAknPanicGridViewInvalidNumberOfColumns ) );
+	return iGridDetails.iColsInView;
+	}
+
+
+// ---------------------------------------------------------------------------
+// Returns the number of visible rows.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknGridView::NumberOfRowsInView() const
+	{
+	__ASSERT_ALWAYS( ( iGridDetails.iRowsInView > 0 ),
+	                 Panic( EAknPanicGridViewInvalidNumberOfRows ) );
+	TInt rows = iGridDetails.iRowsInView;
+
+	return rows;
+	}
+
+
+void CAknGridView::MoveCursorWithRepeatsL( 
+        TBool aNextOrPrev, TSelectionMode aSelectionMode, TInt aAmount )
+    {  
+    _AKNTRACE_FUNC_ENTER;
+    TBool singleColumn = EFalse;
+    if ( IsPrimaryVertical() )
+        {
+        singleColumn = iGridDetails.iGridDimensions.iHeight < 2;
+        }
+    else
+        {
+        singleColumn = iGridDetails.iGridDimensions.iWidth < 2;
+        }
+    
+    TCursorMovement cursorMovement;
+    if ( aNextOrPrev )
+        {
+        cursorMovement = CListBoxView::ECursorNextColumn;
+        if ( singleColumn )
+            {
+            cursorMovement = CListBoxView::ECursorNextItem;
+            }
+        }
+    else
+        {
+        cursorMovement = CListBoxView::ECursorPreviousColumn;
+        if ( singleColumn )
+            {
+            cursorMovement = CListBoxView::ECursorPreviousItem;
+            }
+        }
+        
+    TInt step = aAmount;   
+    if ( !singleColumn )
+        {
+        // Stop looping in grids. Looping is still allowed in list like grid.
+        TInt maxIndex = GridModel()->NumberOfData() - 1;
+        TInt dataIndex = CurrentDataIndex();        
+        TBool isToTail = iGridDetails.iGridFlags & ELeftToRight ?
+            aNextOrPrev : !aNextOrPrev;
+
+        if ( dataIndex + step > maxIndex && isToTail )
+            {
+            step = maxIndex - dataIndex;
+            }
+
+        if ( dataIndex < step && !isToTail )
+            {
+            step = dataIndex;
+            }
+        }
+    
+    for ( TInt ii = 0; ii < step; ii++ )
+        {
+        MoveCursorL( cursorMovement, aSelectionMode );
+        }  
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+// -----------------------------------------------------------------------------
+// LISTBOX EFFECTS IMPLEMENTATION
+// 
+// Sets movement type in the transition controller
+//
+// This function is called from DoMoveL before MoveToItemIndexL is called.
+// -----------------------------------------------------------------------------
+//
+void SetMoveType( CWindowGc* aGc,
+                  CAknGridView::TCursorMovement aCursorMovement )
+    {
+    MAknListBoxTfxInternal* api = CAknListLoader::TfxApiInternal( aGc );
+    if ( api )
+	    {
+	    if ( aCursorMovement == CAknGridView::ECursorNextColumn)
+	        {
+            api->SetMoveType( MAknListBoxTfxInternal::EListMoveRight );
+	        }
+	    else if ( aCursorMovement == CAknGridView::ECursorNextItem )
+	        {
+            api->SetMoveType( MAknListBoxTfxInternal::EListMoveDown );
+	        }
+	    else if ( aCursorMovement == CAknGridView::ECursorPreviousItem )
+	        {
+            api->SetMoveType( MAknListBoxTfxInternal::EListMoveUp );
+	        }
+	    else if ( aCursorMovement == CAknGridView::ECursorPreviousColumn )
+	        {
+            api->SetMoveType( MAknListBoxTfxInternal::EListMoveLeft );
+	            }
+	        else
+	            {
+            api->SetMoveType( MAknListBoxTfxInternal::EListNoMovement );
+	            }
+	        }
+    }
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+EXPORT_C void CAknGridView::DoMoveL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TInt rowIndex = 0;
+	TInt colIndex = 0;
+	LogicalPosFromListBoxIndex(iCurrentItemIndex, rowIndex, colIndex);
+
+	TBool moveDown = IsMoveDown(aCursorMovement);
+	TBool moveRight = IsMoveRight(aCursorMovement);
+
+	TInt newIndex = 0;
+	TScrollingType scrollingType = EScrollStops;
+	TBool moveIsVert = (aCursorMovement==ECursorNextItem)||(aCursorMovement==ECursorPreviousItem);
+	TBool moveInPrim = COMPARE_BOOLS(IsPrimaryVertical(),(moveIsVert));
+	if (moveInPrim)
+		scrollingType = iScrollingType;
+	else
+		scrollingType = iScrollInSecondaryDimension;
+
+	switch(scrollingType)
+		{
+		case EScrollStops: // drop through
+		case EScrollFollowsGrid: // drop through
+		case EScrollFollowsItemsAndStops: // drop through
+		case EScrollFollowsItemsAndLoops:
+			newIndex = SearchByLines(colIndex, rowIndex, aCursorMovement);
+			break;
+		case EScrollIncrementLineAndStops: // drop through
+		case EScrollIncrementLineAndLoops:
+			{
+			TBool edgePassed = IsEdgePassed(iCurrentItemIndex, moveDown, moveRight, !moveIsVert, EFalse, newIndex);
+			if (!moveInPrim && edgePassed && (newIndex >=0))
+				{// special scroll
+				TBool specialMoveNeeded = EFalse;
+				LogicalPosFromListBoxIndex(newIndex, rowIndex, colIndex);
+				if (moveIsVert)
+					if ((rowIndex != 0) && (rowIndex != iGridDetails.iGridDimensions.iHeight - 1))
+						specialMoveNeeded = ETrue;
+				else
+					if ((colIndex != 0) && (colIndex != iGridDetails.iGridDimensions.iWidth - 1))
+						specialMoveNeeded = ETrue;
+				if (specialMoveNeeded)
+					{// fake being at the far edge of the grid
+					if (moveRight)
+						colIndex = 0;
+					else
+						colIndex = iGridDetails.iGridDimensions.iWidth - 1;
+
+					if (moveDown)
+						rowIndex = 0;
+					else
+						rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
+
+					TInt newIndex2 = 0; // fake index
+					ListBoxIndexFromLogicalPos(newIndex2, rowIndex, colIndex);
+					iTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(newIndex2);
+					CalcBottomItemIndex();
+					iCurrentItemIndex = newIndex; // set current to actual index we want to move to
+					iHScrollOffset += CalculateHScrollOffsetSoItemIsVisible(newIndex);
+					DrawItemRange(iTopItemIndex, iBottomItemIndex); // draw range for fake index
+					if (ItemIsVisible(newIndex))
+						return; // moved and drawn
+					// need to scroll some more to make the newIndex visable
+					}
+				}
+			}
+			break;
+		default:
+			break;
+		}
+	
+	if (newIndex >=0)
+		{ // found next item to move to
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            SetMoveType( iGc, aCursorMovement );
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+		MoveToItemIndexL(newIndex, aSelectionMode);
+		_AKNTRACE_FUNC_EXIT;
+		return;
+		}
+
+	TInt oldRowIndex = rowIndex;
+	TInt oldColIndex = colIndex;
+	if (moveRight)
+		colIndex = 0;
+	else
+		colIndex = iGridDetails.iGridDimensions.iWidth - 1;
+
+	if (moveDown)
+		rowIndex = 0;
+	else
+		rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
+
+	switch(scrollingType)
+		{// we are at an edge
+		case EScrollStops:
+			{
+			_AKNTRACE_FUNC_EXIT;
+			return; // easy
+			}
+		case EScrollFollowsGrid:
+			newIndex = SearchByLines((moveIsVert ? oldColIndex : colIndex),(moveIsVert ? rowIndex : oldRowIndex), aCursorMovement, ETrue);
+			break;
+		case EScrollFollowsItemsAndStops:
+		case EScrollFollowsItemsAndLoops:
+			newIndex = FindNextItem(iCurrentItemIndex, moveDown, moveRight, !IsPrimaryVertical());
+			if (moveInPrim)
+				{// move in the primary direction of the grid
+				if (newIndex >=0)
+					{ // found next item to move to
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+                        SetMoveType( iGc, aCursorMovement );
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+					MoveToItemIndexL(newIndex, aSelectionMode);
+					_AKNTRACE_FUNC_EXIT;
+					return;
+					}
+				// did not find anything
+				if (iScrollingType == EScrollFollowsItemsAndStops)
+					{
+					_AKNTRACE_FUNC_EXIT;
+					return; // do nothing
+					}
+
+				// then must be EScrollFollowsItemsAndLoops
+				ListBoxIndexFromLogicalPos(newIndex, rowIndex, colIndex);
+				newIndex = FindNextItem(newIndex, moveDown, moveRight, !moveIsVert, ETrue);
+				}
+			else
+				{// move in scondary
+				if (newIndex < 0)
+					{ // no more items
+					if (iScrollInSecondaryDimension == EScrollFollowsItemsAndStops)
+						{
+						_AKNTRACE_FUNC_EXIT;
+						return;
+						}
+					//must be EScrollFollowsItemsAndLoops
+					}
+				else
+					{ // some more items before the end
+					if (moveIsVert)
+						{
+						if (moveRight)
+							colIndex = oldColIndex + 1;
+						else
+							colIndex = oldColIndex - 1;
+						}
+					else
+						{
+						if (moveDown)
+							rowIndex = oldRowIndex + 1;
+						else
+							rowIndex = oldRowIndex - 1;
+						}
+					}
+				newIndex = SearchByLines(colIndex, rowIndex, aCursorMovement, ETrue);
+				}
+			break;
+		case EScrollIncrementLineAndStops:
+			_AKNTRACE_FUNC_EXIT;
+			return; // do nothing
+		case EScrollIncrementLineAndLoops:
+			{
+			ListBoxIndexFromLogicalPos(newIndex, rowIndex, colIndex);
+			newIndex = FindNextItem(newIndex, moveDown, moveRight, !moveIsVert, ETrue);
+			if (!moveInPrim && newIndex >=0)
+				{// may need to have a special scroll
+				TBool specialMoveNeeded = EFalse;
+				LogicalPosFromListBoxIndex(newIndex, rowIndex, colIndex);
+				if (moveIsVert)
+					if ((rowIndex != 0) && (rowIndex != iGridDetails.iGridDimensions.iHeight - 1))
+						specialMoveNeeded = ETrue;
+				else
+					if ((colIndex != 0) && (colIndex != iGridDetails.iGridDimensions.iWidth - 1))
+						specialMoveNeeded = ETrue;
+				if (specialMoveNeeded)
+					{// first fake being at the far edge of the grid
+					if (moveRight)
+						colIndex = 0;
+					else
+						colIndex = iGridDetails.iGridDimensions.iWidth - 1;
+
+					if (moveDown)
+						rowIndex = 0;
+					else
+						rowIndex = iGridDetails.iGridDimensions.iHeight - 1;
+
+					TInt newIndex2 = 0; // fake index
+					ListBoxIndexFromLogicalPos(newIndex2, rowIndex, colIndex);
+					iTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(newIndex2);
+					CalcBottomItemIndex();
+					iCurrentItemIndex = newIndex; // set current to actual index we want to move to
+					iHScrollOffset += CalculateHScrollOffsetSoItemIsVisible(newIndex);
+					DrawItemRange(iTopItemIndex, iBottomItemIndex); // draw range for fake index
+					if (ItemIsVisible(newIndex))
+						{
+						_AKNTRACE_FUNC_EXIT;
+						return; // moved and drawn
+						}
+					// need to scroll some more to make the newIndex visable
+					}
+				}
+			}
+			break;
+		default:
+			break; // should never get here
+		}
+
+	if (newIndex >=0)
+		{ // found next item to move to
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+            SetMoveType( iGc, aCursorMovement );
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+		MoveToItemIndexL(newIndex, aSelectionMode);
+		}
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+/**
+ * Used with grids which contain empty items
+ * returns the new listbox index of the next item
+ * returns -1 if there is nothing to move to.
+ */
+EXPORT_C TInt CAknGridView::SearchByLines(TInt aX, TInt aY, TCursorMovement aCursorMovement, TBool aBeginSearchOnIndex)
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TInt xMax = iGridDetails.iGridDimensions.iWidth;
+	TInt yMax = iGridDetails.iGridDimensions.iHeight;
+
+	TInt xIteration = 0;
+	TInt yIteration = 0;
+	switch(aCursorMovement)
+		{
+		case ECursorNextColumn:
+				xIteration = 1;
+			break;
+		case ECursorPreviousColumn:
+				xIteration = -1;
+			break;
+		case ECursorNextItem:
+				yIteration = 1;
+			break;
+		case ECursorPreviousItem:
+				yIteration = -1;
+			break;
+		default:
+			break;
+		}
+	// set up first for a Horizontal grid
+	TInt primaryIteration = xIteration;
+	TInt secondaryIteration = yIteration;
+	TInt primaryMax = xMax;
+	TInt secondaryMax = yMax;
+	TInt p = aX;
+	TInt s = aY;
+	// now change variables if it is a Vertical grid
+	if (IsPrimaryVertical())
+		{
+		primaryIteration = yIteration;
+		secondaryIteration = xIteration;
+		primaryMax = yMax;
+		secondaryMax = xMax;
+		p = aY;
+		s = aX;
+		}
+
+	if (!aBeginSearchOnIndex)
+		s += secondaryIteration;
+
+	TInt index = 0;
+	for ( ; (s < secondaryMax) && (s >= 0) ; s += secondaryIteration)
+		{
+		for (TInt primaryOffset = 0;(p - primaryOffset >= 0) || (p + primaryOffset < primaryMax) ; primaryOffset++)
+			{
+			TInt x = 0;
+			TInt y = 0;
+			if (secondaryIteration == 0)
+				{// then we are moving in the primary orientation of the grid 
+				 // so just find the next item in this direction.
+				TInt offSet = (aBeginSearchOnIndex ? primaryOffset : primaryOffset+1);
+				x = p + (primaryIteration * (offSet));
+				if (x < 0 || x >= primaryMax)
+					break;
+				y = s;
+				if (IsPrimaryVertical())
+					{//swap them
+					y = x;
+					x = s;
+					}
+				DataIndexFromLogicalPos(index,y,x);
+				if (GridModel()->IndexContainsData(index))
+					{
+					_AKNTRACE_FUNC_EXIT;
+					return ListBoxIndex(index);
+					}
+				}
+			else
+				{
+				TInt newOffset = p+(primaryOffset);
+				if ((newOffset >= 0) && (newOffset < primaryMax))
+					{
+					x = newOffset;
+					y = s;
+					if (IsPrimaryVertical())
+						{
+						x = s;
+						y = newOffset;
+						}
+					DataIndexFromLogicalPos(index,y,x);
+					if (GridModel()->IndexContainsData(index))
+						{
+						_AKNTRACE_FUNC_EXIT;
+						return ListBoxIndex(index);
+						}
+					}
+				newOffset = p-(primaryOffset);
+				if ((newOffset >= 0) && (newOffset < primaryMax))
+					{
+					x = newOffset;
+					y = s;
+					if (IsPrimaryVertical())
+						{
+						x = s;
+						y = newOffset;
+						}
+					DataIndexFromLogicalPos(index,y,x);
+					if (GridModel()->IndexContainsData(index))
+						{
+						_AKNTRACE_FUNC_EXIT;
+						return ListBoxIndex(index);
+						}
+					}
+				}
+			}
+		if (secondaryIteration == 0)
+			{// no more items
+			_AKNTRACE_FUNC_EXIT;
+			return -1;
+			}
+		}
+	_AKNTRACE_FUNC_EXIT;
+	// no more items
+	return -1;
+	}
+
+EXPORT_C TInt CAknGridView::FindNextItem(TInt aItemIndex, TBool aLookDown, TBool aLookRight, TBool aFirstLookHorizontal, TBool aBeginSearchOnIndex)
+	{
+	TInt newIndex = 0;
+	IsEdgePassed(aItemIndex, aLookDown, aLookRight, aFirstLookHorizontal, aBeginSearchOnIndex, newIndex);
+	return newIndex;
+	}
+
+TBool CAknGridView::IsEdgePassed(TInt aItemIndex, TBool aLookDown, TBool aLookRight, TBool aFirstLookHorizontal, TBool aBeginSearchOnIndex, TInt& aNewIndex)
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TInt rowIndex = 0;
+	TInt colIndex = 0;
+
+	LogicalPosFromListBoxIndex(aItemIndex, rowIndex, colIndex);
+
+	TInt x = 0;
+	TInt y = 0;
+	TBool edgePassed = EFalse;
+
+	CAknGridM* gridModel = GridModel();
+	TInt newDataIndex = -1;
+	if (aFirstLookHorizontal)
+		{
+		x = (aBeginSearchOnIndex ? colIndex : (aLookRight ? colIndex + 1 : colIndex - 1));
+		for (y = rowIndex; (y>=0) && (y < iGridDetails.iGridDimensions.iHeight); y = (aLookDown ? y+1 : y-1))
+			{
+			for ( ; (x>=0) && (x<iGridDetails.iGridDimensions.iWidth); x = (aLookRight ? x+1 : x-1))
+				{
+				DataIndexFromLogicalPos(newDataIndex,y,x);
+				if (gridModel->IndexContainsData(newDataIndex))
+					{
+					aNewIndex = ListBoxIndex(newDataIndex);
+					_AKNTRACE_FUNC_EXIT;
+					return edgePassed;
+					}
+				}
+			edgePassed = ETrue;
+			if (aLookRight)
+				x = 0;
+			else
+				x = iGridDetails.iGridDimensions.iWidth - 1;
+			}
+		}
+	else
+		{
+		y = (aBeginSearchOnIndex ? rowIndex : (aLookDown ? rowIndex + 1 : rowIndex - 1));
+		for (x = colIndex; (x>=0) && (x < iGridDetails.iGridDimensions.iWidth); x = (aLookRight ? x+1 : x-1))
+			{
+			for ( ; (y>=0) && (y<iGridDetails.iGridDimensions.iHeight); y = (aLookDown ? y+1 : y-1))
+				{
+				DataIndexFromLogicalPos(newDataIndex,y,x);
+				if (gridModel->IndexContainsData(newDataIndex))
+					{
+					aNewIndex = ListBoxIndex(newDataIndex);
+					_AKNTRACE_FUNC_EXIT;
+					return edgePassed;
+					}
+				}
+			edgePassed = ETrue;
+			if (aLookDown)
+				y = 0;
+			else
+				y = iGridDetails.iGridDimensions.iHeight - 1;
+			}
+		}
+
+	aNewIndex = -1;
+	_AKNTRACE_FUNC_EXIT;
+	return edgePassed;
+	}
+
+
+TBool CAknGridView::IsMoveRight(TCursorMovement aCursorMovement)
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TBool moveRight = EFalse;
+	switch(aCursorMovement)
+		{
+		case ECursorNextItem:
+			moveRight = COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
+			break;
+		case ECursorPreviousItem:
+			moveRight = !COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
+			break;
+		case ECursorNextColumn:
+			moveRight = ETrue;
+			break;
+		case ECursorPreviousColumn:
+			moveRight = EFalse;
+			break;
+		default:
+			break;
+		}
+	_AKNTRACE_FUNC_EXIT;
+	return moveRight;
+	}
+
+TBool CAknGridView::IsMoveDown(TCursorMovement aCursorMovement)
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TBool moveDown = EFalse;
+	switch(aCursorMovement)
+		{
+		case ECursorNextItem:
+			moveDown = ETrue;
+			break;
+		case ECursorPreviousItem:
+			moveDown = EFalse;
+			break;
+		case ECursorNextColumn:
+			moveDown = COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
+			break;
+		case ECursorPreviousColumn:
+			moveDown = !COMPARE_BOOLS((iGridDetails.iGridFlags & ETopToBottom),(iGridDetails.iGridFlags & ELeftToRight));
+			break;
+		default:
+			break;
+		}
+	_AKNTRACE_FUNC_EXIT;
+	return moveDown;
+	}
+
+
+/**
+ * Overloaded MoveCursorL method to process cursor movement according to
+ * orientation of the grid.
+ */
+EXPORT_C void CAknGridView::MoveCursorL(TCursorMovement aCursorMovement, TSelectionMode aSelectionMode)
+	{ 
+	_AKNTRACE_FUNC_ENTER;
+	// This is driving method for all movement around the grid
+
+	// check that actually some data in the grid
+	if (GridModel()->NumberOfData() == 0)
+		{
+		_AKNTRACE_FUNC_EXIT;
+		return;
+		}
+
+#if defined(_DEBUG)
+	switch (aCursorMovement)
+		{
+		// page movements
+		case ECursorFirstItem: // go back first index
+			MoveToItemIndexL(0, aSelectionMode);
+			_AKNTRACE_FUNC_EXIT;
+			return;
+		case ECursorLastItem: // go to last index
+			MoveToItemIndexL(GridModel()->IndexOfLastDataItem(), aSelectionMode);
+			_AKNTRACE_FUNC_EXIT;
+			return;
+		case ECursorNextPage: 
+			MoveToItemIndexL((iCurrentItemIndex+iGridDetails.iPageSize < GridModel()->NumberOfData() ? iCurrentItemIndex+iGridDetails.iPageSize : GridModel()->NumberOfData() - 1), aSelectionMode);
+			_AKNTRACE_FUNC_EXIT;
+			return;
+		case ECursorPreviousPage: 
+			MoveToItemIndexL((iCurrentItemIndex-iGridDetails.iPageSize >= 0 ? iCurrentItemIndex-iGridDetails.iPageSize : 0 ), aSelectionMode);
+			_AKNTRACE_FUNC_EXIT;
+			return;
+		default: 
+			break;
+		}
+#endif
+	// perform movement required
+	DoMoveL(aCursorMovement, aSelectionMode);
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+/**
+ * Sets the width of the grid column. This should only be called via
+ * the selection box class's SetColumnWidth method.
+ */
+EXPORT_C void CAknGridView::SetColumnWidth(TInt aColumnWidth)
+	{
+	__ASSERT_ALWAYS((aColumnWidth > 0), Panic(EAknPanicGridViewInvalidItemWidth));
+
+	_AKNTRACE( " [%s] aColumnWidth = %d", 
+			   __FUNCTION__, aColumnWidth );
+	iGridDetails.iSizeOfItems.iWidth = aColumnWidth;
+
+	iItemDrawer->SetItemCellSize(ItemSize());
+	}
+
+/////////////////////////////////////////////////
+//////////////////////////////////////////////////
+
+EXPORT_C void CAknGridView::SetTopItemIndex(TInt aNewTopItemIndex)
+	{
+	_AKNTRACE( "[%s] aNewTopItemIndex = %d", 
+			   __FUNCTION__, aNewTopItemIndex );
+	if (iViewRect.Height() == 0)
+		return;
+	CListBoxView::SetTopItemIndex(aNewTopItemIndex);
+	UpdateHScrollOffsetBasedOnTopItemIndex();
+	}
+
+EXPORT_C void CAknGridView::SetItemHeight(TInt aItemHeight)
+	{
+	_AKNTRACE( "[%s] aItemHeight = %d", 
+			   __FUNCTION__, aItemHeight );
+	CListBoxView::SetItemHeight(aItemHeight);
+	iGridDetails.iSizeOfItems.iHeight = aItemHeight;
+	CalcBottomItemIndex();
+	UpdateHScrollOffsetBasedOnTopItemIndex();
+	}
+
+
+// ---------------------------------------------------------------------------
+// Returns ETrue and sets aItemIndex to the index of the item whose
+// bounding box contains aPosition, or EFalse if no such item exists. 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknGridView::XYPosToItemIndex( TPoint aPosition,
+                                               TInt& aItemIndex ) const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TBool itemFound = EFalse;
+
+	if ( ColumnWidth() == 0 || iItemHeight == 0 )
+	    {
+		return EFalse;
+	    }
+
+	if ( iViewRect.Contains( aPosition ) )
+		{
+		// aPosition is inside the display area
+		TInt yOffsetFromViewRectOrigin = aPosition.iY - iViewRect.iTl.iY - iVerticalOffset;
+		TInt xOffsetFromViewRectOrigin = aPosition.iX - iViewRect.iTl.iX;
+		TInt xItemPlusGap = ColumnWidth() + iGridDetails.iSizeBetweenItems.iWidth;
+		TInt yItemPlusGap = iItemHeight + iGridDetails.iSizeBetweenItems.iHeight;
+		TInt colIndex = xOffsetFromViewRectOrigin / xItemPlusGap;
+		TInt rowIndex = yOffsetFromViewRectOrigin / yItemPlusGap;
+		TInt numberOfRowsInView = NumberOfRowsInView();
+		
+		if ( yOffsetFromViewRectOrigin < 0 )
+		    {
+		    rowIndex = -1;
+		    }
+		else if ( yOffsetFromViewRectOrigin > iViewRect.Height() )
+		    {
+            // Ensure it will not go out of boundary...
+		    rowIndex = Min( rowIndex, numberOfRowsInView);
+		    }
+		
+        // If column or row is bigger than there are in view,
+        // then item is not found.
+        if ( colIndex >= NumberOfColsInView() ||
+             rowIndex > numberOfRowsInView ||
+             colIndex < 0 ||
+             rowIndex < -1 )
+            {
+            itemFound = EFalse;
+            }
+        else
+            {
+            // Need to take into account the gaps.
+            TInt yItemOffset = yOffsetFromViewRectOrigin % yItemPlusGap;
+            TInt xItemOffset = xOffsetFromViewRectOrigin % xItemPlusGap;
+            if ( yItemOffset > iItemHeight || xItemOffset > ColumnWidth() )
+                {
+                _AKNTRACE_FUNC_EXIT;
+                return EFalse;
+                }
+
+            // Now work out the item index given that we know which
+            // row and column it is in.
+            TInt itemIndex;
+            CalcItemIndexFromRowAndColIndexes( itemIndex,
+                                               rowIndex,
+                                               colIndex );
+
+            // Error correction that becomes tapping partially
+            // filled colour selection grid.
+            if ( ItemExists( itemIndex ) &&
+                 GridModel()->IndexContainsData( ActualDataIndex( itemIndex ) ) )
+                {
+                aItemIndex = itemIndex;
+                itemFound = ETrue;
+                }
+            }
+        }
+
+	_AKNTRACE_FUNC_EXIT;
+    return itemFound;
+    }
+
+
+EXPORT_C void CAknGridView::CalcDataWidth() 
+	{
+	iDataWidth = iGridDetails.iGridDimensions.iWidth;
+	}
+
+EXPORT_C TInt CAknGridView::VisibleWidth(const TRect& aRect) const
+	{
+	return aRect.Width() / ColumnWidth();
+	}
+
+
+// ---------------------------------------------------------------------------
+// Scrolls the view so that the item with the given index becomes visible
+// if it's currently outside of the view rectangle.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknGridView::ScrollToMakeItemVisible( TInt aItemIndex )
+	{
+	_AKNTRACE_FUNC_ENTER;
+	_AKNTRACE( "[%s] aItemIndex = %d", 
+			   __FUNCTION__, aItemIndex );
+	if ( iViewRect.Height() == 0 || iItemHeight == 0 )
+	    {
+	    _AKNTRACE_FUNC_EXIT;
+	    return EFalse;
+	    }
+	
+    const TBool redrawDisabled = RedrawDisabled();
+    TPoint itemPosition( ItemPos( aItemIndex ) );
+    TBool itemPartiallyVisible = ItemIsPartiallyVisible( aItemIndex );
+
+    if ( itemPartiallyVisible || ItemIsVisible( aItemIndex ) )
+        {
+        _AKNTRACE_FUNC_EXIT;
+        // Item is already visible, so no scrolling required.
+        return EFalse;
+        }
+    
+    // Item is partially visible or not visible.
+
+	HideMatcherCursor();
+	TInt amountToScroll = CalculateHScrollOffsetSoItemIsVisible( aItemIndex );
+
+	if ( amountToScroll == 0 && !itemPartiallyVisible )
+	    {
+	    _AKNTRACE_FUNC_EXIT;
+		return EFalse;
+	    }
+
+	iHScrollOffset += amountToScroll;
+	TBool gridVertical = IsPrimaryVertical();
+
+	// assume horizontal
+	TInt numOfLinesInViewOrientated = gridVertical ? NumberOfColsInView() :
+                                                     NumberOfRowsInView();
+	TInt numOfLinesInViewOrthogonal = gridVertical ? NumberOfRowsInView() :
+                                                     NumberOfColsInView();
+
+	if ( Abs( amountToScroll ) >= numOfLinesInViewOrientated )
+		{ // Entire view content is changed, so don't bother scrolling.
+		iTopItemIndex += numOfLinesInViewOrthogonal * amountToScroll;
+		CalcBottomItemIndex();
+		iCurrentItemIndex = aItemIndex;
+		iVerticalOffset = 0;
+		
+		if ( !redrawDisabled )
+		    {
+		    Draw();
+		    DrawMatcherCursor();
+		    }
+
+		_AKNTRACE_FUNC_EXIT;
+		return ETrue;
+		}
+
+	iCurrentItemIndex = aItemIndex;
+	
+	if ( iExtension && !iExtension->iScrollingDisabled )
+	    {
+        CFormattedCellListBoxItemDrawer* itemDrawer =
+            static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
+        CEikListBox* listBox =
+            static_cast<CEikListBox*>(
+                itemDrawer->FormattedCellData()->Control() );
+        TRAP_IGNORE( listBox->HandlePhysicsScrollEventL(
+                         amountToScroll * iItemHeight + ItemOffsetInPixels() ) );
+	    }
+    else
+        {
+        // Do normal scrolling if physics are not enabled.
+        VScrollTo( CalcNewTopItemIndexSoItemIsVisible( aItemIndex ) );
+        }
+	
+	_AKNTRACE_FUNC_EXIT;
+	return ETrue;
+	}
+
+
+//////////////////////////////////////////////////
+EXPORT_C TInt CAknGridView::CalculateHScrollOffsetSoItemIsVisible(TInt aItemIndex) 
+	{
+	_AKNTRACE_FUNC_ENTER;
+	_AKNTRACE( "[%s] aItemIndex = %d", 
+			   __FUNCTION__, aItemIndex );
+	// returns the number of cols or rows that we need to scroll, 0 if no scrolling is needed
+	TInt newTopItemIndex = CalcNewTopItemIndexSoItemIsVisible(aItemIndex);
+	TInt numToScroll = 0;
+	if (IsPrimaryVertical())
+		{
+		TInt numOfRowsInView = NumberOfRowsInView();
+		TInt oldHScrollOffset = iHScrollOffset;
+		TInt newHScrollOffset = newTopItemIndex / numOfRowsInView;
+		numToScroll = newHScrollOffset - oldHScrollOffset;
+		}
+	else
+		{
+		TInt logicalRow = 0;
+		TInt logicalCol = 0;
+		LogicalPosFromListBoxIndex(iTopItemIndex, logicalRow, logicalCol);
+		TInt oldHScrollOffset = logicalRow;
+		LogicalPosFromListBoxIndex(newTopItemIndex, logicalRow, logicalCol);
+		TInt newHScrollOffset = logicalRow;
+		numToScroll = newHScrollOffset - oldHScrollOffset;
+		}
+	_AKNTRACE_FUNC_EXIT;
+	return numToScroll;
+	}
+
+EXPORT_C TSize CAknGridView::ItemSize(TInt /*aItemIndex*/) const
+	{
+	return TSize(ColumnWidth(), iItemHeight);
+	}
+
+
+EXPORT_C void CAknGridView::CalcRowAndColIndexesFromItemIndex( TInt aItemIndex,
+                                                               TInt& aRowIndex,
+                                                               TInt& aColIndex ) const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	_AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+			   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+	// Should panic if iItemHeight or iViewRect.Height() is 0.
+	// Assumes specified item is currently visible.
+	TInt numOfItemsFromFirstVisibleItem = (aItemIndex - iTopItemIndex);
+
+	if ( IsPrimaryVertical() )
+		{
+		TInt numOfRowsInView = NumberOfRowsInView();
+		aColIndex = numOfItemsFromFirstVisibleItem / numOfRowsInView;
+		aRowIndex = numOfItemsFromFirstVisibleItem % numOfRowsInView;
+		}
+	else
+		{
+		TInt numOfColsInView = NumberOfColsInView();
+
+		if ( numOfItemsFromFirstVisibleItem < 0 )
+            {
+            // This is possible the visible topmost row is partially drawn
+            // and iTopItemIndex has already moved to the next row.
+            // So this handling is required for the top row to be drawn
+            // correctly.
+            aColIndex = ( numOfItemsFromFirstVisibleItem + numOfColsInView ) % numOfColsInView;
+            aRowIndex = -1;
+            }
+		else
+		    {
+            aColIndex = numOfItemsFromFirstVisibleItem % numOfColsInView;
+            aRowIndex = numOfItemsFromFirstVisibleItem / numOfColsInView;
+		    }
+		}
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+
+// ---------------------------------------------------------------------------
+// Calculates the item index that is on the given row and column indices.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknGridView::CalcItemIndexFromRowAndColIndexes( TInt& aItemIndex,
+                                                               TInt aRowIndex,
+                                                               TInt aColIndex ) const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	_AKNTRACE( "[%s] aItemIndex = %d aRowIndex = %d aColIndex = %d", 
+			   __FUNCTION__, aItemIndex, aRowIndex, aColIndex );
+	// Row index can be -1 if the row above top item index is partially
+	// visible.
+	__ASSERT_DEBUG( aRowIndex >= -1, Panic( EAknPanicGridViewInvalidRowIndex ) );
+	__ASSERT_DEBUG( aColIndex >= 0, Panic( EAknPanicGridViewInvalidColumnIndex ) );
+
+	// Should panic if iItemHeight is 0.
+	if ( IsPrimaryVertical() )
+		{
+		TInt numOfRowsInView = NumberOfRowsInView();
+		aItemIndex = iTopItemIndex + ((aColIndex * numOfRowsInView) + aRowIndex); 
+		}
+	else
+		{
+		TInt numOfColsInView = NumberOfColsInView();
+		aItemIndex = iTopItemIndex + ((aRowIndex * numOfColsInView) + aColIndex); 
+		}
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+
+EXPORT_C void CAknGridView::DrawMatcherCursor()
+	{
+	}
+
+// ---------------------------------------------------------------------------
+// Returns the item index of the currently highlighted item.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknGridView::CurrentItemIndex() const
+	{
+	if ( ItemExists( iCurrentItemIndex ) )
+	    {
+		return iCurrentItemIndex;
+	    }
+	else
+	    {
+	    // Means there is no current item.
+		return KErrNotFound;
+	    }
+	}
+	
+////////////////////////////////// protect
+
+// ---------------------------------------------------------------------------
+// Draws a range of columns.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknGridView::DrawColumnRange( TInt aStartColIndex,
+                                             TInt aEndColIndex ) const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	if ( !RedrawDisabled() && iItemHeight > 0 )
+	    {
+        TInt numOfRowsInView = NumberOfRowsInView();
+        TInt startItemIndex = aStartColIndex * numOfRowsInView;
+        TInt endItemIndex = aEndColIndex * numOfRowsInView + numOfRowsInView - 1;
+        DrawItemRange( startItemIndex, endItemIndex );
+	    }
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+
+EXPORT_C void CAknGridView::ClearUnusedItemSpace(TInt aStartItemIndex, TInt aEndItemIndex) const
+	{
+	_AKNTRACE_FUNC_ENTER;
+	TRect blankRect;
+	for (TInt i = aStartItemIndex; i <= aEndItemIndex; i++)
+		{
+		blankRect.SetRect(ItemPos(i), ItemSize());
+		blankRect.Intersection(iViewRect);
+
+		MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+		CFormattedCellListBoxItemDrawer *id = (CFormattedCellListBoxItemDrawer*)ItemDrawer();
+		if (id->FormattedCellData()->Control())
+			{
+			MAknsControlContext *cc = AknsDrawUtils::ControlContext( id->FormattedCellData()->Control() );
+			if ( !cc )
+			    {
+			    cc = id->FormattedCellData()->SkinBackgroundContext();
+			    }
+			AknsDrawUtils::Background( skin, cc, id->FormattedCellData()->Control(), *iGc, blankRect );
+			}
+		else
+			{
+			iGc->Clear(blankRect);
+			}
+		}
+	_AKNTRACE_FUNC_EXIT;
+	}
+
+EXPORT_C void CAknGridView::UpdateHScrollOffsetBasedOnTopItemIndex()
+	{
+	TInt numOfRowsInView = iGridDetails.iRowsInView;
+	if (numOfRowsInView > 0)
+		iHScrollOffset = iTopItemIndex / numOfRowsInView;
+	}
+
+
+EXPORT_C TAny* CAknGridView::Reserved_1()
+	{
+	return NULL;
+	}
+
+
+// ---------------------------------------------------------------------------
+// Draws the part of the view rectangle in which no items are drawn.  
+// ---------------------------------------------------------------------------
+//
+void CAknGridView::DrawUnusedViewPortion() const
+    {
+    _AKNTRACE_FUNC_ENTER;
+    TInt gapWidth = iGridDetails.iSizeBetweenItems.iWidth;
+    TInt numberOfCols  = iGridDetails.iColsInView;
+    TInt usedViewRectPortionWidth = 
+                numberOfCols * ( ColumnWidth() + gapWidth ) - gapWidth;
+    TRect itemUsedRect;
+    //if the gapWidth > 0, the entire background should be drawn.
+    //So use default value of itemUsedRect (0,0,0,0).
+    //And vice versa the view rect except items used should 
+    //draw background 
+    if ( gapWidth <= 0 )
+        {
+        TPoint endPos( CAknGridView::ItemPos( iBottomItemIndex ).iX + ColumnWidth(),
+        		       CAknGridView::ItemPos( iBottomItemIndex ).iY + iItemHeight );
+        itemUsedRect.SetRect( CAknGridView::ItemPos(iTopItemIndex), endPos );
+        if ( iViewRect.Intersects( itemUsedRect ) )
+            {
+            TRect viewRect( iViewRect );
+            viewRect.Intersection( itemUsedRect );
+            }
+        }
+    iGc->SetBrushColor( BackColor() );
+    CFormattedCellListBoxItemDrawer* itemDrawer =
+        static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
+    MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+
+    CWindowGc* gc = itemDrawer->Gc();
+    if ( !gc )
+        {
+        gc = iGc;
+        }
+
+    CCoeControl* listBoxControl = itemDrawer->FormattedCellData()->Control();
+
+    if ( listBoxControl )
+        {
+        MAknsControlContext *cc = AknsDrawUtils::ControlContext(
+            listBoxControl );
+        if ( !cc )
+            {
+            cc = itemDrawer->FormattedCellData()->SkinBackgroundContext();
+            }
+
+        if ( CAknEnv::Static()->TransparencyEnabled() )
+            {
+            AknsDrawUtils::BackgroundBetweenRects( 
+                skin,
+                cc,
+                listBoxControl, 
+                *iGc,
+                iViewRect,
+                itemUsedRect, 
+                KAknsDrawParamNoClearUnderImage );
+            }
+        else
+            {
+            AknsDrawUtils::BackgroundBetweenRects(
+                skin,
+                cc,
+                listBoxControl,
+                *iGc,
+                iViewRect,
+                itemUsedRect ); 
+            }        
+        }
+    else
+        {
+        DrawUtils::ClearBetweenRects( *gc, iViewRect, itemUsedRect );
+        }
+    _AKNTRACE_FUNC_EXIT;
+    }
+
+// End of File