phonebookui/Phonebook/View/src/CPbkContactViewListControl.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *       Provides methods for phonebook contact view list control.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <CPbkContactViewListControl.h>  // This class
       
    22 #include <barsread.h>    // TResourceReader
       
    23 #include <eikclbd.h>     // CColumnListBoxData
       
    24 #include <aknsfld.h>     // CAknSearchField
       
    25 #include <aknlists.h>    // AknListBoxUtils
       
    26 #include <AknsDrawUtils.h>
       
    27 #include <featmgr.h>
       
    28 #include <bldvariant.hrh>
       
    29 #include <PbkView.rsg>
       
    30 #include <AknDef.h>      // KEikDynamicLayoutVariantSwitch
       
    31 #include <AknUtils.h>
       
    32 
       
    33 
       
    34 // PbkView classes
       
    35 #include <PbkView.hrh>
       
    36 #include "CPbkViewState.h"
       
    37 #include "CPbkThumbnailPopup.h"
       
    38 #include <CPbkIconArray.h>
       
    39 #include <MPbkContactViewListControlObserver.h>
       
    40 #include "PbkFindPrimitivesFactory.h"
       
    41 #include "PbkContactViewListModelFactory.h"
       
    42 #include "MPbkFetchDlgSelection.h"
       
    43 
       
    44 // PbkEng classes
       
    45 #include <CPbkContactEngine.h>
       
    46 #include <CPbkConstants.h>
       
    47 #include <CPbkContactFindView.h>
       
    48 
       
    49 // PbkExt classes
       
    50 #include <CPbkExtGlobals.h>
       
    51 #include <MPbkViewExtension.h>
       
    52 #include <MPbkContactUiControlExtension.h>
       
    53 #include <MPbkExtensionFactory.h>
       
    54 
       
    55 // Phonebook common include files
       
    56 #include <PbkDebug.h>        // Phonebook debugging support
       
    57 
       
    58 
       
    59 // Unnamed namespace for local definitions
       
    60 namespace {
       
    61 
       
    62 // LOCAL CONSTANTS AND MACROS
       
    63 
       
    64 /// Listbox model's entry cache size
       
    65 const TInt KCacheSize = 32;
       
    66 
       
    67 const TUint16 KZwsChar = 0x200b;
       
    68 const TUint16 KZwnjChar = 0x200c;
       
    69 
       
    70 enum TPanicCode
       
    71     {
       
    72     EPanicPostCond_Constructor = 1,
       
    73     EPanicPreCond_ConstructFromResourceL,
       
    74     EPanicInvalidListBoxType_ConstructFromResourceL,
       
    75     EPanicPostCond_ConstructFromResource,
       
    76     EPanicPreCond_ConstructL,
       
    77     EPanicPostCond_ConstructL,
       
    78     EPanicListBoxNull,
       
    79     EPanicLogic_ComponentControl,
       
    80     EPanicPostCond_EnableFindBoxL,
       
    81     EPanicPostCond_DisableFindBoxL,
       
    82     EPanicLogic_FindTextL,
       
    83     EPanicPre_SetControlExtensionL
       
    84     };
       
    85 
       
    86 
       
    87 // MODULE DATA STRUCTURES
       
    88 
       
    89 NONSHARABLE_CLASS(TCleanupEnableListBoxViewRedraw)
       
    90     {
       
    91     public:  // Interface
       
    92         inline TCleanupEnableListBoxViewRedraw(CListBoxView& aListBoxView)
       
    93             : iCleanupItem(CleanupOp,&aListBoxView)
       
    94             {
       
    95             }
       
    96 
       
    97         inline operator TCleanupItem() const
       
    98             {
       
    99             return iCleanupItem;
       
   100             }
       
   101 
       
   102     private:  // Implementation
       
   103         static void CleanupOp(TAny* aPtr);
       
   104 
       
   105     private:  // Data
       
   106         TCleanupItem iCleanupItem;
       
   107     };
       
   108 
       
   109 // ==================== LOCAL FUNCTIONS ====================
       
   110 
       
   111 /**
       
   112  * Returns index of aValue in aArray or KErrNotFound.
       
   113  */
       
   114 template<class T>
       
   115 TInt Find(const CArrayFix<T>& aArray, const T& aValue)
       
   116     {
       
   117     const TInt count = aArray.Count();
       
   118     for (TInt i = 0; i < count; ++i)
       
   119         {
       
   120         if (aArray[i] == aValue)
       
   121             {
       
   122             return i;
       
   123             }
       
   124         }
       
   125     return KErrNotFound;
       
   126     }
       
   127 
       
   128 /**
       
   129  * Returns CPbkIconArray icon array from aListBox.
       
   130  */
       
   131 inline CPbkIconArray* IconArray(CEikColumnListBox& aListBox)
       
   132     {
       
   133     return static_cast<CPbkIconArray*>
       
   134         (aListBox.ItemDrawer()->ColumnData()->IconArray());
       
   135     }
       
   136 
       
   137 /**
       
   138  * Sets aIconArray as aListBox'es icon array.
       
   139  */
       
   140 inline void SetIconArray
       
   141         (CEikColumnListBox& aListBox, CPbkIconArray* aIconArray)
       
   142     {
       
   143     aListBox.ItemDrawer()->ColumnData()->SetIconArray(aIconArray);
       
   144     }
       
   145 
       
   146 void Panic(TPanicCode aReason)
       
   147     {
       
   148     _LIT(KPanicText, "CPbkContactViewListControl");
       
   149     User::Panic(KPanicText, aReason);
       
   150     }
       
   151 
       
   152 /**
       
   153  * Returns ETrue, if a character is to be included in the search string
       
   154  */
       
   155 inline TBool IsSearchableChar( const TChar aChar )
       
   156     {
       
   157     switch (aChar)
       
   158         {
       
   159         case KZwsChar:  // FALLTHROUGH
       
   160         case KZwnjChar:
       
   161             {
       
   162             return EFalse;
       
   163             }
       
   164         }
       
   165     return ETrue;
       
   166     }
       
   167 
       
   168 // MACROS
       
   169 
       
   170 /// Define this to print find performance data to debug output
       
   171 #ifdef PBK_BENCHMARK_FIND
       
   172   #pragma message("Warning: PBK_BENCHMARK_FIND is set")
       
   173 #endif
       
   174 
       
   175 // MODULE DATA STRUCTURES
       
   176 
       
   177 #ifdef PBK_BENCHMARK_FIND
       
   178 
       
   179 /// Benchmarking helper class.
       
   180 template<class NumT>
       
   181 NONSHARABLE_CLASS(TRunningTimes)
       
   182     {
       
   183     public:  // Interface
       
   184         /**
       
   185          * Constructor.
       
   186          */
       
   187         inline TRunningTimes()
       
   188             {
       
   189             Reset();
       
   190             }
       
   191         /**
       
   192          * () operator.
       
   193          */
       
   194         inline NumT operator()() const
       
   195             {
       
   196             return iTotal;
       
   197             }
       
   198 
       
   199         inline void Start()
       
   200             {
       
   201             iStart.UniversalTime();
       
   202             }
       
   203         inline void Stop()
       
   204             {
       
   205             iStop.UniversalTime();
       
   206             const TInt timeDiff =
       
   207                 I64LOW(iStop.MicroSecondsFrom(iStart).Int64()) / 1000;
       
   208             iTotal += timeDiff;
       
   209             iCount++;
       
   210             }
       
   211 
       
   212         inline TInt Count() const
       
   213             {
       
   214             return iCount;
       
   215             }
       
   216 
       
   217         /**
       
   218          * Returns total time
       
   219          */
       
   220         inline NumT Total() const
       
   221             {
       
   222             return iTotal;
       
   223             }
       
   224 
       
   225         /**
       
   226          * Reset.
       
   227          */
       
   228         inline void Reset()
       
   229             {
       
   230             iTotal=0; iCount=0;
       
   231             }
       
   232 
       
   233     private:  // Data
       
   234         TTime iStart;
       
   235         TTime iStop;
       
   236         /// Own: count
       
   237         TInt iCount;
       
   238         /// Own: total time
       
   239         NumT iTotal;
       
   240     };
       
   241 
       
   242 #endif  // PBK_BENCHMARK_FIND
       
   243 
       
   244 }  // namespace
       
   245 
       
   246 
       
   247 // ================= MEMBER FUNCTIONS =======================
       
   248 
       
   249 //
       
   250 // CPbkContactViewListControl
       
   251 //
       
   252 inline CEikColumnListBox& CPbkContactViewListControl::ListBox() const
       
   253     {
       
   254     __ASSERT_DEBUG(iListBox, Panic(EPanicListBoxNull));
       
   255     return(*iListBox);
       
   256     }
       
   257 
       
   258 inline MPbkContactViewListModel& CPbkContactViewListControl::Model() const
       
   259     {
       
   260     return(*static_cast<MPbkContactViewListModel*>
       
   261         (iListBox->Model()->ItemTextArray()));
       
   262     }
       
   263 
       
   264 inline TBool CPbkContactViewListControl::PostCond_Constructor()
       
   265     {
       
   266     return
       
   267         (!iListBox && !iFindBox && !iFindTextBuf && !iBaseView && !iView &&
       
   268         !iResourceData.iUnnamedText && !iResourceData.iFindEmptyText &&
       
   269         !iMarkedItemsArray && !iThumbnailPopup);
       
   270     }
       
   271 
       
   272 inline TBool CPbkContactViewListControl::PostCond_ConstructFromResource()
       
   273     {
       
   274     return
       
   275         (iListBox && !iFindBox && !iFindTextBuf &&
       
   276         iResourceData.iUnnamedText && !iMarkedItemsArray);
       
   277     }
       
   278 
       
   279 EXPORT_C CPbkContactViewListControl* CPbkContactViewListControl::NewL
       
   280         (CPbkContactEngine& aEngine,
       
   281         CContactViewBase& aView,
       
   282         TInt aResourceId,
       
   283         const CCoeControl* aParent)
       
   284     {
       
   285     PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactViewListControl::NewL()"));
       
   286     CPbkContactViewListControl* self = new(ELeave) CPbkContactViewListControl();
       
   287     CleanupStack::PushL(self);
       
   288     self->ConstructL(aEngine, aView, aResourceId, aParent);
       
   289     CleanupStack::Pop(self);
       
   290     return self;
       
   291     }
       
   292 
       
   293 EXPORT_C CPbkContactViewListControl::CPbkContactViewListControl() :
       
   294     iLastFocusId(KNullContactId),
       
   295     iChangedIndexes(1 /*allocation granularity*/)
       
   296     {
       
   297     // CBase::operator new(TLeave) resets other members
       
   298     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
   299         ("CPbkContactViewListControl::CPbkContactViewListControl(0x%x)"),
       
   300             this);
       
   301     __ASSERT_DEBUG(PostCond_Constructor(), Panic(EPanicPostCond_Constructor));
       
   302     }
       
   303 
       
   304 void CPbkContactViewListControl::ConstructFromResourceL
       
   305         (TResourceReader& aReader)
       
   306     {
       
   307     __ASSERT_DEBUG(PostCond_Constructor(),
       
   308         Panic(EPanicPreCond_ConstructFromResourceL));
       
   309     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
   310         ("CPbkContactViewListControl::ConstructFromResourceL(0x%x)"),this);
       
   311 
       
   312     // emptyText
       
   313     TPtrC emptyText = aReader.ReadTPtrC();
       
   314     // unnamedText
       
   315     iResourceData.iUnnamedText = aReader.ReadHBufCL();
       
   316     // flags
       
   317     iResourceData.iFlags = aReader.ReadUint32();
       
   318 
       
   319     // Empty text in find state
       
   320     TResourceReader rr;
       
   321     iEikonEnv->CreateResourceReaderLC(rr, R_AVKON_FIND_NO_MATCHES);
       
   322     iResourceData.iFindEmptyText = rr.ReadHBufCL();
       
   323     CleanupStack::PopAndDestroy(); // rr
       
   324 
       
   325     // listboxType
       
   326     TInt listBoxType = aReader.ReadInt16();
       
   327     iListBox = static_cast<CEikColumnListBox*>
       
   328         (EikControlFactory::CreateByTypeL(listBoxType).iControl);
       
   329     __ASSERT_ALWAYS(iListBox, Panic
       
   330         (EPanicInvalidListBoxType_ConstructFromResourceL));
       
   331     iListBox->SetContainerWindowL(*this);
       
   332     // listbox
       
   333     iListBox->ConstructFromResourceL(aReader);
       
   334     iListBox->View()->SetListEmptyTextL(emptyText);
       
   335     iListBox->CreateScrollBarFrameL(ETrue);
       
   336     iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
       
   337         (CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
       
   338     iListBox->SetObserver(this);
       
   339     iListBox->MakeVisible(EFalse);
       
   340 
       
   341     // iconArray, use granularity of 4
       
   342 
       
   343     CPbkIconArray* iconArray = new(ELeave) CPbkIconArray(4);
       
   344     CleanupStack::PushL(iconArray);
       
   345     const TInt iconArrayRes = aReader.ReadInt32();
       
   346     iconArray->ConstructFromResourceL(iconArrayRes);
       
   347 
       
   348     // get extension factory for setting extension icons
       
   349     CPbkExtGlobals* extGlobal = CPbkExtGlobals::InstanceL();
       
   350     extGlobal->PushL();
       
   351     MPbkExtensionFactory& factory = extGlobal->FactoryL();
       
   352     factory.AddPbkFieldIconsL(NULL, iconArray);
       
   353     CleanupStack::PopAndDestroy(extGlobal);
       
   354 
       
   355     CleanupStack::Pop(iconArray);
       
   356 
       
   357     SetIconArray(*iListBox,iconArray);
       
   358 
       
   359     // emptyIconId
       
   360     iResourceData.iEmptyIconId =
       
   361         static_cast<TPbkIconId>(aReader.ReadInt16());
       
   362     // defaultIconId
       
   363     iResourceData.iDefaultIconId =
       
   364         static_cast<TPbkIconId>(aReader.ReadInt16());
       
   365 
       
   366     // Preallocate space for the one required integer
       
   367     iChangedIndexes.AppendL(-1);
       
   368 
       
   369     __ASSERT_DEBUG(PostCond_ConstructFromResource(),
       
   370         Panic(EPanicPostCond_ConstructFromResource));
       
   371     }
       
   372 
       
   373 EXPORT_C void CPbkContactViewListControl::ConstructL
       
   374         (CPbkContactEngine& aEngine,
       
   375         CContactViewBase& aView)
       
   376     {
       
   377     // Check that ConstructFromResourceL is executed
       
   378     __ASSERT_DEBUG(PostCond_ConstructFromResource() && !iBaseView && !iView,
       
   379         Panic(EPanicPreCond_ConstructL));
       
   380     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
   381         ("CPbkContactViewListControl::ConstructL(0x%x)"),this);
       
   382 
       
   383     iFindPrimitives = PbkFindPrimitivesFactory::CreateL(
       
   384         aEngine.ContactNameFormat());
       
   385     iBaseView = &aView;
       
   386     iView = CPbkContactFindView::NewL(
       
   387         aEngine, *iBaseView, *this, *iFindPrimitives);
       
   388 
       
   389     // Set aParams for MPbkContactViewListModel
       
   390     PbkContactViewListModelFactory::TParams params;
       
   391     params.iEngine = &aEngine;
       
   392     params.iView = iView;
       
   393     params.iCacheSize = KCacheSize;
       
   394     params.iIconArray = IconArray(*iListBox);
       
   395     params.iEmptyId = iResourceData.iEmptyIconId;
       
   396     params.iDefaultId = iResourceData.iDefaultIconId;
       
   397 
       
   398     // Listbox model
       
   399     MPbkContactViewListModel* model = PbkContactViewListModelFactory::
       
   400                                             CreateL(params);
       
   401     model->SetUnnamedText(iResourceData.iUnnamedText);
       
   402     iListBox->Model()->SetItemTextArray(model);
       
   403     iListBox->Model()->SetOwnershipType(ELbmOwnsItemArray);
       
   404 
       
   405     // thumbnail handler
       
   406     if (iResourceData.iFlags & KPbkContactViewListControlUpdateContextPane)
       
   407         {
       
   408         iThumbnailPopup = CPbkThumbnailPopup::NewL(aEngine);
       
   409         }
       
   410 
       
   411     // Sets up TLS, must be done before FeatureManager is used.
       
   412     FeatureManager::InitializeLibL();
       
   413     // iEngine != NULL means that Featuremanager has been initialized
       
   414     iEngine = &aEngine;
       
   415 
       
   416     __ASSERT_DEBUG(PostCond_ConstructFromResource() && iBaseView && iView &&
       
   417         iThumbnailPopup || !(iResourceData.iFlags &
       
   418         KPbkContactViewListControlUpdateContextPane),
       
   419         Panic(EPanicPostCond_ConstructL));
       
   420     }
       
   421 
       
   422 CPbkContactViewListControl::~CPbkContactViewListControl()
       
   423     {
       
   424     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
   425         ("CPbkContactViewListControl::~CPbkContactViewListControl(0x%x)"),
       
   426         this);
       
   427 
       
   428     // This should be done before listbox delete
       
   429     // (which deletes dummy control extension)
       
   430     Release(iControlExtension);
       
   431 
       
   432     // Fetch dialog pages might delay calling ConstructL and thus Feature
       
   433     // manager might not be initialized if destructing early.
       
   434     if (iEngine)
       
   435         {
       
   436         // iEngine != NULL means that Featuremanager has been initialized
       
   437         FeatureManager::UnInitializeLib();
       
   438         }
       
   439 
       
   440     delete iOriginalEmptyText;
       
   441     iObservers.Reset();
       
   442     delete iFindTextBuf;
       
   443     if (iView)
       
   444         {
       
   445         iView->Close(*this);
       
   446         }
       
   447     delete iFindPrimitives;
       
   448     delete iThumbnailPopup;
       
   449     delete iMarkedItemsArray;
       
   450     delete iFindBox;
       
   451     delete iListBox;
       
   452     delete iResourceData.iFindEmptyText;
       
   453     delete iResourceData.iUnnamedText;
       
   454     }
       
   455 
       
   456 EXPORT_C TContactItemId CPbkContactViewListControl::ContactIdAtL
       
   457         (TInt aIndex) const
       
   458     {
       
   459     return iView->AtL(aIndex);
       
   460     }
       
   461 
       
   462 EXPORT_C TInt CPbkContactViewListControl::FindContactIdL
       
   463         (TContactItemId aId) const
       
   464     {
       
   465     return iView->FindL(aId);
       
   466     }
       
   467 
       
   468 EXPORT_C TInt CPbkContactViewListControl::CurrentItemIndex() const
       
   469     {
       
   470     return ListBox().CurrentItemIndex();
       
   471     }
       
   472 
       
   473 EXPORT_C void CPbkContactViewListControl::SetCurrentItemIndex(TInt aIndex)
       
   474     {
       
   475     if (ListBox().CurrentItemIndex() != aIndex)
       
   476         {
       
   477         ListBox().SetCurrentItemIndex(aIndex);
       
   478         HandleFocusChange();
       
   479         }
       
   480     }
       
   481 
       
   482 EXPORT_C void CPbkContactViewListControl::SetCurrentItemIndexAndDraw
       
   483         (TInt aIndex)
       
   484     {
       
   485     if (ListBox().CurrentItemIndex() != aIndex)
       
   486         {
       
   487         ListBox().SetCurrentItemIndexAndDraw(aIndex);
       
   488         HandleFocusChange();
       
   489         }
       
   490     }
       
   491 
       
   492 EXPORT_C void CPbkContactViewListControl::HandleMarkableListProcessCommandL
       
   493         (TInt aCommandId)
       
   494     {
       
   495     AknSelectionService::HandleMarkableListProcessCommandL
       
   496         (aCommandId, &ListBox());
       
   497     }
       
   498 
       
   499 EXPORT_C void CPbkContactViewListControl::HandleMarkableListDynInitMenuPane
       
   500         (TInt aResourceId,
       
   501         CEikMenuPane *aMenu)
       
   502     {
       
   503     AknSelectionService::HandleMarkableListDynInitMenuPane
       
   504         (aResourceId, aMenu, &ListBox());
       
   505     }
       
   506 
       
   507 EXPORT_C void
       
   508     CPbkContactViewListControl::HandleMarkableListUpdateAfterCommandExecution()
       
   509     {
       
   510     AknSelectionService::HandleMarkableListUpdateAfterCommandExecution
       
   511         (&ListBox());
       
   512     }
       
   513 
       
   514 EXPORT_C const TDesC& CPbkContactViewListControl::FindTextL() const
       
   515     {
       
   516     // Initial minimum size for the find text buffer
       
   517     const TInt KInitialBufSize = 8;
       
   518 
       
   519     if (iFindBox)
       
   520         {
       
   521         const TInt findBoxTextLength = iFindBox->TextLength();
       
   522         if (findBoxTextLength > 0)
       
   523             {
       
   524             TInt bufCapacity = 0;
       
   525             if (iFindTextBuf)
       
   526                 {
       
   527                 bufCapacity = iFindTextBuf->Des().MaxLength();
       
   528                 }
       
   529             if (bufCapacity < findBoxTextLength)
       
   530                 {
       
   531                 // Allocate a new buffer of at least KInitialBufSize
       
   532                 // characters or twice as large as the previous one
       
   533                 const TInt newBufSize = Max(Max(KInitialBufSize,2*bufCapacity),
       
   534                     findBoxTextLength);
       
   535                 HBufC* newBuf = HBufC::NewL(newBufSize);
       
   536                 delete iFindTextBuf;
       
   537                 iFindTextBuf = newBuf;
       
   538                 }
       
   539             TPtr bufPtr = iFindTextBuf->Des();
       
   540             __ASSERT_DEBUG
       
   541                 (bufPtr.MaxLength()>=KInitialBufSize && bufPtr.MaxLength()>=findBoxTextLength,
       
   542                 Panic(EPanicLogic_FindTextL));
       
   543             iFindBox->GetSearchText(bufPtr);
       
   544             // Strip from search string all unwanted characters that e.g. Hindi input places there
       
   545             for( TInt i = bufPtr.Length()-1; i >= 0; --i )
       
   546                 {
       
   547                 if (!IsSearchableChar(bufPtr[i]))
       
   548                     {
       
   549                     bufPtr.Delete( i, 1 );
       
   550                     }
       
   551                 }
       
   552             return(*iFindTextBuf);
       
   553             }
       
   554         }
       
   555     return KNullDesC;
       
   556     }
       
   557 
       
   558 EXPORT_C void CPbkContactViewListControl::ResetFindL()
       
   559     {
       
   560     if (iFindBox && iFindBox->TextLength() > 0)
       
   561         {
       
   562         iFindBox->ResetL();
       
   563         UpdateFindResultL();
       
   564         iFindBox->DrawDeferred();
       
   565         }
       
   566     }
       
   567 
       
   568 EXPORT_C TBool CPbkContactViewListControl::ItemMarked(TInt aIndex) const
       
   569     {
       
   570     const CListBoxView::CSelectionIndexArray* selections =
       
   571         ListBox().View()->SelectionIndexes();
       
   572     return (selections ? Find(*selections,aIndex)!=KErrNotFound : EFalse);
       
   573     }
       
   574 
       
   575 EXPORT_C TInt CPbkContactViewListControl::NextUnmarkedIndexFromFocus() const
       
   576     {
       
   577     const TInt focus = ListBox().CurrentItemIndex();
       
   578     TInt index = focus;
       
   579     const CListBoxView::CSelectionIndexArray* selections =
       
   580         ListBox().SelectionIndexes();
       
   581     if (selections && selections->Count() > 0)
       
   582         {
       
   583         const TInt count = iListBox->Model()->NumberOfItems();
       
   584         for (index = focus; index < count; ++index)
       
   585             {
       
   586             if (Find(*selections,index) == KErrNotFound)
       
   587                 {
       
   588                 return index;
       
   589                 }
       
   590             }
       
   591         for (index = focus; index >= 0; --index)
       
   592             {
       
   593             if (Find(*selections,index) == KErrNotFound)
       
   594                 {
       
   595                 return index;
       
   596                 }
       
   597             }
       
   598         }
       
   599     return index;
       
   600     }
       
   601 
       
   602 EXPORT_C void CPbkContactViewListControl::MarkItemL
       
   603         (TContactItemId aContactId,
       
   604         TBool aMark)
       
   605     {
       
   606     const TInt index = FindContactIdL(aContactId);
       
   607     if (index >= 0)
       
   608         {
       
   609         if (aMark)
       
   610             {
       
   611             ListBox().View()->SelectItemL(index);
       
   612             }
       
   613         else
       
   614             {
       
   615             ListBox().View()->DeselectItem(index);
       
   616             }
       
   617         }
       
   618     }
       
   619 
       
   620 EXPORT_C void CPbkContactViewListControl::ClearMarks()
       
   621     {
       
   622     if (ItemsMarked())
       
   623         {
       
   624         CListBoxView& listBoxView = *ListBox().View();
       
   625         listBoxView.SetDisableRedraw(ETrue);
       
   626         ListBox().ClearSelection();
       
   627         listBoxView.SetDisableRedraw(EFalse);
       
   628         Redraw();
       
   629         }
       
   630     }
       
   631 
       
   632 EXPORT_C CPbkViewState* CPbkContactViewListControl::GetStateL
       
   633         (TBool aSaveMarks/*=ETrue*/) const
       
   634     {
       
   635     CPbkViewState* state = GetStateLC(aSaveMarks);
       
   636     CleanupStack::Pop();  // state
       
   637     return state;
       
   638     }
       
   639 
       
   640 EXPORT_C CPbkViewState* CPbkContactViewListControl::GetStateLC
       
   641         (TBool aSaveMarks/*=ETrue*/) const
       
   642     {
       
   643     // Create a state object
       
   644     CPbkViewState* state = CPbkViewState::NewLC();
       
   645 
       
   646     // Init the state object
       
   647     if (NumberOfItems() > 0)
       
   648         {
       
   649         TInt index;
       
   650         if ((index = ListBox().TopItemIndex()) >= 0)
       
   651             {
       
   652             state->SetTopContactId(ContactIdAtL(index));
       
   653             }
       
   654         if ((index = ListBox().CurrentItemIndex()) >= 0)
       
   655             {
       
   656             state->SetFocusedContactId(ContactIdAtL(index));
       
   657             }
       
   658         if (aSaveMarks && ItemsMarked())
       
   659             {
       
   660             state->SetMarkedContactIds(CContactIdArray::NewL(&MarkedItemsL()));
       
   661             }
       
   662         }
       
   663 
       
   664     // Return the state object
       
   665     return state;
       
   666     }
       
   667 
       
   668 EXPORT_C void CPbkContactViewListControl::RestoreStateL(const CPbkViewState* aState)
       
   669     {
       
   670     PBK_DEBUG_PRINT(
       
   671         PBK_DEBUG_STRING("CPbkContactViewListControl::RestoreStateL(0x%x,0x%x)"),
       
   672         this, aState);
       
   673 
       
   674     if (!aState || !iStateFlags.IsSet(EReady))
       
   675         {
       
   676         return;
       
   677         }
       
   678 
       
   679     CEikColumnListBox& listBox = ListBox();
       
   680     TBool redraw = EFalse;
       
   681     if (aState->Flags() & CPbkViewState::EInitialized)
       
   682         {
       
   683         // Find box is recreated because default input language needs to
       
   684         // be reset here if Always on feature is enabled for Phonebook
       
   685         delete iFindBox;
       
   686         iFindBox=NULL;
       
   687 
       
   688         // Do not enable the find box if there does not exist any contacts
       
   689         if (iBaseView->CountL() > 0)
       
   690             {
       
   691             EnableFindBoxL();
       
   692             }
       
   693 
       
   694         listBox.Reset();
       
   695         redraw = ETrue;
       
   696         }
       
   697     else
       
   698         {
       
   699         if (iBaseView->CountL() > 0)
       
   700             {
       
   701             if (aState->Flags() & CPbkViewState::EFocusFirst)
       
   702                 {
       
   703                 listBox.SetTopItemIndex(0);
       
   704                 }
       
   705             else if (aState->Flags() & CPbkViewState::EFocusLast)
       
   706                 {
       
   707                 listBox.SetCurrentItemIndex(listBox.Model()->NumberOfItems());
       
   708                 }
       
   709             else
       
   710                 {
       
   711                 // Restore top item
       
   712                 if (aState->TopContactId() != KNullContactId)
       
   713                     {
       
   714                     const TInt index = FindContactIdL(aState->TopContactId());
       
   715                     if (index >= 0)
       
   716                         {
       
   717                         const TInt prevIndex = listBox.TopItemIndex();
       
   718                         listBox.SetTopItemIndex(index);
       
   719                         FixTopItemIndex();
       
   720                         if (index != prevIndex)
       
   721                             {
       
   722                             redraw = ETrue;
       
   723                             }
       
   724                         }
       
   725                     }
       
   726 
       
   727                 // Restore focus
       
   728                 if (aState->FocusedContactId() != KNullContactId)
       
   729                     {
       
   730                     const TInt index = FindContactIdL(aState->FocusedContactId());
       
   731                     if (index >= 0)
       
   732                         {
       
   733                         const TInt prevIndex = listBox.CurrentItemIndex();
       
   734                         listBox.SetCurrentItemIndex(index);
       
   735                         if (index != prevIndex)
       
   736                             {
       
   737                             redraw = ETrue;
       
   738                             }
       
   739                         }
       
   740                     }
       
   741 
       
   742                 }
       
   743             // Restore selections
       
   744             const CContactIdArray* markedContactIds = aState->MarkedContactIds();
       
   745             if (RestoreMarkedItemsL(markedContactIds))
       
   746                 {
       
   747                 redraw = ETrue;
       
   748                 }
       
   749             }
       
   750         }
       
   751 
       
   752     if (redraw)
       
   753         {
       
   754         Redraw();
       
   755         iListBox->UpdateScrollBarsL();
       
   756         HandleFocusChange();
       
   757         }
       
   758     }
       
   759 
       
   760 void CPbkContactViewListControl::ShowThumbnail(TContactItemId aContactId)
       
   761     {
       
   762     if (!iThumbnailPopup && iEngine)
       
   763         {
       
   764         TRAP_IGNORE(iThumbnailPopup = CPbkThumbnailPopup::NewL( *iEngine ));
       
   765         }
       
   766 
       
   767     if (iThumbnailPopup && aContactId!=KNullContactId  && IsReadyToDraw() &&
       
   768         !iStateFlags.IsSet(EBlank))
       
   769         {
       
   770         iThumbnailPopup->Load(aContactId, iListBox);
       
   771         }
       
   772     else if (iThumbnailPopup)
       
   773         {
       
   774         iThumbnailPopup->CancelLoading();
       
   775         }
       
   776     }
       
   777 
       
   778 EXPORT_C void CPbkContactViewListControl::ShowThumbnailL()
       
   779     {
       
   780     if (!iThumbnailPopup && iEngine)
       
   781         {
       
   782         iThumbnailPopup = CPbkThumbnailPopup::NewL( *iEngine );
       
   783         }
       
   784 
       
   785     if (iLastFocusId!=KNullContactId  && IsReadyToDraw() &&
       
   786         !iStateFlags.IsSet(EBlank))
       
   787         {
       
   788         iThumbnailPopup->Load(iLastFocusId, iListBox);
       
   789         }
       
   790     else
       
   791         {
       
   792         iThumbnailPopup->CancelLoading();
       
   793         }
       
   794     }
       
   795 
       
   796 EXPORT_C void CPbkContactViewListControl::HideThumbnail()
       
   797     {
       
   798     if (iThumbnailPopup)
       
   799         {
       
   800         iThumbnailPopup->CancelLoading();
       
   801         }
       
   802     }
       
   803 
       
   804 EXPORT_C void CPbkContactViewListControl::AddObserverL
       
   805         (MPbkContactViewListControlObserver& aObserver)
       
   806     {
       
   807     User::LeaveIfError(iObservers.Append(&aObserver));
       
   808     }
       
   809 
       
   810 EXPORT_C void CPbkContactViewListControl::RemoveObserver
       
   811         (MPbkContactViewListControlObserver& aObserver)
       
   812     {
       
   813     const TInt index = iObservers.Find(&aObserver);
       
   814     if (index >= 0)
       
   815         {
       
   816         iObservers.Remove(index);
       
   817         }
       
   818     }
       
   819 
       
   820 EXPORT_C TBool CPbkContactViewListControl::IsReady() const
       
   821     {
       
   822     return (iStateFlags.IsSet(EReady));
       
   823     }
       
   824 
       
   825 void CPbkContactViewListControl::SetDisableRedraw(TBool aDisableRedraw)
       
   826     {
       
   827     ListBox().View()->SetDisableRedraw(aDisableRedraw);
       
   828     }
       
   829 
       
   830 void CPbkContactViewListControl::DisableRedrawEnablePushL()
       
   831     {
       
   832     CListBoxView& listBoxView = *ListBox().View();
       
   833     listBoxView.SetDisableRedraw(ETrue);
       
   834     CleanupStack::PushL(TCleanupEnableListBoxViewRedraw(listBoxView));
       
   835     }
       
   836 
       
   837 EXPORT_C void CPbkContactViewListControl::SetBlank(TBool aBlank)
       
   838     {
       
   839     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
   840         ("CPbkContactViewListControl::SetBlank(0x%x,%d)"),this,aBlank);
       
   841 
       
   842     if ((iStateFlags.IsSet(EBlank) && aBlank) ||
       
   843         (!iStateFlags.IsSet(EBlank) && !aBlank))
       
   844         {
       
   845         // No change in state
       
   846         return;
       
   847         }
       
   848 
       
   849     // Set the EBlank flag
       
   850     iStateFlags.Assign(EBlank,aBlank);
       
   851 
       
   852     // Hide/unhide component controls
       
   853     MakeComponentsVisible(!aBlank);
       
   854     Redraw();
       
   855     }
       
   856 
       
   857 EXPORT_C void CPbkContactViewListControl::SetEntryLoader
       
   858         (MPbkContactEntryLoader& aContactEntryLoader)
       
   859     {
       
   860     Model().SetEntryLoader(aContactEntryLoader);
       
   861     }
       
   862 
       
   863 
       
   864 void CPbkContactViewListControl::SetSelectionAccepter(MPbkFetchDlgSelection* aAccepter)
       
   865     {
       
   866     iSelectionAccepter = aAccepter;
       
   867     }
       
   868 
       
   869 TInt CPbkContactViewListControl::NumberOfItems() const
       
   870     {
       
   871     return ListBox().Model()->NumberOfItems();
       
   872     }
       
   873 
       
   874 TBool CPbkContactViewListControl::ItemsMarked() const
       
   875     {
       
   876     const CListBoxView::CSelectionIndexArray* selections =
       
   877         ListBox().View()->SelectionIndexes();
       
   878     return (selections && selections->Count()>0);
       
   879     }
       
   880 
       
   881 const CContactIdArray& CPbkContactViewListControl::MarkedItemsL() const
       
   882     {
       
   883     if (!iMarkedItemsArray)
       
   884         {
       
   885         iMarkedItemsArray = CContactIdArray::NewL();
       
   886         }
       
   887 
       
   888     // Remove old contents of array (use Remove instead of Reset to keep the
       
   889     // array buffer)
       
   890     iMarkedItemsArray->Remove(0,iMarkedItemsArray->Count());
       
   891 
       
   892     // Get the list boxes marked items index array
       
   893     const CListBoxView::CSelectionIndexArray* selArray =
       
   894         ListBox().SelectionIndexes();
       
   895 
       
   896     if (selArray && selArray->Count() > 0)
       
   897         {
       
   898         // Initialize the marked contact id array using selArray
       
   899         CContactViewBase::TVirtualFunction1Params params
       
   900             (selArray, iMarkedItemsArray);
       
   901 
       
   902         iView->CContactViewBase_Reserved_1
       
   903             (CContactViewBase::ECContactViewBaseVirtualFunction1, &params);
       
   904         }
       
   905     else
       
   906         {
       
   907         // No items marked, add the focused contact to the array
       
   908         iMarkedItemsArray->AddL(FocusedContactIdL());
       
   909         }
       
   910 
       
   911     return *iMarkedItemsArray;
       
   912     }
       
   913 
       
   914 TContactItemId CPbkContactViewListControl::FocusedContactIdL() const
       
   915     {
       
   916     TContactItemId retId(KNullContactId);
       
   917 
       
   918     const TInt focusIndex = ListBox().CurrentItemIndex();
       
   919     if (focusIndex >= 0)
       
   920         {
       
   921         retId = iView->AtL(focusIndex);
       
   922         }
       
   923     return retId;
       
   924     }
       
   925 
       
   926 const TPbkContactItemField* CPbkContactViewListControl::FocusedField() const
       
   927     {
       
   928     // This control does not support field level focus
       
   929     return NULL;
       
   930     }
       
   931 
       
   932 MObjectProvider* CPbkContactViewListControl::ObjectProvider()
       
   933     {
       
   934     return this;
       
   935     }
       
   936 
       
   937 TKeyResponse CPbkContactViewListControl::OfferKeyEventL
       
   938         (const TKeyEvent& aKeyEvent,TEventCode aType)
       
   939     {
       
   940     if (!iStateFlags.IsSet(EReady) || iStateFlags.IsSet(EBlank))
       
   941         {
       
   942         // Don't handle any keys when not ready or blanked
       
   943         return EKeyWasNotConsumed;
       
   944         }
       
   945 
       
   946     TKeyResponse result = EKeyWasNotConsumed;
       
   947 
       
   948     if (iFindBox)
       
   949         {
       
   950         // Find box is active, offer key first to it
       
   951         result = iFindBox->OfferKeyEventL(aKeyEvent, aType);
       
   952         }
       
   953 
       
   954     if (result == EKeyWasNotConsumed && iListBox)
       
   955         {
       
   956         // Find box didn't consume the event -> offer it to the list box
       
   957         const TInt focusIndex = iListBox->CurrentItemIndex();
       
   958         const TBool markedBefore = ItemMarked(focusIndex);
       
   959 
       
   960         // If selection key was pressed and the focused contact was earlier
       
   961         // unselected, then first check from selection accepter if this item
       
   962         // can be selected
       
   963         // Also do the acception-check if there are no selected items and
       
   964         // OK-softkey was pressed (causing focused item to be selected and
       
   965         // closing the dialog
       
   966         TBool checkSelection = EFalse;
       
   967         const CListBoxView::CSelectionIndexArray* selArray =
       
   968                 ListBox().SelectionIndexes();
       
   969         
       
   970         
       
   971         const TInt selectionKeyPressed(aKeyEvent.iCode == EKeyDevice3);
       
   972         
       
   973         // AVKON may create EKeyApplicationF key event 
       
   974         // when list item is selected.
       
   975         const TInt avkonSelectionKeyNotification(
       
   976                         aKeyEvent.iCode == EKeyApplicationF);
       
   977                         
       
   978         const TBool noSelectionMade(!selArray||selArray->Count() == 0 );
       
   979         
       
   980         const TBool validNewFocusedItem(
       
   981                         !markedBefore && focusIndex >= KErrNone);
       
   982 
       
   983         if ((selectionKeyPressed || (avkonSelectionKeyNotification && noSelectionMade))
       
   984             && validNewFocusedItem)
       
   985             {
       
   986             checkSelection = ETrue;
       
   987             }
       
   988         
       
   989         const CListBoxView::CSelectionIndexArray* selections =
       
   990             ListBox().SelectionIndexes();
       
   991         TInt selCount = selections ? selections->Count() : 0;
       
   992         
       
   993         if (!checkSelection || !iSelectionAccepter ||
       
   994             focusIndex != KErrNotFound &&
       
   995             iSelectionAccepter->ContactSelectionAcceptedL(
       
   996                 ContactIdAtL(focusIndex), selCount))
       
   997             {
       
   998             result = iListBox->OfferKeyEventL(aKeyEvent, aType);
       
   999 
       
  1000             if (result == EKeyWasConsumed)
       
  1001                 {
       
  1002                 const TBool markedAfter = ItemMarked(focusIndex);
       
  1003                 if (markedAfter != markedBefore)
       
  1004                     {
       
  1005                     TPbkContactViewListControlEvent
       
  1006                         event(TPbkContactViewListControlEvent::EContactSelected);
       
  1007                     event.iInt = focusIndex;
       
  1008                     event.iContactId = ContactIdAtL(focusIndex);
       
  1009                     if (!markedAfter)
       
  1010                         {
       
  1011                         event.iEventType =
       
  1012                             TPbkContactViewListControlEvent::EContactUnselected;
       
  1013                         }
       
  1014                     SendEventToObserversL(event);
       
  1015                     }                
       
  1016                 }
       
  1017             }
       
  1018         else
       
  1019             {
       
  1020             result = EKeyWasConsumed;
       
  1021             }
       
  1022         }
       
  1023     return result;
       
  1024     }
       
  1025 
       
  1026 void CPbkContactViewListControl::HandlePointerEventL(
       
  1027         const TPointerEvent& aPointerEvent )
       
  1028     {
       
  1029     if ( AknLayoutUtils::PenEnabled() )
       
  1030         {
       
  1031         if ( iFindBox )
       
  1032             {
       
  1033             iFindBox->HandlePointerEventL( aPointerEvent );
       
  1034             }
       
  1035 
       
  1036         if ( iListBox )
       
  1037             {
       
  1038             switch ( aPointerEvent.iType )
       
  1039                 {
       
  1040                 case TPointerEvent::EButton1Down:
       
  1041                     {
       
  1042                     iPrevIndex = iListBox->CurrentItemIndex();
       
  1043                     iListBox->HandlePointerEventL( aPointerEvent );
       
  1044                     break;
       
  1045                     }
       
  1046                 case TPointerEvent::EButton1Up:
       
  1047                     {
       
  1048                     TInt focusIndex;
       
  1049                     TBool focusableContactPointed =
       
  1050                         iListBox->View()->XYPosToItemIndex(
       
  1051                             aPointerEvent.iPosition, focusIndex );
       
  1052                     if (!focusableContactPointed || focusIndex < 0)
       
  1053                         {
       
  1054                         // Nothing special to do when tapping empty space
       
  1055                         iListBox->HandlePointerEventL( aPointerEvent );
       
  1056                         }
       
  1057                     else
       
  1058                         {
       
  1059                         // Send contact tap events                        
       
  1060                         TPbkContactViewListControlEvent event(
       
  1061                             TPbkContactViewListControlEvent::EContactTapped );
       
  1062                         event.iInt = focusIndex;
       
  1063                         event.iContactId = ContactIdAtL( focusIndex );
       
  1064                         if ( iPrevIndex == iListBox->CurrentItemIndex() )
       
  1065                             {
       
  1066                             event.iEventType =
       
  1067                                 TPbkContactViewListControlEvent::EContactDoubleTapped;
       
  1068                             }
       
  1069                         SendEventToObserversL( event );
       
  1070 
       
  1071                         // Do markings
       
  1072                         const TBool markedBefore = ItemMarked(focusIndex);
       
  1073                         const CListBoxView::CSelectionIndexArray* selections =
       
  1074                             ListBox().SelectionIndexes();
       
  1075                         TInt selCount = selections ? selections->Count() : 0;
       
  1076 
       
  1077                         if ( markedBefore ||         // can unmark always
       
  1078                              !iSelectionAccepter ||  // no select restrictions
       
  1079                              iSelectionAccepter->ContactSelectionAcceptedL(
       
  1080                                 ContactIdAtL(focusIndex), selCount) )
       
  1081                             {
       
  1082                             // Handle the pointer event to list box to fix the problem that items in multiple
       
  1083                             // fetch dialog can't be select with touch screen.
       
  1084                             iListBox->HandlePointerEventL( aPointerEvent );
       
  1085                             
       
  1086                             const TBool markedAfter = ItemMarked( focusIndex );
       
  1087                             if ( markedAfter != markedBefore )
       
  1088                                 {
       
  1089                                 event.iEventType =
       
  1090                                     TPbkContactViewListControlEvent::EContactSelected;
       
  1091                                 event.iInt = focusIndex;
       
  1092                                 event.iContactId = ContactIdAtL(focusIndex);
       
  1093                                 if (!markedAfter)
       
  1094                                     {
       
  1095                                     event.iEventType =
       
  1096                                         TPbkContactViewListControlEvent::EContactUnselected;
       
  1097                                     }
       
  1098                                 SendEventToObserversL(event);
       
  1099                                 }
       
  1100                             }
       
  1101                         }
       
  1102                     break;
       
  1103                     }
       
  1104                 default:
       
  1105                     {
       
  1106                     iListBox->HandlePointerEventL( aPointerEvent );
       
  1107                     }
       
  1108                 }
       
  1109             }
       
  1110         }
       
  1111     }
       
  1112 
       
  1113 void CPbkContactViewListControl::MakeVisible(TBool aVisible)
       
  1114     {
       
  1115     PBK_DEBUG_PRINT(
       
  1116         PBK_DEBUG_STRING("CPbkContactViewListControl::MakeVisible(0x%x,%d)"),
       
  1117         this, aVisible);
       
  1118 
       
  1119     CCoeControl::MakeVisible(aVisible);
       
  1120     MakeComponentsVisible(aVisible);
       
  1121     }
       
  1122 
       
  1123 void CPbkContactViewListControl::UpdateContact(TContactItemId aContactId)
       
  1124     {
       
  1125     TInt listBoxRow = -1;
       
  1126     TRAPD(err, listBoxRow = FindContactIdL(aContactId) );
       
  1127     if (err)
       
  1128         {
       
  1129         iEikonEnv->NotifyIdleErrorWhileRedrawing(err);
       
  1130         }
       
  1131     if (listBoxRow >= 0)
       
  1132         {
       
  1133         // if visible
       
  1134         if (listBoxRow >= ListBox().TopItemIndex() &&
       
  1135             listBoxRow <= ListBox().BottomItemIndex() )
       
  1136             {
       
  1137             ListBox().DrawItem(listBoxRow);
       
  1138             }
       
  1139         }
       
  1140     }
       
  1141 
       
  1142 TInt CPbkContactViewListControl::CountComponentControls() const
       
  1143     {
       
  1144     TInt controls = 0;
       
  1145     if (iListBox)
       
  1146         {
       
  1147         ++controls;
       
  1148         }
       
  1149     if (iFindBox)
       
  1150         {
       
  1151         ++controls;
       
  1152         }
       
  1153     return controls;
       
  1154     }
       
  1155 
       
  1156 CCoeControl* CPbkContactViewListControl::ComponentControl(TInt aIndex) const
       
  1157     {
       
  1158     switch (aIndex)
       
  1159         {
       
  1160         case 0:
       
  1161             {
       
  1162             __ASSERT_DEBUG(iListBox, Panic(EPanicLogic_ComponentControl));
       
  1163             return iListBox;
       
  1164             }
       
  1165         case 1:
       
  1166             {
       
  1167             __ASSERT_DEBUG(iFindBox, Panic(EPanicLogic_ComponentControl));
       
  1168             return iFindBox;
       
  1169             }
       
  1170         default:
       
  1171             {
       
  1172             // Illegal state
       
  1173             __ASSERT_DEBUG(EFalse, Panic(EPanicLogic_ComponentControl));
       
  1174             return NULL;
       
  1175             }
       
  1176         }
       
  1177     }
       
  1178 
       
  1179 void CPbkContactViewListControl::FocusChanged(TDrawNow aDrawNow)
       
  1180     {
       
  1181     const TBool focused = IsFocused();
       
  1182     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1183         ("CPbkContactViewListControl::FocusChanged(0x%x,%d),focused=%d"),
       
  1184         this, aDrawNow, focused ? ETrue : EFalse);
       
  1185 
       
  1186     if (focused)
       
  1187         {
       
  1188         ShowThumbnail(iLastFocusId);
       
  1189         }
       
  1190     else
       
  1191         {
       
  1192         HideThumbnail();
       
  1193         }
       
  1194 
       
  1195     const TInt count = CountComponentControls();
       
  1196     for (TInt i=0; i < count; ++i)
       
  1197         {
       
  1198         CCoeControl* componentControl = ComponentControl(i);
       
  1199         // Don't try to focus non-focusing controls
       
  1200         if (!componentControl->IsNonFocusing())
       
  1201             {
       
  1202             componentControl->SetFocus(focused,aDrawNow);
       
  1203             }
       
  1204         }
       
  1205     }
       
  1206 
       
  1207 void CPbkContactViewListControl::SizeChanged()
       
  1208     {
       
  1209     const TRect rect(Rect());
       
  1210     PBK_DEBUG_PRINT(
       
  1211         PBK_DEBUG_STRING("CPbkContactViewListControl::SizeChanged(0x%x), rect=(%d,%d,%d,%d)"),
       
  1212         this, rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
       
  1213 
       
  1214     if (iListBox && iFindBox)
       
  1215         {
       
  1216         AknLayoutUtils::LayoutControl(iListBox, rect,
       
  1217             AKN_LAYOUT_WINDOW_list_gen_pane(1));
       
  1218         AknLayoutUtils::LayoutControl(iFindBox, rect,
       
  1219             AKN_LAYOUT_WINDOW_find_pane);
       
  1220         if (iFindBox->IsVisible() && iListBox->IsVisible())
       
  1221             {
       
  1222             // The correct line position to use is 2, which corresponds
       
  1223             // EABColumn in Avkon (not a public enumeration,
       
  1224             // hence hard-coding used here)
       
  1225             const TInt KSeparatorLinePos = 2;
       
  1226             iFindBox->SetLinePos(KSeparatorLinePos);
       
  1227             }
       
  1228         }
       
  1229     else if (iListBox)
       
  1230         {
       
  1231         AknLayoutUtils::LayoutControl(iListBox, rect,
       
  1232             AKN_LAYOUT_WINDOW_list_gen_pane(0));
       
  1233         }
       
  1234     }
       
  1235 
       
  1236 void CPbkContactViewListControl::Draw(const TRect& aRect) const
       
  1237     {
       
  1238     PBK_DEBUG_PRINT(PBK_DEBUG_STRING(
       
  1239         "CPbkContactViewListControl::Draw(0x%x, TRect(%d,%d,%d,%d)), iStateFlags=0x%x"),
       
  1240         this, aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY, iStateFlags.iFlags);
       
  1241 
       
  1242     if (!iStateFlags.IsSet(EReady) || iStateFlags.IsSet(EBlank))
       
  1243         {
       
  1244         // If control is not ready or blanked draw a blank background
       
  1245         CWindowGc& gc = SystemGc();
       
  1246         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1247         MAknsControlContext* cc = AknsDrawUtils::ControlContext(iListBox);
       
  1248         if ( !AknsDrawUtils::Background(skin, cc, iListBox, gc, aRect) )
       
  1249             {
       
  1250             // blank background if no skin present
       
  1251             gc.SetPenStyle(CGraphicsContext::ENullPen);
       
  1252             gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1253             gc.DrawRect(aRect);
       
  1254             }
       
  1255         }
       
  1256     }
       
  1257 
       
  1258 void CPbkContactViewListControl::HandleControlEventL
       
  1259         (CCoeControl* aControl,
       
  1260         TCoeEvent aEventType)
       
  1261     {
       
  1262     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1263         ("CPbkContactViewListControl::HandleControlEventL(0x%x,0x%x,%d)"),
       
  1264         this, aControl, aEventType);
       
  1265 
       
  1266     if (aEventType == EEventStateChanged)
       
  1267         {
       
  1268         if (aControl == iListBox)
       
  1269             {
       
  1270             HandleFocusChange();
       
  1271             // Forward listbox state change events to this control's
       
  1272             // observers
       
  1273             ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  1274             }
       
  1275         else if (aControl == iFindBox)
       
  1276             {
       
  1277             UpdateFindResultL();
       
  1278             }
       
  1279         }
       
  1280     }
       
  1281 
       
  1282 void CPbkContactViewListControl::HandleContactViewEvent
       
  1283         (const CContactViewBase& aView,const TContactViewEvent& aEvent)
       
  1284     {
       
  1285     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1286         ("CPbkContactViewListControl::HandleContactViewEvent(0x%x,0x%x,%d)"),
       
  1287         this, &aView, aEvent.iEventType);
       
  1288 
       
  1289     if (&aView == iView)
       
  1290         {
       
  1291         TRAPD(err, DoHandleContactViewEventL(aView,aEvent));
       
  1292         if (err != KErrNone)
       
  1293             {
       
  1294             iEikonEnv->HandleError(err);
       
  1295             }
       
  1296         }
       
  1297     }
       
  1298 
       
  1299 /**
       
  1300  * Called from HandleContactViewEvent().
       
  1301  */
       
  1302 void CPbkContactViewListControl::DoHandleContactViewEventL
       
  1303         (const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent)
       
  1304     {
       
  1305     switch (aEvent.iEventType)
       
  1306         {
       
  1307         case TContactViewEvent::EReady:
       
  1308             {
       
  1309             iStateFlags.Set(EReady);
       
  1310             MakeComponentsVisible(IsVisible());
       
  1311             iListBox->Reset();
       
  1312             UpdateFindBoxL();
       
  1313             iListBox->UpdateScrollBarsL();
       
  1314             Redraw();
       
  1315             HandleFocusChange();
       
  1316             SendEventToObserversL(TPbkContactViewListControlEvent::EReady);
       
  1317             break;
       
  1318             }
       
  1319 
       
  1320         case TContactViewEvent::ESortOrderChanged:
       
  1321             {
       
  1322             Model().FlushCache();
       
  1323             Model().RefreshSortOrderL();
       
  1324             iStateFlags.Set(EReady);
       
  1325             MakeComponentsVisible(IsVisible());
       
  1326             iListBox->Reset();
       
  1327             UpdateFindBoxL();
       
  1328             iListBox->UpdateScrollBarsL();
       
  1329             Redraw();
       
  1330             HandleFocusChange();
       
  1331             // Send EReady event
       
  1332             SendEventToObserversL(TPbkContactViewListControlEvent::EReady);
       
  1333             break;
       
  1334             }
       
  1335 
       
  1336         case TContactViewEvent::EItemAdded:
       
  1337             {
       
  1338             HandleItemAdditionL(aEvent.iInt);
       
  1339             TPbkContactViewListControlEvent event
       
  1340                 (TPbkContactViewListControlEvent::EItemAdded);
       
  1341             event.iInt = aEvent.iInt;
       
  1342             event.iContactId = aEvent.iContactId;
       
  1343             SendEventToObserversL(event);
       
  1344             break;
       
  1345             }
       
  1346 
       
  1347         case TContactViewEvent::EItemRemoved:
       
  1348             {
       
  1349             Model().PurgeEntry(aEvent.iContactId);
       
  1350             HandleItemRemovalL(aEvent.iInt);
       
  1351             TPbkContactViewListControlEvent event
       
  1352                 (TPbkContactViewListControlEvent::EItemRemoved);
       
  1353             event.iInt = aEvent.iInt;
       
  1354             event.iContactId = aEvent.iContactId;
       
  1355             SendEventToObserversL(event);
       
  1356             break;
       
  1357             }
       
  1358 
       
  1359         case TContactViewEvent::EUnavailable:
       
  1360             {
       
  1361             iStateFlags.Clear(EReady);
       
  1362             MakeComponentsVisible(EFalse);
       
  1363             SendEventToObserversL
       
  1364                 (TPbkContactViewListControlEvent::EUnavailable);
       
  1365             break;
       
  1366             }
       
  1367 
       
  1368         case TContactViewEvent::ESortError:  //FALLTHROUGH
       
  1369         case TContactViewEvent::EServerError:  //FALLTHROUGH
       
  1370         case TContactViewEvent::EIndexingError:
       
  1371             {
       
  1372             iStateFlags.Clear(EReady);
       
  1373             MakeComponentsVisible(EFalse);
       
  1374             iEikonEnv->HandleError(aEvent.iInt);
       
  1375             iListBox->Reset();
       
  1376             DisableFindBoxL();
       
  1377             TPbkContactViewListControlEvent event
       
  1378                 (TPbkContactViewListControlEvent::EUnavailable);
       
  1379             event.iInt = aEvent.iInt;
       
  1380             SendEventToObserversL(event);
       
  1381             break;
       
  1382             }
       
  1383 
       
  1384         default:
       
  1385             {
       
  1386             break;
       
  1387             }
       
  1388         }
       
  1389     }
       
  1390 
       
  1391 void CPbkContactViewListControl::SendEventToObserversL
       
  1392         (const TPbkContactViewListControlEvent& aEvent)
       
  1393     {
       
  1394     // Loop backwards in case some observer destroys itself in the
       
  1395     // event handler
       
  1396     for (TInt i=iObservers.Count()-1; i>=0; --i)
       
  1397         {
       
  1398         iObservers[i]->HandleContactViewListControlEventL(*this,aEvent);
       
  1399         }
       
  1400     }
       
  1401 
       
  1402 void CPbkContactViewListControl::ConstructL
       
  1403         (CPbkContactEngine& aEngine,
       
  1404         CContactViewBase& aView,
       
  1405         TInt aResourceId,
       
  1406         const CCoeControl* aParent)
       
  1407     {
       
  1408     if (aParent)
       
  1409         {
       
  1410         SetContainerWindowL(*aParent);
       
  1411         }
       
  1412     else
       
  1413         {
       
  1414         CreateWindowL();
       
  1415         }
       
  1416     ConstructFromResourceL(aResourceId);
       
  1417     ConstructL(aEngine, aView);
       
  1418     CreateControlExtensionL(aEngine);
       
  1419     }
       
  1420 
       
  1421 void CPbkContactViewListControl::ConstructFromResourceL
       
  1422         (TInt aResourceId)
       
  1423     {
       
  1424     TResourceReader resReader;
       
  1425     iCoeEnv->CreateResourceReaderLC(resReader,aResourceId);
       
  1426     ConstructFromResourceL(resReader);
       
  1427     CleanupStack::PopAndDestroy();  // resReader
       
  1428     }
       
  1429 
       
  1430 void CPbkContactViewListControl::FixTopItemIndex()
       
  1431     {
       
  1432     CEikListBox& listBox = ListBox();
       
  1433     TInt index = listBox.TopItemIndex();
       
  1434     const TInt height = listBox.View()->NumberOfItemsThatFitInRect
       
  1435         (iListBox->View()->ViewRect());
       
  1436     const TInt numItems = listBox.Model()->NumberOfItems();
       
  1437     if (index + height > numItems)
       
  1438         {
       
  1439         index += numItems - (height + index);
       
  1440         if (index < 0)
       
  1441             {
       
  1442             index = 0;
       
  1443             }
       
  1444         if (index != listBox.TopItemIndex())
       
  1445             {
       
  1446             listBox.SetTopItemIndex(index);
       
  1447             }
       
  1448         }
       
  1449     }
       
  1450 
       
  1451 /**
       
  1452  * Redraws this control using DrawDeferred().
       
  1453  */
       
  1454 void CPbkContactViewListControl::Redraw()
       
  1455     {
       
  1456     if (iStateFlags.IsSet(EReady) && !iStateFlags.IsSet(EBlank))
       
  1457         {
       
  1458         DrawDeferred();
       
  1459         }
       
  1460     }
       
  1461 
       
  1462 void CPbkContactViewListControl::MakeComponentsVisible(TBool aVisible)
       
  1463     {
       
  1464     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1465         ("CPbkContactViewListControl::MakeComponentsVisible(0x%x,%d)"),
       
  1466         this, aVisible);
       
  1467 
       
  1468     if (aVisible && (!iStateFlags.IsSet(EReady) || iStateFlags.IsSet(EBlank)))
       
  1469         {
       
  1470         // Never make components visible if this control is not ready or in
       
  1471         // blank state
       
  1472         return;
       
  1473         }
       
  1474 
       
  1475     if (iListBox)
       
  1476         {
       
  1477         iListBox->MakeVisible(aVisible);
       
  1478         }
       
  1479 
       
  1480     if (iFindBox)
       
  1481         {
       
  1482         iFindBox->SetFocus(aVisible);
       
  1483         iFindBox->MakeVisible(aVisible);
       
  1484         }
       
  1485 
       
  1486     // Hide/show thumbnail
       
  1487     if (aVisible)
       
  1488         {
       
  1489         ShowThumbnail(iLastFocusId);
       
  1490         }
       
  1491     else
       
  1492         {
       
  1493         HideThumbnail();
       
  1494         }
       
  1495     }
       
  1496 
       
  1497 void CPbkContactViewListControl::HandleItemAdditionL(TInt aIndex)
       
  1498     {
       
  1499     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1500         ("CPbkContactViewListControl::HandleItemAdditionL(0x%x, %d)"),
       
  1501         this, aIndex);
       
  1502 
       
  1503     UpdateFindBoxL();
       
  1504 
       
  1505     // Update listbox
       
  1506     iChangedIndexes[0] = aIndex;
       
  1507     iListBox->HandleItemAdditionL(iChangedIndexes);
       
  1508 
       
  1509     // Maintain focus
       
  1510     const TInt index = iView->FindL(iLastFocusId);
       
  1511     if ( index >= 0 &&
       
  1512          index < iListBox->Model()->NumberOfItems() &&
       
  1513          index != iListBox->CurrentItemIndex() )
       
  1514         {
       
  1515         iListBox->SetCurrentItemIndex(index);
       
  1516         }
       
  1517     Redraw();
       
  1518     HandleFocusChange();
       
  1519     }
       
  1520 
       
  1521 void CPbkContactViewListControl::HandleItemRemovalL(TInt aIndex)
       
  1522     {
       
  1523     PBK_DEBUG_PRINT(PBK_DEBUG_STRING
       
  1524         ("CPbkContactViewListControl::HandleItemRemovalL(0x%x, %d)"),
       
  1525         this, aIndex);
       
  1526 
       
  1527     // Deselect item
       
  1528     CListBoxView& listBoxView = *ListBox().View();
       
  1529     listBoxView.SetDisableRedraw(ETrue);
       
  1530     listBoxView.DeselectItem(aIndex);
       
  1531     listBoxView.SetDisableRedraw(EFalse);
       
  1532 
       
  1533     UpdateFindBoxL();
       
  1534 
       
  1535     // Update listbox
       
  1536     TInt focusIndex = iListBox->CurrentItemIndex();
       
  1537     TInt topIndex = iListBox->TopItemIndex();
       
  1538     iChangedIndexes[0] = aIndex;
       
  1539     iListBox->HandleItemRemovalL(iChangedIndexes);
       
  1540 
       
  1541     // Maintain focus
       
  1542     const TInt lastIndex = iListBox->Model()->NumberOfItems() - 1;
       
  1543     if (lastIndex == KNullContactId)
       
  1544         {
       
  1545         iListBox->Reset();
       
  1546         }
       
  1547     else
       
  1548         {
       
  1549         if (aIndex < focusIndex)
       
  1550             {
       
  1551             --focusIndex;
       
  1552             }
       
  1553         if (focusIndex > lastIndex || focusIndex < 0)
       
  1554             {
       
  1555             focusIndex = lastIndex;
       
  1556             }
       
  1557         const TInt numVisibleItems =
       
  1558             iListBox->View()->NumberOfItemsThatFitInRect
       
  1559                 (iListBox->View()->ViewRect());
       
  1560         if (topIndex + numVisibleItems > lastIndex)
       
  1561             {
       
  1562             topIndex = Max(lastIndex - numVisibleItems + 1, 0);
       
  1563             }
       
  1564         if (topIndex >= 0)
       
  1565             {
       
  1566             iListBox->SetTopItemIndex(topIndex);
       
  1567             }
       
  1568         if (focusIndex >= 0)
       
  1569             {
       
  1570             iListBox->SetCurrentItemIndex(focusIndex);
       
  1571             }
       
  1572         }
       
  1573     Redraw();
       
  1574     HandleFocusChange();
       
  1575     }
       
  1576 
       
  1577 /**
       
  1578  * Hides or displays the find box depending on control state.
       
  1579  */
       
  1580 void CPbkContactViewListControl::UpdateFindBoxL()
       
  1581     {
       
  1582     if ((iResourceData.iFlags & KPbkContactViewListControlFindBox) &&
       
  1583         iBaseView->CountL() > 0)
       
  1584         {
       
  1585         EnableFindBoxL();
       
  1586         }
       
  1587     else
       
  1588         {
       
  1589         DisableFindBoxL();
       
  1590         }
       
  1591     }
       
  1592 
       
  1593 void CPbkContactViewListControl::EnableFindBoxL()
       
  1594     {
       
  1595     if (!iFindBox)
       
  1596         {
       
  1597         // Create a find box
       
  1598         iFindBox = CAknSearchField::NewL
       
  1599             (*this, CAknSearchField::ESearch, NULL,
       
  1600             CPbkConstants::SearchFieldLength());
       
  1601 
       
  1602         iFindBox->SetObserver(this);
       
  1603         iFindBox->SetFocus(ETrue);
       
  1604         iFindBox->ResetL();
       
  1605 
       
  1606         // Set default input mode to Katakana if current UI language is Japanese
       
  1607         if (FeatureManager::FeatureSupported(KFeatureIdJapanese) &&
       
  1608             (User::Language() == ELangJapanese))
       
  1609             {
       
  1610             CEikEdwin& findEditor = iFindBox->Editor();
       
  1611             findEditor.SetAknEditorInputMode(EAknEditorKatakanaInputMode);
       
  1612             }
       
  1613 
       
  1614         // Inform list box that find is visible again
       
  1615         static_cast<CAknColumnListBoxView*>(iListBox->View())
       
  1616             ->SetFindEmptyListState(ETrue);
       
  1617         SetFindEmptyTextL();
       
  1618 
       
  1619         // Relayout view
       
  1620         SizeChanged();
       
  1621         UpdateFindResultL();
       
  1622         }
       
  1623     __ASSERT_DEBUG(iFindBox, Panic(EPanicPostCond_EnableFindBoxL));
       
  1624     }
       
  1625 
       
  1626 void CPbkContactViewListControl::DisableFindBoxL()
       
  1627     {
       
  1628     if (iFindBox)
       
  1629         {
       
  1630         // Important to set the find box non-focusing before
       
  1631         // deleting it, otherwise the focus changes triggered
       
  1632         // by the removal of the control from stack will focus
       
  1633         // the find box which is under deletion
       
  1634         iFindBox->SetNonFocusing();
       
  1635         delete iFindBox;
       
  1636         iFindBox = NULL;
       
  1637         // Inform list box that find is hidden
       
  1638         static_cast<CAknColumnListBoxView*>(iListBox->View())
       
  1639             ->SetFindEmptyListState(EFalse);
       
  1640         RemoveFindEmptyTextL();
       
  1641 
       
  1642         // Relayout view
       
  1643         SizeChanged();
       
  1644         UpdateFindResultL();
       
  1645         }
       
  1646     __ASSERT_DEBUG(!iFindBox, Panic(EPanicPostCond_DisableFindBoxL));
       
  1647     }
       
  1648 
       
  1649 /**
       
  1650  * Updates find result.
       
  1651  * @return ETrue if there was a change in find result set.
       
  1652  */
       
  1653 TBool CPbkContactViewListControl::UpdateFindResultL()
       
  1654     {
       
  1655     TBool result = EFalse;
       
  1656     const CContactIdArray* markedItems = NULL;
       
  1657     const TInt countBefore = iView->CountL();
       
  1658 
       
  1659     if (ItemsMarked())
       
  1660         {
       
  1661         markedItems = &MarkedItemsL();
       
  1662         }
       
  1663     TRAPD( err,
       
  1664         result = iView->SetFindTextL(FindTextL(), markedItems) );
       
  1665     if (err != KErrNone)
       
  1666         {
       
  1667         iEikonEnv->HandleError(err);
       
  1668         }
       
  1669 
       
  1670     const TInt countAfter = iView->CountL();
       
  1671 
       
  1672     if (err)
       
  1673         {
       
  1674         // Error (possibly OOM), only redraw what remains in the screen
       
  1675         SizeChanged();
       
  1676         Redraw();
       
  1677         }
       
  1678     else if (result)
       
  1679         {
       
  1680         iListBox->DrawDeferred();
       
  1681         if (countAfter > countBefore)
       
  1682             {
       
  1683             iListBox->HandleItemAdditionL();
       
  1684             }
       
  1685         else if (countAfter < countBefore)
       
  1686             {
       
  1687             iListBox->HandleItemRemovalL();
       
  1688             }
       
  1689 
       
  1690         if (markedItems)
       
  1691             {
       
  1692             // Restore item marks
       
  1693             CListBoxView& listBoxView = *iListBox->View();
       
  1694             listBoxView.SetDisableRedraw(ETrue);
       
  1695             CleanupStack::PushL(TCleanupEnableListBoxViewRedraw(listBoxView));
       
  1696             listBoxView.ClearSelection();
       
  1697             const TInt count = markedItems->Count();
       
  1698             #ifdef PBK_BENCHMARK_FIND
       
  1699             TRunningTimes<TInt> timer;
       
  1700             #endif
       
  1701             for (TInt i=0; i < count; ++i)
       
  1702                 {
       
  1703                 const TContactItemId contactId = (*markedItems)[i];
       
  1704                 #ifdef PBK_BENCHMARK_FIND
       
  1705                 timer.Start();
       
  1706                 #endif
       
  1707                 const TInt index =iView->FindL(contactId);
       
  1708                 #ifdef PBK_BENCHMARK_FIND
       
  1709                 timer.Stop();
       
  1710                 #endif
       
  1711                 listBoxView.SelectItemL(index);
       
  1712                 }
       
  1713             #ifdef PBK_BENCHMARK_FIND
       
  1714             RDebug::Print(_L(
       
  1715                 "CPbkContactViewListControl::UpdateFindResultL FindL calls %d tot %d"),
       
  1716                 timer.Count(), timer.Total());
       
  1717             #endif
       
  1718             CleanupStack::PopAndDestroy(); //TCleanupEnableListBoxViewRedraw
       
  1719             }
       
  1720 
       
  1721         // This event is send to observers,
       
  1722         // if contact set of the control is changed
       
  1723         TPbkContactViewListControlEvent
       
  1724             event(TPbkContactViewListControlEvent::EContactSetChanged);
       
  1725         SendEventToObserversL(event);
       
  1726         }
       
  1727 
       
  1728     TInt focusIndex = iView->IndexOfFirstFindMatchL();
       
  1729     if (focusIndex < 0)
       
  1730         {
       
  1731         if (countAfter > 0)
       
  1732             {
       
  1733             focusIndex = 0;
       
  1734             }
       
  1735         }
       
  1736     if (focusIndex >= 0 && focusIndex != iListBox->CurrentItemIndex())
       
  1737         {
       
  1738         iListBox->SetCurrentItemIndexAndDraw(focusIndex);
       
  1739         }
       
  1740     HandleFocusChange();
       
  1741 
       
  1742     return result;
       
  1743     }
       
  1744 
       
  1745 void CPbkContactViewListControl::SetFindEmptyTextL()
       
  1746     {
       
  1747     if (!iOriginalEmptyText)
       
  1748         {
       
  1749         iOriginalEmptyText = iListBox->View()->EmptyListText()->AllocL();
       
  1750         }
       
  1751     iListBox->View()->SetListEmptyTextL(*iResourceData.iFindEmptyText);
       
  1752     }
       
  1753 
       
  1754 void CPbkContactViewListControl::RemoveFindEmptyTextL()
       
  1755     {
       
  1756     if (iOriginalEmptyText)
       
  1757         {
       
  1758         iListBox->View()->SetListEmptyTextL(*iOriginalEmptyText);
       
  1759         }
       
  1760     }
       
  1761 
       
  1762 void CPbkContactViewListControl::HandleFocusChange()
       
  1763     {
       
  1764     TRAP_IGNORE(HandleFocusChangeL());
       
  1765     }
       
  1766 
       
  1767 void CPbkContactViewListControl::HandleFocusChangeL()
       
  1768     {
       
  1769     const TInt index = ListBox().CurrentItemIndex();
       
  1770     TContactItemId newFocusId = KNullContactId;
       
  1771     if (index >= 0 && index < iView->CountL())
       
  1772         {
       
  1773         newFocusId = iView->AtL(index);
       
  1774         }
       
  1775     if (newFocusId != iLastFocusId)
       
  1776         {
       
  1777         iLastFocusId = newFocusId;
       
  1778         HideThumbnail();
       
  1779         ShowThumbnail(newFocusId);
       
  1780         }
       
  1781     }
       
  1782 
       
  1783 /**
       
  1784  * Marks specified contacts in the listbox.
       
  1785  *
       
  1786  * @param aMarkedContactIds contacts to mark.
       
  1787  * @return true if any contacts were marked in the list.
       
  1788  */
       
  1789 TBool CPbkContactViewListControl::RestoreMarkedItemsL
       
  1790         (const CContactIdArray* aMarkedContactIds)
       
  1791     {
       
  1792     CEikListBox& listBox = ListBox();
       
  1793     TBool result = EFalse;
       
  1794     DisableRedrawEnablePushL();
       
  1795     listBox.ClearSelection();
       
  1796     if (aMarkedContactIds)
       
  1797         {
       
  1798         const TInt count = aMarkedContactIds->Count();
       
  1799         for (TInt i=0; i < count; ++i)
       
  1800             {
       
  1801             const TInt index = FindContactIdL((*aMarkedContactIds)[i]);
       
  1802             if (index >= 0)
       
  1803                 {
       
  1804                 listBox.View()->SelectItemL(index);
       
  1805                 result = ETrue;
       
  1806                 }
       
  1807             }
       
  1808         }
       
  1809     CleanupStack::PopAndDestroy();  // DisableRedrawEnablePushL
       
  1810     return result;
       
  1811     }
       
  1812 
       
  1813 /**
       
  1814  * Creates control extension for a model, appends new icons
       
  1815  * and sets this object as control updator for the extension.
       
  1816  *
       
  1817  * @param aEngine provided for control extension
       
  1818  */
       
  1819 void CPbkContactViewListControl::CreateControlExtensionL
       
  1820         (CPbkContactEngine& aEngine)
       
  1821     {
       
  1822     __ASSERT_DEBUG(&Model(), Panic(EPanicPre_SetControlExtensionL));
       
  1823     __ASSERT_DEBUG(!iControlExtension, Panic(EPanicPre_SetControlExtensionL));
       
  1824 
       
  1825     CPbkExtGlobals* extGlobal = CPbkExtGlobals::InstanceL();
       
  1826     extGlobal->PushL();
       
  1827     iControlExtension = extGlobal->FactoryL().
       
  1828             CreatePbkUiControlExtensionL(aEngine);
       
  1829     CleanupStack::PopAndDestroy(extGlobal);
       
  1830 
       
  1831     Model().SetContactUiControlExtension(*iControlExtension);
       
  1832 
       
  1833     TInt arrayInfoId = 0;
       
  1834     TInt arrayId = 0;
       
  1835     iControlExtension->IconArrayResourceId(arrayInfoId, arrayId);
       
  1836     if ( arrayInfoId != 0 )
       
  1837         {
       
  1838         IconArray(*iListBox)->AppendIconsFromResourceL(arrayInfoId, arrayId);
       
  1839         }
       
  1840 
       
  1841     iControlExtension->SetContactUiControlUpdate(this);
       
  1842     }
       
  1843 
       
  1844 void CPbkContactViewListControl::HandleResourceChange(TInt aType)
       
  1845     {
       
  1846     CPbkContactListControlBase::HandleResourceChange(aType);
       
  1847 
       
  1848     TRAP_IGNORE(DoHandleResourceChangeL(aType));
       
  1849     }
       
  1850 
       
  1851 void CPbkContactViewListControl::RefreshIconArrayL()
       
  1852     {
       
  1853     // Control extension may be NULL when skin is changed at run-time
       
  1854     if (iControlExtension)
       
  1855         {
       
  1856         CPbkIconArray* iconArray = IconArray(*iListBox);
       
  1857         if (iconArray)
       
  1858             {
       
  1859             // refresh the main pbk icon array
       
  1860             iconArray->RefreshL(R_PBK_ICON_INFO_ARRAY);
       
  1861             // also refresh the control extension icon array
       
  1862             TInt arrayInfoId = 0;
       
  1863             TInt arrayId = 0;
       
  1864             iControlExtension->IconArrayResourceId(arrayInfoId, arrayId);
       
  1865             if (arrayInfoId != 0)
       
  1866                 {
       
  1867                 iconArray->RefreshL(arrayInfoId);
       
  1868                 }
       
  1869             }
       
  1870         }
       
  1871     }
       
  1872 
       
  1873 void CPbkContactViewListControl::DoHandleResourceChangeL(TInt aType)
       
  1874     {
       
  1875     if (aType == KAknsMessageSkinChange)
       
  1876         {
       
  1877         RefreshIconArrayL();
       
  1878         }
       
  1879     else if (aType == KEikDynamicLayoutVariantSwitch)
       
  1880         {
       
  1881         RefreshIconArrayL();
       
  1882         SizeChanged();
       
  1883         const TBool focused( IsFocused() );
       
  1884         const TBool nonFocusing( IsNonFocusing() );
       
  1885         if ( focused && !nonFocusing )
       
  1886             {
       
  1887             ShowThumbnailL();
       
  1888             }
       
  1889         DrawNow();
       
  1890         }
       
  1891     }
       
  1892 
       
  1893 
       
  1894 // TCleanupEnableListBoxViewRedraw
       
  1895 void TCleanupEnableListBoxViewRedraw::CleanupOp(TAny* aPtr)
       
  1896     {
       
  1897     static_cast<CListBoxView*>(aPtr)->SetDisableRedraw(EFalse);
       
  1898     }
       
  1899 
       
  1900 EXPORT_C void CPbkContactViewListControl::DeleteThumbnail()
       
  1901     {
       
  1902     delete iThumbnailPopup;
       
  1903     iThumbnailPopup = NULL;
       
  1904     }
       
  1905     
       
  1906 void CPbkContactViewListControl::EnableMSKObserver( TBool aEnable )
       
  1907     {
       
  1908     iListBox->EnableMSKObserver(aEnable);
       
  1909     }
       
  1910     
       
  1911 TInt CPbkContactViewListControl::ItemCount()
       
  1912     {
       
  1913     return Model().MdcaCount(); 
       
  1914     }
       
  1915 
       
  1916 //  End of File
       
  1917