javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtsortedlist.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     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 #include <aknenv.h>
       
    13 #include <aknlists.h>
       
    14 #include <eikclbd.h>
       
    15 #include <eikclb.h>
       
    16 #include "swtsortedlist.h"
       
    17 
       
    18 
       
    19 const TInt KSwtArrayGranularity = 4;
       
    20 const TInt KSwtSearchFieldTextLimit = 20;
       
    21 const TInt KSwtExtraWidthToDisplayCursorInArabicLayout = 1;
       
    22 
       
    23 
       
    24 // ======== MEMBER FUNCTIONS ========
       
    25 
       
    26 
       
    27 // ---------------------------------------------------------------------------
       
    28 // CSwtSortedList::NewL
       
    29 // ---------------------------------------------------------------------------
       
    30 //
       
    31 CSwtSortedList* CSwtSortedList::NewL(MSwtDisplay& aDisplay, TSwtPeer aPeer,
       
    32                                      MSwtComposite& aParent, TInt aStyle)
       
    33 {
       
    34     CSwtSortedList* self = new(ELeave) CSwtSortedList(
       
    35         aDisplay, aPeer, aParent, aStyle);
       
    36     CleanupStack::PushL(self);
       
    37     self->ConstructL();
       
    38     self->InitControlBaseL();
       
    39     CleanupStack::Pop(self);
       
    40     return self;
       
    41 }
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // CSwtSortedList::~CSwtSortedList
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CSwtSortedList::~CSwtSortedList()
       
    48 {
       
    49     delete iSearchField;
       
    50 }
       
    51 
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // CSwtSortedList::CSwtSortedList
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 CSwtSortedList::CSwtSortedList(MSwtDisplay& aDisplay, TSwtPeer aPeer,
       
    58                                MSwtComposite& aParent, TInt aStyle)
       
    59         : CSwtListBase(aDisplay, aPeer, aParent, aStyle)
       
    60 {
       
    61 }
       
    62 
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // CSwtSortedList::ConstructL
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 void CSwtSortedList::ConstructL()
       
    69 {
       
    70     if ((iStyle & KSwtStyleDown) != 0)
       
    71     {
       
    72         iIsOrderDown = ETrue;
       
    73     }
       
    74 
       
    75     CSwtListBase::ConstructL();
       
    76 }
       
    77 
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // CSwtSortedList::Filter
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 CAknListBoxFilterItems* CSwtSortedList::Filter() const
       
    84 {
       
    85     // The model created by CSwtListBoxSingle or
       
    86     // CSwtListBoxSingleGraphic is CAknFilteredTextListBoxModel.
       
    87     CAknFilteredTextListBoxModel* model = STATIC_CAST(
       
    88                                               CAknFilteredTextListBoxModel*,iList->Model());
       
    89     ASSERT(model);
       
    90 
       
    91     return model->Filter();
       
    92 }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // CSwtSortedList::InsertItemL
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void CSwtSortedList::InsertItemL(
       
    99     const TDesC &aPtr,
       
   100     CDesCArray* aItemArray,
       
   101     TKeyCmpText aTextComparisonType)
       
   102 {
       
   103     ASSERT(aItemArray != NULL);
       
   104     HBufC* itemText = CreateItemTextLC(aPtr);
       
   105     if (!iIsOrderDown)
       
   106     {
       
   107         aItemArray->InsertIsqAllowDuplicatesL(*itemText, aTextComparisonType);
       
   108         iTextItems->InsertIsqAllowDuplicatesL(aPtr, aTextComparisonType);
       
   109     }
       
   110     else
       
   111     {
       
   112         TInt ind(0);
       
   113         for (ind = 0; ind < iTextItems->Count(); ind++)
       
   114         {
       
   115             if ((*iTextItems)[ind].CompareC(aPtr) < 0)
       
   116             {
       
   117                 aItemArray->InsertL(ind, *itemText);
       
   118                 iTextItems->InsertL(ind, aPtr);
       
   119                 break;
       
   120             }
       
   121         }
       
   122         // If no item in list or if the item must be appended at the end of the list
       
   123         if (ind == iTextItems->Count())
       
   124         {
       
   125             aItemArray->AppendL(*itemText);
       
   126             iTextItems->AppendL(aPtr);
       
   127         }
       
   128     }
       
   129     CleanupStack::PopAndDestroy(itemText);
       
   130 
       
   131     UpdateListMskL();
       
   132 }
       
   133 
       
   134 // ---------------------------------------------------------------------------
       
   135 // CSwtSortedList::GetSelectionLC
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 CPtrCArray* CSwtSortedList::GetSelectionLC() const
       
   139 {
       
   140     const CArrayFix<TInt>* selectionIndexes = iList->View()->SelectionIndexes();
       
   141     if (!selectionIndexes)
       
   142     {
       
   143         return NULL;
       
   144     }
       
   145 
       
   146     TInt nbSelection(selectionIndexes->Count());
       
   147 
       
   148     CPtrCArray* selectedItemArray = new(ELeave) CPtrC16Array(KSwtArrayGranularity);
       
   149     CleanupStack::PushL(selectedItemArray);
       
   150     TInt selIndex;
       
   151     CAknListBoxFilterItems* filter = NULL;
       
   152     if (iSearchField)
       
   153     {
       
   154         filter = Filter();
       
   155     }
       
   156     for (TInt index=0; index<nbSelection; ++index)
       
   157     {
       
   158         selIndex = selectionIndexes->At(index);
       
   159         if (selIndex >= 0 && selIndex < iTextItems->Count())
       
   160         {
       
   161             if (iSearchField && filter)
       
   162             {
       
   163                 if (filter->FilteredNumberOfItems() > 0)// if there are visible items after filtering
       
   164                 {
       
   165                     selIndex = filter->FilteredItemIndex(selIndex);
       
   166                     selectedItemArray->AppendL((*iTextItems)[selIndex]);
       
   167                 }
       
   168             }
       
   169             else
       
   170             {
       
   171                 selectedItemArray->AppendL((*iTextItems)[selIndex]);
       
   172             }
       
   173         }
       
   174     }
       
   175     return selectedItemArray;
       
   176 }
       
   177 
       
   178 // ---------------------------------------------------------------------------
       
   179 // CSwtSortedList::HandleItemAdditionL
       
   180 // ---------------------------------------------------------------------------
       
   181 //
       
   182 void CSwtSortedList::HandleItemAdditionL(TInt aNewFocusIndex)
       
   183 {
       
   184     ASSERT(iList->View());
       
   185     ASSERT(iList->Model());
       
   186 
       
   187     SetTextMaxWidth(ComputeTextMaxWidth());
       
   188 
       
   189     if (iSearchField)
       
   190     {
       
   191         CAknListBoxFilterItems* filter = Filter();
       
   192         ASSERT(filter);
       
   193         filter->HandleItemArrayChangeL();
       
   194     }
       
   195     else
       
   196     {
       
   197         // S60 behavior: the new added item is the new focused item
       
   198         // and becomes the top item
       
   199         TInt newItemIndex(0);
       
   200         if ((aNewFocusIndex >= 0) && (aNewFocusIndex < iList->Model()->NumberOfItems()))
       
   201         {
       
   202             newItemIndex = aNewFocusIndex;
       
   203         }
       
   204 
       
   205         iList->SetCurrentItemIndex(newItemIndex);
       
   206 
       
   207         if (iList->CurrentItemIndex() >= 0)
       
   208         {
       
   209             iList->SetTopItemIndex(iList->CurrentItemIndex());
       
   210         }
       
   211 
       
   212         iList->HandleItemAdditionL();
       
   213     }
       
   214 
       
   215     // if we are in single selection, update the selection
       
   216     // to be the same as the current item index.
       
   217     if ((iStyle & KSwtStyleSingle) != 0)
       
   218     {
       
   219         iList->View()->UpdateSelectionL(CListBoxView::ESingleSelection);
       
   220     }
       
   221 
       
   222     UpdateListMskL();
       
   223 }
       
   224 
       
   225 // ---------------------------------------------------------------------------
       
   226 // CSwtSortedList::HandleItemRemovalL
       
   227 // ---------------------------------------------------------------------------
       
   228 //
       
   229 void CSwtSortedList::HandleItemRemovalL(
       
   230     const RArray<TInt>& aRemovedItemIndices,
       
   231     TInt aOldFocusIndex)
       
   232 {
       
   233     SetTextMaxWidth(ComputeTextMaxWidth());
       
   234 
       
   235     TInt newFocusIndex(0);
       
   236     if (aRemovedItemIndices.Count())
       
   237     {
       
   238         CalcFocusIndexAfterItemRemoval(
       
   239             newFocusIndex,
       
   240             aRemovedItemIndices,
       
   241             aOldFocusIndex);
       
   242     }
       
   243 
       
   244     ASSERT((newFocusIndex == 0)
       
   245            || ((newFocusIndex > 0)
       
   246                && (newFocusIndex < iList->Model()->NumberOfItems())));
       
   247     iList->SetCurrentItemIndex(newFocusIndex);
       
   248 
       
   249     iList->HandleItemRemovalL();
       
   250 
       
   251     // Filter update must happen after list update
       
   252     if (iSearchField)
       
   253     {
       
   254         CAknListBoxFilterItems* filter = Filter();
       
   255         ASSERT(filter);
       
   256         filter->HandleItemArrayChangeL();
       
   257     }
       
   258 
       
   259     // if we are in single selection, update the selection
       
   260     // to be the same as the current item index.
       
   261     if ((iStyle & KSwtStyleSingle) != 0)
       
   262     {
       
   263         iList->View()->UpdateSelectionL(CListBoxView::ESingleSelection);
       
   264     }
       
   265 
       
   266     UpdateListMskL();
       
   267 
       
   268     Redraw();
       
   269 }
       
   270 
       
   271 // ---------------------------------------------------------------------------
       
   272 // CSwtSortedList::HandleOfferKeyEventL
       
   273 // ---------------------------------------------------------------------------
       
   274 //
       
   275 void CSwtSortedList::HandleOfferKeyEventL()
       
   276 {
       
   277     if (iSearchField)
       
   278     {
       
   279         if (iStyle & KSwtStyleSingle)
       
   280         {
       
   281             const_cast<CListBoxView::CSelectionIndexArray*>(
       
   282                 iList->View()->SelectionIndexes())->Reset();
       
   283         }
       
   284 
       
   285         CAknListBoxFilterItems* filter = Filter();
       
   286         ASSERT(filter);
       
   287         filter->HandleOfferkeyEventL();
       
   288 
       
   289         if ((iStyle & KSwtStyleSingle) && iTextItems->Count() > 0)
       
   290         {
       
   291             iList->View()->SelectItemL(0);
       
   292         }
       
   293     }
       
   294 }
       
   295 
       
   296 // ---------------------------------------------------------------------------
       
   297 // CSwtSortedList::SearchFieldHeight
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 TInt CSwtSortedList::SearchFieldHeight() const
       
   301 {
       
   302     TInt searchHeight(0);
       
   303     if (iSearchField)
       
   304     {
       
   305         searchHeight = CSwtLafFacade::GetLayoutRect(
       
   306                            CSwtLafFacade::EFindPane, BorderInnerRect()).Rect().Height();
       
   307     }
       
   308     return searchHeight;
       
   309 }
       
   310 
       
   311 // ---------------------------------------------------------------------------
       
   312 // CSwtSortedList::GetSearchFieldPosition
       
   313 // ---------------------------------------------------------------------------
       
   314 //
       
   315 void CSwtSortedList::GetSearchFieldPosition(TPoint& aPosition)
       
   316 {
       
   317     TRect controlRect(BorderInnerRect());
       
   318     aPosition.iX = controlRect.iTl.iX;
       
   319     aPosition.iY = Max(0, controlRect.iBr.iY - SearchFieldHeight());
       
   320 }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // CSwtSortedList::SetSearchFieldSize
       
   324 // ---------------------------------------------------------------------------
       
   325 //
       
   326 void CSwtSortedList::GetSearchFieldSize(TSize& aSize)
       
   327 {
       
   328     TRect controlRect(BorderInnerRect());
       
   329     aSize.iWidth =  controlRect.Width();
       
   330     aSize.iHeight = Min(controlRect.Height(), SearchFieldHeight());
       
   331 }
       
   332 
       
   333 // ---------------------------------------------------------------------------
       
   334 // CSwtSortedList::SetSearchFieldSize
       
   335 // ---------------------------------------------------------------------------
       
   336 //
       
   337 void CSwtSortedList::UpdateSearchTextViewRect(const CAknSearchField* aSearchField)
       
   338 {
       
   339     if (aSearchField != NULL)
       
   340     {
       
   341         // Fix to display text cursor in Arabic layout
       
   342         TAknLayoutId currentLayoutId;
       
   343         CAknEnv::Static()->GetCurrentLayoutId(currentLayoutId);
       
   344         if (currentLayoutId == EAknLayoutIdABRW)
       
   345         {
       
   346             CTextView* textView = aSearchField->Editor().TextView();
       
   347             ASSERT(textView);
       
   348             TRect viewRect(textView->ViewRect());
       
   349             viewRect.iBr.iX += KSwtExtraWidthToDisplayCursorInArabicLayout;
       
   350             textView->SetViewRect(viewRect);
       
   351         }
       
   352     }
       
   353 }
       
   354 
       
   355 // ---------------------------------------------------------------------------
       
   356 // CSwtSortedList::UpdateSearchFieldBounds
       
   357 // ---------------------------------------------------------------------------
       
   358 //
       
   359 void CSwtSortedList::UpdateSearchFieldBounds()
       
   360 {
       
   361     TPoint pos;
       
   362     TSize size;
       
   363     GetSearchFieldPosition(pos);
       
   364     GetSearchFieldSize(size);
       
   365     iSearchField->SetExtent(pos, size);
       
   366     UpdateSearchTextViewRect(iSearchField);
       
   367 }
       
   368 
       
   369 // ---------------------------------------------------------------------------
       
   370 // CSwtSortedList::UpdateSize
       
   371 // From CSwtListBase
       
   372 // ---------------------------------------------------------------------------
       
   373 //
       
   374 void CSwtSortedList::UpdateSize()
       
   375 {
       
   376     TRect controlRect(BorderInnerRect());
       
   377 
       
   378     //Update the search field size if exists
       
   379     TInt listHeight(controlRect.Height());
       
   380     if (iSearchField != NULL)
       
   381     {
       
   382         listHeight = Max(0, listHeight - SearchFieldHeight());
       
   383         UpdateSearchFieldBounds();
       
   384     }
       
   385 
       
   386     iList->SetSize(TSize(controlRect.Width(), listHeight));
       
   387 }
       
   388 
       
   389 // ---------------------------------------------------------------------------
       
   390 // CSwtSortedList::CountComponentControls
       
   391 // From CCoeControl
       
   392 // ---------------------------------------------------------------------------
       
   393 //
       
   394 TInt CSwtSortedList::CountComponentControls() const
       
   395 {
       
   396     // The filter is orphaned to force its editor to draw CAknSearchField's 
       
   397     // background instead of our Shell's background.
       
   398     return 1;
       
   399 }
       
   400 
       
   401 // ---------------------------------------------------------------------------
       
   402 // CSwtSortedList::ComponentControl
       
   403 // From CCoeControl
       
   404 // ---------------------------------------------------------------------------
       
   405 //
       
   406 CCoeControl* CSwtSortedList::ComponentControl(TInt /*aIndex*/) const
       
   407 {
       
   408     // The filter is orphaned to force its editor to draw CAknSearchField's 
       
   409     // background instead of our Shell's background.
       
   410     return iList;
       
   411 }
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // CSwtSortedList::MakeVisible
       
   415 // From CCoeControl
       
   416 // ---------------------------------------------------------------------------
       
   417 //
       
   418 void CSwtSortedList::MakeVisible(TBool aVisible)
       
   419 {
       
   420     CCoeControl::MakeVisible(aVisible);
       
   421     FocusabilityChanged();
       
   422 
       
   423     // WORKAROUND START
       
   424     // There can be situations where the cursor is blinking even when the list
       
   425     // is not focused. This is yet another slow down but there is no other way
       
   426     // to avoid the strange behaviour. The cursor visibility setters are private.
       
   427     // Unfocusing the search field will also hide the cursor :)
       
   428     if (iSearchField && !IsFocused())
       
   429     {
       
   430         // Enforce no focus on the editor
       
   431         iSearchField->Editor().SetFocus(EFalse);
       
   432     }
       
   433     // WORKAROUND END
       
   434 }
       
   435 
       
   436 // ---------------------------------------------------------------------------
       
   437 // CSwtSortedList::SetDimmed
       
   438 // From CCoeControl
       
   439 // ---------------------------------------------------------------------------
       
   440 //
       
   441 void CSwtSortedList::SetDimmed(TBool aDimmed)
       
   442 {
       
   443     CCoeControl::SetDimmed(aDimmed);
       
   444     iList->SetDimmed(aDimmed);
       
   445     if (iSearchField)
       
   446     {
       
   447         iSearchField->SetDimmed(aDimmed);
       
   448     }
       
   449     FocusabilityChanged();
       
   450 }
       
   451 
       
   452 // ---------------------------------------------------------------------------
       
   453 // CSwtSortedList::HandleResourceChange
       
   454 // From CCoeControl
       
   455 // ---------------------------------------------------------------------------
       
   456 //
       
   457 void CSwtSortedList::HandleResourceChange(TInt aType)
       
   458 {
       
   459     if (aType == KAknsMessageSkinChange)
       
   460     {
       
   461         TRAP_IGNORE(CreateIconArrayL(iList));
       
   462     }
       
   463 
       
   464     CAknControl::HandleResourceChange(aType);
       
   465 }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // CSwtSortedList::HandlePointerEventL
       
   469 // From CCoeControl
       
   470 // ---------------------------------------------------------------------------
       
   471 //
       
   472 #ifdef RD_SCALABLE_UI_V2
       
   473 void CSwtSortedList::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   474 {
       
   475     // Check if we should start filter grabbing
       
   476     if (aPointerEvent.iType == TPointerEvent::EButton1Down
       
   477             && !iFilterGrabsPointerEvents)
       
   478     {
       
   479         if (iSearchField && iSearchField->Rect().Contains(aPointerEvent.iPosition))
       
   480         {
       
   481             iFilterGrabsPointerEvents = ETrue;
       
   482         }
       
   483     }
       
   484 
       
   485     // Deliver event to filter
       
   486     if (iFilterGrabsPointerEvents)
       
   487     {
       
   488         if (iSearchField)
       
   489         {
       
   490             iSearchField->HandlePointerEventL(aPointerEvent);
       
   491         }
       
   492     }
       
   493 
       
   494     // Check if we should stop filter grabbing
       
   495     if (aPointerEvent.iType == TPointerEvent::EButton1Up
       
   496             && iFilterGrabsPointerEvents)
       
   497     {
       
   498         iFilterGrabsPointerEvents = EFalse;
       
   499     }
       
   500 
       
   501     // Deliver event to list
       
   502     if (!iFilterGrabsPointerEvents)
       
   503     {
       
   504         CSwtListBase::HandlePointerEventL(aPointerEvent);
       
   505     }
       
   506 }
       
   507 #endif //RD_SCALABLE_UI_V2
       
   508 
       
   509 // ---------------------------------------------------------------------------
       
   510 // CSwtSortedList::PositionChanged
       
   511 // From CCoeControl
       
   512 // ---------------------------------------------------------------------------
       
   513 //
       
   514 void CSwtSortedList::PositionChanged()
       
   515 {
       
   516     //Update the search field size if exists
       
   517     if (iSearchField != NULL)
       
   518     {
       
   519         UpdateSearchFieldBounds();
       
   520     }
       
   521     CSwtListBase::PositionChanged();
       
   522 }
       
   523 
       
   524 // ---------------------------------------------------------------------------
       
   525 // CSwtSortedList::FocusChanged
       
   526 // From CCoeControl
       
   527 // ---------------------------------------------------------------------------
       
   528 //
       
   529 void CSwtSortedList::FocusChanged(TDrawNow aDrawNow)
       
   530 {
       
   531     TBool isFocused = IsFocused();
       
   532     if (iList)
       
   533     {
       
   534         iList->SetFocus(isFocused, aDrawNow);
       
   535         if (iSearchField)
       
   536         {
       
   537             iSearchField->Editor().SetFocus(isFocused);
       
   538         }
       
   539     }
       
   540     HandleFocusChanged(aDrawNow);
       
   541 }
       
   542 
       
   543 // ---------------------------------------------------------------------------
       
   544 // CSwtSortedList::ClientRect
       
   545 // From MSwtControl
       
   546 // ---------------------------------------------------------------------------
       
   547 //
       
   548 TRect CSwtSortedList::ClientRect() const
       
   549 {
       
   550     return SbInnerRect(iList->Rect());
       
   551 }
       
   552 
       
   553 // ---------------------------------------------------------------------------
       
   554 // CSwtSortedList::ComputeSizeL
       
   555 // From MSwtControl
       
   556 // ---------------------------------------------------------------------------
       
   557 //
       
   558 TSize CSwtSortedList::ComputeSizeL(TInt aWHint, TInt aHHint)
       
   559 {
       
   560     TSize preferredSize(aWHint, aHHint);
       
   561 
       
   562     if (aWHint == KSwtDefault)
       
   563     {
       
   564         preferredSize.iWidth = PreferredWidth();
       
   565     }
       
   566 
       
   567     if (aHHint == KSwtDefault)
       
   568     {
       
   569         preferredSize.iHeight = PreferredHeight();
       
   570         preferredSize.iHeight += SearchFieldHeight();
       
   571     }
       
   572 
       
   573     return preferredSize;
       
   574 }
       
   575 
       
   576 // ---------------------------------------------------------------------------
       
   577 // CSwtSortedList::ProcessKeyEventL
       
   578 // From MSwtControl
       
   579 // ---------------------------------------------------------------------------
       
   580 //
       
   581 void CSwtSortedList::ProcessKeyEventL(
       
   582     const TKeyEvent& aKeyEvent,
       
   583     TEventCode aType)
       
   584 {
       
   585     if (iSearchField != NULL)
       
   586     {
       
   587         TKeyResponse keyResponse = iSearchField->OfferKeyEventL(aKeyEvent, aType);
       
   588         if (keyResponse == EKeyWasConsumed)
       
   589         {
       
   590             HandleOfferKeyEventL();
       
   591             return;
       
   592         }
       
   593     }
       
   594 
       
   595     CSwtListBase::ProcessKeyEventL(aKeyEvent, aType);
       
   596 }
       
   597 
       
   598 // ---------------------------------------------------------------------------
       
   599 // CSwtSortedList::DoPaint
       
   600 // From MSwtControl
       
   601 // ---------------------------------------------------------------------------
       
   602 //
       
   603 void CSwtSortedList::DoPaint(const TRect& aRect) const
       
   604 {
       
   605     CSwtListBase::DoPaint(aRect);
       
   606     
       
   607     // The filter is orphaned to force its editor to draw CAknSearchField's 
       
   608     // background instead of our Shell's background. Therefore drawing must
       
   609     // be done 'manually'.
       
   610     if (iSearchField)
       
   611     {
       
   612         CWindowGc& gc = SystemGc();
       
   613         iSearchField->SetGc(&gc); // required by effects
       
   614         iSearchField->DrawBackground(aRect);
       
   615         iSearchField->DrawForeground(aRect);        
       
   616         DrawComponentControls(*iSearchField, aRect, gc, EFalse);
       
   617     }
       
   618 }
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // CSwtSortedList::ComputeTrim
       
   622 // From MSwtScrollable
       
   623 // ---------------------------------------------------------------------------
       
   624 //
       
   625 void CSwtSortedList::ComputeTrim(TRect& aRect) const
       
   626 {
       
   627     // Add list rect with scroll bars
       
   628     TRect outerRect(SbOuterRect(aRect));
       
   629     aRect.SetRect(outerRect.iTl, outerRect.Size());
       
   630 
       
   631     // Add the search field rect
       
   632     if (iSearchField != NULL)
       
   633     {
       
   634         TSize searchFieldMinSize(TSize(0, SearchFieldHeight()));
       
   635         TInt addWidth = searchFieldMinSize.iWidth - aRect.Width();
       
   636         aRect.Resize(addWidth>0 ? addWidth:0, searchFieldMinSize.iHeight);
       
   637     }
       
   638 
       
   639     // Add the borders
       
   640     TRect borderOuterRect(BorderOuterRect(aRect));
       
   641     aRect.SetRect(borderOuterRect.iTl, borderOuterRect.Size());
       
   642 }
       
   643 
       
   644 // ---------------------------------------------------------------------------
       
   645 // CSwtSortedList::AppendL
       
   646 // From MSwtSortedList
       
   647 // ---------------------------------------------------------------------------
       
   648 //
       
   649 void CSwtSortedList::AppendL(const TDesC& aPtr)
       
   650 {
       
   651     ASSERT(iTextItems);
       
   652 
       
   653     CPtrCArray* selectedItemArray = GetSelectionLC();
       
   654 
       
   655     InsertItemL(aPtr, STATIC_CAST(CDesCArray*, iList->Model()->ItemTextArray()));
       
   656 
       
   657     SetSelectionL(selectedItemArray);
       
   658     CleanupStack::PopAndDestroy(selectedItemArray);
       
   659 
       
   660     HandleItemAdditionL(iTextItems->Count()-1);
       
   661 }
       
   662 
       
   663 // ---------------------------------------------------------------------------
       
   664 // CSwtSortedList::GetFocusedItem
       
   665 // From MSwtSortedList
       
   666 // ---------------------------------------------------------------------------
       
   667 //
       
   668 void CSwtSortedList::GetFocusedItem(TPtrC& aItem) const
       
   669 {
       
   670     if (iList->Model()->NumberOfItems() == 0)
       
   671     {
       
   672         return;
       
   673     }
       
   674 
       
   675     // Get focused item index
       
   676     TInt focusedItem = GetFocusIndex();
       
   677 
       
   678     // If filter is active, it is neccessary to recalculate index
       
   679     if (iSearchField)
       
   680     {
       
   681         CAknListBoxFilterItems* filter = Filter();
       
   682         ASSERT(filter);
       
   683         // At least one filtered item is visible
       
   684         if (filter->FilteredNumberOfItems() > 0)
       
   685         {
       
   686             // Update index and get item string
       
   687             focusedItem = filter->FilteredItemIndex(focusedItem);
       
   688             aItem.Set((*iTextItems)[focusedItem]);
       
   689         }
       
   690         else
       
   691         {
       
   692             // When nothing is selected, function returns null-string
       
   693             aItem.Set(KNullDesC);
       
   694         }
       
   695     }
       
   696     else
       
   697     {
       
   698         // Get focused item string
       
   699         aItem.Set((*iTextItems)[focusedItem]);
       
   700     }
       
   701 }
       
   702 
       
   703 // ---------------------------------------------------------------------------
       
   704 // CSwtSortedList::GetItemHeight
       
   705 // From MSwtSortedList
       
   706 // ---------------------------------------------------------------------------
       
   707 //
       
   708 TInt CSwtSortedList::GetItemHeight() const
       
   709 {
       
   710     return iList->ItemHeight();
       
   711 }
       
   712 
       
   713 // ---------------------------------------------------------------------------
       
   714 // CSwtSortedList::GetSelectionCount
       
   715 // From MSwtSortedList
       
   716 // ---------------------------------------------------------------------------
       
   717 //
       
   718 TInt CSwtSortedList::GetSelectionCount() const
       
   719 {
       
   720     return CSwtListBase::GetSelectionCount();
       
   721 }
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // CSwtSortedList::GetSelectionL
       
   725 // From MSwtSortedList
       
   726 // ---------------------------------------------------------------------------
       
   727 //
       
   728 CPtrCArray* CSwtSortedList::GetSelectionL() const
       
   729 {
       
   730     CPtrCArray* selectedItemArray = GetSelectionLC();
       
   731     CleanupStack::Pop(selectedItemArray);
       
   732     return selectedItemArray;
       
   733 }
       
   734 
       
   735 // ---------------------------------------------------------------------------
       
   736 // CSwtSortedList::RemoveAllL
       
   737 // From MSwtSortedList
       
   738 // ---------------------------------------------------------------------------
       
   739 //
       
   740 void CSwtSortedList::RemoveAllL()
       
   741 {
       
   742     if (iTextItems->Count() == 0)
       
   743     {
       
   744         return;
       
   745     }
       
   746 
       
   747     CDesCArray* itemTextArray = static_cast<CDesCArray*>(iList->Model()->ItemTextArray());
       
   748     itemTextArray->Reset();
       
   749     iTextItems->Reset();
       
   750 
       
   751     if (iRemovedItemIndices.Count() > 0)
       
   752     {
       
   753         iRemovedItemIndices.Reset();
       
   754     }
       
   755     HandleItemRemovalL(iRemovedItemIndices, 0);
       
   756     iRemovedItemIndices.Reset();
       
   757 }
       
   758 
       
   759 // ---------------------------------------------------------------------------
       
   760 // CSwtSortedList::RemoveL
       
   761 // From MSwtSortedList
       
   762 // ---------------------------------------------------------------------------
       
   763 //
       
   764 TBool CSwtSortedList::RemoveL(const HBufC& aPtr)
       
   765 {
       
   766     TInt itemPos;
       
   767     TInt res = iTextItems->Find(aPtr, itemPos, ECmpCollated);
       
   768     if (res)
       
   769     {
       
   770         // String not found in list
       
   771         return ETrue;
       
   772     }
       
   773 
       
   774     TInt currentItemIndex(iList->CurrentItemIndex());
       
   775 
       
   776     CDesCArray* itemTextArray = static_cast<CDesCArray*>(iList->Model()->ItemTextArray());
       
   777     itemTextArray->Delete(itemPos);
       
   778     iTextItems->Delete(itemPos);
       
   779 
       
   780     if (iRemovedItemIndices.Count() > 0)
       
   781     {
       
   782         iRemovedItemIndices.Reset();
       
   783     }
       
   784     iRemovedItemIndices.Append(itemPos);
       
   785     HandleItemRemovalL(iRemovedItemIndices, currentItemIndex);
       
   786     iRemovedItemIndices.Reset();
       
   787     return EFalse;
       
   788 }
       
   789 
       
   790 // ---------------------------------------------------------------------------
       
   791 // CSwtSortedList::Scrollable
       
   792 // From MSwtSortedList
       
   793 // ---------------------------------------------------------------------------
       
   794 //
       
   795 MSwtScrollable* CSwtSortedList::Scrollable()
       
   796 {
       
   797     return this;
       
   798 }
       
   799 
       
   800 // ---------------------------------------------------------------------------
       
   801 // CSwtSortedList::SelectItemL
       
   802 // From MSwtSortedList
       
   803 // ---------------------------------------------------------------------------
       
   804 //
       
   805 TBool CSwtSortedList::SelectItemL(const TDesC* aString)
       
   806 {
       
   807     if (aString == NULL)
       
   808     {
       
   809         if (iList->View()->SelectionIndexes()->Count() > 0)
       
   810         {
       
   811             iList->ClearSelection();
       
   812             UpdateListMskL();
       
   813             return EFalse;
       
   814         }
       
   815         else
       
   816         {
       
   817             return ETrue;
       
   818         }
       
   819     }
       
   820 
       
   821     TInt itemPos;
       
   822     TInt res = iTextItems->Find(*aString, itemPos, ECmpCollated);
       
   823     if (res)
       
   824     {
       
   825         // String not found in list
       
   826         return ETrue;
       
   827     }
       
   828 
       
   829     if (iSearchField)
       
   830     {
       
   831         CAknListBoxFilterItems* filter = Filter();
       
   832         ASSERT(filter);
       
   833         itemPos = filter->VisibleItemIndex(itemPos);
       
   834         if (itemPos < 0) // Item not visible do nothing
       
   835         {
       
   836             return EFalse;
       
   837         }
       
   838     }
       
   839 
       
   840     if (iList->View()->ItemIsSelected(itemPos))
       
   841     {
       
   842         // Already selected
       
   843         return EFalse;
       
   844     }
       
   845 
       
   846     if (iStyle & KSwtStyleMulti)
       
   847     {
       
   848         iList->View()->SelectItemL(itemPos);
       
   849         UpdateListMskL();
       
   850     }
       
   851     else
       
   852     {
       
   853         TInt old = iList->CurrentItemIndex();
       
   854 
       
   855         // We do not call CEikListBox::SetCurrentItemIndex, because we do not want to scroll.
       
   856         iList->View()->SetCurrentItemIndex(itemPos);
       
   857         iList->View()->UpdateSelectionL(CListBoxView::ESingleSelection);
       
   858         if (old != -1)
       
   859         {
       
   860             iList->View()->DrawItem(old);
       
   861         }
       
   862     }
       
   863 
       
   864     return EFalse;
       
   865 }
       
   866 
       
   867 // ---------------------------------------------------------------------------
       
   868 // CSwtSortedList::SetItemsL
       
   869 // From MSwtSortedList
       
   870 // ---------------------------------------------------------------------------
       
   871 //
       
   872 void CSwtSortedList::SetItemsL(MDesCArray* aStringArray)
       
   873 {
       
   874     if (iList)
       
   875     {
       
   876         ASSERT(aStringArray);
       
   877 
       
   878         // We remove the old selection
       
   879         iList->ClearSelection();
       
   880 
       
   881         // Reset the text items
       
   882         iTextItems->Reset();
       
   883 
       
   884         CDesCArray* itemArray = new(ELeave) CDesCArrayFlat(aStringArray->MdcaCount());
       
   885         CleanupStack::PushL(itemArray);
       
   886 
       
   887         for (TInt i = 0; i < aStringArray->MdcaCount(); ++i)
       
   888         {
       
   889             // The item is inserted in both iTextItems and itemArray
       
   890             InsertItemL(aStringArray->MdcaPoint(i), itemArray);
       
   891         }
       
   892 
       
   893         iList->Model()->SetItemTextArray(itemArray);
       
   894         CleanupStack::Pop(itemArray);
       
   895 
       
   896         HandleItemAdditionL(0);
       
   897 
       
   898         Redraw();
       
   899     }
       
   900 }
       
   901 
       
   902 // ---------------------------------------------------------------------------
       
   903 // CSwtSortedList::SetModeStyleL
       
   904 // From MSwtSortedList
       
   905 // This function should be called only once.
       
   906 // It creates the filter if the SortedList has the FILTER style.
       
   907 // ---------------------------------------------------------------------------
       
   908 //
       
   909 void CSwtSortedList::SetModeStyleL(TInt aModeStyle)
       
   910 {
       
   911     iModeStyle = aModeStyle;
       
   912 
       
   913     if ((iModeStyle & ESwtFilter) != 0)
       
   914     {
       
   915         iSearchField = CAknSearchField::NewL(*this,
       
   916                                              CAknSearchField::EAdaptiveSearch, NULL, KSwtSearchFieldTextLimit);
       
   917         iSearchField->Editor().AddEdwinObserverL(this);
       
   918         
       
   919         // Orphane the filter to force its editor to draw CAknSearchField's 
       
   920         // background instead of our Shell's background.
       
   921         iSearchField->SetParent(NULL);
       
   922         
       
   923         iSearchField->AddAdaptiveSearchTextObserverL(this);
       
   924         iSearchField->SetComponentsToInheritVisibility(ETrue);
       
   925         CAknFilteredTextListBoxModel* model = STATIC_CAST(
       
   926                                                   CAknFilteredTextListBoxModel*, iList->Model());
       
   927         ASSERT(model);
       
   928         if (!model->Filter())
       
   929         {
       
   930             model->CreateFilterL(iList, iSearchField);
       
   931         }
       
   932     }
       
   933 }
       
   934 
       
   935 // ---------------------------------------------------------------------------
       
   936 // CSwtSortedList::SetSelectionL
       
   937 // From MSwtSortedList
       
   938 // ---------------------------------------------------------------------------
       
   939 //
       
   940 void CSwtSortedList::SetSelectionL(MDesCArray* aStringArray)
       
   941 {
       
   942     ASSERT(aStringArray != NULL);
       
   943 
       
   944     TInt pos;
       
   945     TInt granularity(KSwtArrayGranularity);
       
   946     TInt nbSelection(aStringArray->MdcaCount());
       
   947     TKeyArrayFix keyArray(0, ECmpTUint);
       
   948 
       
   949     if (nbSelection == 0 || iTextItems->Count() == 0)
       
   950     {
       
   951         return;
       
   952     }
       
   953 
       
   954     CArrayFixFlat<TInt>* selectionIndexes = new(ELeave) CArrayFixFlat<TInt>(granularity);
       
   955     CleanupStack::PushL(selectionIndexes);
       
   956     CAknListBoxFilterItems* filter = NULL;
       
   957     if (iSearchField)
       
   958     {
       
   959         filter = Filter();
       
   960     }
       
   961     for (TInt numString=0; numString < nbSelection; ++numString)
       
   962     {
       
   963         if (iTextItems->Find(aStringArray->MdcaPoint(numString), pos, ECmpCollated) == 0)
       
   964         {
       
   965             if (iSearchField && filter)
       
   966             {
       
   967                 pos = filter->VisibleItemIndex(pos);
       
   968             }
       
   969             if (pos != -1)
       
   970             {
       
   971                 selectionIndexes->InsertIsqL(pos, keyArray);
       
   972             }
       
   973         }
       
   974     }
       
   975 
       
   976     iList->ClearSelection();
       
   977 
       
   978     // No selected index is found, return.
       
   979     if (selectionIndexes->Count() > 0)
       
   980     {
       
   981         TInt old = iList->CurrentItemIndex();
       
   982         // If more than one index is selected and List is Single-select, return
       
   983         if (!((iStyle & KSwtStyleSingle) && (selectionIndexes->Count() > 1)))
       
   984         {
       
   985             iList->View()->SetSelectionIndexesL(selectionIndexes);
       
   986         }
       
   987         iList->SetCurrentItemIndex(selectionIndexes->At(0));
       
   988         iList->View()->DrawItem(selectionIndexes->At(0));
       
   989         if (old != -1)
       
   990         {
       
   991             iList->View()->DrawItem(old);
       
   992         }
       
   993     }
       
   994 
       
   995     CleanupStack::PopAndDestroy(selectionIndexes);
       
   996 
       
   997     UpdateListMskL();
       
   998 }
       
   999 
       
  1000 // ---------------------------------------------------------------------------
       
  1001 // CSwtSortedList::ShowSelection
       
  1002 // From MSwtSortedList
       
  1003 // ---------------------------------------------------------------------------
       
  1004 //
       
  1005 void CSwtSortedList::ShowSelection()
       
  1006 {
       
  1007     CSwtListBase::ShowSelection();
       
  1008 }
       
  1009 
       
  1010 // ---------------------------------------------------------------------------
       
  1011 // CSwtSortedList::HandleEdwinEventL
       
  1012 // From MEikEdwinObserver
       
  1013 // ---------------------------------------------------------------------------
       
  1014 //
       
  1015 void CSwtSortedList::HandleEdwinEventL(CEikEdwin* /*aEdwin*/, TEdwinEvent aEventType)
       
  1016 {
       
  1017     if (aEventType == EEventTextUpdate)
       
  1018     {
       
  1019         HandleOfferKeyEventL();
       
  1020     }
       
  1021 }
       
  1022 
       
  1023 // ---------------------------------------------------------------------------
       
  1024 // CSwtSortedList::AdaptiveSearchTextChanged
       
  1025 // From MAdaptiveSearchTextObserver
       
  1026 // ---------------------------------------------------------------------------
       
  1027 //
       
  1028 void CSwtSortedList::AdaptiveSearchTextChanged(CAknSearchField* /*aSearchField*/)
       
  1029 {
       
  1030     TRAP_IGNORE(HandleOfferKeyEventL());
       
  1031 }
       
  1032