javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtlistview.cpp
branchRCL_3
changeset 66 2455ef1f5bbc
child 83 26b2b12093af
equal deleted inserted replaced
65:ae942d28ec0e 66:2455ef1f5bbc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  *
       
     8  * Contributors:
       
     9  *     Nokia Corporation - S60 implementation
       
    10  *******************************************************************************/
       
    11 
       
    12 
       
    13 #include <AknGridView.h>
       
    14 #include <aknlists.h>
       
    15 #include <avkon.mbg>
       
    16 #include <gulicon.h>
       
    17 #include <AknIconArray.h>
       
    18 #include <AknLayoutFont.h>
       
    19 #include <AknsBasicBackgroundControlContext.h>
       
    20 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    21 #include <aknlistloadertfx.h>
       
    22 #include <aknlistboxtfx.h>
       
    23 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
    24 #include <eswtcore.rsg>
       
    25 #include <swtlaffacade.h>
       
    26 #include "swtcontrolmenu.h"
       
    27 #include "swtmenuitem.h"
       
    28 #include "swtgrid.h"
       
    29 #include "swtlistview.h"
       
    30 #include "swtcontrolhelper.h"
       
    31 #include "swtinstancecounts.h"
       
    32 #include "swtdisplay.h"
       
    33 #ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
    34 #include <touchfeedback.h>
       
    35 #endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
    36 
       
    37 #ifdef ESWT_NATIVE_UITHREAD_OWN_HEAP
       
    38 #define DEBUG_CHECK_IMAGES
       
    39 #endif // ESWT_NATIVE_UITHREAD_OWN_HEAP
       
    40 
       
    41 
       
    42 // Column indexes of the subcells in the list item format string.
       
    43 // Gfx cell has to be first for it to be drawn first.
       
    44 static const TInt KIconColumn       = 0;
       
    45 static const TInt KTextColumn       = 1;
       
    46 static const TInt KItemMarkColumn   = 2;
       
    47 
       
    48 // Constants used for listbox text string formatting
       
    49 const TInt KSpaceForIndex = 20;
       
    50 _LIT(KColumnSeparator, "\t");
       
    51 _LIT(KSeparatorReplacement, " ");
       
    52 
       
    53 // The indexes for marked and unmarked icons in the icon array
       
    54 _LIT(KMarkOffIconArrayIndex, "1");
       
    55 _LIT(KMarkOnIconArrayIndex, "0");
       
    56 
       
    57 static const TInt KMarkOnIconArrayIndexInt  = 0;
       
    58 static const TInt KSwtListViewItemGranularity = 4;
       
    59 static const TInt KRowCalculationPrecisionInPixels = 5;
       
    60 
       
    61 
       
    62 // ======== LOCAL FUNCTIONS ========
       
    63 
       
    64 
       
    65 #ifdef DEBUG_CHECK_IMAGES
       
    66 static void CheckRefImages(RPointerArray<const MSwtImage>& aRefImgArr,
       
    67                            CArrayPtrFlat<CGulIcon>& aImgArr,
       
    68                            const TSize& aMaxImageSize)
       
    69 {
       
    70     TInt countImg = aImgArr.Count() - 2;
       
    71     TInt countRefImg = aRefImgArr.Count();
       
    72 
       
    73     if (countImg != countRefImg)
       
    74     {
       
    75         ASSERT(EFalse);
       
    76     }
       
    77 
       
    78     for (TInt i = 0; i < countImg; i++)
       
    79     {
       
    80         const CGulIcon* img = aImgArr[i + 2];
       
    81         const MSwtImage* refImg = aRefImgArr[i];
       
    82         if (img)
       
    83         {
       
    84             const CFbsBitmap* bmp = img->Bitmap();
       
    85             const CFbsBitmap* mask = img->Mask();
       
    86 
       
    87             ASSERT(bmp);
       
    88             if (refImg)
       
    89             {
       
    90                 // The item has a valid image.
       
    91                 // The bitmap is NOT owned.
       
    92                 ASSERT(img->BitmapsOwnedExternally());
       
    93                 const CFbsBitmap& bitmap = refImg->Bitmap();
       
    94                 TSize imageSize = refImg->Bitmap().SizeInPixels();
       
    95                 imageSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
       
    96                                 imageSize, aMaxImageSize);
       
    97 
       
    98                 __UHEAP_MARK;
       
    99                 ASSERT(bmp == &refImg->SubBitmap(imageSize));
       
   100                 ASSERT(mask == refImg->SubMaskBitmap(imageSize, ETrue));
       
   101                 // If image is not scaled, the primary refcount of
       
   102                 // the image >= 2, otherwise it's >= 1 and subrefcount
       
   103                 // for the given size should also be >= 1.
       
   104                 if (imageSize == refImg->Bitmap().SizeInPixels())
       
   105                 {
       
   106                     ASSERT(refImg->RefCount() >= 2);
       
   107                 }
       
   108                 else
       
   109                 {
       
   110                     ASSERT(refImg->RefCount() >= 1);
       
   111                     ASSERT(refImg->SubRefCount(imageSize) >= 1);
       
   112                 }
       
   113 
       
   114                 __UHEAP_MARKEND;
       
   115             }
       
   116             else
       
   117             {
       
   118                 // The item has a blank image (null image set from Java side)
       
   119                 // The bitmap is owned.
       
   120                 ASSERT(bmp->SizeInPixels() == TSize(0, 0));
       
   121                 ASSERT(!mask);
       
   122             }
       
   123         }
       
   124     }
       
   125 }
       
   126 #endif // DEBUG_CHECK_IMAGES
       
   127 
       
   128 
       
   129 // ======== MEMBER FUNCTIONS ========
       
   130 
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // CSwtListView Constructor
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 CSwtListView::CSwtListView(MSwtDisplay& aDisplay, TSwtPeer aPeer,
       
   137                            MSwtComposite& aParent, TInt aStyle)
       
   138         : ASwtScrollableBase(aDisplay, aPeer, &aParent, aStyle),
       
   139         iLeftToRight(ETrue),
       
   140         iTopToBottom(ETrue),
       
   141         iNumOfRows(1),
       
   142         iNumOfColumns(1),
       
   143         iWidthOfSpaceBetweenItems(0),
       
   144         iHeightOfSpaceBetweenItems(0),
       
   145         iDensity(EMediumListViewDensity),   // must match Java-side default
       
   146         iIsGridCellLayoutNeeded(EFalse),
       
   147         iFlickScrollingOngoing(EFalse)
       
   148 
       
   149 {
       
   150     // Default to horizontal layout orientation (vertical scrollbar)
       
   151     //if( iStyle & KSwtStyleVertical )
       
   152     //    {
       
   153     //    iVerticalOrientation = ETrue;
       
   154     //    }
       
   155     //else
       
   156     //    {
       
   157     iVerticalOrientation = EFalse;
       
   158     iStyle &= ~KSwtStyleHScroll;
       
   159     iStyle |= KSwtStyleVScroll;
       
   160     //    }
       
   161 }
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 // 2nd phase construction
       
   165 // ---------------------------------------------------------------------------
       
   166 //
       
   167 void CSwtListView::ConstructL()
       
   168 {
       
   169     CCoeControl& coeParent = iParent->Control()->CoeControl();
       
   170     SetContainerWindowL(coeParent);
       
   171 
       
   172     CCoeControl::MakeVisible(coeParent.IsVisible());
       
   173     CCoeControl::SetDimmed(coeParent.IsDimmed());
       
   174     SetComponentsToInheritVisibility(ETrue);
       
   175 
       
   176     iGrid = new(ELeave) CSwtGrid(this);
       
   177     iGrid->SetContainerWindowL(*this);
       
   178 
       
   179     if (AknLayoutUtils::LayoutMirrored())
       
   180     {
       
   181         iLeftToRight = EFalse;
       
   182     }
       
   183 
       
   184     // Construct either markable or normal grid
       
   185     TInt gridFlags = 0;
       
   186     if (iStyle & KSwtStyleMulti)
       
   187     {
       
   188 #if defined( RD_SCALABLE_UI_V2)
       
   189         // For touch to work the same way as in other lists we need different
       
   190         // list styles for the grid.
       
   191         gridFlags |= CEikListBox::EMultipleSelection |
       
   192                      CEikListBox::ES60StyleMultiselection |
       
   193                      CEikListBox::EShiftEnterMarks;
       
   194 #else
       
   195         gridFlags |= EAknListBoxMarkableGrid;
       
   196 #endif
       
   197         // Enabling marking only by pressing enter key
       
   198         gridFlags |= CEikListBox::EEnterMarks;
       
   199 
       
   200         // Create control menu
       
   201         iMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
       
   202 
       
   203         iMenuItemEditList = CSwtMenuItem::NewL(iDisplay, NULL, *iMenu, 0, 0);
       
   204         HBufC* buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_EDIT_LIST);
       
   205         TPtrC ptr = buffer->Des();
       
   206         iMenuItemEditList->SetTextL(ptr);
       
   207         CleanupStack::PopAndDestroy(buffer);
       
   208 
       
   209         iSubMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
       
   210         iMenuItemEditList->SetMenuL(iSubMenu);
       
   211         iSubMenu->SetObserver(this);
       
   212 
       
   213         iMenuItemMarkUnmark = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 0, 0, EAknCmdMark);
       
   214         iMenuItemMarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 1, 0, EAknMarkAll);
       
   215         iMenuItemUnmarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iSubMenu, 2, 0, EAknUnmarkAll);
       
   216 
       
   217         iMarkString = iCoeEnv->AllocReadResourceL(R_LISTVIEW_MARK_ONE);
       
   218         iUnmarkString = iCoeEnv->AllocReadResourceL(R_LISTVIEW_UNMARK_ONE);
       
   219         ptr.Set(iMarkString->Des());
       
   220         iIsMarkDisplayed = ETrue;
       
   221         iMenuItemMarkUnmark->SetTextL(ptr);
       
   222 
       
   223         buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_MARK_ALL);
       
   224         ptr.Set(buffer->Des());
       
   225         iMenuItemMarkAll->SetTextL(ptr);
       
   226         CleanupStack::PopAndDestroy(buffer);
       
   227 
       
   228         buffer = iCoeEnv->AllocReadResourceLC(R_LISTVIEW_UNMARK_ALL);
       
   229         ptr.Set(buffer->Des());
       
   230         iMenuItemUnmarkAll->SetTextL(ptr);
       
   231         CleanupStack::PopAndDestroy(buffer);
       
   232 
       
   233 #ifdef RD_SCALABLE_UI_V2
       
   234         iStylusPopupMenu = CSwtControlMenu::NewL(iDisplay, NULL, 0);
       
   235         iStylusPopupMenu->SetObserver(this);
       
   236 
       
   237         iStylusPopupMarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iStylusPopupMenu, 0, 0, EAknMarkAll);
       
   238         iStylusPopupMarkAll->SetTextL(iMenuItemMarkAll->Text());
       
   239 
       
   240         iStylusPopupUnmarkAll = CSwtMenuItem::NewL(iDisplay, NULL, *iStylusPopupMenu, 1, 0, EAknUnmarkAll);
       
   241         iStylusPopupUnmarkAll->SetTextL(iMenuItemUnmarkAll->Text());
       
   242 #endif //RD_SCALABLE_UI_V2
       
   243     }
       
   244 
       
   245     iOldSelectionArray = new(ELeave) CArrayFixFlat<TInt>(2);
       
   246     iSelectionArray = new(ELeave) CArrayFixFlat<TInt>(2);
       
   247     iGrid->ConstructL(this, gridFlags);
       
   248 
       
   249     CArrayPtr< CGulIcon >* icons = new(ELeave) CAknIconArray(KSwtListViewItemGranularity);
       
   250     CleanupStack::PushL(icons);
       
   251 
       
   252     // Marked icon
       
   253     CGulIcon* markedIcon = GetMarkedItemIconL();
       
   254     CleanupStack::PushL(markedIcon);
       
   255     icons->AppendL(markedIcon);
       
   256 
       
   257     // Unmarked icon
       
   258     CGulIcon* unmarkedIcon = CreateIconL(NULL);
       
   259     CleanupStack::PushL(unmarkedIcon);
       
   260     icons->AppendL(unmarkedIcon);
       
   261 
       
   262     // Attach icon array to grid’s item drawer, itemDrawer takes ownership
       
   263     iGrid->ItemDrawer()->FormattedCellData()->SetIconArrayL(icons);
       
   264     CleanupStack::Pop(3, icons);
       
   265 
       
   266     DoGridCellLayoutL(iDensity);
       
   267 
       
   268     // This is needed to correct skinned background drawing problems when
       
   269     // the control is repositioned.
       
   270     iGrid->ItemDrawer()->ColumnData()->SetSkinEnabledL(EFalse);
       
   271 
       
   272     // Create non-window owning scrollbars to avoid clipping problems.
       
   273     iGrid->CreateScrollBarFrameL();
       
   274 
       
   275 #ifdef RD_SCALABLE_UI_V2
       
   276     // WARNING!!! The expanded touch area does not move correctly togehter with the scrollbars!
       
   277     iGrid->ScrollBarFrame()->SetScrollBarFrameFlags(CEikScrollBarFrame::EDisableExpandedTouchArea);
       
   278 #endif // RD_SCALABLE_UI_V2
       
   279 
       
   280     // In eSWT all scrollbars must be non window owing the main reason being that
       
   281     // the scrollbars must draw at exact same time with the parent control. This
       
   282     // is especially essential in ScrolledComposite. If the scrollbars would be
       
   283     // window owing, they would draw too much ahead of the parents creating an
       
   284     // ugly visual effect when flicking the ScrolledComposite.
       
   285     // The drawback of having non window owing scrollbars is too many paint events
       
   286     // which affects on the speed of kinetic scrolling in lists.
       
   287     iGrid->ScrollBarFrame()->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, EFalse);
       
   288     iGrid->SetScrollbarVisibility(KSwtStyleVScroll, ETrue);
       
   289     iGrid->SetScrollbarVisibility(KSwtStyleHScroll, EFalse);
       
   290 
       
   291     UpdateControlMenu();
       
   292 
       
   293     // WORKAROUND! This is to avoid CAknGrid crash when its size is 0
       
   294     // and the List Transition Effects try to draw the grid. In fact the
       
   295     // root cause of the crash is our Shell not being always ready to draw
       
   296     // which is what Avkon expects. If that would be the case, the List
       
   297     // Transition Effects will never get a chance to draw a size 0 grid.
       
   298     iGrid->SetRect(TRect(0, 0, 1, 0));
       
   299 
       
   300 #ifdef RD_SCALABLE_UI_V2
       
   301     iGrid->SetListBoxObserver(this);
       
   302 #endif // RD_SCALABLE_UI_V2
       
   303 
       
   304 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   305     // Effects do not work with non window owning scrollbars.
       
   306     CWindowGc* gc = iGrid->View()->ItemDrawer()->Gc();
       
   307     MAknListBoxTfx* transApi = CAknListLoader::TfxApi(gc);
       
   308     if (transApi)
       
   309     {
       
   310         transApi->EnableEffects(EFalse);
       
   311     }
       
   312 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   313 
       
   314     // This is indeed necessary, otherwise the background might not be drawn!
       
   315     SetBackground(this);
       
   316 
       
   317     ActivateL();
       
   318 }
       
   319 
       
   320 // ---------------------------------------------------------------------------
       
   321 // Sets up the grid based on the given density and the style flags received
       
   322 // at the construction time. Can/must be called again to reset the layout.
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 void CSwtListView::DoGridCellLayoutL(const TSwtListViewDensity& aDensity)
       
   326 {
       
   327     // Load the layout data for the resolution
       
   328     TSize cellSize(0, 0);
       
   329     TRect iconSubcell(0, 0, 0, 0);
       
   330     TRect selectionMarkSubcell(0, 0, 0, 0);
       
   331     TRect textSubcell(0, 0, 0, 0);
       
   332     TInt textCellFontId = 0;
       
   333     LoadLayouts(aDensity, cellSize, iconSubcell, selectionMarkSubcell, textSubcell, textCellFontId);
       
   334     ASSERT(textCellFontId != 0);
       
   335 
       
   336     CalcRowsColumns(cellSize, iNumOfColumns, iNumOfRows);
       
   337 
       
   338     iGrid->SetLayoutL(iVerticalOrientation,
       
   339                       iLeftToRight,
       
   340                       iTopToBottom,
       
   341                       iNumOfColumns,
       
   342                       iNumOfRows,
       
   343                       cellSize,
       
   344                       iWidthOfSpaceBetweenItems,
       
   345                       iHeightOfSpaceBetweenItems);
       
   346     iGrid->SetPrimaryScrollingType(CAknGridView::EScrollIncrementLineAndLoops);
       
   347     iGrid->SetSecondaryScrollingType(CAknGridView::EScrollIncrementLineAndLoops);
       
   348 
       
   349     const CAknLayoutFont* font = AknLayoutUtils::LayoutFontFromId(textCellFontId);
       
   350     ASSERT(font != NULL);
       
   351 
       
   352     const TInt KTextDefaultColor = 215; // 215 = black, overridden later
       
   353 
       
   354     CFormattedCellListBoxItemDrawer* itemDrawer = iGrid->ItemDrawer();
       
   355 
       
   356     // Setup the icon subcell
       
   357     AknListBoxLayouts::SetupGridFormGfxCell(
       
   358         *iGrid,                 // Reference to grid control
       
   359         itemDrawer,             // Pointer to the item drawer
       
   360         KIconColumn,            // Column index
       
   361         iconSubcell.iTl.iX,     // Left position
       
   362         iconSubcell.iTl.iY,     // Top position
       
   363         0,                      // Right - unused
       
   364         0,                      // Bottom - unused
       
   365         iconSubcell.Width(),    // Width
       
   366         iconSubcell.Height(),   // Height
       
   367         iconSubcell.iTl,        // Start position
       
   368         iconSubcell.iBr);       // End position
       
   369 
       
   370     // Setup the text subcell
       
   371     AknListBoxLayouts::SetupFormTextCell(
       
   372         *iGrid,                     // Reference to grid
       
   373         itemDrawer,                 // Pointer to the item drawer
       
   374         KTextColumn,                // Column index
       
   375         font,                       // The font
       
   376         KTextDefaultColor,          // Color
       
   377         textSubcell.iTl.iX,         // Left margin
       
   378         0,                          // Right margin - unused
       
   379         (textSubcell.iTl.iY + textSubcell.Height() - (font->MaxDescent())),  // Baseline
       
   380         textSubcell.Width(),        // Text width
       
   381         CGraphicsContext::ECenter,  // Text alignment
       
   382         textSubcell.iTl,            // Start position
       
   383         textSubcell.iBr);           // End position
       
   384 
       
   385     CFormattedCellListBoxData* gridData = itemDrawer->FormattedCellData();
       
   386     gridData->SetTransparentSubCellL(KTextColumn, ETrue);
       
   387 
       
   388     // Set-up markable grid if required
       
   389     if (iStyle & KSwtStyleMulti)
       
   390     {
       
   391         // Set column index in the format string
       
   392         itemDrawer->SetItemMarkPosition(KItemMarkColumn);
       
   393         // Set icon array index of marked item icon
       
   394         itemDrawer->SetItemMarkReplacement(KMarkOnIconArrayIndex);
       
   395         // Don’t display all items as marked initially
       
   396         itemDrawer->SetItemMarkReverse(ETrue);
       
   397         // Setup the selection mark subcell
       
   398         AknListBoxLayouts::SetupFormGfxCell(
       
   399             *iGrid,                         // Reference to grid control
       
   400             itemDrawer,                     // Pointer to the item drawer
       
   401             KItemMarkColumn,                // Column index
       
   402             selectionMarkSubcell.iTl.iX,    // Left position
       
   403             selectionMarkSubcell.iTl.iY,    // Top position
       
   404             0,                              // Right - unused
       
   405             0,                              // Bottom - unused
       
   406             selectionMarkSubcell.Width(),   // Width
       
   407             selectionMarkSubcell.Height(),  // Height
       
   408             selectionMarkSubcell.iTl,       // Start position
       
   409             selectionMarkSubcell.iBr);      // End position
       
   410 
       
   411         gridData->SetTransparentSubCellL(KItemMarkColumn, ETrue);
       
   412     }
       
   413 
       
   414     TSize maxImageSize = iconSubcell.Size();
       
   415 
       
   416     if (iMaxImageSize != maxImageSize)
       
   417     {
       
   418         UpdateImageSizes(maxImageSize);
       
   419         iMaxImageSize = maxImageSize;
       
   420     }
       
   421 
       
   422     UpdateTextColorL();
       
   423 }
       
   424 
       
   425 // ---------------------------------------------------------------------------
       
   426 // A helper to get the text array of item texts.
       
   427 // ---------------------------------------------------------------------------
       
   428 //
       
   429 CDesCArray* CSwtListView::GetTextArray() const
       
   430 {
       
   431     MDesCArray* array = GetGridModel()->ItemTextArray();
       
   432     return static_cast<CDesCArray*>(array);
       
   433 }
       
   434 
       
   435 // ---------------------------------------------------------------------------
       
   436 // A helper to get the array of icons.
       
   437 // ---------------------------------------------------------------------------
       
   438 //
       
   439 CAknIconArray* CSwtListView::GetIconArray() const
       
   440 {
       
   441     CArrayPtr<CGulIcon>* array = iGrid->ItemDrawer()->FormattedCellData()->IconArray();
       
   442     return static_cast<CAknIconArray*>(array);
       
   443 }
       
   444 
       
   445 // ---------------------------------------------------------------------------
       
   446 // A helper to get the model of the grid.
       
   447 // ---------------------------------------------------------------------------
       
   448 //
       
   449 CAknGridM* CSwtListView::GetGridModel() const
       
   450 {
       
   451     return static_cast<CAknGridM*>(iGrid->Model());
       
   452 }
       
   453 
       
   454 // ---------------------------------------------------------------------------
       
   455 // A helper to get the view of the grid.
       
   456 // ---------------------------------------------------------------------------
       
   457 //
       
   458 CAknGridView* CSwtListView::GetGridView() const
       
   459 {
       
   460     return static_cast<CAknGridView*>(iGrid->View());
       
   461 }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // A helper to get array of logical selection indices.
       
   465 // ---------------------------------------------------------------------------
       
   466 //
       
   467 void CSwtListView::GetSelection(CArrayFix<TInt>* aSelectionArray) const
       
   468 {
       
   469     CAknGridView* gridView = GetGridView();
       
   470 
       
   471     if (aSelectionArray && gridView)
       
   472     {
       
   473         aSelectionArray->Reset();
       
   474 
       
   475         TRAP_IGNORE(gridView->GetSelectionIndexesL(aSelectionArray));
       
   476 
       
   477         // The returned indexes are not the logical indexes (which take
       
   478         // right-to-left ordering into account), make them logical if
       
   479         // necessary.
       
   480         if (!iLeftToRight)
       
   481         {
       
   482             for (int i = 0; i < aSelectionArray->Count(); i++)
       
   483             {
       
   484                 aSelectionArray->At(i) =
       
   485                     gridView->ActualDataIndex(aSelectionArray->At(i));
       
   486             }
       
   487         }
       
   488     }
       
   489 }
       
   490 
       
   491 // ---------------------------------------------------------------------------
       
   492 // A helper to get logical selection index.
       
   493 // ---------------------------------------------------------------------------
       
   494 //
       
   495 TInt CSwtListView::GetSelectionL(const TInt aIndex) const
       
   496 {
       
   497     if (iLeftToRight)
       
   498     {
       
   499         return aIndex;
       
   500     }
       
   501 
       
   502     CAknGridView* gridView = GetGridView();
       
   503     if (!gridView)
       
   504     {
       
   505         User::Leave(ESwtErrorCannotGetSelection);
       
   506     }
       
   507 
       
   508     return gridView->ActualDataIndex(aIndex);
       
   509 }
       
   510 
       
   511 // ---------------------------------------------------------------------------
       
   512 // A helper to set selection array of logical selection indices.
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 void CSwtListView::SetSelectionL(const CArrayFix<TInt>* aSelectionArray) const
       
   516 {
       
   517     CAknGridView* gridView = GetGridView();
       
   518 
       
   519     if (aSelectionArray && gridView)
       
   520     {
       
   521         gridView->ClearSelection();
       
   522 
       
   523         for (TInt i = 0; i < aSelectionArray->Count(); i++)
       
   524         {
       
   525             TInt item = aSelectionArray->At(i);
       
   526 
       
   527             if (!iLeftToRight)
       
   528             {
       
   529                 item = gridView->ActualDataIndex(item);
       
   530             }
       
   531 
       
   532             gridView->SelectItemL(item);
       
   533         }
       
   534     }
       
   535 }
       
   536 
       
   537 // ---------------------------------------------------------------------------
       
   538 // A helper to create an icon out of the given image object.
       
   539 // ---------------------------------------------------------------------------
       
   540 //
       
   541 CGulIcon* CSwtListView::CreateIconL(const MSwtImage* aIcon) const
       
   542 {
       
   543     CGulIcon* icon = NULL;
       
   544     if (aIcon)
       
   545     {
       
   546         CFbsBitmap* bmp = 0;
       
   547         CFbsBitmap* mask = 0;
       
   548 
       
   549         TSize bitmapSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
       
   550                                aIcon->Bitmap().SizeInPixels(),
       
   551                                iMaxImageSize);
       
   552 
       
   553         bmp =  const_cast<CFbsBitmap*>(&aIcon->SubBitmap(bitmapSize));
       
   554         mask = const_cast<CFbsBitmap*>(aIcon->SubMaskBitmap(bitmapSize, ETrue));
       
   555         aIcon->AddRef();
       
   556         aIcon->AddSubRef(bitmapSize);
       
   557 
       
   558         icon = CGulIcon::NewL();
       
   559         icon->SetBitmapsOwnedExternally(ETrue);
       
   560         icon->SetBitmap(bmp);
       
   561         icon->SetMask(mask);
       
   562     }
       
   563     else // Create a blank icon
       
   564     {
       
   565         CFbsBitmap* bmp = new(ELeave) CFbsBitmap;
       
   566         CleanupStack::PushL(bmp);
       
   567         User::LeaveIfError(bmp->Create(TSize(0, 0), EColor256));
       
   568         ASSERT(bmp);
       
   569         icon = CGulIcon::NewL(bmp);
       
   570         CleanupStack::Pop(bmp);   // bmp
       
   571     }
       
   572     return icon;
       
   573 }
       
   574 
       
   575 // ---------------------------------------------------------------------------
       
   576 // Loads the layouts for the current resolution.
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 void CSwtListView::LoadLayouts(const TSwtListViewDensity& aDensity,
       
   580                                TSize& aCellSize,
       
   581                                TRect& aIconRect,
       
   582                                TRect& aSelRect,
       
   583                                TRect& aTextRect,
       
   584                                TInt& aTextCellFontId)
       
   585 {
       
   586     // Grid cell variants
       
   587     TInt cellVariant;
       
   588     TInt subcellVariantG1;
       
   589     TInt subcellVariantG2;
       
   590     TInt subcellVariantT;
       
   591     GetCellVariants(aDensity, cellVariant, subcellVariantG1, subcellVariantG2,
       
   592                     subcellVariantT);
       
   593 
       
   594     // LAF rectangle IDs
       
   595     CSwtLafFacade::TSwtLafFacadeRectId rectIdPane;
       
   596     CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1;
       
   597     CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG2;
       
   598     CSwtLafFacade::TSwtLafFacadeTextId rectIdPaneT1;
       
   599     CSwtLafFacade::TSwtLafFacadeFontId rectIdPaneT1Font;
       
   600     GetLafFacadeRectIds(aDensity, rectIdPane, rectIdPaneG1, rectIdPaneG2,
       
   601                         rectIdPaneT1, rectIdPaneT1Font);
       
   602 
       
   603     // Grid cell
       
   604     TAknLayoutRect cellLayoutRect = CSwtLafFacade::GetLayoutRect(rectIdPane,
       
   605                                     TRect(), cellVariant, 0, 0);
       
   606     TRect cellRect = cellLayoutRect.Rect();
       
   607 
       
   608     // Coerces cellrects if necessary
       
   609     CoerceCellRect(aDensity, cellRect);
       
   610 
       
   611     // For mirrored layouts the rect is from left to right (containing negative
       
   612     // values), make sure that the rect has positive coordinates.
       
   613     cellRect.Move(-cellRect.iTl.iX, 0);
       
   614 
       
   615     aCellSize = cellRect.Size();
       
   616 
       
   617     // Icon subcell
       
   618     TAknLayoutRect iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1,
       
   619                               cellRect, subcellVariantG1);
       
   620     aIconRect.SetRect(iconRect.Rect().iTl, iconRect.Rect().iBr);
       
   621 
       
   622     // Markable grid check mark subcell
       
   623     // At this point it looks like the layout for the checkmark is wrong.
       
   624     // The bounds of the checkmark icon exceed the bounds of the item.
       
   625     // Therefore, we use TRect() here and count only on the height and width.
       
   626     TAknLayoutRect selRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG2,
       
   627                              TRect(), subcellVariantG2);
       
   628     aSelRect.SetRect(selRect.Rect().iTl, selRect.Rect().iBr);
       
   629 
       
   630     // Updates sizes get by getIconSize()
       
   631     UpdateIconSizes(aDensity, cellRect);
       
   632 
       
   633     // Caption text subcell
       
   634     TAknLayoutText textRect = CSwtLafFacade::GetLayoutText(rectIdPaneT1,
       
   635                               cellRect, subcellVariantT);
       
   636     aTextRect.SetRect(textRect.TextRect().iTl, textRect.TextRect().iBr);
       
   637 
       
   638     // Layout subcells inside the cell
       
   639     LayoutCell(cellRect, aTextRect, aIconRect, aSelRect);
       
   640 
       
   641     aTextCellFontId = CSwtLafFacade::GetFontId(rectIdPaneT1Font, subcellVariantT);
       
   642 
       
   643     TRect controlRect = BorderInnerRect();
       
   644     TSize controlSize(controlRect.iBr.iX - controlRect.iTl.iX,
       
   645                       controlRect.iBr.iY - controlRect.iTl.iY);
       
   646 
       
   647     // If control size is smaller than cell size, set cell size to 1*1 pixels. This is a workaround
       
   648     // to the problem where full sized cells were drawn outside of control's borders when control
       
   649     // size was smaller than cell size.
       
   650     if (controlSize.iHeight < aCellSize.iHeight ||
       
   651             controlSize.iWidth < aCellSize.iWidth)
       
   652     {
       
   653         aCellSize.iWidth = 1;
       
   654         aCellSize.iHeight = 1;
       
   655         TInt xCoord = cellRect.iTl.iX;
       
   656         TInt yCoord = cellRect.iTl.iY;
       
   657         aIconRect = TRect(xCoord, yCoord, xCoord, yCoord);
       
   658         aSelRect =  TRect(xCoord, yCoord, xCoord, yCoord);
       
   659         aTextRect = TRect(xCoord, yCoord, xCoord, yCoord);
       
   660 
       
   661         iIconSizeInLowDensity.SetXY(0, 0);
       
   662         iIconSizeInMediumDensity.SetXY(0, 0);
       
   663         iIconSizeInHighDensity.SetXY(0, 0);
       
   664     }
       
   665 
       
   666 }
       
   667 
       
   668 // ---------------------------------------------------------------------------
       
   669 // Layout text and icon rectangles inside a cell.
       
   670 // ---------------------------------------------------------------------------
       
   671 //
       
   672 void CSwtListView::LayoutCell(const TRect& aCellRect, TRect& aTextRect,
       
   673                               TRect& aIconRect, TRect& aSelRect)
       
   674 {
       
   675 
       
   676     TInt cellWidth = aCellRect.iBr.iX - aCellRect.iTl.iX;
       
   677     TInt cellHeight = aCellRect.iBr.iY - aCellRect.iTl.iY;
       
   678     TInt textWidth = aTextRect.iBr.iX - aTextRect.iTl.iX;
       
   679     TInt textHeight = aTextRect.iBr.iY - aTextRect.iTl.iY;
       
   680     TInt iconWidth = aIconRect.iBr.iX - aIconRect.iTl.iX;
       
   681     TInt iconHeight = aIconRect.iBr.iY - aIconRect.iTl.iY;
       
   682 
       
   683     // Center the text and icon horizontally
       
   684     TInt textX = (cellWidth - textWidth) / 2;
       
   685     TInt textY = aTextRect.iTl.iY;
       
   686     TInt iconX = (cellWidth - iconWidth) / 2;
       
   687     TInt iconY = aIconRect.iTl.iY;
       
   688 
       
   689     if (iNumberOfIcons == 0 && iNumberOfTexts > 0)
       
   690     {
       
   691         // There's no icon in any item, so center the cell text vertically.
       
   692         textY = (cellHeight - textHeight) / 2;
       
   693     }
       
   694     else if (iNumberOfIcons > 0 && iNumberOfTexts == 0)
       
   695     {
       
   696         // There's no text in any item, so center the icons vertically.
       
   697         iconY = (cellHeight - iconHeight) / 2;
       
   698     }
       
   699 
       
   700 
       
   701     aTextRect.iTl.SetXY(textX, textY);
       
   702     aTextRect.iBr.SetXY(textX + textWidth, textY + textHeight);
       
   703     aIconRect.iTl.SetXY(iconX, iconY);
       
   704     aIconRect.iBr.SetXY(iconX + iconWidth, iconY + iconHeight);
       
   705 
       
   706     if (AknLayoutUtils::LayoutMirrored())
       
   707     {
       
   708         TInt w = aSelRect.Width();
       
   709         TInt h = aSelRect.Height();
       
   710         aSelRect.iTl.SetXY(aCellRect.iTl.iX + 1, aCellRect.iTl.iY + 1);
       
   711         aSelRect.iBr.SetXY(aCellRect.iTl.iX + 1 + w, aCellRect.iTl.iY + 1 + h);
       
   712     }
       
   713     else
       
   714     {
       
   715         TInt w = aSelRect.Width();
       
   716         TInt h = aSelRect.Height();
       
   717         aSelRect.iTl.SetXY(aCellRect.iBr.iX - 1 - w, aCellRect.iTl.iY + 1);
       
   718         aSelRect.iBr.SetXY(aCellRect.iBr.iX - 1, aCellRect.iTl.iY + 1 + h);
       
   719     }
       
   720 }
       
   721 
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // Returns ideal cell size for current grid density.
       
   725 // ---------------------------------------------------------------------------
       
   726 //
       
   727 TSize CSwtListView::GetCellSize() const
       
   728 {
       
   729     // Grid cell variants
       
   730     TInt cellVariant;
       
   731     TInt subcellVariantG1;
       
   732     TInt subcellVariantG2;
       
   733     TInt subcellVariantT;
       
   734     GetCellVariants(iDensity, cellVariant, subcellVariantG1, subcellVariantG2,
       
   735                     subcellVariantT);
       
   736 
       
   737     // LAF rectangle IDs
       
   738     CSwtLafFacade::TSwtLafFacadeRectId rectIdPane;
       
   739     CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1;
       
   740     CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG2;
       
   741     CSwtLafFacade::TSwtLafFacadeTextId rectIdPaneT1;
       
   742     CSwtLafFacade::TSwtLafFacadeFontId rectIdPaneT1Font;
       
   743     GetLafFacadeRectIds(iDensity, rectIdPane, rectIdPaneG1, rectIdPaneG2,
       
   744                         rectIdPaneT1, rectIdPaneT1Font);
       
   745 
       
   746     // Grid cell
       
   747     TAknLayoutRect cellLayoutRect = CSwtLafFacade::GetLayoutRect(rectIdPane,
       
   748                                     TRect(), cellVariant, 0, 0);
       
   749     TRect cellRect = cellLayoutRect.Rect();
       
   750 
       
   751     // Coerces cellrects if necessary
       
   752     CoerceCellRect(iDensity, cellRect);
       
   753 
       
   754     // For arabic layout, rect might be negative, so move it to (0,0) so that we get positive size.
       
   755     cellRect.Move(-cellRect.iTl.iX, 0);
       
   756 
       
   757     return cellRect.Size();
       
   758 }
       
   759 
       
   760 // ---------------------------------------------------------------------------
       
   761 // A helper to calculate how many cells to have per row/column based on
       
   762 // the given cell size.
       
   763 // ---------------------------------------------------------------------------
       
   764 //
       
   765 void CSwtListView::CalcRowsColumns(const TSize& aCellSize,
       
   766                                    TInt& aXCells,
       
   767                                    TInt& aYCells) const
       
   768 {
       
   769     TRect clientRect = ClientRect();
       
   770 
       
   771     aXCells = 1;
       
   772     aYCells = 1;
       
   773 
       
   774     if (aCellSize.iWidth != 0)
       
   775     {
       
   776         aXCells = clientRect.Width() / aCellSize.iWidth;
       
   777     }
       
   778     if (aCellSize.iHeight != 0)
       
   779     {
       
   780         aYCells = clientRect.Height() / aCellSize.iHeight;
       
   781         if (clientRect.Height() % aCellSize.iHeight > KRowCalculationPrecisionInPixels)
       
   782         {
       
   783             aYCells++;
       
   784         }
       
   785     }
       
   786 
       
   787     // 1x1 grid is the minimum, the grid asserts this
       
   788     if (aXCells < 1)
       
   789     {
       
   790         aXCells = 1;
       
   791     }
       
   792     if (aYCells < 1)
       
   793     {
       
   794         aYCells = 1;
       
   795     }
       
   796 }
       
   797 
       
   798 // ---------------------------------------------------------------------------
       
   799 // A helper to handle adding of a listbox item text.
       
   800 // ---------------------------------------------------------------------------
       
   801 //
       
   802 void CSwtListView::AddTextL(const TDesC& aPtr,
       
   803                             const TInt& aPos)
       
   804 {
       
   805     // Untabify the item caption
       
   806     RBuf caption;
       
   807     caption.CreateL(aPtr);
       
   808     caption.CleanupClosePushL();
       
   809     UntabifyL(caption);
       
   810 
       
   811     // Create the format string for the grid item
       
   812 
       
   813     TInt iconIndex = ItemIconIndex(aPos);
       
   814     RBuf buf;
       
   815     buf.CreateL(KSpaceForIndex +
       
   816                 KColumnSeparator().Length() * 2 + // 2 = two separators
       
   817                 caption.Length() +
       
   818                 KMarkOffIconArrayIndex().Length());
       
   819     buf.AppendNum(iconIndex);
       
   820     buf.Append(KColumnSeparator);
       
   821     buf.Append(caption);
       
   822     buf.Append(KColumnSeparator);
       
   823     buf.Append(KMarkOffIconArrayIndex);
       
   824 
       
   825     // Append the text to the text array
       
   826     buf.CleanupClosePushL();
       
   827     CDesCArray* textArray = GetTextArray();
       
   828     if (textArray)
       
   829     {
       
   830         textArray->InsertL(aPos, buf);
       
   831     }
       
   832 
       
   833     if (caption.Length() > 0)
       
   834     {
       
   835         UpdateSetItemCount(1, 0);
       
   836     }
       
   837 
       
   838     CleanupStack::PopAndDestroy(2);
       
   839 }
       
   840 
       
   841 // ---------------------------------------------------------------------------
       
   842 // A helper to handle adding of an icon for a list item.
       
   843 // ---------------------------------------------------------------------------
       
   844 //
       
   845 void CSwtListView::AddIconL(const MSwtImage* aImage,
       
   846                             const TInt& aPos)
       
   847 {
       
   848     CGulIcon* icon = CreateIconL(aImage);
       
   849     CleanupStack::PushL(icon);
       
   850     TInt index = ItemIconIndex(aPos);
       
   851     GetIconArray()->InsertL(index, icon);
       
   852 
       
   853     const MSwtImage* refImg = aImage;
       
   854     const TInt refImgCount = iRefImages.Count();
       
   855     if (refImgCount > aPos)
       
   856     {
       
   857         iRefImages.InsertL(refImg, aPos);
       
   858     }
       
   859     else
       
   860     {
       
   861         iRefImages.AppendL(refImg);
       
   862     }
       
   863 
       
   864 #ifdef DEBUG_CHECK_IMAGES
       
   865     CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
       
   866 #endif
       
   867 
       
   868     if (aImage)
       
   869     {
       
   870         UpdateSetItemCount(0, 1);
       
   871     }
       
   872 
       
   873     CleanupStack::Pop(icon);
       
   874 }
       
   875 
       
   876 // ---------------------------------------------------------------------------
       
   877 // A helper to handle adding of an item. This includes the item text and
       
   878 // the icon. Also selection/selection events/focus are handled appropriately.
       
   879 // Can be called with null image.
       
   880 // ---------------------------------------------------------------------------
       
   881 //
       
   882 void CSwtListView::AddItemL(const TDesC& aPtr,
       
   883                             const MSwtImage* aImage,
       
   884                             const TInt& aPos)
       
   885 {
       
   886     // Store the selection state
       
   887     GetSelection(iOldSelectionArray);
       
   888 
       
   889     TRAPD(textError, AddTextL(aPtr, aPos));
       
   890     if (textError)
       
   891     {
       
   892         User::Leave(ESwtErrorItemNotAdded);
       
   893     }
       
   894     TRAPD(iconError, AddIconL(aImage, aPos));
       
   895     if (iconError)
       
   896     {
       
   897         // Remove the text as the icon can't be added
       
   898         ASSERT(GetTextArray()->Count() > 0);
       
   899         GetTextArray()->Delete(GetTextArray()->Count() - 1);
       
   900         User::Leave(ESwtErrorItemNotAdded);
       
   901     }
       
   902 
       
   903     // Item added successfully
       
   904 
       
   905     // Update grid cell layout if neccessary
       
   906     DoGridCellLayoutIfNeededL();
       
   907 
       
   908     // All the icon indexes after the added item need updating
       
   909     TInt textCount = GetTextArray()->Count();
       
   910     for (TInt iTxt = aPos + 1; iTxt < textCount; ++iTxt)
       
   911     {
       
   912         UpdateIconIndexL(iTxt);
       
   913     }
       
   914 
       
   915     iGrid->HandleItemAdditionL();
       
   916 
       
   917     // Restore the selection state updating the indexes.
       
   918     UpdateSelectionIndexesL(aPos, aPos, ETrue);
       
   919 
       
   920     // Focus must move to the newly added item.
       
   921     if (iStyle & KSwtStyleMulti)
       
   922     {
       
   923         iGrid->SetCurrentDataIndex(aPos);
       
   924     }
       
   925     SingleSelectL(GetSelectionL(aPos), ETrue);
       
   926 
       
   927     UpdateMSKLabelL();
       
   928 
       
   929     Redraw();
       
   930     iDisplay.PostSelectionEventL(iPeer);
       
   931 }
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 // Updates the icon index in the item text array at the given index.
       
   935 // Icon index is invalidated when adding or removing items anywhere but
       
   936 // the end of the array.
       
   937 // ---------------------------------------------------------------------------
       
   938 //
       
   939 void CSwtListView::UpdateIconIndexL(const TInt& aIndex)
       
   940 {
       
   941     CDesCArray* textArray = GetTextArray();
       
   942     TPtrC itemText = textArray->MdcaPoint(aIndex);
       
   943     TInt separatorPos = itemText.Find(KColumnSeparator);
       
   944     User::LeaveIfError(separatorPos);
       
   945 
       
   946     RBuf buf;
       
   947     buf.CreateL(KSpaceForIndex + itemText.Length());
       
   948     buf.AppendNum(ItemIconIndex(aIndex));
       
   949     buf.Append(itemText.Mid(separatorPos));
       
   950 
       
   951     buf.CleanupClosePushL();
       
   952     textArray->Delete(aIndex);
       
   953     textArray->InsertL(aIndex, buf);
       
   954 
       
   955     CleanupStack::PopAndDestroy(1);
       
   956 }
       
   957 
       
   958 // ---------------------------------------------------------------------------
       
   959 // Updates the selection indexes of items starting from the given index.
       
   960 // Selected item indexes after the given index are decremented or incremented
       
   961 // depending on if items have been added or removed.
       
   962 // ---------------------------------------------------------------------------
       
   963 //
       
   964 void CSwtListView::UpdateSelectionIndexesL(TInt aStart, TInt aEnd, TBool aItemsAdded)
       
   965 {
       
   966     ASSERT(iOldSelectionArray != NULL);
       
   967     TInt numberOfItemsInRange = aEnd - aStart + 1;
       
   968 
       
   969     // Update the selection indexes
       
   970     TInt selectionCount = iOldSelectionArray->Count();
       
   971     for (TInt iOld = selectionCount - 1; iOld >= 0; --iOld)
       
   972     {
       
   973         // First delete the selection indexes for items that have been removed
       
   974         if (aItemsAdded == EFalse &&
       
   975                 (*iOldSelectionArray)[iOld] >= aStart && (*iOldSelectionArray)[iOld] <= aEnd)
       
   976         {
       
   977             iOldSelectionArray->Delete(iOld);
       
   978             continue;
       
   979         }
       
   980         // Then update the affected selection indexes
       
   981         if ((*iOldSelectionArray)[iOld] >= aStart)
       
   982         {
       
   983             if (aItemsAdded)
       
   984             {
       
   985                 (*iOldSelectionArray)[iOld] += numberOfItemsInRange;
       
   986             }
       
   987             else // items were removed
       
   988             {
       
   989                 (*iOldSelectionArray)[iOld] -= numberOfItemsInRange;
       
   990             }
       
   991         }
       
   992     }
       
   993 
       
   994     // New updated selections to the control
       
   995     SetSelectionL(iOldSelectionArray);
       
   996 
       
   997     iOldSelectionArray->Reset();
       
   998 }
       
   999 
       
  1000 // ---------------------------------------------------------------------------
       
  1001 // Recursively replaces the tab characters in the buffer. Tab characters are
       
  1002 // not allowed in the item texts because they are used exclusively as
       
  1003 // field separators.
       
  1004 // ---------------------------------------------------------------------------
       
  1005 //
       
  1006 void CSwtListView::UntabifyL(RBuf& aAll)
       
  1007 {
       
  1008     TInt separatorPos = aAll.Find(KColumnSeparator);
       
  1009     if (separatorPos != KErrNotFound)
       
  1010     {
       
  1011         RBuf end;
       
  1012         end.CreateL(aAll.Length());
       
  1013         end.CleanupClosePushL();
       
  1014         end.Append(aAll.Mid(separatorPos + 1));
       
  1015         UntabifyL(end);
       
  1016 
       
  1017         // Now 'end' doesn't have any separators in it
       
  1018 
       
  1019         end.Insert(0, KSeparatorReplacement);
       
  1020         end.Insert(0, aAll.Left(separatorPos));
       
  1021         aAll.Copy(end);
       
  1022         CleanupStack::PopAndDestroy();
       
  1023     }
       
  1024 }
       
  1025 
       
  1026 // ---------------------------------------------------------------------------
       
  1027 // Obtains a pointer descriptor to the part of the item text that contains
       
  1028 // the caption.
       
  1029 // ---------------------------------------------------------------------------
       
  1030 //
       
  1031 TInt CSwtListView::GetCaption(const TInt& aIndex, TPtrC& aTxt) const
       
  1032 {
       
  1033     ASSERT(KTextColumn == 1);
       
  1034     ASSERT(GetItemCount() > 0);
       
  1035 
       
  1036     // Get a pointer to the item's complete text
       
  1037     aTxt.Set(GetGridModel()->ItemText(aIndex));
       
  1038 
       
  1039     // Find the 1st separator from where the caption starts
       
  1040     TInt separatorPos = aTxt.Find(KColumnSeparator);
       
  1041     if (separatorPos == KErrNotFound)
       
  1042     {
       
  1043         return KErrNotFound;
       
  1044     }
       
  1045 
       
  1046     // Reset the pointer to point to the beginning of the caption
       
  1047     TInt newLength = aTxt.Length() - separatorPos;
       
  1048     aTxt.Set(&aTxt[ separatorPos + 1 ], newLength);
       
  1049 
       
  1050     // Find the 1st (2nd) separator where the caption ends
       
  1051     separatorPos = aTxt.Find(KColumnSeparator);
       
  1052     if (separatorPos == KErrNotFound)
       
  1053     {
       
  1054         return KErrNotFound;
       
  1055     }
       
  1056 
       
  1057     // Set length correctly to just reach the end of the caption
       
  1058     newLength = separatorPos;
       
  1059     aTxt.Set(&aTxt[ 0 ], newLength);
       
  1060 
       
  1061     return KErrNone;
       
  1062 }
       
  1063 
       
  1064 // ---------------------------------------------------------------------------
       
  1065 // View must show as many items as possible. It's not allowed that the last
       
  1066 // row/column would be empty while some of the items would be outside
       
  1067 // the view. The view must scroll to fully utilise the available space to
       
  1068 // show as many rows/columns as fit in the view.
       
  1069 // ---------------------------------------------------------------------------
       
  1070 //
       
  1071 void CSwtListView::ScrollViewToShowAsManyItemsAsPossibleL()
       
  1072 {
       
  1073     TInt lastItemRowIndex;
       
  1074     TInt lastItemColIndex;
       
  1075     TInt firstItemRowIndex;
       
  1076     TInt firstItemColIndex;
       
  1077     TBool scrollingNeeded = EFalse;
       
  1078 
       
  1079     if (!(GetItemCount() > 0))
       
  1080     {
       
  1081         return;
       
  1082     }
       
  1083 
       
  1084     // Get the view positions of the first and last list items.
       
  1085     GetGridView()->CalcRowAndColIndexesFromItemIndex(GetItemCount() -1,
       
  1086             lastItemRowIndex,
       
  1087             lastItemColIndex);
       
  1088     GetGridView()->CalcRowAndColIndexesFromItemIndex(0,
       
  1089             firstItemRowIndex,
       
  1090             firstItemColIndex);
       
  1091 
       
  1092     // Check if there is 1 or more complete rows/columns of unused space
       
  1093     // in the end of the view.
       
  1094     if (iVerticalOrientation == EFalse)
       
  1095     {
       
  1096         if (lastItemRowIndex >= 0 && lastItemRowIndex < iNumOfRows - 1)
       
  1097         {
       
  1098             // Last item is in the view and is not on the last row.
       
  1099             //  Check if the first item is outside the view.
       
  1100             if (firstItemRowIndex < 0)
       
  1101             {
       
  1102                 scrollingNeeded = ETrue;
       
  1103             }
       
  1104         }
       
  1105     }
       
  1106     else
       
  1107     {
       
  1108         if (lastItemColIndex >= 0 && lastItemColIndex < iNumOfColumns - 1)
       
  1109         {
       
  1110             // Last item is displayed in the view and is not on the last
       
  1111             // column. Check if the first item is outside the view.
       
  1112             if (firstItemColIndex < 0)
       
  1113             {
       
  1114                 scrollingNeeded = ETrue;
       
  1115             }
       
  1116         }
       
  1117     }
       
  1118 
       
  1119     if (scrollingNeeded)
       
  1120     {
       
  1121         // Move the focus to the beginning and back to the correct index
       
  1122         // to reposition the view.
       
  1123         TInt currentDataIndex = iGrid->CurrentDataIndex();
       
  1124         GetGridView()->MoveToItemIndexL(0, CListBoxView::ENoSelection);
       
  1125         GetGridView()->MoveToItemIndexL(currentDataIndex,
       
  1126                                         CListBoxView::ENoSelection);
       
  1127     }
       
  1128 }
       
  1129 
       
  1130 TInt CSwtListView::ScrollBarBreadth(const CEikScrollBar* aBar)
       
  1131 {
       
  1132     return iDisplay.UiUtils().ScrollBarBreadth(aBar);
       
  1133 }
       
  1134 
       
  1135 // ---------------------------------------------------------------------------
       
  1136 // A helper for selecting items appropriately in single selection grid.
       
  1137 // Called when selection is desired only in single style.
       
  1138 // ---------------------------------------------------------------------------
       
  1139 //
       
  1140 void CSwtListView::SingleSelectL(const TInt& aIndex, TBool aScroll)
       
  1141 {
       
  1142     if (!(iStyle & KSwtStyleMulti))
       
  1143     {
       
  1144         if (aScroll && GetGridView()->ViewRect().Height() >= iGrid->ItemHeight())
       
  1145         {
       
  1146             iGrid->View()->VerticalMoveToItemL(aIndex, CListBoxView::ESingleSelection);
       
  1147         }
       
  1148         else
       
  1149         {
       
  1150             TInt old = iGrid->CurrentItemIndex();
       
  1151             GetGridView()->SetCurrentItemIndex(aIndex); //we do not call CEikListBox::SetCurrentItemIndex, because we do not want to scroll.
       
  1152             GetGridView()->UpdateSelectionL(CListBoxView::ESingleSelection);
       
  1153             if (old != -1)
       
  1154             {
       
  1155                 GetGridView()->DrawItem(old);
       
  1156             }
       
  1157             ASSERT(iGrid->SelectionIndexes()->Count() <= 1);
       
  1158         }
       
  1159     }
       
  1160 }
       
  1161 
       
  1162 // ---------------------------------------------------------------------------
       
  1163 // A helper for selecting items appropriately in either single or multi
       
  1164 // selection grid. Called when selection is desired in either case.
       
  1165 // ---------------------------------------------------------------------------
       
  1166 //
       
  1167 void CSwtListView::SingleOrMultiSelectL(const TInt& aIndex, TBool aScroll)
       
  1168 {
       
  1169     CAknGridView* gridView = GetGridView();
       
  1170 
       
  1171     ASSERT(gridView);
       
  1172 
       
  1173     if (iStyle & KSwtStyleMulti)
       
  1174     {
       
  1175         gridView->SelectItemL(gridView->ActualDataIndex(aIndex));
       
  1176 
       
  1177         if (aScroll)
       
  1178         {
       
  1179             iGrid->ScrollToMakeItemVisible(aIndex);
       
  1180         }
       
  1181     }
       
  1182     else
       
  1183     {
       
  1184         SingleSelectL(aIndex, aScroll);
       
  1185     }
       
  1186 }
       
  1187 
       
  1188 // ---------------------------------------------------------------------------
       
  1189 // Updates the colors used to draw text in the grid. The normal text color
       
  1190 // and the highlighted (focused) text color.
       
  1191 // ---------------------------------------------------------------------------
       
  1192 //
       
  1193 void CSwtListView::UpdateTextColorL()
       
  1194 {
       
  1195     CFormattedCellListBoxData::TColors colors;
       
  1196     TInt error = 0;
       
  1197 
       
  1198     if (iTextColor)
       
  1199     {
       
  1200         // Use the user defined color for all text
       
  1201         colors.iText = TRgb(iTextColor->RgbValue());
       
  1202         colors.iHighlightedText = TRgb(iTextColor->RgbValue());
       
  1203     }
       
  1204     else
       
  1205     {
       
  1206         // Get the colors from the skin
       
  1207         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1208         error = AknsUtils::GetCachedColor(skin, colors.iText, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG9);
       
  1209         error += AknsUtils::GetCachedColor(skin, colors.iHighlightedText, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG11);
       
  1210     }
       
  1211     if (!error)
       
  1212     {
       
  1213         iGrid->ItemDrawer()->FormattedCellData()->SetSubCellColorsL(KTextColumn, colors);
       
  1214         iGrid->ItemDrawer()->SetTextColor(colors.iText);
       
  1215     }
       
  1216 }
       
  1217 
       
  1218 // ---------------------------------------------------------------------------
       
  1219 // Helper to get the marked item icon from the current skin.
       
  1220 // ---------------------------------------------------------------------------
       
  1221 //
       
  1222 CGulIcon* CSwtListView::GetMarkedItemIconL()
       
  1223 {
       
  1224     CGulIcon* icon = AknsUtils::CreateGulIconL(AknsUtils::SkinInstance(),
       
  1225                      KAknsIIDQgnIndiMarkedGridAdd,
       
  1226                      AknIconUtils::AvkonIconFileName(),
       
  1227                      EMbmAvkonQgn_indi_marked_grid_add,
       
  1228                      EMbmAvkonQgn_indi_marked_grid_add_mask);
       
  1229     return icon;
       
  1230 }
       
  1231 
       
  1232 // ---------------------------------------------------------------------------
       
  1233 // Helper to update all the scaled images.
       
  1234 // Assumes that iMaxImageSize contains the old maximum image size.
       
  1235 // ---------------------------------------------------------------------------
       
  1236 //
       
  1237 void CSwtListView::UpdateImageSizes(const TSize& aNewMaxSize)
       
  1238 {
       
  1239     TInt count = iRefImages.Count();
       
  1240     const MSwtImage* img = 0;
       
  1241 
       
  1242     CAknIconArray* iconArray = GetIconArray();
       
  1243 
       
  1244     for (TInt i = 0; i < count; i++)
       
  1245     {
       
  1246         img = iRefImages[i];
       
  1247         if (img)
       
  1248         {
       
  1249             TSize imageSize = img->Bitmap().SizeInPixels();
       
  1250             TSize oldSize, newSize;
       
  1251             TBool doScaling = ETrue;
       
  1252 
       
  1253             if (imageSize.iHeight > iMaxImageSize.iHeight ||
       
  1254                     imageSize.iWidth > iMaxImageSize.iWidth)
       
  1255             {
       
  1256                 // If image size is bigger than the old maximum size, then
       
  1257                 // the image has been also previously scaled.
       
  1258                 oldSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
       
  1259                               imageSize, iMaxImageSize);
       
  1260             }
       
  1261             else if (imageSize.iHeight > aNewMaxSize.iHeight ||
       
  1262                      imageSize.iWidth > aNewMaxSize.iWidth)
       
  1263             {
       
  1264                 // Image is bigger than the new boundaries, but it did fit
       
  1265                 // inside the old boundaries, so the image is default size.
       
  1266                 oldSize = imageSize;
       
  1267             }
       
  1268             else
       
  1269             {
       
  1270                 doScaling = EFalse;
       
  1271             }
       
  1272 
       
  1273             if (doScaling)
       
  1274             {
       
  1275                 newSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
       
  1276                               imageSize, aNewMaxSize);
       
  1277                 CFbsBitmap* bmp = const_cast<CFbsBitmap*>(&img->SubBitmap(newSize));
       
  1278                 CFbsBitmap* mask = const_cast<CFbsBitmap*>(img->SubMaskBitmap(newSize, ETrue));
       
  1279 
       
  1280                 img->AddSubRef(newSize);
       
  1281 
       
  1282                 // Remove the old reference
       
  1283                 img->RemoveSubRef(oldSize);
       
  1284 
       
  1285                 CGulIcon* icon = (*iconArray)[ ItemIconIndex(i)];
       
  1286 
       
  1287                 icon->SetBitmap(bmp);
       
  1288                 icon->SetMask(mask);
       
  1289             }
       
  1290         }
       
  1291     }
       
  1292 
       
  1293 }
       
  1294 
       
  1295 // ---------------------------------------------------------------------------
       
  1296 // Removes reference to the image at a given index. If the image has been
       
  1297 // scaled, removes the correct sized reference.
       
  1298 // ---------------------------------------------------------------------------
       
  1299 //
       
  1300 void CSwtListView::RemoveImageRef(const TInt& aIndex)
       
  1301 {
       
  1302     const MSwtImage* img = iRefImages[ aIndex ];
       
  1303 
       
  1304     if (img)
       
  1305     {
       
  1306         TSize imageSize = img->Bitmap().SizeInPixels();
       
  1307 
       
  1308         // If the original size of the image is bigger than the maximum image
       
  1309         // size, it has been scaled to fit in iMaxImageSize. Remove reference
       
  1310         // to the scaled bitmap.
       
  1311         if (imageSize.iHeight > iMaxImageSize.iHeight ||
       
  1312                 imageSize.iWidth > iMaxImageSize.iWidth)
       
  1313         {
       
  1314             imageSize = SwtControlHelper::GetAspectRatioScaledBitmapSize(
       
  1315                             imageSize, iMaxImageSize);
       
  1316         }
       
  1317 
       
  1318         img->RemoveSubRef(imageSize);
       
  1319         img->RemoveRef();
       
  1320     }
       
  1321 }
       
  1322 
       
  1323 
       
  1324 // ---------------------------------------------------------------------------
       
  1325 // Leaving version of HandleResourceChange.
       
  1326 // ---------------------------------------------------------------------------
       
  1327 //
       
  1328 void CSwtListView::HandleResourceChangeL(TInt aType)
       
  1329 {
       
  1330     if (aType == KAknsMessageSkinChange)
       
  1331     {
       
  1332         // Refresh the selected item mark icon
       
  1333         CAknIconArray* iconArray = GetIconArray();
       
  1334         CGulIcon* icon = (*iconArray)[ KMarkOnIconArrayIndexInt ];
       
  1335         delete icon;
       
  1336         (*iconArray)[ KMarkOnIconArrayIndexInt ] = GetMarkedItemIconL();
       
  1337     }
       
  1338 
       
  1339     if (aType == KEikDynamicLayoutVariantSwitch)
       
  1340     {
       
  1341         if (AknLayoutUtils::LayoutMirrored())
       
  1342         {
       
  1343             iLeftToRight = EFalse;
       
  1344         }
       
  1345         else
       
  1346         {
       
  1347             iLeftToRight = ETrue;
       
  1348         }
       
  1349 
       
  1350         CCoeControl::HandleResourceChange(aType);
       
  1351         SizeChangedL();
       
  1352     }
       
  1353     else if (aType == KEikMessageUnfadeWindows
       
  1354              || aType == KEikMessageWindowsFadeChange)
       
  1355     {
       
  1356         CCoeControl::HandleResourceChange(aType);
       
  1357     }
       
  1358     else
       
  1359     {
       
  1360         CCoeControl::HandleResourceChange(aType);
       
  1361         DoGridCellLayoutL(iDensity);
       
  1362     }
       
  1363 }
       
  1364 
       
  1365 // ---------------------------------------------------------------------------
       
  1366 // Leaving version of SizeChanged.
       
  1367 // ---------------------------------------------------------------------------
       
  1368 //
       
  1369 void CSwtListView::SizeChangedL()
       
  1370 {
       
  1371     DoGridCellLayoutL(iDensity);
       
  1372     TRect clientRect(BorderInnerRect());
       
  1373 
       
  1374     // WORKAROUND! This is to avoid CAknGrid crash when its size is 0
       
  1375     // and the List Transition Effects try to draw the grid. In fact the
       
  1376     // root cause of the crash is our Shell not being always ready to draw
       
  1377     // which is what Avkon expects. If that would be the case, the List
       
  1378     // Transition Effects will never get a chance to draw a size 0 grid.
       
  1379     if (clientRect.Width() <= 0 && clientRect.Height() <= 0)
       
  1380     {
       
  1381         clientRect = TRect(0, 0, 1, 0);
       
  1382     }
       
  1383 
       
  1384     iGrid->SetRect(clientRect);
       
  1385     iGrid->HandleViewRectSizeChangeL();
       
  1386 }
       
  1387 
       
  1388 // ---------------------------------------------------------------------------
       
  1389 // Helper to get the array index of the icon from the item index.
       
  1390 // ---------------------------------------------------------------------------
       
  1391 //
       
  1392 TInt CSwtListView::ItemIconIndex(const TInt& aItemPos)
       
  1393 {
       
  1394     return (aItemPos + 2);
       
  1395 }
       
  1396 
       
  1397 // ---------------------------------------------------------------------------
       
  1398 // Updates the control menu.
       
  1399 // ---------------------------------------------------------------------------
       
  1400 //
       
  1401 void CSwtListView::UpdateControlMenu()
       
  1402 {
       
  1403     if (iStyle & KSwtStyleMulti)
       
  1404     {
       
  1405         TInt focusIndex = GetFocusIndex();
       
  1406         if (focusIndex != -1)
       
  1407         {
       
  1408             iMenuItemMarkUnmark->SetEnabled(ETrue);
       
  1409             if (IsSelected(focusIndex))
       
  1410             {
       
  1411                 if (iIsMarkDisplayed)
       
  1412                 {
       
  1413                     iIsMarkDisplayed = EFalse;
       
  1414                     TPtrC ptr = iUnmarkString->Des();
       
  1415                     TRAP_IGNORE(iMenuItemMarkUnmark->SetTextL(ptr));
       
  1416                 }
       
  1417             }
       
  1418             else
       
  1419             {
       
  1420                 if (!iIsMarkDisplayed)
       
  1421                 {
       
  1422                     iIsMarkDisplayed = ETrue;
       
  1423                     TPtrC ptr = iMarkString->Des();
       
  1424                     TRAP_IGNORE(iMenuItemMarkUnmark->SetTextL(ptr));
       
  1425                 }
       
  1426             }
       
  1427         }
       
  1428         else
       
  1429         {
       
  1430             iMenuItemMarkUnmark->SetEnabled(EFalse);
       
  1431         }
       
  1432 
       
  1433         if (GetGridView()->SelectionIndexes()->Count() == 0)
       
  1434         {
       
  1435             iMenuItemUnmarkAll->SetEnabled(EFalse);
       
  1436 #ifdef RD_SCALABLE_UI_V2
       
  1437             iStylusPopupUnmarkAll->SetEnabled(EFalse);
       
  1438 #endif //RD_SCALABLE_UI_V2
       
  1439         }
       
  1440         else
       
  1441         {
       
  1442             iMenuItemUnmarkAll->SetEnabled(ETrue);
       
  1443 #ifdef RD_SCALABLE_UI_V2
       
  1444             iStylusPopupUnmarkAll->SetEnabled(ETrue);
       
  1445 #endif //RD_SCALABLE_UI_V2
       
  1446         }
       
  1447 
       
  1448         if (GetGridView()->SelectionIndexes()->Count() == GetGridModel()->NumberOfItems())
       
  1449         {
       
  1450             iMenuItemMarkAll->SetEnabled(EFalse);
       
  1451 #ifdef RD_SCALABLE_UI_V2
       
  1452             iStylusPopupMarkAll->SetEnabled(EFalse);
       
  1453 #endif //RD_SCALABLE_UI_V2
       
  1454         }
       
  1455         else
       
  1456         {
       
  1457             iMenuItemMarkAll->SetEnabled(ETrue);
       
  1458 #ifdef RD_SCALABLE_UI_V2
       
  1459             iStylusPopupMarkAll->SetEnabled(ETrue);
       
  1460 #endif //RD_SCALABLE_UI_V2
       
  1461         }
       
  1462     }
       
  1463 }
       
  1464 
       
  1465 // ---------------------------------------------------------------------------
       
  1466 // 2nd phase construction
       
  1467 // ---------------------------------------------------------------------------
       
  1468 //
       
  1469 CSwtListView* CSwtListView::NewL(MSwtDisplay& aDisplay,
       
  1470                                  TSwtPeer aPeer,
       
  1471                                  MSwtComposite& aParent,
       
  1472                                  TInt aStyle)
       
  1473 {
       
  1474     CSwtListView* self = CSwtListView::NewLC(aDisplay, aPeer, aParent, aStyle);
       
  1475     CleanupStack::Pop(self);
       
  1476     return self;
       
  1477 }
       
  1478 
       
  1479 // ---------------------------------------------------------------------------
       
  1480 // 2nd phase construction
       
  1481 // ---------------------------------------------------------------------------
       
  1482 //
       
  1483 CSwtListView* CSwtListView::NewLC(MSwtDisplay& aDisplay,
       
  1484                                   TSwtPeer aPeer,
       
  1485                                   MSwtComposite& aParent,
       
  1486                                   TInt aStyle)
       
  1487 {
       
  1488     CSwtListView* self = new(ELeave) CSwtListView(aDisplay,
       
  1489             aPeer,
       
  1490             aParent,
       
  1491             aStyle);
       
  1492     CleanupStack::PushL(self);
       
  1493     self->ConstructL();
       
  1494     self->InitControlBaseL();
       
  1495     return self;
       
  1496 }
       
  1497 
       
  1498 // ---------------------------------------------------------------------------
       
  1499 // The destructor
       
  1500 // ---------------------------------------------------------------------------
       
  1501 //
       
  1502 CSwtListView::~CSwtListView()
       
  1503 {
       
  1504     if (iMenuItemMarkUnmark)
       
  1505     {
       
  1506         iMenuItemMarkUnmark->Dispose();
       
  1507     }
       
  1508 
       
  1509     if (iMenuItemMarkAll)
       
  1510     {
       
  1511         iMenuItemMarkAll->Dispose();
       
  1512     }
       
  1513 
       
  1514     if (iMenuItemUnmarkAll)
       
  1515     {
       
  1516         iMenuItemUnmarkAll->Dispose();
       
  1517     }
       
  1518 
       
  1519     if (iSubMenu)
       
  1520     {
       
  1521         iSubMenu->Dispose();
       
  1522     }
       
  1523 
       
  1524     if (iMenuItemEditList)
       
  1525     {
       
  1526         iMenuItemEditList->Dispose();
       
  1527     }
       
  1528 
       
  1529     if (iMenu)
       
  1530     {
       
  1531         iMenu->Dispose();
       
  1532     }
       
  1533 
       
  1534 #ifdef RD_SCALABLE_UI_V2
       
  1535     if (iStylusPopupMarkAll)
       
  1536     {
       
  1537         iStylusPopupMarkAll->Dispose();
       
  1538     }
       
  1539 
       
  1540     if (iStylusPopupUnmarkAll)
       
  1541     {
       
  1542         iStylusPopupUnmarkAll->Dispose();
       
  1543     }
       
  1544 
       
  1545     if (iStylusPopupMenu)
       
  1546     {
       
  1547         iStylusPopupMenu->Dispose();
       
  1548     }
       
  1549 #endif //RD_SCALABLE_UI_V2
       
  1550 
       
  1551     delete iMarkString;
       
  1552     delete iUnmarkString;
       
  1553 
       
  1554     delete iOldSelectionArray;
       
  1555     iOldSelectionArray = NULL;
       
  1556 
       
  1557     delete iSelectionArray;
       
  1558     iSelectionArray = NULL;
       
  1559 
       
  1560 #ifdef DEBUG_CHECK_IMAGES
       
  1561     CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
       
  1562 #endif
       
  1563 
       
  1564     delete iGrid;
       
  1565     iGrid = NULL;
       
  1566 
       
  1567     TInt count = iRefImages.Count();
       
  1568     for (TInt i = 0; i < count; i++)
       
  1569     {
       
  1570         RemoveImageRef(i);
       
  1571     }
       
  1572 
       
  1573     iRefImages.Close();
       
  1574 }
       
  1575 
       
  1576 // ---------------------------------------------------------------------------
       
  1577 // From class CCoeControl.
       
  1578 // ---------------------------------------------------------------------------
       
  1579 //
       
  1580 CCoeControl* CSwtListView::ComponentControl(TInt /*aIndex*/) const
       
  1581 {
       
  1582     return iGrid;
       
  1583 }
       
  1584 
       
  1585 // ---------------------------------------------------------------------------
       
  1586 // From class CCoeControl.
       
  1587 // ---------------------------------------------------------------------------
       
  1588 //
       
  1589 TInt CSwtListView::CountComponentControls() const
       
  1590 {
       
  1591     return 1; // there's only the grid
       
  1592 }
       
  1593 
       
  1594 // ---------------------------------------------------------------------------
       
  1595 // From class CCoeControl.
       
  1596 // ---------------------------------------------------------------------------
       
  1597 //
       
  1598 void CSwtListView::SizeChanged()
       
  1599 {
       
  1600     TRAP_IGNORE(SizeChangedL());
       
  1601     HandleSizeChanged();
       
  1602 }
       
  1603 
       
  1604 // ---------------------------------------------------------------------------
       
  1605 // From class CCoeControl.
       
  1606 // ---------------------------------------------------------------------------
       
  1607 //
       
  1608 void CSwtListView::PositionChanged()
       
  1609 {
       
  1610     iGrid->SetPosition(BorderInnerRect().iTl);
       
  1611     TRAP_IGNORE(iGrid->HandleViewRectSizeChangeL());
       
  1612     HandlePositionChanged();
       
  1613 }
       
  1614 
       
  1615 // ---------------------------------------------------------------------------
       
  1616 // From class CCoeControl.
       
  1617 // ---------------------------------------------------------------------------
       
  1618 //
       
  1619 void CSwtListView::HandleResourceChange(TInt aType)
       
  1620 {
       
  1621     TRAP_IGNORE(HandleResourceChangeL(aType));
       
  1622 }
       
  1623 
       
  1624 // ---------------------------------------------------------------------------
       
  1625 // From class CCoeControl.
       
  1626 // ---------------------------------------------------------------------------
       
  1627 //
       
  1628 void CSwtListView::FocusChanged(TDrawNow aDrawNow)
       
  1629 {
       
  1630     TBool isFocused = IsFocused();
       
  1631 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  1632     EnableFocusHighlight(isFocused);
       
  1633 #endif //RD_JAVA_S60_RELEASE_9_2
       
  1634     iGrid->SetFocus(isFocused);
       
  1635     HandleFocusChanged(aDrawNow);
       
  1636 }
       
  1637 
       
  1638 // ---------------------------------------------------------------------------
       
  1639 // From class CCoeControl.
       
  1640 // Only horizontal layout (vertical scrolling) is supported.
       
  1641 // ---------------------------------------------------------------------------
       
  1642 //
       
  1643 TKeyResponse CSwtListView::OfferKeyEventL(const TKeyEvent& aKeyEvent,
       
  1644         TEventCode aType)
       
  1645 {
       
  1646     ASSERT(iVerticalOrientation == EFalse);
       
  1647 
       
  1648     TBool traversalDoIt = ETrue;
       
  1649     TInt firstItemRowIndex;
       
  1650     TInt firstItemColIndex;
       
  1651     TInt lastItemRowIndex;
       
  1652     TInt lastItemColIndex;
       
  1653     TInt currentItemRowIndex;
       
  1654     TInt currentItemColIndex;
       
  1655     TSwtTraversal detail = ESwtTraverseNone;
       
  1656     TBool isMirrored = AknLayoutUtils::LayoutMirrored();
       
  1657 
       
  1658     if (aKeyEvent.iCode == EKeyEnter || aKeyEvent.iCode == EKeyOK ||
       
  1659             aKeyEvent.iCode == EKeyEscape)
       
  1660     {
       
  1661         traversalDoIt = EFalse;
       
  1662     }
       
  1663 
       
  1664     if (GetItemCount() > 0)
       
  1665     {
       
  1666         if (aKeyEvent.iCode == EKeyDownArrow ||
       
  1667                 aKeyEvent.iCode == EKeyUpArrow ||
       
  1668                 aKeyEvent.iCode == EKeyLeftArrow ||
       
  1669                 aKeyEvent.iCode == EKeyRightArrow)
       
  1670         {
       
  1671             traversalDoIt = EFalse;
       
  1672             GetGridView()->CalcRowAndColIndexesFromItemIndex(0,
       
  1673                     firstItemRowIndex,
       
  1674                     firstItemColIndex);
       
  1675             GetGridView()->CalcRowAndColIndexesFromItemIndex(GetItemCount() - 1,
       
  1676                     lastItemRowIndex,
       
  1677                     lastItemColIndex);
       
  1678             GetGridView()->CalcRowAndColIndexesFromItemIndex(iGrid->CurrentDataIndex(),
       
  1679                     currentItemRowIndex,
       
  1680                     currentItemColIndex);
       
  1681         }
       
  1682         if (aKeyEvent.iCode == EKeyDownArrow)
       
  1683         {
       
  1684             if (currentItemRowIndex == lastItemRowIndex)
       
  1685             {
       
  1686                 detail = ESwtTraverseArrowNext;
       
  1687             }
       
  1688         }
       
  1689         else if (aKeyEvent.iCode == EKeyUpArrow)
       
  1690         {
       
  1691             if (currentItemRowIndex == firstItemRowIndex)
       
  1692             {
       
  1693                 detail = ESwtTraverseArrowPrevious;
       
  1694             }
       
  1695         }
       
  1696         else if ((isMirrored  && aKeyEvent.iCode == EKeyRightArrow) ||
       
  1697                  (!isMirrored && aKeyEvent.iCode == EKeyLeftArrow))
       
  1698         {
       
  1699             if (iGrid->CurrentDataIndex() == 0)
       
  1700             {
       
  1701                 detail = ESwtTraverseArrowPrevious;
       
  1702             }
       
  1703         }
       
  1704         else if ((isMirrored  && aKeyEvent.iCode == EKeyLeftArrow) ||
       
  1705                  (!isMirrored && aKeyEvent.iCode == EKeyRightArrow))
       
  1706         {
       
  1707             if (iGrid->CurrentDataIndex() == GetItemCount() - 1)
       
  1708             {
       
  1709                 detail = ESwtTraverseArrowNext;
       
  1710             }
       
  1711         }
       
  1712     }
       
  1713     if (detail != ESwtTraverseNone &&
       
  1714             (GetShell().FindTraversalTargetL(detail, *this)))
       
  1715     {
       
  1716         traversalDoIt = ETrue;
       
  1717     }
       
  1718     return HandleKeyL(aKeyEvent, aType, traversalDoIt);
       
  1719 }
       
  1720 
       
  1721 // ---------------------------------------------------------------------------
       
  1722 // From class CCoeControl.
       
  1723 // ---------------------------------------------------------------------------
       
  1724 //
       
  1725 void CSwtListView::MakeVisible(TBool aVisible)
       
  1726 {
       
  1727     CCoeControl::MakeVisible(aVisible);
       
  1728     FocusabilityChanged();
       
  1729 }
       
  1730 
       
  1731 // ---------------------------------------------------------------------------
       
  1732 // From class CCoeControl.
       
  1733 // ---------------------------------------------------------------------------
       
  1734 //
       
  1735 void CSwtListView::SetDimmed(TBool aDimmed)
       
  1736 {
       
  1737     CCoeControl::SetDimmed(aDimmed);
       
  1738     if (iGrid)
       
  1739     {
       
  1740         iGrid->SetDimmed(aDimmed);
       
  1741     }
       
  1742     FocusabilityChanged();
       
  1743 }
       
  1744 
       
  1745 // ---------------------------------------------------------------------------
       
  1746 // From class CCoeControl.
       
  1747 // ---------------------------------------------------------------------------
       
  1748 //
       
  1749 TTypeUid::Ptr CSwtListView::MopSupplyObject(TTypeUid aId)
       
  1750 {
       
  1751     TTypeUid::Ptr id = ASwtControlBase::SwtMopSupplyObject(aId);
       
  1752 
       
  1753     if (id.Pointer() == NULL)
       
  1754     {
       
  1755         return CAknControl::MopSupplyObject(aId);
       
  1756     }
       
  1757     else
       
  1758     {
       
  1759         return id;
       
  1760     }
       
  1761 }
       
  1762 
       
  1763 // ---------------------------------------------------------------------------
       
  1764 // From class CCoeControl.
       
  1765 // Overriding Draw just to set correct clipping rect for the item drawer of
       
  1766 // the contained grid. The contained grid will be drawn immediately after this.
       
  1767 // ---------------------------------------------------------------------------
       
  1768 //
       
  1769 void CSwtListView::Draw(const TRect& /*aRect*/) const
       
  1770 {
       
  1771     if (GetShell().UrgentPaintControl() == this)
       
  1772         return;
       
  1773 
       
  1774     TRect clipRect(ClipToVisibleRect(iGrid->View()->ViewRect()));
       
  1775     if (clipRect != iLastViewVisibleRect)
       
  1776     {
       
  1777         iGrid->SetItemDrawerClippingRect(clipRect);
       
  1778         iLastViewVisibleRect = clipRect;
       
  1779     }
       
  1780 }
       
  1781 
       
  1782 // ---------------------------------------------------------------------------
       
  1783 // From class MSwtListView.
       
  1784 // ---------------------------------------------------------------------------
       
  1785 //
       
  1786 MSwtScrollable* CSwtListView::Scrollable()
       
  1787 {
       
  1788     return this;
       
  1789 }
       
  1790 
       
  1791 // ---------------------------------------------------------------------------
       
  1792 // From class MSwtListView.
       
  1793 // This is called when the Java application calls ListView.add without
       
  1794 // the index parameter
       
  1795 // ---------------------------------------------------------------------------
       
  1796 //
       
  1797 void CSwtListView::AppendL(const TDesC& aPtr, const MSwtImage* aImage)
       
  1798 {
       
  1799     AddItemL(aPtr, aImage, GetItemCount());
       
  1800     UpdateControlMenu();
       
  1801 }
       
  1802 
       
  1803 // ---------------------------------------------------------------------------
       
  1804 // From class MSwtListView.
       
  1805 // This is called when the Java application calls ListView.add with
       
  1806 // the index parameter.
       
  1807 // ---------------------------------------------------------------------------
       
  1808 //
       
  1809 void CSwtListView::InsertL(TInt aPos,
       
  1810                            const TDesC& aPtr,
       
  1811                            const MSwtImage* aImage)
       
  1812 {
       
  1813     if (aPos < 0 || aPos > GetItemCount())
       
  1814     {
       
  1815         User::Leave(ESwtErrorInvalidRange);
       
  1816     }
       
  1817     AddItemL(aPtr, aImage, aPos);
       
  1818     UpdateControlMenu();
       
  1819 }
       
  1820 
       
  1821 // ---------------------------------------------------------------------------
       
  1822 // From class MSwtListView.
       
  1823 // ---------------------------------------------------------------------------
       
  1824 //
       
  1825 void CSwtListView::DeselectItem(TInt aIndex)
       
  1826 {
       
  1827     // Ignore if not applicable
       
  1828     TInt count(GetItemCount());
       
  1829     if (!(iStyle & KSwtStyleMulti) ||               // not multi select
       
  1830             count == 0 ||                               // empty
       
  1831             aIndex >= count ||                          // no items in range
       
  1832             aIndex < 0 ||                               // no items in range
       
  1833             iGrid->SelectionIndexes()->Count() == 0)    // no selected items
       
  1834     {
       
  1835         return;
       
  1836     }
       
  1837 
       
  1838     CAknGridView* gridView = GetGridView();
       
  1839 
       
  1840     ASSERT(gridView);
       
  1841 
       
  1842     gridView->DeselectItem(gridView->ActualDataIndex(aIndex));
       
  1843     UpdateControlMenu();
       
  1844 }
       
  1845 
       
  1846 // ---------------------------------------------------------------------------
       
  1847 // From class MSwtListView.
       
  1848 // ---------------------------------------------------------------------------
       
  1849 //
       
  1850 void CSwtListView::DeselectRange(TInt aStart, TInt aEnd)
       
  1851 {
       
  1852     ASSERT(aStart <= aEnd);   // Checked in the Java method
       
  1853 
       
  1854     // Ignore if not applicable
       
  1855     TInt count(GetItemCount());
       
  1856     if (!(iStyle & KSwtStyleMulti) ||               // not multi select
       
  1857             count == 0 ||                               // empty
       
  1858             aStart >= count ||                          // no items in range
       
  1859             iGrid->SelectionIndexes()->Count() == 0)    // no selected items
       
  1860     {
       
  1861         return;
       
  1862     }
       
  1863 
       
  1864     // Validate range
       
  1865     if (aStart < 0)
       
  1866     {
       
  1867         aStart = 0;
       
  1868     }
       
  1869     if (aEnd >= count)
       
  1870     {
       
  1871         aEnd = count - 1;
       
  1872     }
       
  1873 
       
  1874     TRAP_IGNORE(GetGridView()->DeselectRangeL(aStart, aEnd));
       
  1875     UpdateControlMenu();
       
  1876 }
       
  1877 
       
  1878 // ---------------------------------------------------------------------------
       
  1879 // From class MSwtListView.
       
  1880 // ---------------------------------------------------------------------------
       
  1881 //
       
  1882 void CSwtListView::DeselectItems(const TInt* aIndices, TInt aCount)
       
  1883 {
       
  1884     // Ignore if not applicable
       
  1885     TInt count(GetItemCount());
       
  1886     if (!aIndices ||
       
  1887             aCount == 0 ||
       
  1888             !(iStyle & KSwtStyleMulti) ||               // not multi select
       
  1889             count == 0 ||                               // empty
       
  1890             iGrid->SelectionIndexes()->Count() == 0)    // no selected items
       
  1891     {
       
  1892         return;
       
  1893     }
       
  1894 
       
  1895     for (TInt i = 0; i < aCount; ++i)
       
  1896     {
       
  1897         if (GetGridModel()->IndexContainsData(aIndices[i]))
       
  1898         {
       
  1899             GetGridView()->DeselectItem(aIndices[i]);
       
  1900         }
       
  1901     }
       
  1902     UpdateControlMenu();
       
  1903 }
       
  1904 
       
  1905 // ---------------------------------------------------------------------------
       
  1906 // From class MSwtListView.
       
  1907 // ---------------------------------------------------------------------------
       
  1908 //
       
  1909 void CSwtListView::DeselectAll()
       
  1910 {
       
  1911     // Ignore if not applicable
       
  1912     TInt count(GetItemCount());
       
  1913     if (!(iStyle & KSwtStyleMulti) ||               // not multi select
       
  1914             count == 0 ||                               // empty
       
  1915             iGrid->SelectionIndexes()->Count() == 0)    // no selected items
       
  1916     {
       
  1917         return;
       
  1918     }
       
  1919     iGrid->ClearSelection();
       
  1920     UpdateControlMenu();
       
  1921 }
       
  1922 
       
  1923 // ---------------------------------------------------------------------------
       
  1924 // From class MSwtListView.
       
  1925 // ---------------------------------------------------------------------------
       
  1926 //
       
  1927 TInt CSwtListView::GetFocusIndex() const
       
  1928 {
       
  1929     if (GetGridModel()->NumberOfItems() == 0)
       
  1930     {
       
  1931         return -1;
       
  1932     }
       
  1933     return iGrid->CurrentDataIndex();
       
  1934 }
       
  1935 
       
  1936 // ---------------------------------------------------------------------------
       
  1937 // From class MSwtListView.
       
  1938 // ---------------------------------------------------------------------------
       
  1939 //
       
  1940 void CSwtListView::GetItemL(TInt aItemIndex, TPtrC& aString) const
       
  1941 {
       
  1942     if (GetGridModel()->IndexContainsData(aItemIndex))
       
  1943     {
       
  1944         GetCaption(aItemIndex, aString);
       
  1945     }
       
  1946     else
       
  1947     {
       
  1948         User::Leave(ESwtErrorInvalidRange);
       
  1949     }
       
  1950 }
       
  1951 
       
  1952 // ---------------------------------------------------------------------------
       
  1953 // From class MSwtListView.
       
  1954 // ---------------------------------------------------------------------------
       
  1955 //
       
  1956 TPoint CSwtListView::GetIconSize(TInt aStyle) const
       
  1957 {
       
  1958     ASSERT(aStyle == ELowListViewDensity ||
       
  1959            aStyle == EHighListViewDensity ||
       
  1960            aStyle == EMediumListViewDensity);   // checked in Java side
       
  1961 
       
  1962     if (aStyle == ELowListViewDensity)
       
  1963     {
       
  1964         return iIconSizeInLowDensity;
       
  1965     }
       
  1966     else
       
  1967     {
       
  1968         if (aStyle == EHighListViewDensity)
       
  1969         {
       
  1970             return iIconSizeInHighDensity;
       
  1971         }
       
  1972         else
       
  1973         {
       
  1974             return iIconSizeInMediumDensity;
       
  1975         }
       
  1976     }
       
  1977 }
       
  1978 
       
  1979 // ---------------------------------------------------------------------------
       
  1980 // From class MSwtListView.
       
  1981 // ---------------------------------------------------------------------------
       
  1982 //
       
  1983 TInt CSwtListView::GetItemCount() const
       
  1984 {
       
  1985     return GetGridModel()->NumberOfItems();
       
  1986 }
       
  1987 
       
  1988 // ---------------------------------------------------------------------------
       
  1989 // From class MSwtListView.
       
  1990 // ---------------------------------------------------------------------------
       
  1991 //
       
  1992 CPtrCArray* CSwtListView::GetItemsL() const
       
  1993 {
       
  1994     TInt count(GetItemCount());
       
  1995     if (count == 0)
       
  1996     {
       
  1997         return NULL;
       
  1998     }
       
  1999 
       
  2000     // Allocate space for the items, deleted by the jni export function
       
  2001     CPtrCArray* itemsArray = new(ELeave) CPtrC16Array(KSwtListViewItemGranularity);
       
  2002     CleanupStack::PushL(itemsArray);
       
  2003 
       
  2004     for (TInt i = 0; i < count; ++i)
       
  2005     {
       
  2006         TPtrC caption;
       
  2007         GetCaption(i, caption);
       
  2008         itemsArray->AppendL(caption);
       
  2009     }
       
  2010 
       
  2011     CleanupStack::Pop();
       
  2012     return itemsArray;
       
  2013 }
       
  2014 
       
  2015 // ---------------------------------------------------------------------------
       
  2016 // From class MSwtListView.
       
  2017 // ---------------------------------------------------------------------------
       
  2018 //
       
  2019 CPtrCArray* CSwtListView::GetSelectionL() const
       
  2020 {
       
  2021     if (!(GetItemCount() > 0))
       
  2022     {
       
  2023         return NULL;
       
  2024     }
       
  2025 
       
  2026     const CAknGridView::CSelectionIndexArray* selArray = NULL;
       
  2027     if (iStyle & KSwtStyleMulti)
       
  2028     {
       
  2029         selArray = iGrid->SelectionIndexes();
       
  2030         if (!selArray || selArray->Count() == 0)
       
  2031         {
       
  2032             return NULL;
       
  2033         }
       
  2034     }
       
  2035 
       
  2036     // Allocate space for the items, deleted by the jni export function
       
  2037     CPtrCArray* itemsArray = new(ELeave) CPtrC16Array(KSwtListViewItemGranularity);
       
  2038     CleanupStack::PushL(itemsArray);
       
  2039 
       
  2040     if (iStyle & KSwtStyleMulti)
       
  2041     {
       
  2042         for (TInt i = 0; i < selArray->Count(); ++i)
       
  2043         {
       
  2044             ASSERT(selArray->At(i) < GetItemCount());
       
  2045             TPtrC caption;
       
  2046             GetItemL(GetGridView()->ActualDataIndex(selArray->At(i)), caption);
       
  2047             itemsArray->AppendL(caption);
       
  2048         }
       
  2049     }
       
  2050     else // single style
       
  2051     {
       
  2052         TPtrC caption;
       
  2053         GetItemL(iGrid->CurrentDataIndex(), caption);
       
  2054         itemsArray->AppendL(caption);
       
  2055     }
       
  2056 
       
  2057     CleanupStack::Pop();
       
  2058     return itemsArray;
       
  2059 }
       
  2060 
       
  2061 // ---------------------------------------------------------------------------
       
  2062 // From class MSwtListView.
       
  2063 // ---------------------------------------------------------------------------
       
  2064 //
       
  2065 TInt CSwtListView::GetSelectionCount() const
       
  2066 {
       
  2067     return iGrid->SelectionIndexes()->Count();
       
  2068 }
       
  2069 
       
  2070 // ---------------------------------------------------------------------------
       
  2071 // From class MSwtListView.
       
  2072 // ---------------------------------------------------------------------------
       
  2073 //
       
  2074 const CArrayFix<TInt>* CSwtListView::GetSelectionIndices() const
       
  2075 {
       
  2076     GetSelection(iSelectionArray);
       
  2077 
       
  2078     return iSelectionArray;
       
  2079 }
       
  2080 
       
  2081 // ---------------------------------------------------------------------------
       
  2082 // From class MSwtListView.
       
  2083 // ---------------------------------------------------------------------------
       
  2084 //
       
  2085 TInt CSwtListView::GetTopIndex() const
       
  2086 {
       
  2087     if (GetItemCount() <= 0)
       
  2088     {
       
  2089         return -1;
       
  2090     }
       
  2091     else
       
  2092     {
       
  2093         return iGrid->TopItemIndex();
       
  2094     }
       
  2095 }
       
  2096 
       
  2097 // ---------------------------------------------------------------------------
       
  2098 // From class MSwtListView.
       
  2099 // ---------------------------------------------------------------------------
       
  2100 //
       
  2101 TInt CSwtListView::IndexOf(const TDesC& aString, TInt& aStart) const
       
  2102 {
       
  2103     TInt index = -1;
       
  2104     CDesCArray* itemTextArray = GetTextArray();
       
  2105 
       
  2106     // Range check
       
  2107     if (!(aStart < 0 || aStart >= GetItemCount()))
       
  2108     {
       
  2109         for (TInt i = aStart; i < itemTextArray->Count(); ++i)
       
  2110         {
       
  2111             TPtrC caption;
       
  2112             TInt result = GetCaption(i, caption);
       
  2113             if (result == KErrNotFound)
       
  2114             {
       
  2115                 break;
       
  2116             }
       
  2117             if (aString.Compare(caption) == KErrNone)
       
  2118             {
       
  2119                 index = i;
       
  2120                 break;
       
  2121             }
       
  2122         }
       
  2123     }
       
  2124     return index;
       
  2125 }
       
  2126 
       
  2127 // ---------------------------------------------------------------------------
       
  2128 // From class MSwtListView.
       
  2129 // ---------------------------------------------------------------------------
       
  2130 //
       
  2131 TBool CSwtListView::IsSelected(TInt aIndex) const
       
  2132 {
       
  2133     return GetGridView()->ItemIsSelected(GetGridView()->ActualDataIndex(aIndex));
       
  2134 }
       
  2135 
       
  2136 // ---------------------------------------------------------------------------
       
  2137 // From class MSwtListView.
       
  2138 // ---------------------------------------------------------------------------
       
  2139 //
       
  2140 void CSwtListView::RemoveItemL(TInt aIndex)
       
  2141 {
       
  2142     if (aIndex < 0 || aIndex >= GetItemCount())
       
  2143     {
       
  2144         User::Leave(ESwtErrorInvalidRange);
       
  2145     }
       
  2146 
       
  2147     // Store the selection state
       
  2148     GetSelection(iOldSelectionArray);
       
  2149 
       
  2150     // Check if the focused and/or the last item is being removed
       
  2151     TBool focused = EFalse;
       
  2152     if (aIndex == iGrid->CurrentDataIndex())
       
  2153     {
       
  2154         focused = ETrue;
       
  2155     }
       
  2156     TBool last = EFalse;
       
  2157     if (aIndex == GetItemCount() - 1)
       
  2158     {
       
  2159         last = ETrue;
       
  2160     }
       
  2161 
       
  2162     UpdateRemovedItemCountersL(aIndex);
       
  2163 
       
  2164     // Remove the item text
       
  2165     CDesCArray* itemTextArray = GetTextArray();
       
  2166     itemTextArray->Delete(aIndex);
       
  2167     itemTextArray->Compress();
       
  2168 
       
  2169     // All the icon indexes after the removed item need updating
       
  2170     TInt textCount = GetTextArray()->Count();
       
  2171     for (TInt i = aIndex; i < textCount; ++i)
       
  2172     {
       
  2173         UpdateIconIndexL(i);
       
  2174     }
       
  2175 
       
  2176     // Remove the icon
       
  2177     CAknIconArray* iconArray = GetIconArray();
       
  2178     CGulIcon* icon = (*iconArray)[ ItemIconIndex(aIndex)];
       
  2179     iconArray->Delete(ItemIconIndex(aIndex));
       
  2180     iconArray->Compress();
       
  2181     delete icon;
       
  2182 
       
  2183     // Remove the reference
       
  2184     RemoveImageRef(aIndex);
       
  2185     iRefImages.Remove(aIndex);
       
  2186     iRefImages.Compress();
       
  2187 
       
  2188 #ifdef DEBUG_CHECK_IMAGES
       
  2189     CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
       
  2190 #endif
       
  2191 
       
  2192     // Notify the grid
       
  2193     iGrid->HandleItemRemovalL();
       
  2194 
       
  2195     // Restore the selection state updating the indexes.
       
  2196     UpdateSelectionIndexesL(aIndex, aIndex, EFalse);
       
  2197 
       
  2198     // If last and focused item was removed then focus moves to the first
       
  2199     if (GetItemCount() > 0)
       
  2200     {
       
  2201         if (focused && last)
       
  2202         {
       
  2203             iGrid->SetCurrentDataIndex(0);
       
  2204             iGrid->ScrollToMakeItemVisible(0);
       
  2205         }
       
  2206 
       
  2207         SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  2208         ScrollViewToShowAsManyItemsAsPossibleL();
       
  2209     }
       
  2210     UpdateControlMenu();
       
  2211     UpdateMSKLabelL();
       
  2212     Redraw();
       
  2213 }
       
  2214 
       
  2215 // ---------------------------------------------------------------------------
       
  2216 // From class MSwtListView.
       
  2217 // ---------------------------------------------------------------------------
       
  2218 //
       
  2219 void CSwtListView::RemoveRangeL(TInt aStart, TInt aEnd)
       
  2220 {
       
  2221     ASSERT(aStart <= aEnd);   // Checked in the Java method
       
  2222 
       
  2223     if (aStart < 0 || aEnd >= GetItemCount())
       
  2224     {
       
  2225         User::Leave(ESwtErrorInvalidRange);
       
  2226     }
       
  2227 
       
  2228     // Store the selection state
       
  2229     GetSelection(iOldSelectionArray);
       
  2230 
       
  2231     // Remove texts
       
  2232     CDesCArray* itemTextArray = GetTextArray();
       
  2233 
       
  2234     for (TInt i = aStart; i < aEnd; ++i)
       
  2235     {
       
  2236         UpdateRemovedItemCountersL(i);
       
  2237     }
       
  2238 
       
  2239     TInt itemsInRange = (aEnd - aStart) + 1;
       
  2240     itemTextArray->Delete(aStart, itemsInRange);
       
  2241     itemTextArray->Compress();
       
  2242 
       
  2243     // All the icon indexes after the 1st removed item need updating
       
  2244     TInt textCount = GetTextArray()->Count();
       
  2245     for (TInt i = aStart; i < textCount; ++i)
       
  2246     {
       
  2247         UpdateIconIndexL(i);
       
  2248     }
       
  2249 
       
  2250     // Delete icons and references
       
  2251     CAknIconArray* iconArray = GetIconArray();
       
  2252 
       
  2253     // Must go backwards here for correct removal of references
       
  2254     for (TInt i = aEnd; i >= aStart; i--)
       
  2255     {
       
  2256         CGulIcon* icon = (*iconArray)[ItemIconIndex(i)];
       
  2257         delete icon;
       
  2258         RemoveImageRef(i);
       
  2259         iRefImages.Remove(i);
       
  2260     }
       
  2261     iconArray->Delete(ItemIconIndex(aStart), itemsInRange);
       
  2262     iconArray->Compress();
       
  2263     iRefImages.Compress();
       
  2264 
       
  2265 #ifdef DEBUG_CHECK_IMAGES
       
  2266     CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
       
  2267 #endif
       
  2268 
       
  2269     // Notify grid
       
  2270     iGrid->HandleItemRemovalL();
       
  2271 
       
  2272     // Restore the selection state updating the indexes.
       
  2273     UpdateSelectionIndexesL(aStart, aEnd, EFalse);
       
  2274 
       
  2275     if (GetItemCount() > 0)
       
  2276     {
       
  2277         SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  2278         ScrollViewToShowAsManyItemsAsPossibleL();
       
  2279     }
       
  2280 
       
  2281     UpdateControlMenu();
       
  2282     UpdateMSKLabelL();
       
  2283     Redraw();
       
  2284 }
       
  2285 
       
  2286 // ---------------------------------------------------------------------------
       
  2287 // From class MSwtListView.
       
  2288 // ---------------------------------------------------------------------------
       
  2289 //
       
  2290 void CSwtListView::RemoveItemsL(const TInt* aIndices, TInt aCount)
       
  2291 {
       
  2292     if (!aIndices)
       
  2293     {
       
  2294         return;
       
  2295     }
       
  2296 
       
  2297     // Store the selection state
       
  2298     GetSelection(iOldSelectionArray);
       
  2299 
       
  2300     TInt count = GetItemCount();
       
  2301 
       
  2302     // Elements are ordered from high to low in Java side.
       
  2303     TInt min = aIndices[ aCount - 1 ];
       
  2304     TInt max = aIndices[ 0 ];
       
  2305     if (min < 0 || max >= count)
       
  2306     {
       
  2307         User::Leave(ESwtErrorInvalidRange);
       
  2308     }
       
  2309 
       
  2310     CDesCArray* textArray = GetTextArray();
       
  2311     CAknIconArray* iconArray = GetIconArray();
       
  2312     TInt prevIndex = -1;
       
  2313 
       
  2314     for (TInt i = 0; i < aCount; ++i)
       
  2315     {
       
  2316         // Assert that items are in high-to-low order
       
  2317         ASSERT(i + 1 < aCount ? aIndices[ i + 1 ] <= aIndices[ i ] : ETrue);
       
  2318 
       
  2319         if (aIndices[i] != prevIndex)  // not the same index many times
       
  2320         {
       
  2321             UpdateRemovedItemCountersL(aIndices[i]);
       
  2322             textArray->Delete(aIndices[ i ]);
       
  2323             CGulIcon* icon = (*iconArray)[ ItemIconIndex(aIndices[ i ])];
       
  2324             iconArray->Delete(ItemIconIndex(aIndices[ i ]));
       
  2325             delete icon;
       
  2326             const MSwtImage* refImg = iRefImages[aIndices[ i ]];
       
  2327             RemoveImageRef(aIndices[ i ]);
       
  2328             iRefImages.Remove(aIndices[ i ]);
       
  2329             prevIndex = aIndices[ i ];
       
  2330         }
       
  2331     }
       
  2332 
       
  2333     textArray->Compress();
       
  2334     iconArray->Compress();
       
  2335     iRefImages.Compress();
       
  2336 
       
  2337 #ifdef DEBUG_CHECK_IMAGES
       
  2338     CheckRefImages(iRefImages, *(GetIconArray()), iMaxImageSize);
       
  2339 #endif
       
  2340 
       
  2341     // All the icon indexes starting from the first removed item
       
  2342     // need updating
       
  2343     TInt textCount = GetTextArray()->Count();
       
  2344     for (TInt i = min; i < textCount; ++i)
       
  2345     {
       
  2346         UpdateIconIndexL(i);
       
  2347     }
       
  2348 
       
  2349     // Notify the grid
       
  2350     iGrid->HandleItemRemovalL();
       
  2351 
       
  2352     // Restore the selection state updating the indexes.
       
  2353     prevIndex = -1;
       
  2354     for (TInt i = 0; i < aCount; ++i)
       
  2355     {
       
  2356         // Assert that items are in high-to-low order
       
  2357         ASSERT(i + 1 < aCount ? aIndices[ i + 1 ] <= aIndices[ i ] : ETrue);
       
  2358 
       
  2359         if (aIndices[i] != prevIndex)  // not the same index many times
       
  2360         {
       
  2361             // Restore the selection state updating the indexes.
       
  2362             UpdateSelectionIndexesL(aIndices[i], aIndices[i], EFalse);
       
  2363 
       
  2364             GetSelection(iOldSelectionArray);   //was reseted by former method
       
  2365 
       
  2366             prevIndex = aIndices[ i ];
       
  2367         }
       
  2368     }
       
  2369 
       
  2370     iOldSelectionArray->Reset();
       
  2371 
       
  2372     if (GetItemCount() > 0)
       
  2373     {
       
  2374         SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  2375         ScrollViewToShowAsManyItemsAsPossibleL();
       
  2376     }
       
  2377 
       
  2378     UpdateControlMenu();
       
  2379     UpdateMSKLabelL();
       
  2380     Redraw();
       
  2381 }
       
  2382 
       
  2383 // ---------------------------------------------------------------------------
       
  2384 // From class MSwtListView.
       
  2385 // ---------------------------------------------------------------------------
       
  2386 //
       
  2387 void CSwtListView::RemoveAllL()
       
  2388 {
       
  2389     TInt itemCount = GetItemCount();
       
  2390     if (itemCount > 0)
       
  2391     {
       
  2392         RemoveRangeL(0, itemCount - 1);
       
  2393     }
       
  2394 }
       
  2395 
       
  2396 // ---------------------------------------------------------------------------
       
  2397 // From class MSwtListView.
       
  2398 // ---------------------------------------------------------------------------
       
  2399 //
       
  2400 void CSwtListView::SelectItemL(TInt aIndex, TBool aScroll)
       
  2401 {
       
  2402     // Checked on Java side
       
  2403     ASSERT(aIndex >= 0);
       
  2404 
       
  2405     // Range check
       
  2406     if (aIndex >= GetItemCount())
       
  2407     {
       
  2408         return;
       
  2409     }
       
  2410 
       
  2411     SingleOrMultiSelectL(aIndex, aScroll);
       
  2412 
       
  2413     UpdateControlMenu();
       
  2414 }
       
  2415 
       
  2416 // ---------------------------------------------------------------------------
       
  2417 // From class MSwtListView.
       
  2418 // ---------------------------------------------------------------------------
       
  2419 //
       
  2420 void CSwtListView::SelectRangeL(TInt aStart, TInt aEnd)
       
  2421 {
       
  2422     // Checked on Java side
       
  2423     ASSERT(iStyle & KSwtStyleMulti || aStart != aEnd);
       
  2424     ASSERT(aEnd >= 0);
       
  2425     ASSERT(aStart <= aEnd);
       
  2426 
       
  2427     // Ignore if not applicable
       
  2428     TInt count(GetItemCount());
       
  2429     if (count == 0 ||           // empty
       
  2430             aStart >= count)        // no items in range
       
  2431     {
       
  2432         return;
       
  2433     }
       
  2434 
       
  2435     // Ignore items out of range
       
  2436     if (aEnd >= count)
       
  2437     {
       
  2438         aEnd = count - 1;
       
  2439     }
       
  2440 
       
  2441     for (TInt i = aStart; i <= aEnd; ++i)
       
  2442     {
       
  2443         SingleOrMultiSelectL(i, EFalse);
       
  2444     }
       
  2445 
       
  2446     UpdateControlMenu();
       
  2447 }
       
  2448 
       
  2449 // ---------------------------------------------------------------------------
       
  2450 // From class MSwtListView.
       
  2451 // ---------------------------------------------------------------------------
       
  2452 //
       
  2453 void CSwtListView::SelectAllL()
       
  2454 {
       
  2455     // Checked on Java side
       
  2456     ASSERT(iStyle & KSwtStyleMulti);
       
  2457 
       
  2458     // Ignore if not applicable
       
  2459     TInt count(GetItemCount());
       
  2460     if (count == 0)
       
  2461     {
       
  2462         return;
       
  2463     }
       
  2464     SelectRangeL(0, count - 1);
       
  2465 }
       
  2466 
       
  2467 // ---------------------------------------------------------------------------
       
  2468 // From class MSwtListView.
       
  2469 // ---------------------------------------------------------------------------
       
  2470 //
       
  2471 void CSwtListView::SetFocusIndex(TInt aIndex)
       
  2472 {
       
  2473     ASSERT(iGrid);
       
  2474 
       
  2475     // By now, we only call this method in multiple selection.
       
  2476     // In single selection, we assume that setting the focus means selecting.
       
  2477     ASSERT(iStyle & KSwtStyleMulti);
       
  2478 
       
  2479     if (aIndex < 0 || aIndex >= iGrid->Model()->NumberOfItems())
       
  2480     {
       
  2481         return;
       
  2482     }
       
  2483 
       
  2484     TInt old = iGrid->CurrentItemIndex();
       
  2485     if (old != aIndex)
       
  2486     {
       
  2487         iGrid->SetCurrentItemIndex(aIndex);
       
  2488         iGrid->View()->DrawItem(aIndex);
       
  2489         if (old != -1)
       
  2490         {
       
  2491             iGrid->View()->DrawItem(old);
       
  2492         }
       
  2493     }
       
  2494     UpdateControlMenu();
       
  2495 }
       
  2496 
       
  2497 // ---------------------------------------------------------------------------
       
  2498 // From class MSwtListView.
       
  2499 // ---------------------------------------------------------------------------
       
  2500 //
       
  2501 void CSwtListView::SetItemsL(MDesCArray* aStringArray, RPointerArray<MSwtImage>& aImagesArray)
       
  2502 {
       
  2503     // Null argument and invalid range are covered in Java side.
       
  2504     // If there are no icons (client passed null) then we have an empty array here.
       
  2505     ASSERT(aStringArray);
       
  2506     TInt texts = aStringArray->MdcaCount();
       
  2507     TInt icons = aImagesArray.Count();
       
  2508     ASSERT(texts == icons || icons == 0);
       
  2509 
       
  2510     // Remove the existing items
       
  2511     RemoveAllL();
       
  2512 
       
  2513     // Add the new items
       
  2514     for (TInt i = 0; i < texts; ++i)
       
  2515     {
       
  2516         // Add the text
       
  2517         TRAPD(textError, AddTextL(aStringArray->MdcaPoint(i), i));
       
  2518         if (textError)
       
  2519         {
       
  2520             User::Leave(ESwtErrorItemNotAdded);
       
  2521         }
       
  2522 
       
  2523         // Add the icon
       
  2524         TInt iconError;
       
  2525         if (icons)
       
  2526         {
       
  2527             TRAP(iconError, AddIconL(aImagesArray[ i ], i));
       
  2528         }
       
  2529         else
       
  2530         {
       
  2531             TRAP(iconError, AddIconL(NULL, i));
       
  2532         }
       
  2533         if (iconError)
       
  2534         {
       
  2535             // Remove the text as the icon can't be added
       
  2536             ASSERT(GetTextArray()->Count() > 0);
       
  2537             GetTextArray()->Delete(GetTextArray()->Count() - 1);
       
  2538             User::Leave(ESwtErrorItemNotAdded);
       
  2539         }
       
  2540 
       
  2541         // Update grid cell layout if neccessary
       
  2542         DoGridCellLayoutIfNeededL();
       
  2543     }
       
  2544 
       
  2545     // All items added successfully
       
  2546 
       
  2547     iGrid->HandleItemAdditionL();
       
  2548 
       
  2549     // Focus must move to the newly added item.
       
  2550     iGrid->SetCurrentDataIndex(texts - 1);
       
  2551     SingleSelectL(texts - 1, ETrue);
       
  2552 
       
  2553     UpdateControlMenu();
       
  2554     UpdateMSKLabelL();
       
  2555 
       
  2556     Redraw();
       
  2557     iDisplay.PostSelectionEventL(iPeer);
       
  2558 }
       
  2559 
       
  2560 // ---------------------------------------------------------------------------
       
  2561 // From class MSwtListView.
       
  2562 // Only the horizontal orientation (vertical scrolling)
       
  2563 // is supported currently. No need to do anything here.
       
  2564 // ---------------------------------------------------------------------------
       
  2565 //
       
  2566 void CSwtListView::SetLayoutL(TInt /*aLayout*/)
       
  2567 {
       
  2568     //TBool currentOrientation = iVerticalOrientation;
       
  2569     //if( aLayout == KSwtStyleVertical)
       
  2570     //    iVerticalOrientation = ETrue;
       
  2571     //if( aLayout == KSwtStyleHorizontal )
       
  2572     //    iVerticalOrientation = EFalse;
       
  2573     //if( iVerticalOrientation != currentOrientation )
       
  2574     //    DoGridCellLayoutL( iDensity );
       
  2575 }
       
  2576 
       
  2577 // ---------------------------------------------------------------------------
       
  2578 // From class MSwtListView.
       
  2579 // ---------------------------------------------------------------------------
       
  2580 //
       
  2581 void CSwtListView::SetLayoutDensityL(TInt aDensity)
       
  2582 {
       
  2583     if (aDensity == iDensity)
       
  2584     {
       
  2585         return;
       
  2586     }
       
  2587 
       
  2588     switch (aDensity)
       
  2589     {
       
  2590     case 1:
       
  2591     {
       
  2592         iDensity = ELowListViewDensity;
       
  2593         break;
       
  2594     }
       
  2595     case 2:
       
  2596     {
       
  2597         iDensity = EMediumListViewDensity;
       
  2598         break;
       
  2599     }
       
  2600     case 3:
       
  2601     {
       
  2602         iDensity = EHighListViewDensity;
       
  2603         break;
       
  2604     }
       
  2605     default:
       
  2606     {
       
  2607         break;
       
  2608     }
       
  2609     }
       
  2610     DoGridCellLayoutL(iDensity);
       
  2611     ScrollViewToShowAsManyItemsAsPossibleL();
       
  2612     Redraw();
       
  2613     UpdateControlMenu();
       
  2614 }
       
  2615 
       
  2616 // ---------------------------------------------------------------------------
       
  2617 // From class MSwtListView.
       
  2618 // ---------------------------------------------------------------------------
       
  2619 //
       
  2620 void CSwtListView::ShowSelection()
       
  2621 {
       
  2622     const CAknGridView::CSelectionIndexArray& indexArray = *(iGrid->SelectionIndexes());
       
  2623     if (indexArray.Count() > 0)
       
  2624     {
       
  2625         // Make the first selected item visible in case there are many
       
  2626         iGrid->ScrollToMakeItemVisible(indexArray[ 0 ]);
       
  2627     }
       
  2628 
       
  2629     UpdateControlMenu();
       
  2630     Redraw();
       
  2631 }
       
  2632 
       
  2633 // ---------------------------------------------------------------------------
       
  2634 // From class ASwtScrollableBase
       
  2635 // ---------------------------------------------------------------------------
       
  2636 //
       
  2637 CEikScrollBarFrame* CSwtListView::SbFrame() const
       
  2638 {
       
  2639     return (iGrid ? iGrid->ScrollBarFrame() : NULL);
       
  2640 }
       
  2641 
       
  2642 // ---------------------------------------------------------------------------
       
  2643 // From class MSwtControl.
       
  2644 // ---------------------------------------------------------------------------
       
  2645 //
       
  2646 CCoeControl& CSwtListView::CoeControl()
       
  2647 {
       
  2648     return *this;
       
  2649 }
       
  2650 
       
  2651 // ---------------------------------------------------------------------------
       
  2652 // From class MSwtControl.
       
  2653 // ---------------------------------------------------------------------------
       
  2654 //
       
  2655 const CCoeControl& CSwtListView::CoeControl() const
       
  2656 {
       
  2657     return *this;
       
  2658 }
       
  2659 
       
  2660 // ---------------------------------------------------------------------------
       
  2661 // From class MSwtControl.
       
  2662 // ---------------------------------------------------------------------------
       
  2663 //
       
  2664 void CSwtListView::ProcessKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
       
  2665 {
       
  2666 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2667     if (aType == EEventKeyDown)
       
  2668     {
       
  2669         // After panning focus highlight was disabled, so enabling again
       
  2670         EnableFocusHighlight(ETrue);
       
  2671     }
       
  2672 #endif //RD_JAVA_S60_RELEASE_9_2
       
  2673 
       
  2674     if (GetItemCount() == 0)
       
  2675     {
       
  2676         iGrid->OfferKeyEventL(aKeyEvent, aType);
       
  2677         return;
       
  2678     }
       
  2679 
       
  2680     if (!(iStyle & KSwtStyleMulti))
       
  2681     {
       
  2682         if (aKeyEvent.iCode == EKeyOK || aKeyEvent.iCode == EKeyEnter)
       
  2683         {
       
  2684             // Send default selection event.
       
  2685             iDisplay.PostDefaultSelectionEventL(iPeer);
       
  2686         }
       
  2687         else
       
  2688         {
       
  2689             iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
       
  2690 
       
  2691             iGrid->OfferKeyEventL(aKeyEvent, aType);
       
  2692 
       
  2693             // Post an event if the selected item has changed
       
  2694             if (iPrevFocusIndex != GetSelectionL(iGrid->CurrentDataIndex()))
       
  2695             {
       
  2696                 SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  2697                 // its workaround to fix the problem in ListView items name changing when
       
  2698                 //they get focus in mirrored layout. it should be fixed in avkon
       
  2699                 // CListBoxView::VerticalMoveToItemL. Remove below Redraw() after fixing.
       
  2700                 if (!iLeftToRight)
       
  2701                 {
       
  2702                     Redraw();
       
  2703                 }
       
  2704                 iDisplay.PostSelectionEventL(iPeer);
       
  2705             }
       
  2706         }
       
  2707     }
       
  2708     else  // Multi-style
       
  2709     {
       
  2710         GetSelection(iOldSelectionArray);
       
  2711 
       
  2712         iGrid->OfferKeyEventL(aKeyEvent, aType);
       
  2713 
       
  2714         if (aType == EEventKeyUp)
       
  2715         {
       
  2716             UpdateControlMenu();
       
  2717         }
       
  2718 
       
  2719         // Post an event if selection has changed.
       
  2720         if (iOldSelectionArray->Count() != iGrid->SelectionIndexes()->Count())
       
  2721         {
       
  2722             iDisplay.PostSelectionEventL(iPeer);
       
  2723         }
       
  2724         else
       
  2725         {
       
  2726             for (TInt i = 0; i < iOldSelectionArray->Count(); ++i)
       
  2727             {
       
  2728                 if (!IsSelected(iOldSelectionArray->At(i)))
       
  2729                 {
       
  2730                     iDisplay.PostSelectionEventL(iPeer);
       
  2731                     return;
       
  2732                 }
       
  2733             }
       
  2734         }
       
  2735     }
       
  2736     iOldSelectionArray->Reset();
       
  2737 }
       
  2738 
       
  2739 // ---------------------------------------------------------------------------
       
  2740 // From class MSwtControl.
       
  2741 // Returns the color set by the user if it exists.
       
  2742 // ---------------------------------------------------------------------------
       
  2743 //
       
  2744 TRgb CSwtListView::GetBackground() const
       
  2745 {
       
  2746     if (iBgColor)
       
  2747     {
       
  2748         return TRgb(iBgColor->RgbValue());
       
  2749     }
       
  2750     else
       
  2751     {
       
  2752         return ASwtControlBase::GetBackground();
       
  2753     }
       
  2754 }
       
  2755 
       
  2756 // ---------------------------------------------------------------------------
       
  2757 // From class MSwtControl.
       
  2758 // The normal text color is returned.
       
  2759 // Highlighted (focused) text might have a different color.
       
  2760 // ---------------------------------------------------------------------------
       
  2761 //
       
  2762 TRgb CSwtListView::GetForeground() const
       
  2763 {
       
  2764     return iGrid->ItemDrawer()->FormattedCellData()->SubCellColors(KTextColumn).iText;
       
  2765 }
       
  2766 
       
  2767 // ---------------------------------------------------------------------------
       
  2768 // From class MSwtControl.
       
  2769 // Background color is not currently used for anything besides being returned
       
  2770 // from GetBackGround.
       
  2771 // ---------------------------------------------------------------------------
       
  2772 //
       
  2773 void CSwtListView::SetBackgroundL(const MSwtColor* aColor)
       
  2774 {
       
  2775     iBgColor = aColor;
       
  2776 }
       
  2777 
       
  2778 // ---------------------------------------------------------------------------
       
  2779 // From class MSwtControl.
       
  2780 // ---------------------------------------------------------------------------
       
  2781 //
       
  2782 void CSwtListView::SetForegroundL(const MSwtColor* aColor)
       
  2783 {
       
  2784     iTextColor = aColor;
       
  2785     UpdateTextColorL();
       
  2786     Redraw();
       
  2787 }
       
  2788 
       
  2789 // ---------------------------------------------------------------------------
       
  2790 // From class MSwtControl.
       
  2791 // The preferred size is the top-level-shell's client area size.
       
  2792 // If hints are given then the preferred size is the closest full column
       
  2793 // and/or row. But not larger than the top-level-shell client area and not
       
  2794 // smaller than 1x1. Parent size or contents don't affect the preferred
       
  2795 // size.
       
  2796 // ---------------------------------------------------------------------------
       
  2797 //
       
  2798 TSize CSwtListView::ComputeSizeL(TInt aWHint, TInt aHHint)
       
  2799 {
       
  2800     TSize preferredSize(aWHint, aHHint);
       
  2801 
       
  2802     if (aWHint != KSwtDefault && aHHint != KSwtDefault)
       
  2803     {
       
  2804         return preferredSize;
       
  2805     }
       
  2806 
       
  2807     TSize cellSize = GetCellSize();
       
  2808     TUint itemCount = GetItemCount();
       
  2809     TUint columnCount = 0;
       
  2810     TUint rowCount = 0;
       
  2811 
       
  2812     if (aHHint != KSwtDefault)
       
  2813     {
       
  2814         // Height is set, calculate needed number of columns.
       
  2815         if (cellSize.iHeight != 0)
       
  2816         {
       
  2817             rowCount = aHHint / cellSize.iHeight;
       
  2818         }
       
  2819 
       
  2820         columnCount = GetRowColumnCount(itemCount, rowCount);
       
  2821 
       
  2822         preferredSize.iWidth = columnCount * cellSize.iWidth;
       
  2823         preferredSize.iWidth += GetBorderSize(KSwtStyleHorizontal);
       
  2824     }
       
  2825     else if (aWHint != KSwtDefault)
       
  2826     {
       
  2827         // Width is set, calculate needed number of rows.
       
  2828         if (cellSize.iWidth != 0)
       
  2829         {
       
  2830             columnCount = aWHint / cellSize.iWidth;
       
  2831         }
       
  2832 
       
  2833         rowCount = GetRowColumnCount(itemCount, columnCount);
       
  2834 
       
  2835         preferredSize.iHeight = rowCount * cellSize.iHeight;
       
  2836         preferredSize.iHeight += GetBorderSize(KSwtStyleVertical);
       
  2837     }
       
  2838     else
       
  2839     {
       
  2840         // Width and height are not set
       
  2841         columnCount = ISqrt(itemCount);
       
  2842 
       
  2843         rowCount = GetRowColumnCount(itemCount, columnCount);
       
  2844 
       
  2845         preferredSize.iWidth = columnCount * cellSize.iWidth;
       
  2846         preferredSize.iWidth += GetBorderSize(KSwtStyleHorizontal);
       
  2847         preferredSize.iHeight = rowCount * cellSize.iHeight;
       
  2848         preferredSize.iHeight += GetBorderSize(KSwtStyleVertical);
       
  2849     }
       
  2850 
       
  2851     // Workaround for case where listview in a layout has no borders and no items.
       
  2852     // In such a case preferred size is 0*0 pixels, which causes problems when
       
  2853     // laying out the layout.
       
  2854     if (preferredSize.iWidth <= 0 && preferredSize.iHeight <= 0)
       
  2855     {
       
  2856         preferredSize.iHeight = 1;
       
  2857         preferredSize.iWidth = 1;
       
  2858     }
       
  2859 
       
  2860     return preferredSize;
       
  2861 }
       
  2862 
       
  2863 // ---------------------------------------------------------------------------
       
  2864 // Returns number of rows/columns needed on a list with aItemCount items and
       
  2865 // aRowColumnCount rows/columns.
       
  2866 // ---------------------------------------------------------------------------
       
  2867 //
       
  2868 TInt CSwtListView::GetRowColumnCount(const TInt& aItemCount, const TInt& aRowColumnCount) const
       
  2869 {
       
  2870     TInt rowsColumns = 0;
       
  2871 
       
  2872     if (aRowColumnCount > 0)
       
  2873     {
       
  2874         rowsColumns = (aItemCount / aRowColumnCount);
       
  2875         if ((aItemCount % aRowColumnCount) * GetCellSize().iWidth > KRowCalculationPrecisionInPixels)
       
  2876         {
       
  2877             // itemCount/rowColumnCount division returns the number of
       
  2878             // full columns, so an additional one may be needed.
       
  2879             rowsColumns++;
       
  2880         }
       
  2881     }
       
  2882 
       
  2883     return rowsColumns;
       
  2884 }
       
  2885 
       
  2886 
       
  2887 void CSwtListView::UpdateMSKLabelL()
       
  2888 {
       
  2889     if (AknLayoutUtils::MSKEnabled() && !HasDoNotDrawFlag())
       
  2890     {
       
  2891         MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
       
  2892         if (commandArranger)
       
  2893         {
       
  2894             commandArranger->UpdateMSKLabelL();
       
  2895         }
       
  2896     }
       
  2897 }
       
  2898 
       
  2899 // ---------------------------------------------------------------------------
       
  2900 // Returns horizontal or vertical border size for a list cell.
       
  2901 // ---------------------------------------------------------------------------
       
  2902 //
       
  2903 TInt CSwtListView::GetBorderSize(const TInt& aAlignment) const
       
  2904 {
       
  2905     ASSERT(aAlignment == KSwtStyleHorizontal || aAlignment == KSwtStyleVertical);
       
  2906 
       
  2907     TInt borderSize = GetBorderWidth() + GetBorderWidth();
       
  2908 
       
  2909     if (aAlignment == KSwtStyleHorizontal)
       
  2910     {
       
  2911         // Horizontal borders, i.e. vertical scrollbar
       
  2912 
       
  2913         // Vertical scrollbar exists always
       
  2914         //if( SbFrame()->ScrollBarExists( CEikScrollBar::EVertical ) &&
       
  2915         //    SbFrame()->ScrollBarVisibility( CEikScrollBar::EVertical) != CEikScrollBarFrame::EOff )
       
  2916         //    {
       
  2917         borderSize += iDisplay.UiUtils().ScrollBarBreadth(SbFrame()->VerticalScrollBar());
       
  2918         //    }
       
  2919     }
       
  2920     else
       
  2921     {
       
  2922         if (SbFrame()->ScrollBarExists(CEikScrollBar::EHorizontal) &&
       
  2923                 SbFrame()->ScrollBarVisibility(CEikScrollBar::EHorizontal) != CEikScrollBarFrame::EOff)
       
  2924         {
       
  2925             borderSize += iDisplay.UiUtils().ScrollBarBreadth(
       
  2926                               SbFrame()->GetScrollBarHandle(CEikScrollBar::EHorizontal));
       
  2927         }
       
  2928     }
       
  2929 
       
  2930     return borderSize;
       
  2931 }
       
  2932 
       
  2933 // ---------------------------------------------------------------------------
       
  2934 // From MSwtControl.
       
  2935 // ---------------------------------------------------------------------------
       
  2936 //
       
  2937 TBool CSwtListView::IsKeyUsed(TUint aKeyCode) const
       
  2938 {
       
  2939     // Does not use the Backspace but uses OK key
       
  2940     if (aKeyCode == EKeyBackspace)
       
  2941     {
       
  2942         return EFalse;
       
  2943     }
       
  2944     else if (aKeyCode == EKeyOK || aKeyCode == EKeyEnter)
       
  2945     {
       
  2946         MSwtCommandArranger* commandArranger = iDisplay.CommandArranger();
       
  2947         if (commandArranger)
       
  2948         {
       
  2949             if (iStyle & KSwtStyleSingle &&
       
  2950                     commandArranger->IsContextSensitiveOperationSet())
       
  2951             {
       
  2952                 return EFalse;
       
  2953             }
       
  2954         }
       
  2955         return ETrue;
       
  2956     }
       
  2957     return ETrue;
       
  2958 }
       
  2959 
       
  2960 TBool CSwtListView::MSKSelCmdEnabled() const
       
  2961 {
       
  2962     return ETrue;
       
  2963 }
       
  2964 
       
  2965 // ---------------------------------------------------------------------------
       
  2966 // From class MSwtControl.
       
  2967 // Return the control menu to the menu arranger
       
  2968 // ---------------------------------------------------------------------------
       
  2969 //
       
  2970 const MSwtMenu* CSwtListView::GetControlMenu() const
       
  2971 {
       
  2972     return iMenu;
       
  2973 }
       
  2974 
       
  2975 // ---------------------------------------------------------------------------
       
  2976 // From class MSwtControl.
       
  2977 // ---------------------------------------------------------------------------
       
  2978 //
       
  2979 void CSwtListView::UpdateDoNotDrawFlag()
       
  2980 {
       
  2981     ASwtControlBase::UpdateDoNotDrawFlag();
       
  2982 
       
  2983     // Update redrawing state of the compound control also.
       
  2984     if (iGrid)
       
  2985     {
       
  2986         GetGridView()->SetDisableRedraw(HasDoNotDrawFlag());
       
  2987     }
       
  2988 }
       
  2989 
       
  2990 // ---------------------------------------------------------------------------
       
  2991 // From class MSwtControl.
       
  2992 // ---------------------------------------------------------------------------
       
  2993 //
       
  2994 HBufC* CSwtListView::MSKLabelL() const
       
  2995 {
       
  2996     if (!(GetItemCount() > 0))
       
  2997     {
       
  2998         return ASwtControlBase::MSKLabelL();
       
  2999     }
       
  3000 
       
  3001     if ((iStyle & KSwtStyleSingle))
       
  3002     {
       
  3003         HBufC* label = iEikonEnv->AllocReadResourceL(R_QTN_MSK_SELECT);
       
  3004         return label;
       
  3005     }
       
  3006     return ASwtControlBase::MSKLabelL();
       
  3007 }
       
  3008 
       
  3009 // ---------------------------------------------------------------------------
       
  3010 // From class MEikCommandObserver
       
  3011 // ---------------------------------------------------------------------------
       
  3012 void CSwtListView::ProcessCommandL(TInt aCmdId)
       
  3013 {
       
  3014     TInt focusIndex = GetFocusIndex();
       
  3015     switch (aCmdId)
       
  3016     {
       
  3017     case EAknCmdMark:
       
  3018         if (focusIndex != -1)
       
  3019         {
       
  3020             if (IsSelected(focusIndex))
       
  3021             {
       
  3022                 DeselectItem(focusIndex);
       
  3023             }
       
  3024             else
       
  3025             {
       
  3026                 SelectItemL(focusIndex, true);
       
  3027             }
       
  3028             iDisplay.PostSelectionEventL(iPeer);
       
  3029         }
       
  3030         break;
       
  3031     case EAknMarkAll:
       
  3032         SelectAllL();
       
  3033         iDisplay.PostSelectionEventL(iPeer);
       
  3034         break;
       
  3035     case EAknUnmarkAll:
       
  3036         DeselectAll();
       
  3037         iDisplay.PostSelectionEventL(iPeer);
       
  3038         break;
       
  3039     default:
       
  3040         ASSERT(EFalse);
       
  3041         break;
       
  3042     }
       
  3043 }
       
  3044 
       
  3045 // ---------------------------------------------------------------------------
       
  3046 // CSwtListView::HandleListBoxEventL
       
  3047 // From MEikListBoxObserver
       
  3048 // Handles default selection for touch. Unable to handle the selection events
       
  3049 // here since EEventItemClicked is not always sent for every tap.
       
  3050 // The selection events are handled in HandlePointerEvent.
       
  3051 // ---------------------------------------------------------------------------
       
  3052 //
       
  3053 #ifdef RD_SCALABLE_UI_V2
       
  3054 void CSwtListView::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType)
       
  3055 {
       
  3056     if (aListBox != iGrid)
       
  3057     {
       
  3058         return;
       
  3059     }
       
  3060 
       
  3061     UpdateFlickScrollingState(aEventType);
       
  3062 
       
  3063     switch (aEventType)
       
  3064     {
       
  3065         // On 5.0, drawing trough Java gives simply a better fps.
       
  3066 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3067     case EEventPanningStarted:
       
  3068         GetShell().SetUrgentPaintControl(this);
       
  3069         break;
       
  3070     case EEventFlickStopped:
       
  3071         GetShell().SetUrgentPaintControl(NULL);
       
  3072         break;
       
  3073 #endif // RD_JAVA_S60_RELEASE_9_2
       
  3074 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3075     case EEventItemSingleClicked:
       
  3076 #else
       
  3077     case EEventItemDoubleClicked:
       
  3078 #endif // RD_JAVA_S60_RELEASE_9_2
       
  3079         if (!(iStyle & KSwtStyleMulti))
       
  3080         {
       
  3081             if (!iDisplay.RevertPointerEvent())
       
  3082             {
       
  3083                 // Ensure the selection and focus index are in sync.
       
  3084                 SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  3085 
       
  3086                 iDisplay.PostDefaultSelectionEventL(iPeer);
       
  3087             }
       
  3088         }
       
  3089         break;
       
  3090     default:
       
  3091         // Do nothing
       
  3092         break;
       
  3093     }
       
  3094 }
       
  3095 #else //RD_SCALABLE_UI_V2
       
  3096 void CSwtListView::HandleListBoxEventL(CEikListBox*, TListBoxEvent)
       
  3097 {
       
  3098 }
       
  3099 #endif //RD_SCALABLE_UI_V2
       
  3100 
       
  3101 // ---------------------------------------------------------------------------
       
  3102 // A fairly fast integer square root algorithm
       
  3103 // ---------------------------------------------------------------------------
       
  3104 TUint CSwtListView::ISqrt(TUint x)
       
  3105 {
       
  3106     TUint r, nr, m;
       
  3107 
       
  3108     r = 0;
       
  3109     m = 0x40000000;
       
  3110 
       
  3111     do
       
  3112     {
       
  3113         nr = r + m;
       
  3114         if (nr <= x)
       
  3115         {
       
  3116             x -= nr;
       
  3117             r = nr + m;
       
  3118         }
       
  3119         r >>= 1;
       
  3120         m >>= 2;
       
  3121     }
       
  3122     while (m != 0);
       
  3123 
       
  3124     if (x > r)
       
  3125     {
       
  3126         r++;
       
  3127     }
       
  3128 
       
  3129     return r;
       
  3130 }
       
  3131 
       
  3132 // ---------------------------------------------------------------------------
       
  3133 // Update text and icon counters for a given item.
       
  3134 // ---------------------------------------------------------------------------
       
  3135 //
       
  3136 void CSwtListView::UpdateRemovedItemCountersL(const TInt& aIndex)
       
  3137 {
       
  3138     ASSERT(aIndex >= 0 && aIndex < GetItemCount());
       
  3139 
       
  3140     TInt textChange = 0;
       
  3141     TInt iconChange = 0;
       
  3142     TPtrC caption;
       
  3143     CGulIcon* icon = (*GetIconArray())[ ItemIconIndex(aIndex)];
       
  3144 
       
  3145     // Does the item have a caption
       
  3146     GetCaption(aIndex, caption);
       
  3147     if (caption.Length() != 0)
       
  3148     {
       
  3149         textChange = -1;
       
  3150     }
       
  3151 
       
  3152     // Does the item have an icon
       
  3153     TSize iconSize = icon->Bitmap()->SizeInPixels();
       
  3154     if (iconSize.iHeight != 0 && iconSize.iWidth != 0)
       
  3155     {
       
  3156         // Icon size is not (0,0) conclude that icon was set.
       
  3157         iconChange = -1;
       
  3158     }
       
  3159 
       
  3160     if (textChange || iconChange)
       
  3161     {
       
  3162         UpdateSetItemCount(textChange, iconChange);
       
  3163         DoGridCellLayoutIfNeededL();
       
  3164     }
       
  3165 }
       
  3166 
       
  3167 // ---------------------------------------------------------------------------
       
  3168 // Update counters for items that have icon/text, and set update cell layout
       
  3169 // status.
       
  3170 // ---------------------------------------------------------------------------
       
  3171 void CSwtListView::UpdateSetItemCount(const TInt& aTextChange, const TInt& aIconChange)
       
  3172 {
       
  3173     TBool layoutNeeded = EFalse;
       
  3174 
       
  3175     // An item that has a text has changed (added or removed)
       
  3176     if (aTextChange)
       
  3177     {
       
  3178         iNumberOfTexts += aTextChange;
       
  3179 
       
  3180         if (iNumberOfTexts < 0)
       
  3181         {
       
  3182             // Just in case..
       
  3183             iNumberOfTexts = 0;
       
  3184         }
       
  3185 
       
  3186         // If we are going from 0->n or from n->0, layout is needed.
       
  3187         if ((aTextChange < 0 && iNumberOfTexts == 0) ||
       
  3188                 (aTextChange > 0 && iNumberOfTexts == 1))
       
  3189         {
       
  3190             layoutNeeded = ETrue;
       
  3191         }
       
  3192     }
       
  3193 
       
  3194     // An item that has an icon has changed (added or removed)
       
  3195     if (aIconChange)
       
  3196     {
       
  3197         iNumberOfIcons += aIconChange;
       
  3198 
       
  3199         if (iNumberOfIcons < 0)
       
  3200         {
       
  3201             iNumberOfIcons = 0;
       
  3202         }
       
  3203 
       
  3204         if ((aIconChange < 0 && iNumberOfIcons == 0) ||
       
  3205                 (aIconChange > 0 && iNumberOfIcons == 1))
       
  3206         {
       
  3207             layoutNeeded = ETrue;
       
  3208         }
       
  3209     }
       
  3210 
       
  3211     // Layout change is needed if we have e.g. gone from a state where there
       
  3212     // are no items that have an icon on the list (i.e. texts are centered on
       
  3213     // list items) to a state where an item has an icon (and texts need to be
       
  3214     // laid out to the bottom of the items leaving space for the icon).
       
  3215     iIsGridCellLayoutNeeded = layoutNeeded;
       
  3216 }
       
  3217 
       
  3218 
       
  3219 // ---------------------------------------------------------------------------
       
  3220 // Update cell layout if needed
       
  3221 // ---------------------------------------------------------------------------
       
  3222 //
       
  3223 void CSwtListView::DoGridCellLayoutIfNeededL()
       
  3224 {
       
  3225     if (iIsGridCellLayoutNeeded)
       
  3226     {
       
  3227         DoGridCellLayoutL(iDensity);
       
  3228         iIsGridCellLayoutNeeded = EFalse;
       
  3229     }
       
  3230 }
       
  3231 
       
  3232 // ---------------------------------------------------------------------------
       
  3233 // Gets cell and subcell LAF variants for current orientation and density
       
  3234 // ---------------------------------------------------------------------------
       
  3235 //
       
  3236 void CSwtListView::GetCellVariants(const TSwtListViewDensity& aDensity,
       
  3237                                    TInt& aCellVariant, TInt& aSubcellVariantG1, TInt& aSubcellVariantG2,
       
  3238                                    TInt& aSubcellVariantT) const
       
  3239 {
       
  3240     if (CSwtLafFacade::IsLandscapeOrientation())
       
  3241     {
       
  3242         // Landscape orientation
       
  3243 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3244         switch (aDensity)
       
  3245         {
       
  3246         case EHighListViewDensity:
       
  3247             // 5x4
       
  3248             aCellVariant = 6;
       
  3249             aSubcellVariantG1 = 6;
       
  3250             aSubcellVariantG2 = 6;
       
  3251             aSubcellVariantT = 5;
       
  3252             break;
       
  3253         case ELowListViewDensity:
       
  3254             // 3x2
       
  3255             aCellVariant = 2;
       
  3256             aSubcellVariantG1 = 1;
       
  3257             aSubcellVariantG2 = 1;
       
  3258             aSubcellVariantT = 1;
       
  3259             break;
       
  3260         default:
       
  3261             // 6x2
       
  3262             aCellVariant = 3;
       
  3263             aSubcellVariantG1 = 3;
       
  3264             aSubcellVariantG2 = 1;
       
  3265             aSubcellVariantT = 3;
       
  3266             break;
       
  3267         }
       
  3268 #else
       
  3269         switch (aDensity)
       
  3270         {
       
  3271         case EHighListViewDensity:
       
  3272             // 5x4
       
  3273             aCellVariant = 6;
       
  3274             aSubcellVariantG1 = 6;
       
  3275             aSubcellVariantG2 = 6;
       
  3276             aSubcellVariantT = 5;
       
  3277             break;
       
  3278         case ELowListViewDensity:
       
  3279             // 3x2
       
  3280             aCellVariant = 2;
       
  3281             aSubcellVariantG1 = 1;
       
  3282             aSubcellVariantG2 = 1;
       
  3283             aSubcellVariantT = 1;
       
  3284             break;
       
  3285         default:
       
  3286             // 4x3
       
  3287             aCellVariant = 4;
       
  3288             aSubcellVariantG1 = 0;
       
  3289             aSubcellVariantG2 = 0;
       
  3290             aSubcellVariantT = 0;
       
  3291             break;
       
  3292         }
       
  3293 #endif
       
  3294     }
       
  3295     else
       
  3296     {
       
  3297         // Portrait orientation
       
  3298         switch (aDensity)
       
  3299         {
       
  3300         case EHighListViewDensity:
       
  3301             // 4x5
       
  3302             aCellVariant = 5;
       
  3303             aSubcellVariantG1 = 6;
       
  3304             aSubcellVariantG2 = 6;
       
  3305             aSubcellVariantT = 5;
       
  3306             break;
       
  3307         case ELowListViewDensity:
       
  3308             // 2x3
       
  3309             aCellVariant = 1;
       
  3310             aSubcellVariantG1 = 1;
       
  3311             aSubcellVariantG2 = 1;
       
  3312             aSubcellVariantT = 1;
       
  3313             break;
       
  3314         default:
       
  3315             // 3x4
       
  3316             aCellVariant = 3;
       
  3317             aSubcellVariantG1 = 0;
       
  3318             aSubcellVariantG2 = 0;
       
  3319             aSubcellVariantT = 0;
       
  3320             break;
       
  3321         }
       
  3322     }
       
  3323 }
       
  3324 
       
  3325 // ---------------------------------------------------------------------------
       
  3326 // Store the sizes for all densities for getIconSize
       
  3327 // ---------------------------------------------------------------------------
       
  3328 //
       
  3329 void CSwtListView::UpdateIconSizes(const TSwtListViewDensity& aDensity,
       
  3330                                    const TRect& aCellRect)
       
  3331 {
       
  3332     TAknLayoutRect iconRect;
       
  3333     CSwtLafFacade::TSwtLafFacadeRectId rectIdPaneG1 = CSwtLafFacade::ECellHcAppPaneG1;
       
  3334 
       
  3335     // Low density
       
  3336     TInt subcellVariantG1Low = 1;
       
  3337     iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
       
  3338                                             subcellVariantG1Low);
       
  3339     iIconSizeInLowDensity.SetXY(iconRect.Rect().Width(),
       
  3340                                 iconRect.Rect().Height());
       
  3341 
       
  3342     // High density
       
  3343     TInt subcellVariantG1High = 6;
       
  3344     iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
       
  3345                                             subcellVariantG1High);
       
  3346     iIconSizeInHighDensity.SetXY(iconRect.Rect().Width(),
       
  3347                                  iconRect.Rect().Height());
       
  3348 
       
  3349     // Medium density
       
  3350     TInt subcellVariantG1Medium = 0;
       
  3351 
       
  3352 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3353     if (CSwtLafFacade::IsLandscapeOrientation())
       
  3354     {
       
  3355         switch (aDensity)
       
  3356         {
       
  3357         case EMediumListViewDensity:
       
  3358             subcellVariantG1Medium = 1;
       
  3359             rectIdPaneG1 = CSwtLafFacade::ECellAppPaneG1;
       
  3360             break;
       
  3361         }
       
  3362     }
       
  3363 #else
       
  3364     (void)aDensity; // Suppress compilation warning
       
  3365 #endif
       
  3366 
       
  3367     iconRect = CSwtLafFacade::GetLayoutRect(rectIdPaneG1, aCellRect,
       
  3368                                             subcellVariantG1Medium);
       
  3369     iIconSizeInMediumDensity.SetXY(iconRect.Rect().Width(),
       
  3370                                    iconRect.Rect().Height());
       
  3371 }
       
  3372 
       
  3373 // ---------------------------------------------------------------------------
       
  3374 // Gets layout rectangle IDs
       
  3375 // ---------------------------------------------------------------------------
       
  3376 //
       
  3377 void CSwtListView::GetLafFacadeRectIds(
       
  3378     const TSwtListViewDensity& aDensity,
       
  3379     CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPane,
       
  3380     CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPaneG1,
       
  3381     CSwtLafFacade::TSwtLafFacadeRectId& aRectIdPaneG2,
       
  3382     CSwtLafFacade::TSwtLafFacadeTextId& aRectIdPaneT1,
       
  3383     CSwtLafFacade::TSwtLafFacadeFontId& aRectIdPaneT1Font) const
       
  3384 {
       
  3385     aRectIdPane = CSwtLafFacade::ECellHcAppPane;
       
  3386     aRectIdPaneG1 = CSwtLafFacade::ECellHcAppPaneG1;
       
  3387     aRectIdPaneG2 = CSwtLafFacade::ECellHcAppPaneG2;
       
  3388     aRectIdPaneT1 = CSwtLafFacade::ECellHcAppPaneT1;
       
  3389     aRectIdPaneT1Font = CSwtLafFacade::ECellHcAppPaneT1Font;
       
  3390 
       
  3391 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3392     if (CSwtLafFacade::IsLandscapeOrientation())
       
  3393     {
       
  3394         switch (aDensity)
       
  3395         {
       
  3396         case EMediumListViewDensity:
       
  3397             aRectIdPane = CSwtLafFacade::ECellAppPane;
       
  3398             aRectIdPaneG1 = CSwtLafFacade::ECellAppPaneG1;
       
  3399             aRectIdPaneG2 = CSwtLafFacade::ECellAppPaneG2;
       
  3400             aRectIdPaneT1 = CSwtLafFacade::ECellAppPaneT1;
       
  3401             aRectIdPaneT1Font = CSwtLafFacade::ECellAppPaneT1Font;
       
  3402             break;
       
  3403         }
       
  3404     }
       
  3405 #else
       
  3406     (void)aDensity; // Suppress compilation warning
       
  3407 #endif
       
  3408 }
       
  3409 
       
  3410 
       
  3411 // ---------------------------------------------------------------------------
       
  3412 // Coerces cell rectangle to match native one
       
  3413 // ---------------------------------------------------------------------------
       
  3414 //
       
  3415 void CSwtListView::CoerceCellRect(const TSwtListViewDensity& aDensity, TRect& aCellRect) const
       
  3416 {
       
  3417 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3418     if (CSwtLafFacade::IsLandscapeOrientation())
       
  3419     {
       
  3420         switch (aDensity)
       
  3421         {
       
  3422         case EMediumListViewDensity:
       
  3423             aCellRect.iBr.iX -= 2;
       
  3424             break;
       
  3425         }
       
  3426     }
       
  3427 #else
       
  3428     (void)aDensity; // Suppress compilation warning
       
  3429     (void)aCellRect; // Suppress compilation warning
       
  3430 #endif
       
  3431 }
       
  3432 
       
  3433 
       
  3434 // ---------------------------------------------------------------------------
       
  3435 // CSwtListView::SetVisibleScrollBar
       
  3436 // From ASwtScrollableBase
       
  3437 // ---------------------------------------------------------------------------
       
  3438 //
       
  3439 void CSwtListView::SetVisibleScrollBar(TInt aStyle, TBool aVisible)
       
  3440 {
       
  3441     iGrid->SetScrollbarVisibility(aStyle, aVisible);
       
  3442     ASwtScrollableBase::SetVisibleScrollBar(aStyle, aVisible);
       
  3443 }
       
  3444 
       
  3445 // ---------------------------------------------------------------------------
       
  3446 // CSwtListView::ScrollBarDestroyed
       
  3447 // From ASwtScrollableBase
       
  3448 // ---------------------------------------------------------------------------
       
  3449 //
       
  3450 void CSwtListView::ScrollBarDestroyed(const MSwtScrollBar* aScrollBar)
       
  3451 {
       
  3452     if (aScrollBar == iHScroll)
       
  3453     {
       
  3454         iGrid->SetScrollbarVisibility(KSwtStyleHScroll, EFalse);
       
  3455     }
       
  3456     else
       
  3457     {
       
  3458         iGrid->SetScrollbarVisibility(KSwtStyleVScroll, EFalse);
       
  3459     }
       
  3460     ASwtScrollableBase::ScrollBarDestroyed(aScrollBar);
       
  3461 }
       
  3462 
       
  3463 #if defined( RD_SCALABLE_UI_V2)
       
  3464 // ---------------------------------------------------------------------------
       
  3465 // CSwtListView::HandleScrollEventL
       
  3466 // From ASwtScrollableBase
       
  3467 // ---------------------------------------------------------------------------
       
  3468 //
       
  3469 void CSwtListView::HandleScrollEventL(CEikScrollBar* aScrollBar,
       
  3470                                       TEikScrollEvent aEventType)
       
  3471 {
       
  3472     // On 5.0, drawing trough Java gives simply a better fps.
       
  3473 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3474     switch (aEventType)
       
  3475     {
       
  3476     case EEikScrollThumbDragVert:
       
  3477         GetShell().SetUrgentPaintControl(this);
       
  3478         break;
       
  3479     case EEikScrollThumbReleaseVert:
       
  3480         GetShell().SetUrgentPaintControl(NULL);
       
  3481         break;
       
  3482     default:
       
  3483         break;
       
  3484     }
       
  3485 #endif // RD_JAVA_S60_RELEASE_9_2
       
  3486 
       
  3487     iGrid->DoHandleScrollEventL(aScrollBar, aEventType);
       
  3488     ASwtScrollableBase::HandleScrollEventL(aScrollBar, aEventType);
       
  3489 }
       
  3490 
       
  3491 // ---------------------------------------------------------------------------
       
  3492 // CSwtListView::HandlePointerEventL
       
  3493 // From ASwtControlBase
       
  3494 // ---------------------------------------------------------------------------
       
  3495 //
       
  3496 void CSwtListView::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  3497 {
       
  3498     ASSERT(iGrid);
       
  3499 
       
  3500     CEikScrollBarFrame* sbFrame = iGrid->ScrollBarFrame();
       
  3501     CEikScrollBar* vsb = sbFrame ? sbFrame->GetScrollBarHandle(CEikScrollBar::EVertical) : NULL;
       
  3502 
       
  3503     // Check if we should start scrollbar grabbing
       
  3504     if (aPointerEvent.iType == TPointerEvent::EButton1Down && !iVScrollBarGrabsPointerEvents)
       
  3505     {
       
  3506         if (vsb && vsb->Rect().Contains(aPointerEvent.iPosition))
       
  3507         {
       
  3508             iVScrollBarGrabsPointerEvents = ETrue;
       
  3509         }
       
  3510     }
       
  3511 
       
  3512     // Deliver event to scrollbar
       
  3513     if (iVScrollBarGrabsPointerEvents && vsb)
       
  3514     {
       
  3515         if (!iFlickScrollingOngoing
       
  3516                 && aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  3517         {
       
  3518             // Scrollbar was tapped after scrolling stopped
       
  3519             // by itself, so no need to redirect events
       
  3520             iScrollbarPointerEventToListbox = EFalse;
       
  3521         }
       
  3522 
       
  3523         if (iScrollbarPointerEventToListbox)
       
  3524         {
       
  3525             // Stops kinetic scrolling when scrollbar is tapped
       
  3526             iGrid->ForwardPointerEventL(aPointerEvent);
       
  3527             // Continue delivering events until button up appears to prevent
       
  3528             // some unexpected behavior in both scrollbar and listbox
       
  3529             switch (aPointerEvent.iType)
       
  3530             {
       
  3531             case TPointerEvent::EButton1Up:
       
  3532                 iScrollbarPointerEventToListbox = EFalse;
       
  3533                 break;
       
  3534             }
       
  3535         }
       
  3536         else
       
  3537         {
       
  3538             // Handles scrollbar behavior
       
  3539             vsb->HandlePointerEventL(aPointerEvent);
       
  3540         }
       
  3541     }
       
  3542 
       
  3543     // Deliver event to list
       
  3544     if (!iVScrollBarGrabsPointerEvents)
       
  3545     {
       
  3546         // Store the selection on first pointer event.
       
  3547         if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  3548         {
       
  3549             if (iStyle & KSwtStyleMulti)
       
  3550             {
       
  3551                 // Multi lists
       
  3552                 ASSERT(iOldSelectionArray);
       
  3553                 GetSelection(iOldSelectionArray);
       
  3554             }
       
  3555             iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
       
  3556         }
       
  3557 
       
  3558         iGrid->HandlePointerEventL(aPointerEvent);
       
  3559 
       
  3560 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3561         // When flicking CEikListBox sets selection to 0 (during EDrag event).
       
  3562         // So eSWT has to reload the iPrevFocusIndex, otherwise it might scroll
       
  3563         // to the top of the ListView
       
  3564         if (aPointerEvent.iType == TPointerEvent::EDrag)
       
  3565         {
       
  3566             iPrevFocusIndex = GetSelectionL(iGrid->CurrentDataIndex());
       
  3567         }
       
  3568 #endif //RD_JAVA_S60_RELEASE_9_2
       
  3569 
       
  3570         if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  3571         {
       
  3572             TInt focusIndex = GetSelectionL(iGrid->CurrentDataIndex());
       
  3573 
       
  3574             if (iStyle & KSwtStyleMulti)
       
  3575             {
       
  3576                 // Multi lists
       
  3577                 if ((iGrid->SelectionIndexes()->Count() != iOldSelectionArray->Count()))
       
  3578                 {
       
  3579                     if (iDisplay.RevertPointerEvent())
       
  3580                     {
       
  3581                         // Revert.
       
  3582                         if (iGrid->View()->ItemIsSelected(focusIndex))
       
  3583                         {
       
  3584                             iGrid->View()->DeselectItem(focusIndex);
       
  3585                         }
       
  3586                         else
       
  3587                         {
       
  3588                             iGrid->View()->SelectItemL(focusIndex);
       
  3589                         }
       
  3590                     }
       
  3591                     else
       
  3592                     {
       
  3593                         iDisplay.PostSelectionEventL(iPeer);
       
  3594                     }
       
  3595                 }
       
  3596             }
       
  3597             else
       
  3598             {
       
  3599                 // Single lists
       
  3600                 // Compare the focus index after tap or drag ended
       
  3601                 if (focusIndex != iPrevFocusIndex)
       
  3602                 {
       
  3603                     // Ensure the selection and focus index are in sync.
       
  3604                     SingleSelectL(GetSelectionL(iGrid->CurrentDataIndex()), ETrue);
       
  3605 
       
  3606                     // Item focus highlight moved, send selection event.
       
  3607                     // Changing the focus index is not subject to reverting.
       
  3608                     iDisplay.PostSelectionEventL(iPeer);
       
  3609                 }
       
  3610 
       
  3611                 // The default selection is sent from HandleListBoxEventL!
       
  3612             }
       
  3613         }
       
  3614     }
       
  3615 
       
  3616     // Stop scrollbar grabbing
       
  3617     if (iVScrollBarGrabsPointerEvents
       
  3618             && aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  3619     {
       
  3620         iVScrollBarGrabsPointerEvents = EFalse;
       
  3621     }
       
  3622 
       
  3623     PostMouseEventL(aPointerEvent);
       
  3624 }
       
  3625 
       
  3626 // ---------------------------------------------------------------------------
       
  3627 // CSwtListView::GetStylusPopupControlMenu()
       
  3628 // From MSwtControl
       
  3629 // ---------------------------------------------------------------------------
       
  3630 //
       
  3631 const MSwtMenu* CSwtListView::GetStylusPopupControlMenu() const
       
  3632 {
       
  3633     return iStylusPopupMenu;
       
  3634 }
       
  3635 #endif // RD_SCALABLE_UI_V2
       
  3636 
       
  3637 
       
  3638 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3639 // ---------------------------------------------------------------------------
       
  3640 // CSwtListView::EnableFocusHighlight
       
  3641 // From MSwtControl
       
  3642 // ---------------------------------------------------------------------------
       
  3643 //
       
  3644 void CSwtListView::EnableFocusHighlight(TBool aEnable)
       
  3645 {
       
  3646     ASSERT(iGrid);
       
  3647     ASSERT(iGrid->View());
       
  3648 
       
  3649     CListItemDrawer* itemDrawer = iGrid->View()->ItemDrawer();
       
  3650     if (itemDrawer)
       
  3651     {
       
  3652         TInt disabledHighlight =
       
  3653             itemDrawer->Flags() & CListItemDrawer::EDisableHighlight;
       
  3654 
       
  3655         if (aEnable && disabledHighlight)
       
  3656         {
       
  3657             itemDrawer->ClearFlags(CListItemDrawer::EDisableHighlight);
       
  3658         }
       
  3659         else if (!aEnable && !disabledHighlight)
       
  3660         {
       
  3661             itemDrawer->SetFlags(CListItemDrawer::EDisableHighlight);
       
  3662         }
       
  3663     }
       
  3664 }
       
  3665 #endif //RD_JAVA_S60_RELEASE_9_2
       
  3666 
       
  3667 TInt CSwtListView::FocusBackgroundPolicy() const
       
  3668 {
       
  3669 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3670     return ENoFocusBackgroundInCaptionedControl;
       
  3671 #else
       
  3672     return EDefaultFocusBackground;
       
  3673 #endif // RD_JAVA_S60_RELEASE_9_2
       
  3674 }
       
  3675 
       
  3676 void CSwtListView::PrepareForTraverse()
       
  3677 {
       
  3678     ASSERT(iGrid);
       
  3679     ASSERT(iGrid->View());
       
  3680 
       
  3681 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  3682     // AvKon enables highlight only when key event is recieved.
       
  3683     // When traversing, no key event is sent to AvKon, so we
       
  3684     // have to enable highlight by ourselves.
       
  3685     CListItemDrawer* itemDrawer = iGrid->View()->ItemDrawer();
       
  3686     if (itemDrawer)
       
  3687     {
       
  3688         itemDrawer->ClearFlags(CListItemDrawer::ESingleClickDisabledHighlight);
       
  3689     }
       
  3690 #endif //RD_JAVA_S60_RELEASE_9_2
       
  3691 }
       
  3692 
       
  3693 #ifdef RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
  3694 void CSwtListView::DoControlSpecificFeedback(
       
  3695     const TBool& aFirstTap,
       
  3696     const TBool& aTappedToChildRect,
       
  3697     const TPointerEvent& aPointerEvent) const
       
  3698 {
       
  3699     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  3700     if (feedback && !aTappedToChildRect)
       
  3701     {
       
  3702         switch (aPointerEvent.iType)
       
  3703         {
       
  3704         case TPointerEvent::EButton1Down:
       
  3705             if (aFirstTap)
       
  3706             {
       
  3707                 feedback->InstantFeedback(ETouchFeedbackSensitiveList);
       
  3708             }
       
  3709             break;
       
  3710         }
       
  3711     }
       
  3712 }
       
  3713 #endif //RD_JAVA_ADVANCED_TACTILE_FEEDBACK
       
  3714 
       
  3715 // ---------------------------------------------------------------------------
       
  3716 // CSwtTableListBox::UpdateFlickScrollingState
       
  3717 // Updates flick scrolling status based on received listbox event.
       
  3718 // ---------------------------------------------------------------------------
       
  3719 //
       
  3720 void CSwtListView::UpdateFlickScrollingState(TListBoxEvent aEventType)
       
  3721 {
       
  3722     switch (aEventType)
       
  3723     {
       
  3724     case EEventFlickStarted:
       
  3725         iFlickScrollingOngoing = ETrue;
       
  3726         iScrollbarPointerEventToListbox = ETrue;
       
  3727         break;
       
  3728     case EEventFlickStopped:
       
  3729         iFlickScrollingOngoing = EFalse;
       
  3730         break;
       
  3731     }
       
  3732 }