javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtlistview.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtlistview.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,3623 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Nokia Corporation - S60 implementation
+ *******************************************************************************/
+
+
+#include <AknGridView.h>
+#include <aknlists.h>
+#include <avkon.mbg>
+#include <gulicon.h>
+#include <AknIconArray.h>
+#include <AknLayoutFont.h>
+#include <AknsBasicBackgroundControlContext.h>
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+#include <aknlistloadertfx.h>
+#include <aknlistboxtfx.h>
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+#include <eswtcore.rsg>
+#include <swtlaffacade.h>
+#include "swtcontrolmenu.h"
+#include "swtmenuitem.h"
+#include "swtgrid.h"
+#include "swtlistview.h"
+#include "swtcontrolhelper.h"
+#include "swtinstancecounts.h"
+#include "swtdisplay.h"
+#ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+#include <touchfeedback.h>
+#endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+
+#ifdef ESWT_NATIVE_UITHREAD_OWN_HEAP
+#define DEBUG_CHECK_IMAGES
+#endif // ESWT_NATIVE_UITHREAD_OWN_HEAP
+
+
+// Column indexes of the subcells in the list item format string.
+// Gfx cell has to be first for it to be drawn first.
+static const TInt KIconColumn       = 0;
+static const TInt KTextColumn       = 1;
+static const TInt KItemMarkColumn   = 2;
+
+// Constants used for listbox text string formatting
+const TInt KSpaceForIndex = 20;
+_LIT(KColumnSeparator, "\t");
+_LIT(KSeparatorReplacement, " ");
+
+// The indexes for marked and unmarked icons in the icon array
+_LIT(KMarkOffIconArrayIndex, "1");
+_LIT(KMarkOnIconArrayIndex, "0");
+
+static const TInt KMarkOnIconArrayIndexInt  = 0;
+static const TInt KSwtListViewItemGranularity = 4;
+static const TInt KRowCalculationPrecisionInPixels = 5;
+
+
+// ======== LOCAL FUNCTIONS ========
+
+
+#ifdef DEBUG_CHECK_IMAGES
+static void CheckRefImages(RPointerArray<const MSwtImage>& aRefImgArr,
+                           CArrayPtrFlat<CGulIcon>& aImgArr,
+                           const TSize& aMaxImageSize)
+{
+    TInt countImg = aImgArr.Count() - 2;
+    TInt countRefImg = aRefImgArr.Count();
+
+    if (countImg != countRefImg)
+    {
+        ASSERT(EFalse);
+    }
+
+    for (TInt i = 0; i < countImg; i++)
+    {
+        const CGulIcon* img = aImgArr[i + 2];
+        const MSwtImage* refImg = aRefImgArr[i];
+        if (img)
+        {
+            const CFbsBitmap* bmp = img->Bitmap();
+            const CFbsBitmap* mask = img->Mask();
+
+            ASSERT(bmp);
+            if (refImg)
+            {
+                // The item has a valid image.
+                // The bitmap is NOT owned.
+                ASSERT(img->BitmapsOwnedExternally());
+                const CFbsBitmap& bitmap = refImg->Bitmap();
+                TSize imageSize = refImg->Bitmap().SizeInPixels();
+                imageSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
+                                imageSize, aMaxImageSize);
+
+                __UHEAP_MARK;
+                ASSERT(bmp == &refImg->SubBitmap(imageSize));
+                ASSERT(mask == refImg->SubMaskBitmap(imageSize, ETrue));
+                // If image is not scaled, the primary refcount of
+                // the image >= 2, otherwise it's >= 1 and subrefcount
+                // for the given size should also be >= 1.
+                if (imageSize == refImg->Bitmap().SizeInPixels())
+                {
+                    ASSERT(refImg->RefCount() >= 2);
+                }
+                else
+                {
+                    ASSERT(refImg->RefCount() >= 1);
+                    ASSERT(refImg->SubRefCount(imageSize) >= 1);
+                }
+
+                __UHEAP_MARKEND;
+            }
+            else
+            {
+                // The item has a blank image (null image set from Java side)
+                // The bitmap is owned.
+                ASSERT(bmp->SizeInPixels() == TSize(0, 0));
+                ASSERT(!mask);
+            }
+        }
+    }
+}
+#endif // DEBUG_CHECK_IMAGES
+
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// CSwtListView Constructor
+// ---------------------------------------------------------------------------
+//
+CSwtListView::CSwtListView(MSwtDisplay& aDisplay, TSwtPeer aPeer,
+                           MSwtComposite& aParent, TInt aStyle)
+        : ASwtScrollableBase(aDisplay, aPeer, &aParent, aStyle),
+        iLeftToRight(ETrue),
+        iTopToBottom(ETrue),
+        iNumOfRows(1),
+        iNumOfColumns(1),
+        iWidthOfSpaceBetweenItems(0),
+        iHeightOfSpaceBetweenItems(0),
+        iDensity(EMediumListViewDensity),   // must match Java-side default
+        iIsGridCellLayoutNeeded(EFalse)
+{
+    // Default to horizontal layout orientation (vertical scrollbar)
+    //if( iStyle & KSwtStyleVertical )
+    //    {
+    //    iVerticalOrientation = ETrue;
+    //    }
+    //else
+    //    {
+    iVerticalOrientation = EFalse;
+    iStyle &= ~KSwtStyleHScroll;
+    iStyle |= KSwtStyleVScroll;
+    //    }
+}
+
+// ---------------------------------------------------------------------------
+// 2nd phase construction
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::ConstructL()
+{
+    CCoeControl& coeParent = iParent->Control()->CoeControl();
+    SetContainerWindowL(coeParent);
+
+    CCoeControl::MakeVisible(coeParent.IsVisible());
+    CCoeControl::SetDimmed(coeParent.IsDimmed());
+    SetComponentsToInheritVisibility(ETrue);
+
+    iGrid = new(ELeave) CSwtGrid(this);
+    iGrid->SetContainerWindowL(*this);
+
+    if (AknLayoutUtils::LayoutMirrored())
+    {
+        iLeftToRight = EFalse;
+    }
+
+    // Construct either markable or normal grid
+    TInt gridFlags = 0;
+    if (iStyle & KSwtStyleMulti)
+    {
+#if defined( RD_SCALABLE_UI_V2)
+        // For touch to work the same way as in other lists we need different
+        // list styles for the grid.
+        gridFlags |= CEikListBox::EMultipleSelection |
+                     CEikListBox::ES60StyleMultiselection |
+                     CEikListBox::EShiftEnterMarks;
+#else
+        gridFlags |= EAknListBoxMarkableGrid;
+#endif
+
+        // Create control menu
+        iMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
+
+        iMenuItemEditList = CSwtMenuItem::NewL(iDisplay, NULL, *iMenu, 0, 0);
+        HBufC* buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_EDIT_LIST);
+        TPtrC ptr = buffer->Des();
+        iMenuItemEditList->SetTextL(ptr);
+        CleanupStack::PopAndDestroy(buffer);
+
+        iSubMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
+        iMenuItemEditList->SetMenuL(iSubMenu);
+        iSubMenu->SetObserver(this);
+
+        iMenuItemMarkUnmark = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 0, 0, EAknCmdMark);
+        iMenuItemMarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 1, 0, EAknMarkAll);
+        iMenuItemUnmarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 2, 0, EAknUnmarkAll);
+
+        iMarkString = iCoeEnv->AllocReadResourceL(R_LISTVIEW_MARK_ONE);
+        iUnmarkString = iCoeEnv->AllocReadResourceL(R_LISTVIEW_UNMARK_ONE);
+        ptr.Set(iMarkString->Des());
+        iIsMarkDisplayed = ETrue;
+        iMenuItemMarkUnmark->SetTextL(ptr);
+
+        buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_MARK_ALL);
+        ptr.Set(buffer->Des());
+        iMenuItemMarkAll->SetTextL(ptr);
+        CleanupStack::PopAndDestroy(buffer);
+
+        buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_UNMARK_ALL);
+        ptr.Set(buffer->Des());
+        iMenuItemUnmarkAll->SetTextL(ptr);
+        CleanupStack::PopAndDestroy(buffer);
+
+#ifdef RD_SCALABLE_UI_V2
+        iStylusPopupMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
+        iStylusPopupMenu->SetObserver(this);
+
+        iStylusPopupMarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iStylusPopupMenu, 0, 0, EAknMarkAll);
+        iStylusPopupMarkAll->SetTextL(iMenuItemMarkAll->Text());
+
+        iStylusPopupUnmarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iStylusPopupMenu, 1, 0, EAknUnmarkAll);
+        iStylusPopupUnmarkAll->SetTextL(iMenuItemUnmarkAll->Text());
+#endif //RD_SCALABLE_UI_V2        
+    }
+
+    iOldSelectionArray = new(ELeave) CArrayFixFlat<TInt>(2);
+    iSelectionArray = new(ELeave) CArrayFixFlat<TInt>(2);
+    iGrid->ConstructL(this, gridFlags);
+
+    CArrayPtr< CGulIcon >* icons = new(ELeave) CAknIconArray(KSwtListViewItemGranularity);
+    CleanupStack::PushL(icons);
+
+    // Marked icon
+    CGulIcon* markedIcon = GetMarkedItemIconL();
+    CleanupStack::PushL(markedIcon);
+    icons->AppendL(markedIcon);
+
+    // Unmarked icon
+    CGulIcon* unmarkedIcon = CreateIconL(NULL);
+    CleanupStack::PushL(unmarkedIcon);
+    icons->AppendL(unmarkedIcon);
+
+    // Attach icon array to grid’s item drawer, itemDrawer takes ownership
+    iGrid->ItemDrawer()->FormattedCellData()->SetIconArrayL(icons);
+    CleanupStack::Pop(3, icons);
+
+    DoGridCellLayoutL(iDensity);
+
+    // This is needed to correct skinned background drawing problems when
+    // the control is repositioned.
+    iGrid->ItemDrawer()->ColumnData()->SetSkinEnabledL(EFalse);
+
+    // Create non-window owning scrollbars to avoid clipping problems.
+    iGrid->CreateScrollBarFrameL();
+
+#ifdef RD_SCALABLE_UI_V2
+    // WARNING!!! The expanded touch area does not move correctly togehter with the scrollbars!
+    iGrid->ScrollBarFrame()->SetScrollBarFrameFlags(CEikScrollBarFrame::EDisableExpandedTouchArea);
+#endif // RD_SCALABLE_UI_V2
+
+    // In eSWT all scrollbars must be non window owing the main reason being that
+    // the scrollbars must draw at exact same time with the parent control. This
+    // is especially essential in ScrolledComposite. If the scrollbars would be
+    // window owing, they would draw too much ahead of the parents creating an
+    // ugly visual effect when flicking the ScrolledComposite.
+    // The drawback of having non window owing scrollbars is too many paint events
+    // which affects on the speed of kinetic scrolling in lists.
+    iGrid->ScrollBarFrame()->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, EFalse);
+    iGrid->SetScrollbarVisibility(KSwtStyleVScroll, ETrue);
+    iGrid->SetScrollbarVisibility(KSwtStyleHScroll, EFalse);
+
+    UpdateControlMenu();
+
+    // WORKAROUND! This is to avoid CAknGrid crash when its size is 0
+    // and the List Transition Effects try to draw the grid. In fact the
+    // root cause of the crash is our Shell not being always ready to draw
+    // which is what Avkon expects. If that would be the case, the List
+    // Transition Effects will never get a chance to draw a size 0 grid.
+    iGrid->SetRect(TRect(0, 0, 1, 0));
+
+#ifdef RD_SCALABLE_UI_V2
+    iGrid->SetListBoxObserver(this);
+#endif // RD_SCALABLE_UI_V2
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+    // Effects do not work with non window owning scrollbars.
+    CWindowGc* gc = iGrid->View()->ItemDrawer()->Gc();
+    MAknListBoxTfx* transApi = CAknListLoader::TfxApi(gc);
+    if (transApi)
+    {
+        transApi->EnableEffects(EFalse);
+    }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+
+    // This is indeed necessary, otherwise the background might not be drawn!
+    SetBackground(this);
+
+    ActivateL();
+}
+
+// ---------------------------------------------------------------------------
+// Sets up the grid based on the given density and the style flags received
+// at the construction time. Can/must be called again to reset the layout.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DoGridCellLayoutL(const TSwtListViewDensity& aDensity)
+{
+    // Load the layout data for the resolution
+    TSize cellSize(0, 0);
+    TRect iconSubcell(0, 0, 0, 0);
+    TRect selectionMarkSubcell(0, 0, 0, 0);
+    TRect textSubcell(0, 0, 0, 0);
+    TInt textCellFontId = 0;
+    LoadLayouts(aDensity, cellSize, iconSubcell, selectionMarkSubcell, textSubcell, textCellFontId);
+    ASSERT(textCellFontId != 0);
+
+    CalcRowsColumns(cellSize, iNumOfColumns, iNumOfRows);
+
+    iGrid->SetLayoutL(iVerticalOrientation,
+                      iLeftToRight,
+                      iTopToBottom,
+                      iNumOfColumns,
+                      iNumOfRows,
+                      cellSize,
+                      iWidthOfSpaceBetweenItems,
+                      iHeightOfSpaceBetweenItems);
+    iGrid->SetPrimaryScrollingType(CAknGridView::EScrollIncrementLineAndLoops);
+    iGrid->SetSecondaryScrollingType(CAknGridView::EScrollIncrementLineAndLoops);
+
+    const CAknLayoutFont* font = AknLayoutUtils::LayoutFontFromId(textCellFontId);
+    ASSERT(font != NULL);
+
+    const TInt KTextDefaultColor = 215; // 215 = black, overridden later
+
+    CFormattedCellListBoxItemDrawer* itemDrawer = iGrid->ItemDrawer();
+
+    // Setup the icon subcell
+    AknListBoxLayouts::SetupGridFormGfxCell(
+        *iGrid,                 // Reference to grid control
+        itemDrawer,             // Pointer to the item drawer
+        KIconColumn,            // Column index
+        iconSubcell.iTl.iX,     // Left position
+        iconSubcell.iTl.iY,     // Top position
+        0,                      // Right - unused
+        0,                      // Bottom - unused
+        iconSubcell.Width(),    // Width
+        iconSubcell.Height(),   // Height
+        iconSubcell.iTl,        // Start position
+        iconSubcell.iBr);       // End position
+
+    // Setup the text subcell
+    AknListBoxLayouts::SetupFormTextCell(
+        *iGrid,                     // Reference to grid
+        itemDrawer,                 // Pointer to the item drawer
+        KTextColumn,                // Column index
+        font,                       // The font
+        KTextDefaultColor,          // Color
+        textSubcell.iTl.iX,         // Left margin
+        0,                          // Right margin - unused
+        (textSubcell.iTl.iY + textSubcell.Height() - (font->MaxDescent())),  // Baseline
+        textSubcell.Width(),        // Text width
+        CGraphicsContext::ECenter,  // Text alignment
+        textSubcell.iTl,            // Start position
+        textSubcell.iBr);           // End position
+
+    CFormattedCellListBoxData* gridData = itemDrawer->FormattedCellData();
+    gridData->SetTransparentSubCellL(KTextColumn, ETrue);
+
+    // Set-up markable grid if required
+    if (iStyle & KSwtStyleMulti)
+    {
+        // Set column index in the format string
+        itemDrawer->SetItemMarkPosition(KItemMarkColumn);
+        // Set icon array index of marked item icon
+        itemDrawer->SetItemMarkReplacement(KMarkOnIconArrayIndex);
+        // Don’t display all items as marked initially
+        itemDrawer->SetItemMarkReverse(ETrue);
+        // Setup the selection mark subcell
+        AknListBoxLayouts::SetupFormGfxCell(
+            *iGrid,                         // Reference to grid control
+            itemDrawer,                     // Pointer to the item drawer
+            KItemMarkColumn,                // Column index
+            selectionMarkSubcell.iTl.iX,    // Left position
+            selectionMarkSubcell.iTl.iY,    // Top position
+            0,                              // Right - unused
+            0,                              // Bottom - unused
+            selectionMarkSubcell.Width(),   // Width
+            selectionMarkSubcell.Height(),  // Height
+            selectionMarkSubcell.iTl,       // Start position
+            selectionMarkSubcell.iBr);      // End position
+
+        gridData->SetTransparentSubCellL(KItemMarkColumn, ETrue);
+    }
+
+    TSize maxImageSize = iconSubcell.Size();
+
+    if (iMaxImageSize != maxImageSize)
+    {
+        UpdateImageSizes(maxImageSize);
+        iMaxImageSize = maxImageSize;
+    }
+
+    UpdateTextColorL();
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get the text array of item texts.
+// ---------------------------------------------------------------------------
+//
+CDesCArray* CSwtListView::GetTextArray() const
+{
+    MDesCArray* array = GetGridModel()->ItemTextArray();
+    return static_cast<CDesCArray*>(array);
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get the array of icons.
+// ---------------------------------------------------------------------------
+//
+CAknIconArray* CSwtListView::GetIconArray() const
+{
+    CArrayPtr<CGulIcon>* array = iGrid->ItemDrawer()->FormattedCellData()->IconArray();
+    return static_cast<CAknIconArray*>(array);
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get the model of the grid.
+// ---------------------------------------------------------------------------
+//
+CAknGridM* CSwtListView::GetGridModel() const
+{
+    return static_cast<CAknGridM*>(iGrid->Model());
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get the view of the grid.
+// ---------------------------------------------------------------------------
+//
+CAknGridView* CSwtListView::GetGridView() const
+{
+    return static_cast<CAknGridView*>(iGrid->View());
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get array of logical selection indices.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::GetSelection(CArrayFix<TInt>* aSelectionArray) const
+{
+    CAknGridView* gridView = GetGridView();
+
+    if (aSelectionArray && gridView)
+    {
+        aSelectionArray->Reset();
+
+        TRAP_IGNORE(gridView->GetSelectionIndexesL(aSelectionArray));
+
+        // The returned indexes are not the logical indexes (which take
+        // right-to-left ordering into account), make them logical if
+        // necessary.
+        if (!iLeftToRight)
+        {
+            for (int i = 0; i < aSelectionArray->Count(); i++)
+            {
+                aSelectionArray->At(i) =
+                    gridView->ActualDataIndex(aSelectionArray->At(i));
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// A helper to get logical selection index.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetSelectionL(const TInt aIndex) const
+{
+    if (iLeftToRight)
+    {
+        return aIndex;
+    }
+
+    CAknGridView* gridView = GetGridView();
+    if (!gridView)
+    {
+        User::Leave(ESwtErrorCannotGetSelection);
+    }
+
+    return gridView->ActualDataIndex(aIndex);
+}
+
+// ---------------------------------------------------------------------------
+// A helper to set selection array of logical selection indices.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetSelectionL(const CArrayFix<TInt>* aSelectionArray) const
+{
+    CAknGridView* gridView = GetGridView();
+
+    if (aSelectionArray && gridView)
+    {
+        gridView->ClearSelection();
+
+        for (TInt i = 0; i < aSelectionArray->Count(); i++)
+        {
+            TInt item = aSelectionArray->At(i);
+
+            if (!iLeftToRight)
+            {
+                item = gridView->ActualDataIndex(item);
+            }
+
+            gridView->SelectItemL(item);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// A helper to create an icon out of the given image object.
+// ---------------------------------------------------------------------------
+//
+CGulIcon* CSwtListView::CreateIconL(const MSwtImage* aIcon) const
+{
+    CGulIcon* icon = NULL;
+    if (aIcon)
+    {
+        CFbsBitmap* bmp = 0;
+        CFbsBitmap* mask = 0;
+
+        TSize bitmapSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
+                               aIcon->Bitmap().SizeInPixels(),
+                               iMaxImageSize);
+
+        bmp =  const_cast<CFbsBitmap*>(&aIcon->SubBitmap(bitmapSize));
+        mask = const_cast<CFbsBitmap*>(aIcon->SubMaskBitmap(bitmapSize, ETrue));
+        aIcon->AddRef();
+        aIcon->AddSubRef(bitmapSize);
+
+        icon = CGulIcon::NewL();
+        icon->SetBitmapsOwnedExternally(ETrue);
+        icon->SetBitmap(bmp);
+        icon->SetMask(mask);
+    }
+    else // Create a blank icon
+    {
+        CFbsBitmap* bmp = new(ELeave) CFbsBitmap;
+        CleanupStack::PushL(bmp);
+        User::LeaveIfError(bmp->Create(TSize(0, 0), EColor256));
+        ASSERT(bmp);
+        icon = CGulIcon::NewL(bmp);
+        CleanupStack::Pop(bmp);   // bmp
+    }
+    return icon;
+}
+
+// ---------------------------------------------------------------------------
+// Loads the layouts for the current resolution.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::LoadLayouts(const TSwtListViewDensity& aDensity,
+                               TSize& aCellSize,
+                               TRect& aIconRect,
+                               TRect& aSelRect,
+                               TRect& aTextRect,
+                               TInt& aTextCellFontId)
+{
+    // Grid cell variants
+    TInt cellVariant;
+    TInt subcellVariantG1;
+    TInt subcellVariantG2;
+    TInt subcellVariantT;
+    GetCellVariants(aDensity, cellVariant, subcellVariantG1, subcellVariantG2,
+                    subcellVariantT);
+
+    // LAF rectangle IDs
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPane;
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1;
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG2;
+    CSwtLafFacade::TSwtLafFacadeTextId rectIdPaneT1;
+    CSwtLafFacade::TSwtLafFacadeFontId rectIdPaneT1Font;
+    GetLafFacadeRectIds(aDensity, rectIdPane, rectIdPaneG1, rectIdPaneG2,
+                        rectIdPaneT1, rectIdPaneT1Font);
+
+    // Grid cell
+    TAknLayoutRect cellLayoutRect = CSwtLafFacade::GetLayoutRect(rectIdPane,
+                                    TRect(), cellVariant, 0, 0);
+    TRect cellRect = cellLayoutRect.Rect();
+
+    // Coerces cellrects if necessary
+    CoerceCellRect(aDensity, cellRect);
+
+    // For mirrored layouts the rect is from left to right (containing negative
+    // values), make sure that the rect has positive coordinates.
+    cellRect.Move(-cellRect.iTl.iX, 0);
+
+    aCellSize = cellRect.Size();
+
+    // Icon subcell
+    TAknLayoutRect iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1,
+                              cellRect, subcellVariantG1);
+    aIconRect.SetRect(iconRect.Rect().iTl, iconRect.Rect().iBr);
+
+    // Markable grid check mark subcell
+    // At this point it looks like the layout for the checkmark is wrong.
+    // The bounds of the checkmark icon exceed the bounds of the item.
+    // Therefore, we use TRect() here and count only on the height and width.
+    TAknLayoutRect selRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG2,
+                             TRect(), subcellVariantG2);
+    aSelRect.SetRect(selRect.Rect().iTl, selRect.Rect().iBr);
+
+    // Updates sizes get by getIconSize()
+    UpdateIconSizes(aDensity, cellRect);
+
+    // Caption text subcell
+    TAknLayoutText textRect = CSwtLafFacade::GetLayoutText(rectIdPaneT1,
+                              cellRect, subcellVariantT);
+    aTextRect.SetRect(textRect.TextRect().iTl, textRect.TextRect().iBr);
+
+    // Layout subcells inside the cell
+    LayoutCell(cellRect, aTextRect, aIconRect, aSelRect);
+
+    aTextCellFontId = CSwtLafFacade::GetFontId(rectIdPaneT1Font, subcellVariantT);
+
+    TRect controlRect = BorderInnerRect();
+    TSize controlSize(controlRect.iBr.iX - controlRect.iTl.iX,
+                      controlRect.iBr.iY - controlRect.iTl.iY);
+
+    // If control size is smaller than cell size, set cell size to 1*1 pixels. This is a workaround
+    // to the problem where full sized cells were drawn outside of control's borders when control
+    // size was smaller than cell size.
+    if (controlSize.iHeight < aCellSize.iHeight ||
+            controlSize.iWidth < aCellSize.iWidth)
+    {
+        aCellSize.iWidth = 1;
+        aCellSize.iHeight = 1;
+        TInt xCoord = cellRect.iTl.iX;
+        TInt yCoord = cellRect.iTl.iY;
+        aIconRect = TRect(xCoord, yCoord, xCoord, yCoord);
+        aSelRect =  TRect(xCoord, yCoord, xCoord, yCoord);
+        aTextRect = TRect(xCoord, yCoord, xCoord, yCoord);
+
+        iIconSizeInLowDensity.SetXY(0, 0);
+        iIconSizeInMediumDensity.SetXY(0, 0);
+        iIconSizeInHighDensity.SetXY(0, 0);
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+// Layout text and icon rectangles inside a cell.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::LayoutCell(const TRect& aCellRect, TRect& aTextRect,
+                              TRect& aIconRect, TRect& aSelRect)
+{
+
+    TInt cellWidth = aCellRect.iBr.iX - aCellRect.iTl.iX;
+    TInt cellHeight = aCellRect.iBr.iY - aCellRect.iTl.iY;
+    TInt textWidth = aTextRect.iBr.iX - aTextRect.iTl.iX;
+    TInt textHeight = aTextRect.iBr.iY - aTextRect.iTl.iY;
+    TInt iconWidth = aIconRect.iBr.iX - aIconRect.iTl.iX;
+    TInt iconHeight = aIconRect.iBr.iY - aIconRect.iTl.iY;
+
+    // Center the text and icon horizontally
+    TInt textX = (cellWidth - textWidth) / 2;
+    TInt textY = aTextRect.iTl.iY;
+    TInt iconX = (cellWidth - iconWidth) / 2;
+    TInt iconY = aIconRect.iTl.iY;
+
+    if (iNumberOfIcons == 0 && iNumberOfTexts > 0)
+    {
+        // There's no icon in any item, so center the cell text vertically.
+        textY = (cellHeight - textHeight) / 2;
+    }
+    else if (iNumberOfIcons > 0 && iNumberOfTexts == 0)
+    {
+        // There's no text in any item, so center the icons vertically.
+        iconY = (cellHeight - iconHeight) / 2;
+    }
+
+
+    aTextRect.iTl.SetXY(textX, textY);
+    aTextRect.iBr.SetXY(textX + textWidth, textY + textHeight);
+    aIconRect.iTl.SetXY(iconX, iconY);
+    aIconRect.iBr.SetXY(iconX + iconWidth, iconY + iconHeight);
+
+    if (AknLayoutUtils::LayoutMirrored())
+    {
+        TInt w = aSelRect.Width();
+        TInt h = aSelRect.Height();
+        aSelRect.iTl.SetXY(aCellRect.iTl.iX + 1, aCellRect.iTl.iY + 1);
+        aSelRect.iBr.SetXY(aCellRect.iTl.iX + 1 + w, aCellRect.iTl.iY + 1 + h);
+    }
+    else
+    {
+        TInt w = aSelRect.Width();
+        TInt h = aSelRect.Height();
+        aSelRect.iTl.SetXY(aCellRect.iBr.iX - 1 - w, aCellRect.iTl.iY + 1);
+        aSelRect.iBr.SetXY(aCellRect.iBr.iX - 1, aCellRect.iTl.iY + 1 + h);
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+// Returns ideal cell size for current grid density.
+// ---------------------------------------------------------------------------
+//
+TSize CSwtListView::GetCellSize() const
+{
+    // Grid cell variants
+    TInt cellVariant;
+    TInt subcellVariantG1;
+    TInt subcellVariantG2;
+    TInt subcellVariantT;
+    GetCellVariants(iDensity, cellVariant, subcellVariantG1, subcellVariantG2,
+                    subcellVariantT);
+
+    // LAF rectangle IDs
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPane;
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1;
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG2;
+    CSwtLafFacade::TSwtLafFacadeTextId rectIdPaneT1;
+    CSwtLafFacade::TSwtLafFacadeFontId rectIdPaneT1Font;
+    GetLafFacadeRectIds(iDensity, rectIdPane, rectIdPaneG1, rectIdPaneG2,
+                        rectIdPaneT1, rectIdPaneT1Font);
+
+    // Grid cell
+    TAknLayoutRect cellLayoutRect = CSwtLafFacade::GetLayoutRect(rectIdPane,
+                                    TRect(), cellVariant, 0, 0);
+    TRect cellRect = cellLayoutRect.Rect();
+
+    // Coerces cellrects if necessary
+    CoerceCellRect(iDensity, cellRect);
+
+    // For arabic layout, rect might be negative, so move it to (0,0) so that we get positive size.
+    cellRect.Move(-cellRect.iTl.iX, 0);
+
+    return cellRect.Size();
+}
+
+// ---------------------------------------------------------------------------
+// A helper to calculate how many cells to have per row/column based on
+// the given cell size.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::CalcRowsColumns(const TSize& aCellSize,
+                                   TInt& aXCells,
+                                   TInt& aYCells) const
+{
+    TRect clientRect = ClientRect();
+
+    aXCells = 1;
+    aYCells = 1;
+
+    if (aCellSize.iWidth != 0)
+    {
+        aXCells = clientRect.Width() / aCellSize.iWidth;
+    }
+    if (aCellSize.iHeight != 0)
+    {
+        aYCells = clientRect.Height() / aCellSize.iHeight;
+        if (clientRect.Height() % aCellSize.iHeight > KRowCalculationPrecisionInPixels)
+        {
+            aYCells++;
+        }
+    }
+
+    // 1x1 grid is the minimum, the grid asserts this
+    if (aXCells < 1)
+    {
+        aXCells = 1;
+    }
+    if (aYCells < 1)
+    {
+        aYCells = 1;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// A helper to handle adding of a listbox item text.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::AddTextL(const TDesC& aPtr,
+                            const TInt& aPos)
+{
+    // Untabify the item caption
+    RBuf caption;
+    caption.CreateL(aPtr);
+    caption.CleanupClosePushL();
+    UntabifyL(caption);
+
+    // Create the format string for the grid item
+
+    TInt iconIndex = ItemIconIndex(aPos);
+    RBuf buf;
+    buf.CreateL(KSpaceForIndex +
+                KColumnSeparator().Length() * 2 + // 2 = two separators
+                caption.Length() +
+                KMarkOffIconArrayIndex().Length());
+    buf.AppendNum(iconIndex);
+    buf.Append(KColumnSeparator);
+    buf.Append(caption);
+    buf.Append(KColumnSeparator);
+    buf.Append(KMarkOffIconArrayIndex);
+
+    // Append the text to the text array
+    buf.CleanupClosePushL();
+    CDesCArray* textArray = GetTextArray();
+    if (textArray)
+    {
+        textArray->InsertL(aPos, buf);
+    }
+
+    if (caption.Length() > 0)
+    {
+        UpdateSetItemCount(1, 0);
+    }
+
+    CleanupStack::PopAndDestroy(2);
+}
+
+// ---------------------------------------------------------------------------
+// A helper to handle adding of an icon for a list item.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::AddIconL(const MSwtImage* aImage,
+                            const TInt& aPos)
+{
+    CGulIcon* icon = CreateIconL(aImage);
+    CleanupStack::PushL(icon);
+    TInt index = ItemIconIndex(aPos);
+    GetIconArray()->InsertL(index, icon);
+
+    const MSwtImage* refImg = aImage;
+    const TInt refImgCount = iRefImages.Count();
+    if (refImgCount > aPos)
+    {
+        iRefImages.Insert(refImg, aPos);
+    }
+    else
+    {
+        iRefImages.Append(refImg);
+    }
+
+#ifdef DEBUG_CHECK_IMAGES
+    CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
+#endif
+
+    if (aImage)
+    {
+        UpdateSetItemCount(0, 1);
+    }
+
+    CleanupStack::Pop(icon);
+}
+
+// ---------------------------------------------------------------------------
+// A helper to handle adding of an item. This includes the item text and
+// the icon. Also selection/selection events/focus are handled appropriately.
+// Can be called with null image.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::AddItemL(const TDesC& aPtr,
+                            const MSwtImage* aImage,
+                            const TInt& aPos)
+{
+    // Store the selection state
+    GetSelection(iOldSelectionArray);
+
+    TRAPD(textError, AddTextL(aPtr, aPos));
+    if (textError)
+    {
+        User::Leave(ESwtErrorItemNotAdded);
+    }
+    TRAPD(iconError, AddIconL(aImage, aPos));
+    if (iconError)
+    {
+        // Remove the text as the icon can't be added
+        ASSERT(GetTextArray()->Count() > 0);
+        GetTextArray()->Delete(GetTextArray()->Count() - 1);
+        User::Leave(ESwtErrorItemNotAdded);
+    }
+
+    // Item added successfully
+
+    // Update grid cell layout if neccessary
+    DoGridCellLayoutIfNeededL();
+
+    // All the icon indexes after the added item need updating
+    TInt textCount = GetTextArray()->Count();
+    for (TInt iTxt = aPos + 1; iTxt < textCount; ++iTxt)
+    {
+        UpdateIconIndexL(iTxt);
+    }
+
+    iGrid->HandleItemAdditionL();
+
+    // Restore the selection state updating the indexes.
+    UpdateSelectionIndexesL(aPos, aPos, ETrue);
+
+    // Focus must move to the newly added item.
+    if (iStyle & KSwtStyleMulti)
+    {
+        iGrid->SetCurrentDataIndex(aPos);
+    }
+    SingleSelectL(GetSelectionL(aPos), ETrue);
+
+    UpdateMSKLabelL();
+
+    Redraw();
+    iDisplay.PostSelectionEventL(iPeer);
+}
+
+// ---------------------------------------------------------------------------
+// Updates the icon index in the item text array at the given index.
+// Icon index is invalidated when adding or removing items anywhere but
+// the end of the array.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateIconIndexL(const TInt& aIndex)
+{
+    CDesCArray* textArray = GetTextArray();
+    TPtrC itemText = textArray->MdcaPoint(aIndex);
+    TInt separatorPos = itemText.Find(KColumnSeparator);
+    User::LeaveIfError(separatorPos);
+
+    RBuf buf;
+    buf.CreateL(KSpaceForIndex + itemText.Length());
+    buf.AppendNum(ItemIconIndex(aIndex));
+    buf.Append(itemText.Mid(separatorPos));
+
+    buf.CleanupClosePushL();
+    textArray->Delete(aIndex);
+    textArray->InsertL(aIndex, buf);
+
+    CleanupStack::PopAndDestroy(1);
+}
+
+// ---------------------------------------------------------------------------
+// Updates the selection indexes of items starting from the given index.
+// Selected item indexes after the given index are decremented or incremented
+// depending on if items have been added or removed.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateSelectionIndexesL(TInt aStart, TInt aEnd, TBool aItemsAdded)
+{
+    ASSERT(iOldSelectionArray != NULL);
+    TInt numberOfItemsInRange = aEnd - aStart + 1;
+
+    // Update the selection indexes
+    TInt selectionCount = iOldSelectionArray->Count();
+    for (TInt iOld = selectionCount - 1; iOld >= 0; --iOld)
+    {
+        // First delete the selection indexes for items that have been removed
+        if (aItemsAdded == EFalse &&
+                (*iOldSelectionArray)[iOld] >= aStart && (*iOldSelectionArray)[iOld] <= aEnd)
+        {
+            iOldSelectionArray->Delete(iOld);
+            continue;
+        }
+        // Then update the affected selection indexes
+        if ((*iOldSelectionArray)[iOld] >= aStart)
+        {
+            if (aItemsAdded)
+            {
+                (*iOldSelectionArray)[iOld] += numberOfItemsInRange;
+            }
+            else // items were removed
+            {
+                (*iOldSelectionArray)[iOld] -= numberOfItemsInRange;
+            }
+        }
+    }
+
+    // New updated selections to the control
+    SetSelectionL(iOldSelectionArray);
+
+    iOldSelectionArray->Reset();
+}
+
+// ---------------------------------------------------------------------------
+// Recursively replaces the tab characters in the buffer. Tab characters are
+// not allowed in the item texts because they are used exclusively as
+// field separators.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UntabifyL(RBuf& aAll)
+{
+    TInt separatorPos = aAll.Find(KColumnSeparator);
+    if (separatorPos != KErrNotFound)
+    {
+        RBuf end;
+        end.CreateL(aAll.Length());
+        end.CleanupClosePushL();
+        end.Append(aAll.Mid(separatorPos + 1));
+        UntabifyL(end);
+
+        // Now 'end' doesn't have any separators in it
+
+        end.Insert(0, KSeparatorReplacement);
+        end.Insert(0, aAll.Left(separatorPos));
+        aAll.Copy(end);
+        CleanupStack::PopAndDestroy();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Obtains a pointer descriptor to the part of the item text that contains
+// the caption.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetCaption(const TInt& aIndex, TPtrC& aTxt) const
+{
+    ASSERT(KTextColumn == 1);
+    ASSERT(GetItemCount() > 0);
+
+    // Get a pointer to the item's complete text
+    aTxt.Set(GetGridModel()->ItemText(aIndex));
+
+    // Find the 1st separator from where the caption starts
+    TInt separatorPos = aTxt.Find(KColumnSeparator);
+    if (separatorPos == KErrNotFound)
+    {
+        return KErrNotFound;
+    }
+
+    // Reset the pointer to point to the beginning of the caption
+    TInt newLength = aTxt.Length() - separatorPos;
+    aTxt.Set(&aTxt[ separatorPos + 1 ], newLength);
+
+    // Find the 1st (2nd) separator where the caption ends
+    separatorPos = aTxt.Find(KColumnSeparator);
+    if (separatorPos == KErrNotFound)
+    {
+        return KErrNotFound;
+    }
+
+    // Set length correctly to just reach the end of the caption
+    newLength = separatorPos;
+    aTxt.Set(&aTxt[ 0 ], newLength);
+
+    return KErrNone;
+}
+
+// ---------------------------------------------------------------------------
+// View must show as many items as possible. It's not allowed that the last
+// row/column would be empty while some of the items would be outside
+// the view. The view must scroll to fully utilise the available space to
+// show as many rows/columns as fit in the view.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::ScrollViewToShowAsManyItemsAsPossibleL()
+{
+    TInt lastItemRowIndex;
+    TInt lastItemColIndex;
+    TInt firstItemRowIndex;
+    TInt firstItemColIndex;
+    TBool scrollingNeeded = EFalse;
+
+    if (!(GetItemCount() > 0))
+    {
+        return;
+    }
+
+    // Get the view positions of the first and last list items.
+    GetGridView()->CalcRowAndColIndexesFromItemIndex(GetItemCount() -1,
+            lastItemRowIndex,
+            lastItemColIndex);
+    GetGridView()->CalcRowAndColIndexesFromItemIndex(0,
+            firstItemRowIndex,
+            firstItemColIndex);
+
+    // Check if there is 1 or more complete rows/columns of unused space
+    // in the end of the view.
+    if (iVerticalOrientation == EFalse)
+    {
+        if (lastItemRowIndex >= 0 && lastItemRowIndex < iNumOfRows - 1)
+        {
+            // Last item is in the view and is not on the last row.
+            //  Check if the first item is outside the view.
+            if (firstItemRowIndex < 0)
+            {
+                scrollingNeeded = ETrue;
+            }
+        }
+    }
+    else
+    {
+        if (lastItemColIndex >= 0 && lastItemColIndex < iNumOfColumns - 1)
+        {
+            // Last item is displayed in the view and is not on the last
+            // column. Check if the first item is outside the view.
+            if (firstItemColIndex < 0)
+            {
+                scrollingNeeded = ETrue;
+            }
+        }
+    }
+
+    if (scrollingNeeded)
+    {
+        // Move the focus to the beginning and back to the correct index
+        // to reposition the view.
+        TInt currentDataIndex = iGrid->CurrentDataIndex();
+        GetGridView()->MoveToItemIndexL(0, CListBoxView::ENoSelection);
+        GetGridView()->MoveToItemIndexL(currentDataIndex,
+                                        CListBoxView::ENoSelection);
+    }
+}
+
+TInt CSwtListView::ScrollBarBreadth(const CEikScrollBar* aBar)
+{
+    return iDisplay.UiUtils().ScrollBarBreadth(aBar);
+}
+
+// ---------------------------------------------------------------------------
+// A helper for selecting items appropriately in single selection grid.
+// Called when selection is desired only in single style.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SingleSelectL(const TInt& aIndex, TBool aScroll)
+{
+    if (!(iStyle & KSwtStyleMulti))
+    {
+        if (aScroll && GetGridView()->ViewRect().Height() >= iGrid->ItemHeight())
+        {
+            iGrid->View()->VerticalMoveToItemL(aIndex, CListBoxView::ESingleSelection);
+        }
+        else
+        {
+            TInt old = iGrid->CurrentItemIndex();
+            GetGridView()->SetCurrentItemIndex(aIndex); //we do not call CEikListBox::SetCurrentItemIndex, because we do not want to scroll.
+            GetGridView()->UpdateSelectionL(CListBoxView::ESingleSelection);
+            if (old != -1)
+            {
+                GetGridView()->DrawItem(old);
+            }
+            ASSERT(iGrid->SelectionIndexes()->Count() <= 1);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// A helper for selecting items appropriately in either single or multi
+// selection grid. Called when selection is desired in either case.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SingleOrMultiSelectL(const TInt& aIndex, TBool aScroll)
+{
+    CAknGridView* gridView = GetGridView();
+
+    ASSERT(gridView);
+
+    if (iStyle & KSwtStyleMulti)
+    {
+        gridView->SelectItemL(gridView->ActualDataIndex(aIndex));
+
+        if (aScroll)
+        {
+            iGrid->ScrollToMakeItemVisible(aIndex);
+        }
+    }
+    else
+    {
+        SingleSelectL(aIndex, aScroll);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Updates the colors used to draw text in the grid. The normal text color
+// and the highlighted (focused) text color.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateTextColorL()
+{
+    CFormattedCellListBoxData::TColors colors;
+    TInt error = 0;
+
+    if (iTextColor)
+    {
+        // Use the user defined color for all text
+        colors.iText = TRgb(iTextColor->RgbValue());
+        colors.iHighlightedText = TRgb(iTextColor->RgbValue());
+    }
+    else
+    {
+        // Get the colors from the skin
+        MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+        error = AknsUtils::GetCachedColor(skin, colors.iText, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG9);
+        error += AknsUtils::GetCachedColor(skin, colors.iHighlightedText, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG11);
+    }
+    if (!error)
+    {
+        iGrid->ItemDrawer()->FormattedCellData()->SetSubCellColorsL(KTextColumn, colors);
+        iGrid->ItemDrawer()->SetTextColor(colors.iText);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Helper to get the marked item icon from the current skin.
+// ---------------------------------------------------------------------------
+//
+CGulIcon* CSwtListView::GetMarkedItemIconL()
+{
+    CGulIcon* icon = AknsUtils::CreateGulIconL(AknsUtils::SkinInstance(),
+                     KAknsIIDQgnIndiMarkedGridAdd,
+                     AknIconUtils::AvkonIconFileName(),
+                     EMbmAvkonQgn_indi_marked_grid_add,
+                     EMbmAvkonQgn_indi_marked_grid_add_mask);
+    return icon;
+}
+
+// ---------------------------------------------------------------------------
+// Helper to update all the scaled images.
+// Assumes that iMaxImageSize contains the old maximum image size.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateImageSizes(const TSize& aNewMaxSize)
+{
+    TInt count = iRefImages.Count();
+    const MSwtImage* img = 0;
+
+    CAknIconArray* iconArray = GetIconArray();
+
+    for (TInt i = 0; i < count; i++)
+    {
+        img = iRefImages[i];
+        if (img)
+        {
+            TSize imageSize = img->Bitmap().SizeInPixels();
+            TSize oldSize, newSize;
+            TBool doScaling = ETrue;
+
+            if (imageSize.iHeight > iMaxImageSize.iHeight ||
+                    imageSize.iWidth > iMaxImageSize.iWidth)
+            {
+                // If image size is bigger than the old maximum size, then
+                // the image has been also previously scaled.
+                oldSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
+                              imageSize, iMaxImageSize);
+            }
+            else if (imageSize.iHeight > aNewMaxSize.iHeight ||
+                     imageSize.iWidth > aNewMaxSize.iWidth)
+            {
+                // Image is bigger than the new boundaries, but it did fit
+                // inside the old boundaries, so the image is default size.
+                oldSize = imageSize;
+            }
+            else
+            {
+                doScaling = EFalse;
+            }
+
+            if (doScaling)
+            {
+                newSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
+                              imageSize, aNewMaxSize);
+                CFbsBitmap* bmp = const_cast<CFbsBitmap*>(&img->SubBitmap(newSize));
+                CFbsBitmap* mask = const_cast<CFbsBitmap*>(img->SubMaskBitmap(newSize, ETrue));
+
+                img->AddSubRef(newSize);
+
+                // Remove the old reference
+                img->RemoveSubRef(oldSize);
+
+                CGulIcon* icon = (*iconArray)[ ItemIconIndex(i)];
+
+                icon->SetBitmap(bmp);
+                icon->SetMask(mask);
+            }
+        }
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+// Removes reference to the image at a given index. If the image has been
+// scaled, removes the correct sized reference.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::RemoveImageRef(const TInt& aIndex)
+{
+    const MSwtImage* img = iRefImages[ aIndex ];
+
+    if (img)
+    {
+        TSize imageSize = img->Bitmap().SizeInPixels();
+
+        // If the original size of the image is bigger than the maximum image
+        // size, it has been scaled to fit in iMaxImageSize. Remove reference
+        // to the scaled bitmap.
+        if (imageSize.iHeight > iMaxImageSize.iHeight ||
+                imageSize.iWidth > iMaxImageSize.iWidth)
+        {
+            imageSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
+                            imageSize, iMaxImageSize);
+        }
+
+        img->RemoveSubRef(imageSize);
+        img->RemoveRef();
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+// Leaving version of HandleResourceChange.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::HandleResourceChangeL(TInt aType)
+{
+    if (aType == KAknsMessageSkinChange)
+    {
+        // Refresh the selected item mark icon
+        CAknIconArray* iconArray = GetIconArray();
+        CGulIcon* icon = (*iconArray)[ KMarkOnIconArrayIndexInt ];
+        delete icon;
+        (*iconArray)[ KMarkOnIconArrayIndexInt ] = GetMarkedItemIconL();
+    }
+
+    if (aType == KEikDynamicLayoutVariantSwitch)
+    {
+        if (AknLayoutUtils::LayoutMirrored())
+        {
+            iLeftToRight = EFalse;
+        }
+        else
+        {
+            iLeftToRight = ETrue;
+        }
+
+        CCoeControl::HandleResourceChange(aType);
+        SizeChangedL();
+    }
+    else
+    {
+        CCoeControl::HandleResourceChange(aType);
+        DoGridCellLayoutL(iDensity);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Leaving version of SizeChanged.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SizeChangedL()
+{
+    DoGridCellLayoutL(iDensity);
+    TRect clientRect(BorderInnerRect());
+
+    // WORKAROUND! This is to avoid CAknGrid crash when its size is 0
+    // and the List Transition Effects try to draw the grid. In fact the
+    // root cause of the crash is our Shell not being always ready to draw
+    // which is what Avkon expects. If that would be the case, the List
+    // Transition Effects will never get a chance to draw a size 0 grid.
+    if (clientRect.Width() <= 0 && clientRect.Height() <= 0)
+    {
+        clientRect = TRect(0, 0, 1, 0);
+    }
+
+    iGrid->SetRect(clientRect);
+    iGrid->HandleViewRectSizeChangeL();
+}
+
+// ---------------------------------------------------------------------------
+// Helper to get the array index of the icon from the item index.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::ItemIconIndex(const TInt& aItemPos)
+{
+    return (aItemPos + 2);
+}
+
+// ---------------------------------------------------------------------------
+// Updates the control menu.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateControlMenu()
+{
+    if (iStyle & KSwtStyleMulti)
+    {
+        TInt focusIndex = GetFocusIndex();
+        if (focusIndex != -1)
+        {
+            iMenuItemMarkUnmark->SetEnabled(ETrue);
+            if (IsSelected(focusIndex))
+            {
+                if (iIsMarkDisplayed)
+                {
+                    iIsMarkDisplayed = EFalse;
+                    TPtrC ptr = iUnmarkString->Des();
+                    TRAP_IGNORE(iMenuItemMarkUnmark->SetTextL(ptr));
+                }
+            }
+            else
+            {
+                if (!iIsMarkDisplayed)
+                {
+                    iIsMarkDisplayed = ETrue;
+                    TPtrC ptr = iMarkString->Des();
+                    TRAP_IGNORE(iMenuItemMarkUnmark->SetTextL(ptr));
+                }
+            }
+        }
+        else
+        {
+            iMenuItemMarkUnmark->SetEnabled(EFalse);
+        }
+
+        if (GetGridView()->SelectionIndexes()->Count() == 0)
+        {
+            iMenuItemUnmarkAll->SetEnabled(EFalse);
+#ifdef RD_SCALABLE_UI_V2
+            iStylusPopupUnmarkAll->SetEnabled(EFalse);
+#endif //RD_SCALABLE_UI_V2            
+        }
+        else
+        {
+            iMenuItemUnmarkAll->SetEnabled(ETrue);
+#ifdef RD_SCALABLE_UI_V2
+            iStylusPopupUnmarkAll->SetEnabled(ETrue);
+#endif //RD_SCALABLE_UI_V2                            
+        }
+
+        if (GetGridView()->SelectionIndexes()->Count() == GetGridModel()->NumberOfItems())
+        {
+            iMenuItemMarkAll->SetEnabled(EFalse);
+#ifdef RD_SCALABLE_UI_V2
+            iStylusPopupMarkAll->SetEnabled(EFalse);
+#endif //RD_SCALABLE_UI_V2                        
+        }
+        else
+        {
+            iMenuItemMarkAll->SetEnabled(ETrue);
+#ifdef RD_SCALABLE_UI_V2
+            iStylusPopupMarkAll->SetEnabled(ETrue);
+#endif //RD_SCALABLE_UI_V2                                    
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// 2nd phase construction
+// ---------------------------------------------------------------------------
+//
+CSwtListView* CSwtListView::NewL(MSwtDisplay& aDisplay,
+                                 TSwtPeer aPeer,
+                                 MSwtComposite& aParent,
+                                 TInt aStyle)
+{
+    CSwtListView* self = CSwtListView::NewLC(aDisplay, aPeer, aParent, aStyle);
+    CleanupStack::Pop(self);
+    return self;
+}
+
+// ---------------------------------------------------------------------------
+// 2nd phase construction
+// ---------------------------------------------------------------------------
+//
+CSwtListView* CSwtListView::NewLC(MSwtDisplay& aDisplay,
+                                  TSwtPeer aPeer,
+                                  MSwtComposite& aParent,
+                                  TInt aStyle)
+{
+    CSwtListView* self = new(ELeave) CSwtListView(aDisplay,
+            aPeer,
+            aParent,
+            aStyle);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    self->InitControlBaseL();
+    return self;
+}
+
+// ---------------------------------------------------------------------------
+// The destructor
+// ---------------------------------------------------------------------------
+//
+CSwtListView::~CSwtListView()
+{
+    if (iMenuItemMarkUnmark)
+    {
+        iMenuItemMarkUnmark->Dispose();
+    }
+
+    if (iMenuItemMarkAll)
+    {
+        iMenuItemMarkAll->Dispose();
+    }
+
+    if (iMenuItemUnmarkAll)
+    {
+        iMenuItemUnmarkAll->Dispose();
+    }
+
+    if (iSubMenu)
+    {
+        iSubMenu->Dispose();
+    }
+
+    if (iMenuItemEditList)
+    {
+        iMenuItemEditList->Dispose();
+    }
+
+    if (iMenu)
+    {
+        iMenu->Dispose();
+    }
+
+#ifdef RD_SCALABLE_UI_V2
+    if (iStylusPopupMarkAll)
+    {
+        iStylusPopupMarkAll->Dispose();
+    }
+
+    if (iStylusPopupUnmarkAll)
+    {
+        iStylusPopupUnmarkAll->Dispose();
+    }
+
+    if (iStylusPopupMenu)
+    {
+        iStylusPopupMenu->Dispose();
+    }
+#endif //RD_SCALABLE_UI_V2    
+
+    delete iMarkString;
+    delete iUnmarkString;
+
+    delete iOldSelectionArray;
+    iOldSelectionArray = NULL;
+
+    delete iSelectionArray;
+    iSelectionArray = NULL;
+
+#ifdef DEBUG_CHECK_IMAGES
+    CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
+#endif
+
+    delete iGrid;
+    iGrid = NULL;
+
+    TInt count = iRefImages.Count();
+    for (TInt i = 0; i < count; i++)
+    {
+        RemoveImageRef(i);
+    }
+
+    iRefImages.Close();
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CSwtListView::ComponentControl(TInt /*aIndex*/) const
+{
+    return iGrid;
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::CountComponentControls() const
+{
+    return 1; // there's only the grid
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SizeChanged()
+{
+    TRAP_IGNORE(SizeChangedL());
+    HandleSizeChanged();
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::PositionChanged()
+{
+    iGrid->SetPosition(BorderInnerRect().iTl);
+    TRAP_IGNORE(iGrid->HandleViewRectSizeChangeL());
+    HandlePositionChanged();
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::HandleResourceChange(TInt aType)
+{
+    TRAP_IGNORE(HandleResourceChangeL(aType));
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::FocusChanged(TDrawNow aDrawNow)
+{
+    TBool focused = IsFocused();
+    iGrid->SetFocus(focused);
+    HandleFocusChanged(aDrawNow);
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// Only horizontal layout (vertical scrolling) is supported.
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CSwtListView::OfferKeyEventL(const TKeyEvent& aKeyEvent,
+        TEventCode aType)
+{
+    ASSERT(iVerticalOrientation == EFalse);
+
+    TBool traversalDoIt = ETrue;
+    TInt firstItemRowIndex;
+    TInt firstItemColIndex;
+    TInt lastItemRowIndex;
+    TInt lastItemColIndex;
+    TInt currentItemRowIndex;
+    TInt currentItemColIndex;
+    TSwtTraversal detail = ESwtTraverseNone;
+    TBool isMirrored = AknLayoutUtils::LayoutMirrored();
+
+    if (aKeyEvent.iCode == EKeyEnter || aKeyEvent.iCode == EKeyOK ||
+            aKeyEvent.iCode == EKeyEscape)
+    {
+        traversalDoIt = EFalse;
+    }
+
+    if (GetItemCount() > 0)
+    {
+        if (aKeyEvent.iCode == EKeyDownArrow ||
+                aKeyEvent.iCode == EKeyUpArrow ||
+                aKeyEvent.iCode == EKeyLeftArrow ||
+                aKeyEvent.iCode == EKeyRightArrow)
+        {
+            traversalDoIt = EFalse;
+            GetGridView()->CalcRowAndColIndexesFromItemIndex(0,
+                    firstItemRowIndex,
+                    firstItemColIndex);
+            GetGridView()->CalcRowAndColIndexesFromItemIndex(GetItemCount() - 1,
+                    lastItemRowIndex,
+                    lastItemColIndex);
+            GetGridView()->CalcRowAndColIndexesFromItemIndex(iGrid->CurrentDataIndex(),
+                    currentItemRowIndex,
+                    currentItemColIndex);
+        }
+        if (aKeyEvent.iCode == EKeyDownArrow)
+        {
+            if (currentItemRowIndex == lastItemRowIndex)
+            {
+                detail = ESwtTraverseArrowNext;
+            }
+        }
+        else if (aKeyEvent.iCode == EKeyUpArrow)
+        {
+            if (currentItemRowIndex == firstItemRowIndex)
+            {
+                detail = ESwtTraverseArrowPrevious;
+            }
+        }
+        else if ((isMirrored  && aKeyEvent.iCode == EKeyRightArrow) ||
+                 (!isMirrored && aKeyEvent.iCode == EKeyLeftArrow))
+        {
+            if (iGrid->CurrentDataIndex() == 0)
+            {
+                detail = ESwtTraverseArrowPrevious;
+            }
+        }
+        else if ((isMirrored  && aKeyEvent.iCode == EKeyLeftArrow) ||
+                 (!isMirrored && aKeyEvent.iCode == EKeyRightArrow))
+        {
+            if (iGrid->CurrentDataIndex() == GetItemCount() - 1)
+            {
+                detail = ESwtTraverseArrowNext;
+            }
+        }
+    }
+    if (detail != ESwtTraverseNone &&
+            (GetShell().FindTraversalTargetL(detail, *this)))
+    {
+        traversalDoIt = ETrue;
+    }
+    return HandleKeyL(aKeyEvent, aType, traversalDoIt);
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::MakeVisible(TBool aVisible)
+{
+    CCoeControl::MakeVisible(aVisible);
+    FocusabilityChanged();
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetDimmed(TBool aDimmed)
+{
+    CCoeControl::SetDimmed(aDimmed);
+    if (iGrid)
+    {
+        iGrid->SetDimmed(aDimmed);
+    }
+    FocusabilityChanged();
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// ---------------------------------------------------------------------------
+//
+TTypeUid::Ptr CSwtListView::MopSupplyObject(TTypeUid aId)
+{
+    TTypeUid::Ptr id = ASwtControlBase::SwtMopSupplyObject(aId);
+
+    if (id.Pointer() == NULL)
+    {
+        return CAknControl::MopSupplyObject(aId);
+    }
+    else
+    {
+        return id;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class CCoeControl.
+// Overriding Draw just to set correct clipping rect for the item drawer of
+// the contained grid. The contained grid will be drawn immediately after this.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::Draw(const TRect& /*aRect*/) const
+{
+    if (GetShell().UrgentPaintControl() == this)
+        return;
+
+    TRect clipRect(ClipToVisibleRect(iGrid->View()->ViewRect()));
+    if (clipRect != iLastViewVisibleRect)
+    {
+        iGrid->SetItemDrawerClippingRect(clipRect);
+        iLastViewVisibleRect = clipRect;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+MSwtScrollable* CSwtListView::Scrollable()
+{
+    return this;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// This is called when the Java application calls ListView.add without
+// the index parameter
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::AppendL(const TDesC& aPtr, const MSwtImage* aImage)
+{
+    AddItemL(aPtr, aImage, GetItemCount());
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// This is called when the Java application calls ListView.add with
+// the index parameter.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::InsertL(TInt aPos,
+                           const TDesC& aPtr,
+                           const MSwtImage* aImage)
+{
+    if (aPos < 0 || aPos > GetItemCount())
+    {
+        User::Leave(ESwtErrorInvalidRange);
+    }
+    AddItemL(aPtr, aImage, aPos);
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DeselectItem(TInt aIndex)
+{
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (!(iStyle & KSwtStyleMulti) ||               // not multi select
+            count == 0 ||                               // empty
+            aIndex >= count ||                          // no items in range
+            aIndex < 0 ||                               // no items in range
+            iGrid->SelectionIndexes()->Count() == 0)    // no selected items
+    {
+        return;
+    }
+
+    CAknGridView* gridView = GetGridView();
+
+    ASSERT(gridView);
+
+    gridView->DeselectItem(gridView->ActualDataIndex(aIndex));
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DeselectRange(TInt aStart, TInt aEnd)
+{
+    ASSERT(aStart <= aEnd);   // Checked in the Java method
+
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (!(iStyle & KSwtStyleMulti) ||               // not multi select
+            count == 0 ||                               // empty
+            aStart >= count ||                          // no items in range
+            iGrid->SelectionIndexes()->Count() == 0)    // no selected items
+    {
+        return;
+    }
+
+    // Validate range
+    if (aStart < 0)
+    {
+        aStart = 0;
+    }
+    if (aEnd >= count)
+    {
+        aEnd = count - 1;
+    }
+
+    TRAP_IGNORE(GetGridView()->DeselectRangeL(aStart, aEnd));
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DeselectItems(const TInt* aIndices, TInt aCount)
+{
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (!aIndices ||
+            aCount == 0 ||
+            !(iStyle & KSwtStyleMulti) ||               // not multi select
+            count == 0 ||                               // empty
+            iGrid->SelectionIndexes()->Count() == 0)    // no selected items
+    {
+        return;
+    }
+
+    for (TInt i = 0; i < aCount; ++i)
+    {
+        if (GetGridModel()->IndexContainsData(aIndices[i]))
+        {
+            GetGridView()->DeselectItem(aIndices[i]);
+        }
+    }
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DeselectAll()
+{
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (!(iStyle & KSwtStyleMulti) ||               // not multi select
+            count == 0 ||                               // empty
+            iGrid->SelectionIndexes()->Count() == 0)    // no selected items
+    {
+        return;
+    }
+    iGrid->ClearSelection();
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetFocusIndex() const
+{
+    if (GetGridModel()->NumberOfItems() == 0)
+    {
+        return -1;
+    }
+    return iGrid->CurrentDataIndex();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::GetItemL(TInt aItemIndex, TPtrC& aString) const
+{
+    if (GetGridModel()->IndexContainsData(aItemIndex))
+    {
+        GetCaption(aItemIndex, aString);
+    }
+    else
+    {
+        User::Leave(ESwtErrorInvalidRange);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TPoint CSwtListView::GetIconSize(TInt aStyle) const
+{
+    ASSERT(aStyle == ELowListViewDensity ||
+           aStyle == EHighListViewDensity ||
+           aStyle == EMediumListViewDensity);   // checked in Java side
+
+    if (aStyle == ELowListViewDensity)
+    {
+        return iIconSizeInLowDensity;
+    }
+    else
+    {
+        if (aStyle == EHighListViewDensity)
+        {
+            return iIconSizeInHighDensity;
+        }
+        else
+        {
+            return iIconSizeInMediumDensity;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetItemCount() const
+{
+    return GetGridModel()->NumberOfItems();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+CPtrCArray* CSwtListView::GetItemsL() const
+{
+    TInt count(GetItemCount());
+    if (count == 0)
+    {
+        return NULL;
+    }
+
+    // Allocate space for the items, deleted by the jni export function
+    CPtrCArray* itemsArray = new(ELeave) CPtrC16Array(KSwtListViewItemGranularity);
+    CleanupStack::PushL(itemsArray);
+
+    for (TInt i = 0; i < count; ++i)
+    {
+        TPtrC caption;
+        GetCaption(i, caption);
+        itemsArray->AppendL(caption);
+    }
+
+    CleanupStack::Pop();
+    return itemsArray;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+CPtrCArray* CSwtListView::GetSelectionL() const
+{
+    if (!(GetItemCount() > 0))
+    {
+        return NULL;
+    }
+
+    const CAknGridView::CSelectionIndexArray* selArray = NULL;
+    if (iStyle & KSwtStyleMulti)
+    {
+        selArray = iGrid->SelectionIndexes();
+        if (!selArray || selArray->Count() == 0)
+        {
+            return NULL;
+        }
+    }
+
+    // Allocate space for the items, deleted by the jni export function
+    CPtrCArray* itemsArray = new(ELeave) CPtrC16Array(KSwtListViewItemGranularity);
+    CleanupStack::PushL(itemsArray);
+
+    if (iStyle & KSwtStyleMulti)
+    {
+        for (TInt i = 0; i < selArray->Count(); ++i)
+        {
+            ASSERT(selArray->At(i) < GetItemCount());
+            TPtrC caption;
+            GetItemL(GetGridView()->ActualDataIndex(selArray->At(i)), caption);
+            itemsArray->AppendL(caption);
+        }
+    }
+    else // single style
+    {
+        TPtrC caption;
+        GetItemL(iGrid->CurrentDataIndex(), caption);
+        itemsArray->AppendL(caption);
+    }
+
+    CleanupStack::Pop();
+    return itemsArray;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetSelectionCount() const
+{
+    return iGrid->SelectionIndexes()->Count();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+const CArrayFix<TInt>* CSwtListView::GetSelectionIndices() const
+{
+    GetSelection(iSelectionArray);
+
+    return iSelectionArray;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetTopIndex() const
+{
+    if (GetItemCount() <= 0)
+    {
+        return -1;
+    }
+    else
+    {
+        return iGrid->TopItemIndex();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::IndexOf(const TDesC& aString, TInt& aStart) const
+{
+    TInt index = -1;
+    CDesCArray* itemTextArray = GetTextArray();
+
+    // Range check
+    if (!(aStart < 0 || aStart >= GetItemCount()))
+    {
+        for (TInt i = aStart; i < itemTextArray->Count(); ++i)
+        {
+            TPtrC caption;
+            TInt result = GetCaption(i, caption);
+            if (result == KErrNotFound)
+            {
+                break;
+            }
+            if (aString.Compare(caption) == KErrNone)
+            {
+                index = i;
+                break;
+            }
+        }
+    }
+    return index;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+TBool CSwtListView::IsSelected(TInt aIndex) const
+{
+    return GetGridView()->ItemIsSelected(GetGridView()->ActualDataIndex(aIndex));
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::RemoveItemL(TInt aIndex)
+{
+    if (aIndex < 0 || aIndex >= GetItemCount())
+    {
+        User::Leave(ESwtErrorInvalidRange);
+    }
+
+    // Store the selection state
+    GetSelection(iOldSelectionArray);
+
+    // Check if the focused and/or the last item is being removed
+    TBool focused = EFalse;
+    if (aIndex == iGrid->CurrentDataIndex())
+    {
+        focused = ETrue;
+    }
+    TBool last = EFalse;
+    if (aIndex == GetItemCount() - 1)
+    {
+        last = ETrue;
+    }
+
+    UpdateRemovedItemCountersL(aIndex);
+
+    // Remove the item text
+    CDesCArray* itemTextArray = GetTextArray();
+    itemTextArray->Delete(aIndex);
+    itemTextArray->Compress();
+
+    // All the icon indexes after the removed item need updating
+    TInt textCount = GetTextArray()->Count();
+    for (TInt i = aIndex; i < textCount; ++i)
+    {
+        UpdateIconIndexL(i);
+    }
+
+    // Remove the icon
+    CAknIconArray* iconArray = GetIconArray();
+    CGulIcon* icon = (*iconArray)[ ItemIconIndex(aIndex)];
+    iconArray->Delete(ItemIconIndex(aIndex));
+    iconArray->Compress();
+    delete icon;
+
+    // Remove the reference
+    RemoveImageRef(aIndex);
+    iRefImages.Remove(aIndex);
+    iRefImages.Compress();
+
+#ifdef DEBUG_CHECK_IMAGES
+    CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
+#endif
+
+    // Notify the grid
+    iGrid->HandleItemRemovalL();
+
+    // Restore the selection state updating the indexes.
+    UpdateSelectionIndexesL(aIndex, aIndex, EFalse);
+
+    // If last and focused item was removed then focus moves to the first
+    if (GetItemCount() > 0)
+    {
+        if (focused && last)
+        {
+            iGrid->SetCurrentDataIndex(0);
+            iGrid->ScrollToMakeItemVisible(0);
+        }
+
+        SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+        ScrollViewToShowAsManyItemsAsPossibleL();
+    }
+    UpdateControlMenu();
+    UpdateMSKLabelL();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::RemoveRangeL(TInt aStart, TInt aEnd)
+{
+    ASSERT(aStart <= aEnd);   // Checked in the Java method
+
+    if (aStart < 0 || aEnd >= GetItemCount())
+    {
+        User::Leave(ESwtErrorInvalidRange);
+    }
+
+    // Store the selection state
+    GetSelection(iOldSelectionArray);
+
+    // Remove texts
+    CDesCArray* itemTextArray = GetTextArray();
+
+    for (TInt i = aStart; i < aEnd; ++i)
+    {
+        UpdateRemovedItemCountersL(i);
+    }
+
+    TInt itemsInRange = (aEnd - aStart) + 1;
+    itemTextArray->Delete(aStart, itemsInRange);
+    itemTextArray->Compress();
+
+    // All the icon indexes after the 1st removed item need updating
+    TInt textCount = GetTextArray()->Count();
+    for (TInt i = aStart; i < textCount; ++i)
+    {
+        UpdateIconIndexL(i);
+    }
+
+    // Delete icons and references
+    CAknIconArray* iconArray = GetIconArray();
+
+    // Must go backwards here for correct removal of references
+    for (TInt i = aEnd; i >= aStart; i--)
+    {
+        CGulIcon* icon = (*iconArray)[ItemIconIndex(i)];
+        delete icon;
+        RemoveImageRef(i);
+        iRefImages.Remove(i);
+    }
+    iconArray->Delete(ItemIconIndex(aStart), itemsInRange);
+    iconArray->Compress();
+    iRefImages.Compress();
+
+#ifdef DEBUG_CHECK_IMAGES
+    CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
+#endif
+
+    // Notify grid
+    iGrid->HandleItemRemovalL();
+
+    // Restore the selection state updating the indexes.
+    UpdateSelectionIndexesL(aStart, aEnd, EFalse);
+
+    if (GetItemCount() > 0)
+    {
+        SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+        ScrollViewToShowAsManyItemsAsPossibleL();
+    }
+
+    UpdateControlMenu();
+    UpdateMSKLabelL();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::RemoveItemsL(const TInt* aIndices, TInt aCount)
+{
+    if (!aIndices)
+    {
+        return;
+    }
+
+    // Store the selection state
+    GetSelection(iOldSelectionArray);
+
+    TInt count = GetItemCount();
+
+    // Elements are ordered from high to low in Java side.
+    TInt min = aIndices[ aCount - 1 ];
+    TInt max = aIndices[ 0 ];
+    if (min < 0 || max >= count)
+    {
+        User::Leave(ESwtErrorInvalidRange);
+    }
+
+    CDesCArray* textArray = GetTextArray();
+    CAknIconArray* iconArray = GetIconArray();
+    TInt prevIndex = -1;
+
+    for (TInt i = 0; i < aCount; ++i)
+    {
+        // Assert that items are in high-to-low order
+        ASSERT(i + 1 < aCount ? aIndices[ i + 1 ] <= aIndices[ i ] : ETrue);
+
+        if (aIndices[i] != prevIndex)  // not the same index many times
+        {
+            UpdateRemovedItemCountersL(aIndices[i]);
+            textArray->Delete(aIndices[ i ]);
+            CGulIcon* icon = (*iconArray)[ ItemIconIndex(aIndices[ i ])];
+            iconArray->Delete(ItemIconIndex(aIndices[ i ]));
+            delete icon;
+            const MSwtImage* refImg = iRefImages[aIndices[ i ]];
+            RemoveImageRef(aIndices[ i ]);
+            iRefImages.Remove(aIndices[ i ]);
+            prevIndex = aIndices[ i ];
+        }
+    }
+
+    textArray->Compress();
+    iconArray->Compress();
+    iRefImages.Compress();
+
+#ifdef DEBUG_CHECK_IMAGES
+    CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
+#endif
+
+    // All the icon indexes starting from the first removed item
+    // need updating
+    TInt textCount = GetTextArray()->Count();
+    for (TInt i = min; i < textCount; ++i)
+    {
+        UpdateIconIndexL(i);
+    }
+
+    // Notify the grid
+    iGrid->HandleItemRemovalL();
+
+    // Restore the selection state updating the indexes.
+    prevIndex = -1;
+    for (TInt i = 0; i < aCount; ++i)
+    {
+        // Assert that items are in high-to-low order
+        ASSERT(i + 1 < aCount ? aIndices[ i + 1 ] <= aIndices[ i ] : ETrue);
+
+        if (aIndices[i] != prevIndex)  // not the same index many times
+        {
+            // Restore the selection state updating the indexes.
+            UpdateSelectionIndexesL(aIndices[i], aIndices[i], EFalse);
+
+            GetSelection(iOldSelectionArray);   //was reseted by former method
+
+            prevIndex = aIndices[ i ];
+        }
+    }
+
+    iOldSelectionArray->Reset();
+
+    if (GetItemCount() > 0)
+    {
+        SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+        ScrollViewToShowAsManyItemsAsPossibleL();
+    }
+
+    UpdateControlMenu();
+    UpdateMSKLabelL();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::RemoveAllL()
+{
+    TInt itemCount = GetItemCount();
+    if (itemCount > 0)
+    {
+        RemoveRangeL(0, itemCount - 1);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SelectItemL(TInt aIndex, TBool aScroll)
+{
+    // Checked on Java side
+    ASSERT(aIndex >= 0);
+
+    // Range check
+    if (aIndex >= GetItemCount())
+    {
+        return;
+    }
+
+    SingleOrMultiSelectL(aIndex, aScroll);
+
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SelectRangeL(TInt aStart, TInt aEnd)
+{
+    // Checked on Java side
+    ASSERT(iStyle & KSwtStyleMulti || aStart != aEnd);
+    ASSERT(aEnd >= 0);
+    ASSERT(aStart <= aEnd);
+
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (count == 0 ||           // empty
+            aStart >= count)        // no items in range
+    {
+        return;
+    }
+
+    // Ignore items out of range
+    if (aEnd >= count)
+    {
+        aEnd = count - 1;
+    }
+
+    for (TInt i = aStart; i <= aEnd; ++i)
+    {
+        SingleOrMultiSelectL(i, EFalse);
+    }
+
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SelectAllL()
+{
+    // Checked on Java side
+    ASSERT(iStyle & KSwtStyleMulti);
+
+    // Ignore if not applicable
+    TInt count(GetItemCount());
+    if (count == 0)
+    {
+        return;
+    }
+    SelectRangeL(0, count - 1);
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetFocusIndex(TInt aIndex)
+{
+    ASSERT(iGrid);
+
+    // By now, we only call this method in multiple selection.
+    // In single selection, we assume that setting the focus means selecting.
+    ASSERT(iStyle & KSwtStyleMulti);
+
+    if (aIndex < 0 || aIndex >= iGrid->Model()->NumberOfItems())
+    {
+        return;
+    }
+
+    TInt old = iGrid->CurrentItemIndex();
+    if (old != aIndex)
+    {
+        iGrid->SetCurrentItemIndex(aIndex);
+        iGrid->View()->DrawItem(aIndex);
+        if (old != -1)
+        {
+            iGrid->View()->DrawItem(old);
+        }
+    }
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetItemsL(MDesCArray* aStringArray, RPointerArray<MSwtImage>& aImagesArray)
+{
+    // Null argument and invalid range are covered in Java side.
+    // If there are no icons (client passed null) then we have an empty array here.
+    ASSERT(aStringArray);
+    TInt texts = aStringArray->MdcaCount();
+    TInt icons = aImagesArray.Count();
+    ASSERT(texts == icons || icons == 0);
+
+    // Remove the existing items
+    RemoveAllL();
+
+    // Add the new items
+    for (TInt i = 0; i < texts; ++i)
+    {
+        // Add the text
+        TRAPD(textError, AddTextL(aStringArray->MdcaPoint(i), i));
+        if (textError)
+        {
+            User::Leave(ESwtErrorItemNotAdded);
+        }
+
+        // Add the icon
+        TInt iconError;
+        if (icons)
+        {
+            TRAP(iconError, AddIconL(aImagesArray[ i ], i));
+        }
+        else
+        {
+            TRAP(iconError, AddIconL(NULL, i));
+        }
+        if (iconError)
+        {
+            // Remove the text as the icon can't be added
+            ASSERT(GetTextArray()->Count() > 0);
+            GetTextArray()->Delete(GetTextArray()->Count() - 1);
+            User::Leave(ESwtErrorItemNotAdded);
+        }
+
+        // Update grid cell layout if neccessary
+        DoGridCellLayoutIfNeededL();
+    }
+
+    // All items added successfully
+
+    iGrid->HandleItemAdditionL();
+
+    // Focus must move to the newly added item.
+    iGrid->SetCurrentDataIndex(texts - 1);
+    SingleSelectL(texts - 1, ETrue);
+
+    UpdateControlMenu();
+    UpdateMSKLabelL();
+
+    Redraw();
+    iDisplay.PostSelectionEventL(iPeer);
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// Only the horizontal orientation (vertical scrolling)
+// is supported currently. No need to do anything here.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetLayoutL(TInt /*aLayout*/)
+{
+    //TBool currentOrientation = iVerticalOrientation;
+    //if( aLayout == KSwtStyleVertical)
+    //    iVerticalOrientation = ETrue;
+    //if( aLayout == KSwtStyleHorizontal )
+    //    iVerticalOrientation = EFalse;
+    //if( iVerticalOrientation != currentOrientation )
+    //    DoGridCellLayoutL( iDensity );
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetLayoutDensityL(TInt aDensity)
+{
+    if (aDensity == iDensity)
+    {
+        return;
+    }
+
+    switch (aDensity)
+    {
+    case 1:
+    {
+        iDensity = ELowListViewDensity;
+        break;
+    }
+    case 2:
+    {
+        iDensity = EMediumListViewDensity;
+        break;
+    }
+    case 3:
+    {
+        iDensity = EHighListViewDensity;
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+    DoGridCellLayoutL(iDensity);
+    ScrollViewToShowAsManyItemsAsPossibleL();
+    Redraw();
+    UpdateControlMenu();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtListView.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::ShowSelection()
+{
+    const CAknGridView::CSelectionIndexArray& indexArray = *(iGrid->SelectionIndexes());
+    if (indexArray.Count() > 0)
+    {
+        // Make the first selected item visible in case there are many
+        iGrid->ScrollToMakeItemVisible(indexArray[ 0 ]);
+    }
+
+    UpdateControlMenu();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// From class ASwtScrollableBase
+// ---------------------------------------------------------------------------
+//
+CEikScrollBarFrame* CSwtListView::SbFrame() const
+{
+    return (iGrid ? iGrid->ScrollBarFrame() : NULL);
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+CCoeControl& CSwtListView::CoeControl()
+{
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+const CCoeControl& CSwtListView::CoeControl() const
+{
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::ProcessKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+{
+    if (GetItemCount() == 0)
+    {
+        iGrid->OfferKeyEventL(aKeyEvent, aType);
+        return;
+    }
+
+    if (!(iStyle & KSwtStyleMulti))
+    {
+        if (aKeyEvent.iCode == EKeyOK || aKeyEvent.iCode == EKeyEnter)
+        {
+            // Send default selection event.
+            iDisplay.PostDefaultSelectionEventL(iPeer);
+        }
+        else
+        {
+            iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
+
+            iGrid->OfferKeyEventL(aKeyEvent, aType);
+
+            // Post an event if the selected item has changed
+            if (iPrevFocusIndex != GetSelectionL(iGrid->CurrentDataIndex()))
+            {
+                SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+                // its workaround to fix the problem in ListView items name changing when
+                //they get focus in mirrored layout. it should be fixed in avkon
+                // CListBoxView::VerticalMoveToItemL. Remove below Redraw() after fixing.
+                if (!iLeftToRight)
+                {
+                    Redraw();
+                }
+                iDisplay.PostSelectionEventL(iPeer);
+            }
+        }
+    }
+    else  // Multi-style
+    {
+        GetSelection(iOldSelectionArray);
+
+        TBool shiftKeyPressed = (aKeyEvent.iModifiers & EModifierShift) ||
+                                (aKeyEvent.iModifiers & EModifierLeftShift) ||
+                                (aKeyEvent.iModifiers & EModifierRightShift);
+
+        // Do not offer menu opening ok key event to the grid
+        if ((aKeyEvent.iCode != EKeyOK && aKeyEvent.iCode != EKeyEnter) || shiftKeyPressed)
+        {
+            iGrid->OfferKeyEventL(aKeyEvent, aType);
+        }
+
+        if (aType == EEventKeyUp)
+        {
+            UpdateControlMenu();
+        }
+
+        // Post an event if selection has changed.
+        if (iOldSelectionArray->Count() != iGrid->SelectionIndexes()->Count())
+        {
+            iDisplay.PostSelectionEventL(iPeer);
+        }
+        else
+        {
+            for (TInt i = 0; i < iOldSelectionArray->Count(); ++i)
+            {
+                if (!IsSelected(iOldSelectionArray->At(i)))
+                {
+                    iDisplay.PostSelectionEventL(iPeer);
+                    return;
+                }
+            }
+        }
+    }
+    iOldSelectionArray->Reset();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// Returns the color set by the user if it exists.
+// ---------------------------------------------------------------------------
+//
+TRgb CSwtListView::GetBackground() const
+{
+    if (iBgColor)
+    {
+        return TRgb(iBgColor->RgbValue());
+    }
+    else
+    {
+        return ASwtControlBase::GetBackground();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// The normal text color is returned.
+// Highlighted (focused) text might have a different color.
+// ---------------------------------------------------------------------------
+//
+TRgb CSwtListView::GetForeground() const
+{
+    return iGrid->ItemDrawer()->FormattedCellData()->SubCellColors(KTextColumn).iText;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// Background color is not currently used for anything besides being returned
+// from GetBackGround.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetBackgroundL(const MSwtColor* aColor)
+{
+    iBgColor = aColor;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetForegroundL(const MSwtColor* aColor)
+{
+    iTextColor = aColor;
+    UpdateTextColorL();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// The preferred size is the top-level-shell's client area size.
+// If hints are given then the preferred size is the closest full column
+// and/or row. But not larger than the top-level-shell client area and not
+// smaller than 1x1. Parent size or contents don't affect the preferred
+// size.
+// ---------------------------------------------------------------------------
+//
+TSize CSwtListView::ComputeSizeL(TInt aWHint, TInt aHHint)
+{
+    TSize preferredSize(aWHint, aHHint);
+
+    if (aWHint != KSwtDefault && aHHint != KSwtDefault)
+    {
+        return preferredSize;
+    }
+
+    TSize cellSize = GetCellSize();
+    TUint itemCount = GetItemCount();
+    TUint columnCount = 0;
+    TUint rowCount = 0;
+
+    if (aHHint != KSwtDefault)
+    {
+        // Height is set, calculate needed number of columns.
+        if (cellSize.iHeight != 0)
+        {
+            rowCount = aHHint / cellSize.iHeight;
+        }
+
+        columnCount = GetRowColumnCount(itemCount, rowCount);
+
+        preferredSize.iWidth = columnCount * cellSize.iWidth;
+        preferredSize.iWidth += GetBorderSize(KSwtStyleHorizontal);
+    }
+    else if (aWHint != KSwtDefault)
+    {
+        // Width is set, calculate needed number of rows.
+        if (cellSize.iWidth != 0)
+        {
+            columnCount = aWHint / cellSize.iWidth;
+        }
+
+        rowCount = GetRowColumnCount(itemCount, columnCount);
+
+        preferredSize.iHeight = rowCount * cellSize.iHeight;
+        preferredSize.iHeight += GetBorderSize(KSwtStyleVertical);
+    }
+    else
+    {
+        // Width and height are not set
+        columnCount = ISqrt(itemCount);
+
+        rowCount = GetRowColumnCount(itemCount, columnCount);
+
+        preferredSize.iWidth = columnCount * cellSize.iWidth;
+        preferredSize.iWidth += GetBorderSize(KSwtStyleHorizontal);
+        preferredSize.iHeight = rowCount * cellSize.iHeight;
+        preferredSize.iHeight += GetBorderSize(KSwtStyleVertical);
+    }
+
+    // Workaround for case where listview in a layout has no borders and no items.
+    // In such a case preferred size is 0*0 pixels, which causes problems when
+    // laying out the layout.
+    if (preferredSize.iWidth <= 0 && preferredSize.iHeight <= 0)
+    {
+        preferredSize.iHeight = 1;
+        preferredSize.iWidth = 1;
+    }
+
+    return preferredSize;
+}
+
+// ---------------------------------------------------------------------------
+// Returns number of rows/columns needed on a list with aItemCount items and
+// aRowColumnCount rows/columns.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetRowColumnCount(const TInt& aItemCount, const TInt& aRowColumnCount) const
+{
+    TInt rowsColumns = 0;
+
+    if (aRowColumnCount > 0)
+    {
+        rowsColumns = (aItemCount / aRowColumnCount);
+        if ((aItemCount % aRowColumnCount) * GetCellSize().iWidth > KRowCalculationPrecisionInPixels)
+        {
+            // itemCount/rowColumnCount division returns the number of
+            // full columns, so an additional one may be needed.
+            rowsColumns++;
+        }
+    }
+
+    return rowsColumns;
+}
+
+
+void CSwtListView::UpdateMSKLabelL()
+{
+    if (AknLayoutUtils::MSKEnabled() && !HasDoNotDrawFlag())
+    {
+        MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
+        if (commandArranger)
+        {
+            commandArranger->UpdateMSKLabelL();
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Returns horizontal or vertical border size for a list cell.
+// ---------------------------------------------------------------------------
+//
+TInt CSwtListView::GetBorderSize(const TInt& aAlignment) const
+{
+    ASSERT(aAlignment == KSwtStyleHorizontal || aAlignment == KSwtStyleVertical);
+
+    TInt borderSize = GetBorderWidth() + GetBorderWidth();
+
+    if (aAlignment == KSwtStyleHorizontal)
+    {
+        // Horizontal borders, i.e. vertical scrollbar
+
+        // Vertical scrollbar exists always
+        //if( SbFrame()->ScrollBarExists( CEikScrollBar::EVertical ) &&
+        //    SbFrame()->ScrollBarVisibility( CEikScrollBar::EVertical) != CEikScrollBarFrame::EOff )
+        //    {
+        borderSize += iDisplay.UiUtils().ScrollBarBreadth(SbFrame()->VerticalScrollBar());
+        //    }
+    }
+    else
+    {
+        if (SbFrame()->ScrollBarExists(CEikScrollBar::EHorizontal) &&
+                SbFrame()->ScrollBarVisibility(CEikScrollBar::EHorizontal) != CEikScrollBarFrame::EOff)
+        {
+            borderSize += iDisplay.UiUtils().ScrollBarBreadth(
+                              SbFrame()->GetScrollBarHandle(CEikScrollBar::EHorizontal));
+        }
+    }
+
+    return borderSize;
+}
+
+// ---------------------------------------------------------------------------
+// From MSwtControl.
+// ---------------------------------------------------------------------------
+//
+TBool CSwtListView::IsKeyUsed(TUint aKeyCode) const
+{
+    // Does not use the Backspace but uses OK key
+    if (aKeyCode == EKeyBackspace)
+    {
+        return EFalse;
+    }
+    else if (aKeyCode == EKeyOK || aKeyCode == EKeyEnter)
+    {
+        if (iStyle & KSwtStyleSingle)
+        {
+            MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
+            if (commandArranger)
+            {
+                if (commandArranger->IsContextSensitiveOperationSet())
+                {
+                    return EFalse;
+                }
+            }
+            return ETrue;
+        }
+        else
+        {
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+TBool CSwtListView::MSKSelCmdEnabled() const
+{
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// Return the control menu to the menu arranger
+// ---------------------------------------------------------------------------
+//
+const MSwtMenu* CSwtListView::GetControlMenu() const
+{
+    return iMenu;
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateDoNotDrawFlag()
+{
+    ASwtControlBase::UpdateDoNotDrawFlag();
+
+    // Update redrawing state of the compound control also.
+    if (iGrid)
+    {
+        GetGridView()->SetDisableRedraw(HasDoNotDrawFlag());
+    }
+}
+
+// ---------------------------------------------------------------------------
+// From class MSwtControl.
+// ---------------------------------------------------------------------------
+//
+HBufC* CSwtListView::MSKLabelL() const
+{
+    if (!(GetItemCount() > 0))
+    {
+        return ASwtControlBase::MSKLabelL();
+    }
+
+    if ((iStyle & KSwtStyleSingle))
+    {
+        HBufC* label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_SELECT);
+        return label;
+    }
+    return ASwtControlBase::MSKLabelL();
+}
+
+// ---------------------------------------------------------------------------
+// From class MEikCommandObserver
+// ---------------------------------------------------------------------------
+void CSwtListView::ProcessCommandL(TInt aCmdId)
+{
+    TInt focusIndex = GetFocusIndex();
+    switch (aCmdId)
+    {
+    case EAknCmdMark:
+        if (focusIndex != -1)
+        {
+            if (IsSelected(focusIndex))
+            {
+                DeselectItem(focusIndex);
+            }
+            else
+            {
+                SelectItemL(focusIndex, true);
+            }
+            iDisplay.PostSelectionEventL(iPeer);
+        }
+        break;
+    case EAknMarkAll:
+        SelectAllL();
+        iDisplay.PostSelectionEventL(iPeer);
+        break;
+    case EAknUnmarkAll:
+        DeselectAll();
+        iDisplay.PostSelectionEventL(iPeer);
+        break;
+    default:
+        ASSERT(EFalse);
+        break;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtListView::HandleListBoxEventL
+// From MEikListBoxObserver
+// Handles default selection for touch. Unable to handle the selection events
+// here since EEventItemClicked is not always sent for every tap.
+// The selection events are handled in HandlePointerEvent.
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CSwtListView::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType)
+{
+    if (aListBox != iGrid)
+    {
+        return;
+    }
+
+    switch (aEventType)
+    {
+        // On 5.0, drawing trough Java gives simply a better fps.
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    case EEventPanningStarted:
+        GetShell().SetUrgentPaintControl(this);
+        break;
+    case EEventFlickStopped:
+        GetShell().SetUrgentPaintControl(NULL);
+        break;
+#endif // RD_JAVA_S60_RELEASE_9_2
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    case EEventItemSingleClicked:
+#else
+    case EEventItemDoubleClicked:
+#endif // RD_JAVA_S60_RELEASE_9_2
+        if (!(iStyle & KSwtStyleMulti))
+        {
+            if (!iDisplay.RevertPointerEvent())
+            {
+                // Ensure the selection and focus index are in sync.
+                SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+
+                iDisplay.PostDefaultSelectionEventL(iPeer);
+            }
+        }
+        break;
+    default:
+        // Do nothing
+        break;
+    }
+}
+#else //RD_SCALABLE_UI_V2
+void CSwtListView::HandleListBoxEventL(CEikListBox*, TListBoxEvent)
+{
+}
+#endif //RD_SCALABLE_UI_V2
+
+// ---------------------------------------------------------------------------
+// A fairly fast integer square root algorithm
+// ---------------------------------------------------------------------------
+TUint CSwtListView::ISqrt(TUint x)
+{
+    TUint r, nr, m;
+
+    r = 0;
+    m = 0x40000000;
+
+    do
+    {
+        nr = r + m;
+        if (nr <= x)
+        {
+            x -= nr;
+            r = nr + m;
+        }
+        r >>= 1;
+        m >>= 2;
+    }
+    while (m != 0);
+
+    if (x > r)
+    {
+        r++;
+    }
+
+    return r;
+}
+
+// ---------------------------------------------------------------------------
+// Update text and icon counters for a given item.
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateRemovedItemCountersL(const TInt& aIndex)
+{
+    ASSERT(aIndex >= 0 && aIndex < GetItemCount());
+
+    TInt textChange = 0;
+    TInt iconChange = 0;
+    TPtrC caption;
+    CGulIcon* icon = (*GetIconArray())[ ItemIconIndex(aIndex)];
+
+    // Does the item have a caption
+    GetCaption(aIndex, caption);
+    if (caption.Length() != 0)
+    {
+        textChange = -1;
+    }
+
+    // Does the item have an icon
+    TSize iconSize = icon->Bitmap()->SizeInPixels();
+    if (iconSize.iHeight != 0 && iconSize.iWidth != 0)
+    {
+        // Icon size is not (0,0) conclude that icon was set.
+        iconChange = -1;
+    }
+
+    if (textChange || iconChange)
+    {
+        UpdateSetItemCount(textChange, iconChange);
+        DoGridCellLayoutIfNeededL();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Update counters for items that have icon/text, and set update cell layout
+// status.
+// ---------------------------------------------------------------------------
+void CSwtListView::UpdateSetItemCount(const TInt& aTextChange, const TInt& aIconChange)
+{
+    TBool layoutNeeded = EFalse;
+
+    // An item that has a text has changed (added or removed)
+    if (aTextChange)
+    {
+        iNumberOfTexts += aTextChange;
+
+        if (iNumberOfTexts < 0)
+        {
+            // Just in case..
+            iNumberOfTexts = 0;
+        }
+
+        // If we are going from 0->n or from n->0, layout is needed.
+        if ((aTextChange < 0 && iNumberOfTexts == 0) ||
+                (aTextChange > 0 && iNumberOfTexts == 1))
+        {
+            layoutNeeded = ETrue;
+        }
+    }
+
+    // An item that has an icon has changed (added or removed)
+    if (aIconChange)
+    {
+        iNumberOfIcons += aIconChange;
+
+        if (iNumberOfIcons < 0)
+        {
+            iNumberOfIcons = 0;
+        }
+
+        if ((aIconChange < 0 && iNumberOfIcons == 0) ||
+                (aIconChange > 0 && iNumberOfIcons == 1))
+        {
+            layoutNeeded = ETrue;
+        }
+    }
+
+    // Layout change is needed if we have e.g. gone from a state where there
+    // are no items that have an icon on the list (i.e. texts are centered on
+    // list items) to a state where an item has an icon (and texts need to be
+    // laid out to the bottom of the items leaving space for the icon).
+    iIsGridCellLayoutNeeded = layoutNeeded;
+}
+
+
+// ---------------------------------------------------------------------------
+// Update cell layout if needed
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::DoGridCellLayoutIfNeededL()
+{
+    if (iIsGridCellLayoutNeeded)
+    {
+        DoGridCellLayoutL(iDensity);
+        iIsGridCellLayoutNeeded = EFalse;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Gets cell and subcell LAF variants for current orientation and density
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::GetCellVariants(const TSwtListViewDensity& aDensity,
+                                   TInt& aCellVariant, TInt& aSubcellVariantG1, TInt& aSubcellVariantG2,
+                                   TInt& aSubcellVariantT) const
+{
+    if (CSwtLafFacade::IsLandscapeOrientation())
+    {
+        // Landscape orientation
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        switch (aDensity)
+        {
+        case EHighListViewDensity:
+            // 5x4
+            aCellVariant = 6;
+            aSubcellVariantG1 = 6;
+            aSubcellVariantG2 = 6;
+            aSubcellVariantT = 5;
+            break;
+        case ELowListViewDensity:
+            // 3x2
+            aCellVariant = 2;
+            aSubcellVariantG1 = 1;
+            aSubcellVariantG2 = 1;
+            aSubcellVariantT = 1;
+            break;
+        default:
+            // 6x2
+            aCellVariant = 3;
+            aSubcellVariantG1 = 3;
+            aSubcellVariantG2 = 1;
+            aSubcellVariantT = 3;
+            break;
+        }
+#else
+        switch (aDensity)
+        {
+        case EHighListViewDensity:
+            // 5x4
+            aCellVariant = 6;
+            aSubcellVariantG1 = 6;
+            aSubcellVariantG2 = 6;
+            aSubcellVariantT = 5;
+            break;
+        case ELowListViewDensity:
+            // 3x2
+            aCellVariant = 2;
+            aSubcellVariantG1 = 1;
+            aSubcellVariantG2 = 1;
+            aSubcellVariantT = 1;
+            break;
+        default:
+            // 4x3
+            aCellVariant = 4;
+            aSubcellVariantG1 = 0;
+            aSubcellVariantG2 = 0;
+            aSubcellVariantT = 0;
+            break;
+        }
+#endif
+    }
+    else
+    {
+        // Portrait orientation
+        switch (aDensity)
+        {
+        case EHighListViewDensity:
+            // 4x5
+            aCellVariant = 5;
+            aSubcellVariantG1 = 6;
+            aSubcellVariantG2 = 6;
+            aSubcellVariantT = 5;
+            break;
+        case ELowListViewDensity:
+            // 2x3
+            aCellVariant = 1;
+            aSubcellVariantG1 = 1;
+            aSubcellVariantG2 = 1;
+            aSubcellVariantT = 1;
+            break;
+        default:
+            // 3x4
+            aCellVariant = 3;
+            aSubcellVariantG1 = 0;
+            aSubcellVariantG2 = 0;
+            aSubcellVariantT = 0;
+            break;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Store the sizes for all densities for getIconSize
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::UpdateIconSizes(const TSwtListViewDensity& aDensity,
+                                   const TRect& aCellRect)
+{
+    TAknLayoutRect iconRect;
+    CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1 = CSwtLafFacade::ECellHcAppPaneG1;
+
+    // Low density
+    TInt subcellVariantG1Low = 1;
+    iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
+                                            subcellVariantG1Low);
+    iIconSizeInLowDensity.SetXY(iconRect.Rect().Width(),
+                                iconRect.Rect().Height());
+
+    // High density
+    TInt subcellVariantG1High = 6;
+    iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
+                                            subcellVariantG1High);
+    iIconSizeInHighDensity.SetXY(iconRect.Rect().Width(),
+                                 iconRect.Rect().Height());
+
+    // Medium density
+    TInt subcellVariantG1Medium = 0;
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    if (CSwtLafFacade::IsLandscapeOrientation())
+    {
+        switch (aDensity)
+        {
+        case EMediumListViewDensity:
+            subcellVariantG1Medium = 1;
+            rectIdPaneG1 = CSwtLafFacade::ECellAppPaneG1;
+            break;
+        }
+    }
+#else
+    (void)aDensity; // Suppress compilation warning
+#endif
+
+    iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
+                                            subcellVariantG1Medium);
+    iIconSizeInMediumDensity.SetXY(iconRect.Rect().Width(),
+                                   iconRect.Rect().Height());
+}
+
+// ---------------------------------------------------------------------------
+// Gets layout rectangle IDs
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::GetLafFacadeRectIds(
+    const TSwtListViewDensity& aDensity,
+    CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPane,
+    CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPaneG1,
+    CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPaneG2,
+    CSwtLafFacade::TSwtLafFacadeTextId& aRectIdPaneT1,
+    CSwtLafFacade::TSwtLafFacadeFontId& aRectIdPaneT1Font) const
+{
+    aRectIdPane = CSwtLafFacade::ECellHcAppPane;
+    aRectIdPaneG1 = CSwtLafFacade::ECellHcAppPaneG1;
+    aRectIdPaneG2 = CSwtLafFacade::ECellHcAppPaneG2;
+    aRectIdPaneT1 = CSwtLafFacade::ECellHcAppPaneT1;
+    aRectIdPaneT1Font = CSwtLafFacade::ECellHcAppPaneT1Font;
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    if (CSwtLafFacade::IsLandscapeOrientation())
+    {
+        switch (aDensity)
+        {
+        case EMediumListViewDensity:
+            aRectIdPane = CSwtLafFacade::ECellAppPane;
+            aRectIdPaneG1 = CSwtLafFacade::ECellAppPaneG1;
+            aRectIdPaneG2 = CSwtLafFacade::ECellAppPaneG2;
+            aRectIdPaneT1 = CSwtLafFacade::ECellAppPaneT1;
+            aRectIdPaneT1Font = CSwtLafFacade::ECellAppPaneT1Font;
+            break;
+        }
+    }
+#else
+    (void)aDensity; // Suppress compilation warning
+#endif
+}
+
+
+// ---------------------------------------------------------------------------
+// Coerces cell rectangle to match native one
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::CoerceCellRect(const TSwtListViewDensity& aDensity, TRect& aCellRect) const
+{
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    if (CSwtLafFacade::IsLandscapeOrientation())
+    {
+        switch (aDensity)
+        {
+        case EMediumListViewDensity:
+            aCellRect.iBr.iX -= 2;
+            break;
+        }
+    }
+#else
+    (void)aDensity; // Suppress compilation warning
+    (void)aCellRect; // Suppress compilation warning
+#endif
+}
+
+
+// ---------------------------------------------------------------------------
+// CSwtListView::SetVisibleScrollBar
+// From ASwtScrollableBase
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::SetVisibleScrollBar(TInt aStyle, TBool aVisible)
+{
+    iGrid->SetScrollbarVisibility(aStyle, aVisible);
+    ASwtScrollableBase::SetVisibleScrollBar(aStyle, aVisible);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtListView::ScrollBarDestroyed
+// From ASwtScrollableBase
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::ScrollBarDestroyed(const MSwtScrollBar* aScrollBar)
+{
+    if (aScrollBar == iHScroll)
+    {
+        iGrid->SetScrollbarVisibility(KSwtStyleHScroll, EFalse);
+    }
+    else
+    {
+        iGrid->SetScrollbarVisibility(KSwtStyleVScroll, EFalse);
+    }
+    ASwtScrollableBase::ScrollBarDestroyed(aScrollBar);
+}
+
+#if defined( RD_SCALABLE_UI_V2)
+// ---------------------------------------------------------------------------
+// CSwtListView::HandleScrollEventL
+// From ASwtScrollableBase
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::HandleScrollEventL(CEikScrollBar* aScrollBar,
+                                      TEikScrollEvent aEventType)
+{
+    // On 5.0, drawing trough Java gives simply a better fps.
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    switch (aEventType)
+    {
+    case EEikScrollThumbDragVert:
+        GetShell().SetUrgentPaintControl(this);
+        break;
+    case EEikScrollThumbReleaseVert:
+        GetShell().SetUrgentPaintControl(NULL);
+        break;
+    default:
+        break;
+    }
+#endif // RD_JAVA_S60_RELEASE_9_2
+
+    iGrid->DoHandleScrollEventL(aScrollBar, aEventType);
+    ASwtScrollableBase::HandleScrollEventL(aScrollBar, aEventType);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtListView::HandlePointerEventL
+// From ASwtControlBase
+// ---------------------------------------------------------------------------
+//
+void CSwtListView::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+{
+    ASSERT(iGrid);
+
+    CEikScrollBarFrame* sbFrame = iGrid->ScrollBarFrame();
+    CEikScrollBar* vsb = sbFrame ? sbFrame->GetScrollBarHandle(CEikScrollBar::EVertical) : NULL;
+
+    // Check if we should start scrollbar grabbing
+    if (aPointerEvent.iType == TPointerEvent::EButton1Down && !iVScrollBarGrabsPointerEvents)
+    {
+        if (vsb && vsb->Rect().Contains(aPointerEvent.iPosition))
+        {
+            iVScrollBarGrabsPointerEvents = ETrue;
+        }
+    }
+
+    // Deliver event to scrollbar
+    if (iVScrollBarGrabsPointerEvents && vsb)
+    {
+        vsb->HandlePointerEventL(aPointerEvent);
+    }
+
+    // Deliver event to list
+    if (!iVScrollBarGrabsPointerEvents)
+    {
+        // Store the selection on first pointer event.
+        if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+        {
+            if (iStyle & KSwtStyleMulti)
+            {
+                // Multi lists
+                ASSERT(iOldSelectionArray);
+                GetSelection(iOldSelectionArray);
+            }
+            iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
+        }
+
+        iGrid->HandlePointerEventL(aPointerEvent);
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        // When flicking CEikListBox sets selection to 0 (during EDrag event).
+        // So eSWT has to reload the iPrevFocusIndex, otherwise it might scroll
+        // to the top of the ListView
+        if (aPointerEvent.iType == TPointerEvent::EDrag)
+        {
+            iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
+        }
+#endif //RD_JAVA_S60_RELEASE_9_2
+
+        if (aPointerEvent.iType == TPointerEvent::EButton1Up)
+        {
+            TInt focusIndex = GetSelectionL(iGrid->CurrentDataIndex());
+
+            if (iStyle & KSwtStyleMulti)
+            {
+                // Multi lists
+                if ((iGrid->SelectionIndexes()->Count() != iOldSelectionArray->Count()))
+                {
+                    if (iDisplay.RevertPointerEvent())
+                    {
+                        // Revert.
+                        if (iGrid->View()->ItemIsSelected(focusIndex))
+                        {
+                            iGrid->View()->DeselectItem(focusIndex);
+                        }
+                        else
+                        {
+                            iGrid->View()->SelectItemL(focusIndex);
+                        }
+                    }
+                    else
+                    {
+                        iDisplay.PostSelectionEventL(iPeer);
+                    }
+                }
+            }
+            else
+            {
+                // Single lists
+                // Compare the focus index after tap or drag ended
+                if (focusIndex != iPrevFocusIndex)
+                {
+                    // Ensure the selection and focus index are in sync.
+                    SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
+
+                    // Item focus highlight moved, send selection event.
+                    // Changing the focus index is not subject to reverting.
+                    iDisplay.PostSelectionEventL(iPeer);
+                }
+
+                // The default selection is sent from HandleListBoxEventL!
+            }
+        }
+    }
+
+    // Stop scrollbar grabbing
+    if (iVScrollBarGrabsPointerEvents
+            && aPointerEvent.iType == TPointerEvent::EButton1Up)
+    {
+        iVScrollBarGrabsPointerEvents = EFalse;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtListView::GetStylusPopupControlMenu()
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+const MSwtMenu* CSwtListView::GetStylusPopupControlMenu() const
+{
+    return iStylusPopupMenu;
+}
+#endif // RD_SCALABLE_UI_V2
+
+#ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+void CSwtListView::DoControlSpecificFeedback(
+    const TBool& aFirstTap,
+    const TBool& aTappedToChildRect,
+    const TPointerEvent& aPointerEvent) const
+{
+    MTouchFeedback* feedback = MTouchFeedback::Instance();
+    if (feedback && !aTappedToChildRect)
+    {
+        switch (aPointerEvent.iType)
+        {
+        case TPointerEvent::EButton1Down:
+            if (aFirstTap)
+            {
+                feedback->InstantFeedback(ETouchFeedbackSensitiveList);
+            }
+            break;
+        }
+    }
+}
+#endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
+