uifw/EikStd/coctlsrc/EIKLBX.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 1997-2009 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:   List box implementation.
       
    15 *
       
    16 */
       
    17 
       
    18   
       
    19 #include <e32base.h>
       
    20 #include <e32keys.h>
       
    21 #include <bamatch.h>
       
    22 #include <badesca.h>
       
    23 #include <barsread.h>
       
    24 #include <eiklbx.h>
       
    25 #include <eiklbv.h>
       
    26 #include <eiklbi.h>
       
    27 #include <eiklbm.h>
       
    28 #include <eikenv.h>
       
    29 #include <eiklbx.pan>
       
    30 #include <gulbordr.h>
       
    31 #include <eikbutb.h>
       
    32 #include <coemain.h>
       
    33 #include <w32std.h>
       
    34 #include <gulutil.h>
       
    35 #include <uikon.hrh>
       
    36 #include <eikkeys.h>
       
    37 //#include <laflistb.h>
       
    38 #include <laflbx.h>
       
    39 
       
    40 #include <eikpanic.h>
       
    41 #include <eikcmobs.h>
       
    42 
       
    43 // Needed to use MopGetObject
       
    44 #include <coemop.h>
       
    45 #include <eikmenub.h> 
       
    46 #include <AknLayout.lag>
       
    47 #include <aknenv.h>
       
    48 #include <AknDef.h>
       
    49 #include <AknUtils.h>
       
    50 
       
    51 #include <aknappui.h>
       
    52 #include <aknPopup.h>
       
    53 
       
    54 #include <AknTasHook.h>
       
    55 // For hash key marking.
       
    56 #include <e32property.h>
       
    57 #include <featmgr.h>
       
    58 #include <centralrepository.h>
       
    59 #include <cenrepnotifyhandler.h>
       
    60 #include <AknFepInternalCRKeys.h> // KAknFepHashKeySelection
       
    61 #include <AvkonInternalCRKeys.h>  // KAknQwertyInputModeActive
       
    62 #include <aknlayoutscalable_avkon.cdl.h>
       
    63 #include <aknphysics.h>
       
    64 #include <aknphysicsobserveriface.h>
       
    65 
       
    66 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    67 #include <aknlistboxtfxinternal.h> // LISTBOX EFFECTS IMPLEMENTATION
       
    68 #include <aknlistloadertfx.h>
       
    69 #include <aknlistboxtfx.h>
       
    70 #endif
       
    71 
       
    72 #include <touchfeedback.h>
       
    73 #include <akncollection.h>
       
    74 #include <aknitemactionmenu.h>
       
    75 #include <aknlongtapdetector.h>
       
    76 #include <aknpriv.hrh>
       
    77 #include "akntrace.h"
       
    78 
       
    79 // timeout for long keypress used in markable lists
       
    80 const TInt KLongPressInterval = 600000; // 0,6 seconds
       
    81 const TInt KEikListBoxPointerRepeatInterval = 100000;  // in micro conds (= 0.1 secod)
       
    82 
       
    83 // Maximum scroll speed ( max amount of items moved one time )
       
    84 const TInt KDefaultMaxSpeed = 30;
       
    85 const TInt KDefaultStepSpeed = 5;
       
    86 const TInt KEikListBoxInvalidIndex=-1;
       
    87 //interval time for disable second point event
       
    88 const TInt KTwoPointerUpEventInterval = 120;    //  120 millisecond ( = 0.12 second ) 
       
    89 // -----------------------------------------------------------------------------
       
    90 // If a parent to the supplied control has its Gc set, this function will find 
       
    91 // it and return it.
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 LOCAL_C CWindowGc* ReplaceGcWithCustomGc( const CEikListBox* aListBox )
       
    95     {
       
    96     _AKNTRACE_FUNC_ENTER;
       
    97     const CCoeControl* parent = aListBox;
       
    98     CWindowGc* customGc;
       
    99     while(parent)
       
   100         {
       
   101         customGc = parent->GetGc();
       
   102         if ( customGc )
       
   103             {
       
   104             CListItemDrawer* itemDrawer = aListBox->View()->ItemDrawer();
       
   105             CWindowGc* originalGc = itemDrawer->Gc();
       
   106             if ( customGc == originalGc )
       
   107             {
       
   108                 _AKNTRACE_FUNC_EXIT;
       
   109                 return NULL;
       
   110                 }
       
   111             else
       
   112                 {
       
   113                 itemDrawer->SetGc( customGc );
       
   114                 _AKNTRACE_FUNC_EXIT;
       
   115                 return originalGc;
       
   116                 }
       
   117             }
       
   118         parent = parent->Parent();
       
   119         }
       
   120     _AKNTRACE_FUNC_EXIT;
       
   121     return NULL;
       
   122     }
       
   123 
       
   124 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   125 // ---------------------------------------------------------------------------
       
   126 // Helper function that selects list items
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 LOCAL_C void SelectL( CListBoxView* aView, MAknListBoxTfxInternal* transApi, TInt aIndex, TBool select, TBool force = EFalse )
       
   130     {
       
   131     _AKNTRACE_FUNC_ENTER;
       
   132     if ( aView->ItemIsSelected( aIndex ) == select )
       
   133         {
       
   134         if ( force || transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( aIndex ), aIndex ) != KErrNone )
       
   135             {
       
   136             aView->DrawItem( aIndex );
       
   137             }
       
   138         }
       
   139     else if ( select )
       
   140         {
       
   141         if ( aIndex >= aView->TopItemIndex() && aIndex <= aView->BottomItemIndex() )
       
   142             {
       
   143             aView->SelectItemL( aIndex );
       
   144             }
       
   145         else if ( !transApi->Exist( MAknListBoxTfxInternal::EListItem, aIndex ) )
       
   146             {
       
   147             aView->SelectItemL( aIndex );
       
   148             }
       
   149         else
       
   150             {
       
   151             TInt topItemIndex = aView->TopItemIndex();
       
   152             aView->SetTopItemIndex( aIndex );
       
   153             aView->SelectItemL( aIndex );
       
   154             aView->SetTopItemIndex( topItemIndex );
       
   155             }
       
   156         }
       
   157     else
       
   158         {
       
   159         if ( aIndex >= aView->TopItemIndex() && aIndex <= aView->BottomItemIndex() )
       
   160             {
       
   161             aView->DeselectItem( aIndex );
       
   162             }
       
   163         else if ( !transApi->Exist( MAknListBoxTfxInternal::EListItem, aIndex ) )
       
   164             {
       
   165             aView->DeselectItem( aIndex );
       
   166             }
       
   167         else
       
   168             {
       
   169             TInt topItemIndex = aView->TopItemIndex();
       
   170             aView->SetTopItemIndex( aIndex );
       
   171             aView->DeselectItem( aIndex );
       
   172             aView->SetTopItemIndex( topItemIndex );
       
   173             }
       
   174         }
       
   175     _AKNTRACE_FUNC_EXIT;
       
   176     }
       
   177 
       
   178 // ---------------------------------------------------------------------------
       
   179 // Helper function that updates list item selections
       
   180 // ---------------------------------------------------------------------------
       
   181 //
       
   182 LOCAL_C void UpdateSelectionsL( CListBoxView* aView, MAknListBoxTfxInternal* transApi, TInt aHl, TInt aOld, TInt aAnchor, TBool aSelect )
       
   183     {
       
   184     _AKNTRACE_FUNC_ENTER;
       
   185     if ( aHl < aOld )
       
   186         {
       
   187         // Going up
       
   188         if ( aOld <= aAnchor )
       
   189             {
       
   190             // Going up away
       
   191             SelectL( aView, transApi, aOld, aSelect, ETrue );
       
   192             for ( TInt i = aOld - 1; i > aHl; i-- )
       
   193                 {
       
   194                 SelectL( aView, transApi, i, aSelect );
       
   195                 }
       
   196             SelectL( aView, transApi, aHl, aSelect, ETrue );
       
   197             }
       
   198         else if ( aHl >= aAnchor )
       
   199             {
       
   200             // Going up against
       
   201             for ( TInt i = aOld; i > aHl; i-- )
       
   202                 {
       
   203                 SelectL( aView, transApi, i, !aSelect );
       
   204                 }
       
   205             SelectL( aView, transApi, aHl, aSelect, ETrue );
       
   206             }
       
   207         else
       
   208             {
       
   209             // Passing anchor
       
   210             for ( TInt i = aOld; i > aAnchor; i-- )
       
   211                 {
       
   212                 SelectL( aView, transApi, i, !aSelect );
       
   213                 }
       
   214             for ( TInt i = aAnchor; i >= aHl; i-- )
       
   215                 {
       
   216                 SelectL( aView, transApi, i, aSelect );
       
   217                 }
       
   218             }
       
   219         for ( TInt i = aView->BottomItemIndex(); i >= aView->TopItemIndex(); i-- )
       
   220             {
       
   221             if ( i < aHl || i > aOld )
       
   222                 {
       
   223                 if ( transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( i ), i ) != KErrNone )
       
   224                     {
       
   225                     aView->DrawItem( i );
       
   226                     }
       
   227                 }
       
   228             }
       
   229         }
       
   230     else if ( aHl >= aOld )
       
   231         {
       
   232         // Going down
       
   233         if ( aOld >= aAnchor )
       
   234             {
       
   235             // Going down away
       
   236             SelectL( aView, transApi, aOld, aSelect, ETrue );
       
   237             for ( TInt i = aOld + 1; i < aHl; i++ )
       
   238                 {
       
   239                 SelectL( aView, transApi, i, aSelect );
       
   240                 }
       
   241             SelectL( aView, transApi, aHl, aSelect, ETrue );
       
   242             }
       
   243         else if ( aHl <= aAnchor )
       
   244             {
       
   245             // Going down against
       
   246             for ( TInt i = aOld; i < aHl; i++ )
       
   247                 {
       
   248                 SelectL( aView, transApi, i, !aSelect );
       
   249                 }
       
   250             SelectL( aView, transApi, aHl, aSelect, ETrue );
       
   251             }
       
   252         else
       
   253             {
       
   254             // Passing anchor
       
   255             for ( TInt i = aOld; i < aAnchor; i++ )
       
   256                 {
       
   257                 SelectL( aView, transApi, i, !aSelect );
       
   258                 }
       
   259             for ( TInt i = aAnchor; i <= aHl; i++ )
       
   260                 {
       
   261                 SelectL( aView, transApi, i, aSelect );
       
   262                 }
       
   263             }
       
   264         for ( TInt i = aView->BottomItemIndex(); i >= aView->TopItemIndex(); i-- )
       
   265             {
       
   266             if ( i > aHl || i < aOld )
       
   267                 {
       
   268                 if ( transApi->SetPosition( MAknListBoxTfxInternal::EListItem, aView->ItemPos( i ), i ) != KErrNone )
       
   269                     {
       
   270                     aView->DrawItem( i );
       
   271                     }
       
   272                 }
       
   273             }
       
   274         }
       
   275     _AKNTRACE_FUNC_EXIT;
       
   276     }
       
   277 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   278 
       
   279 //
       
   280 // class CMatchBuffer
       
   281 //
       
   282 
       
   283 NONSHARABLE_CLASS(CMatchBuffer) : public CBase
       
   284     {   
       
   285 public:
       
   286     enum TExtent
       
   287         { EFull, EMinimal };
       
   288 public:
       
   289     static CMatchBuffer* NewL(TExtent aExtent);
       
   290     ~CMatchBuffer();
       
   291     void ConstructMatchBufferL();
       
   292 public:
       
   293     RIncrMatcherBase* iMatchBuffer;
       
   294     TInt iPressedIndex; 
       
   295     TBool iDragToAnotherItem; 
       
   296     };
       
   297 
       
   298 CMatchBuffer* CMatchBuffer::NewL(TExtent aExtent)
       
   299     {
       
   300     CMatchBuffer* buffer=new(ELeave) CMatchBuffer;
       
   301     if (aExtent==EFull)
       
   302         {
       
   303         CleanupStack::PushL(buffer);
       
   304         buffer->iMatchBuffer=new(ELeave)RIncrMatcherBuf<CEikListBox::KEikMaxMatchingBufferLength>;
       
   305         CleanupStack::Pop( buffer );
       
   306         }
       
   307     return buffer;
       
   308     }
       
   309 
       
   310 CMatchBuffer::~CMatchBuffer()
       
   311     {
       
   312     delete iMatchBuffer;
       
   313     }
       
   314 
       
   315 void CMatchBuffer::ConstructMatchBufferL()
       
   316     {
       
   317     iMatchBuffer=new(ELeave)RIncrMatcherBuf<CEikListBox::KEikMaxMatchingBufferLength>;
       
   318     }
       
   319 
       
   320 //
       
   321 // class CLBMSKCommandObserver
       
   322 //
       
   323 
       
   324 NONSHARABLE_CLASS(CLBMSKCommandObserver) : public MEikCommandObserver
       
   325     {
       
   326 public:
       
   327     CLBMSKCommandObserver(CEikButtonGroupContainer *aCba, CEikListBox *aListBox);
       
   328     void ProcessCommandL(TInt aCommandId);
       
   329     CEikButtonGroupContainer *iCba;
       
   330     CEikListBox *iListBox;
       
   331     TInt iCurrentResource;
       
   332     };
       
   333 
       
   334 
       
   335 CLBMSKCommandObserver::CLBMSKCommandObserver(CEikButtonGroupContainer *aCba, CEikListBox *aListBox)
       
   336      : iCba(aCba), iListBox(aListBox)
       
   337     {
       
   338     }
       
   339 
       
   340 void CLBMSKCommandObserver::ProcessCommandL(TInt aCommandId)
       
   341     {
       
   342     switch ( aCommandId )
       
   343         {
       
   344         case EAknSoftkeyMark:
       
   345             {
       
   346             TInt index = iListBox->CurrentItemIndex();
       
   347             iListBox->View()->SelectItemL(index);
       
   348             iCba->SetCommandL(3,R_AVKON_SOFTKEY_UNMARK);
       
   349             iCba->DrawNow();
       
   350             iCurrentResource = R_AVKON_SOFTKEY_UNMARK;        
       
   351             }
       
   352             break;
       
   353         case EAknSoftkeyUnmark:
       
   354             {
       
   355             TInt index = iListBox->CurrentItemIndex();
       
   356             iListBox->View()->DeselectItem(index);
       
   357             iCba->SetCommandL(3,R_AVKON_SOFTKEY_MARK);
       
   358             iCba->DrawNow();
       
   359             iCurrentResource = R_AVKON_SOFTKEY_MARK;        
       
   360             }
       
   361             break;
       
   362         case EAknSoftkeyShiftMSK:
       
   363             {
       
   364             iListBox->DoShiftMSKMarkingL();
       
   365             }
       
   366             break;
       
   367         default:
       
   368             break;
       
   369         }
       
   370     }
       
   371 
       
   372 //
       
   373 // class CListBoxExt
       
   374 //
       
   375 
       
   376 NONSHARABLE_CLASS(CListBoxExt) : public CBase, public MListVisibilityObserver,
       
   377     public MCenRepNotifyHandlerCallback,
       
   378     public MAknPhysicsObserver,
       
   379     public MAknCollection,
       
   380     public MAknLongTapDetectorCallBack
       
   381     {
       
   382 public:
       
   383     static CListBoxExt* NewL(CEikListBox& aListBox);
       
   384     ~CListBoxExt();
       
   385 
       
   386     // new functions
       
   387     void CreateMatchBufferL();
       
   388     void CheckCreateBufferL();
       
   389     CMatchBuffer* Buffer() const;
       
   390     TBool IsMatchBuffer() const;
       
   391     void SetReasonForFocusLost(CEikListBox::TReasonForFocusLost aReasonForFocusLost);
       
   392     CEikListBox::TReasonForFocusLost ReasonForFocusLost() const;
       
   393 
       
   394     /// @since 3.0
       
   395     void AddItemChangeObserverL( MListBoxItemChangeObserver* aObserver );
       
   396     /// @since 3.0
       
   397     TBool RemoveItemChangeObserver( MListBoxItemChangeObserver* aObserver );
       
   398     /// @since 3.0
       
   399     void FireItemChange(CEikListBox* aListBox);
       
   400     
       
   401     void CreateMSKObserverL(CEikButtonGroupContainer *aCba, 
       
   402                                      CEikListBox *aListBox);
       
   403     void RemoveMSKObserver(CEikListBox *aListBox);
       
   404 
       
   405     // @since 3.2
       
   406     void AddSelectionObserverL( MListBoxSelectionObserver* aObserver );
       
   407     TBool RemoveSelectionObserver( MListBoxSelectionObserver* aObserver );
       
   408     // Starts the long press timer.
       
   409     void StartLongPressTimerL();
       
   410     TBool IsInIgnoreRect( const TPoint& aPoint ) const;
       
   411     //Tests the item needs to handle all point event or not.
       
   412     TBool IsInHandleAllPointEventArray(const TInt aIndex);
       
   413 public: // from MListVisibilityObserver
       
   414     TBool IsVisible() const;
       
   415     void SetUpdateScrollBarsColors(TBool aUpdate);
       
   416     TBool UpdateScrollBarsColors() const;
       
   417 public: // from MCenRepNotifyHandlerCallback
       
   418     void HandleNotifyInt(TUint32 aId, TInt aNewValue);
       
   419     
       
   420 public: // MAknPhysicsObserver
       
   421     virtual void ViewPositionChanged( const TPoint& aNewPosition,
       
   422                                       TBool aDrawNow = ETrue,
       
   423                                       TUint aFlags = 0 );
       
   424     virtual void PhysicEmulationEnded();
       
   425     virtual TPoint ViewPosition() const;
       
   426 
       
   427 // From MAknCollection
       
   428     /**
       
   429      * Returns the collection state. The state is combination of
       
   430      * flags defined in MAknCollection::TStateFlag. 
       
   431      *
       
   432      * @return  Collection state.
       
   433      */
       
   434     TUint CollectionState() const;
       
   435 
       
   436     /**
       
   437      * Notifies that item action menu (CAknItemActionMenu)
       
   438      * was closed. 
       
   439      */
       
   440     void ItemActionMenuClosed();
       
   441 
       
   442     /** 
       
   443      * Extension function.
       
   444      *
       
   445      * @param  aExtensionId  Extension id. 
       
   446      * @param  a0            First extension method parameter.
       
   447      * @param  a1            Second extension method parameter.
       
   448      */    
       
   449     TInt CollectionExtension( TUint aExtensionId, TAny*& a0, TAny* a1 );
       
   450 
       
   451 // From MAknLongTapDetectorCallBack
       
   452     /**
       
   453      * Long tap detector callback 
       
   454      *
       
   455      * @param aPenEventLocation Long tap event location relative to parent control.
       
   456      * @param aPenEventScreenLocation Long tap event location relative to screen.
       
   457      */
       
   458     void HandleLongTapEventL( const TPoint& aPenEventLocation,
       
   459                               const TPoint& aPenEventScreenLocation );
       
   460 
       
   461 // New single click related methods
       
   462     /**
       
   463      * Reports collection change event.
       
   464      */
       
   465     void ReportCollectionChangedEvent();
       
   466 
       
   467     /**
       
   468      * Enables or disables the highlight 
       
   469      * @param aEnabled ETrue to enable EFalse to disable
       
   470      * @param aPointerEnabled ETrue if highlight was enabled by pointer event.
       
   471      */
       
   472     void EnableHighlight( TBool aEnabled, TBool aPointerEnabled = EFalse );
       
   473 
       
   474     /**
       
   475      * Sets the highlight for the first item visible after single click 
       
   476      * is disabled
       
   477      */
       
   478     void DisableSingleClick();
       
   479 
       
   480     /**
       
   481      * Disables item specific menu.
       
   482      */
       
   483     void DisableItemSpecificMenu();
       
   484 
       
   485     /**
       
   486      * Sends pointer event to long tap detector if necessary.
       
   487      * 
       
   488      * @aPointerEvent Pointer event to send to long tap detector.
       
   489      */
       
   490     void LongTapPointerEventL( const TPointerEvent& aPointerEvent );
       
   491 
       
   492     /**
       
   493      * Cancels long tap detecting if detector is active.
       
   494      */
       
   495     void CancelLongTapL();
       
   496 
       
   497     /**
       
   498      * Enables highlight with key event if listbox is single click enabled.
       
   499      * 
       
   500      * @param aKeyEvent Received key event.
       
   501      * @param aType Key event type.
       
   502      * @return ETrue if key should be consumed.
       
   503      */
       
   504     TBool EnableHighlightWithKeyEventL(
       
   505             TInt aTopItemIndex,
       
   506             const TKeyEvent& aKeyEvent,
       
   507             TEventCode aType );
       
   508 
       
   509     /**
       
   510      * Returns ETrue if list has currently marked items.
       
   511      * 
       
   512      * @return ETrue if list has marked items.
       
   513      */
       
   514     TBool MarkedItems() const;
       
   515 
       
   516 public:
       
   517     void InitPhysicsL();
       
   518 	
       
   519     /**
       
   520     * Moves the current item cursor in the specified direction. This function 
       
   521     * is called by @c CEikListBox in response to user input when physics 
       
   522     * is enabled.
       
   523      *
       
   524     * @return @c ETrue if the event was consumed.
       
   525     *
       
   526     * @param aCursorMovement The cursor movement to apply. 
       
   527     * @param aSelectionMode The selection mode of the calling list box.
       
   528     */
       
   529     TBool MovePhysicsCursorL(CListBoxView::TCursorMovement aCursorMovement, 
       
   530                              CListBoxView::TSelectionMode aSelectionMode);
       
   531    
       
   532     static TInt HighlightTimerCallback( TAny* aPtr );
       
   533 	void CheckScrollBarVisibility();
       
   534     void StartHighlightTimer();
       
   535     void CancelHighlightTimer();
       
   536     TBool HighlightTimerActive() const;
       
   537     void ImmediateFeedback( TTouchLogicalFeedback aFeedback,
       
   538                             TTouchFeedbackType aFeedbackType,
       
   539                             const TPointerEvent& aPointerEvent );
       
   540     TBool FeedbackEnabledOnUpEvent();
       
   541     void SetFlickOngoing( TBool );
       
   542     void SetPanningOngoing( TBool );
       
   543     TBool FlickOrPanningOngoing();
       
   544     TInt ListBottomLimit();
       
   545     
       
   546 private: 
       
   547     CListBoxExt(CEikListBox& aListBox);
       
   548     void ConstructL();    
       
   549     static TInt QwertyModeChangeNotification(TAny* aObj);  
       
   550     void HandleQwertyModeChangeNotification();
       
   551     // Callback method for long press timer.
       
   552     static TInt ReportLongPressL( TAny* aThis );
       
   553     // Handles long press.
       
   554     void DoHandleLongPressL();
       
   555        
       
   556 private:
       
   557     enum {
       
   558         EUpdateScrollBarsColors =0x1,
       
   559         EMSKKeyDownEventReceived = 0x2,
       
   560         EHighlightEnabledByPointer = 0x4
       
   561     };
       
   562 
       
   563 private: 
       
   564     NONSHARABLE_CLASS(CSubscriber) : public CActive
       
   565         {
       
   566     public:
       
   567         CSubscriber(TCallBack aCallBack, RProperty& aProperty);
       
   568         ~CSubscriber();
       
   569 
       
   570     public: // New functions
       
   571         void SubscribeL();
       
   572         void StopSubscribe();
       
   573 
       
   574     private: // from CActive
       
   575         void RunL();
       
   576         void DoCancel();
       
   577 
       
   578     private:
       
   579         TCallBack   iCallBack;
       
   580         RProperty&  iProperty;
       
   581         };    
       
   582 public:
       
   583 
       
   584     // The index of an item, which has received the latest pointer down event.
       
   585     // This value is used in pointer up event handling to check whether or
       
   586     // not the same item received both down and up events.
       
   587     TInt iLastDownTappedItem;
       
   588 
       
   589     TInt iEventModifiers;
       
   590     TBool iWesternVariant;
       
   591     TBool iAknFepHashKeySelection;
       
   592     TBool iQwertyMode;
       
   593     TBool iMSKObserverEnabled;
       
   594     TBool iMSKButtonGroupAlive; // status of buttongroup, which is used for MSK observer
       
   595     // these are used for shift, ctrl and hash keys in markable lists    
       
   596     CPeriodic* iLongPressTimer; 
       
   597     TBool iSelectionModeEnabled;
       
   598     TBool iShortHashMark;
       
   599     // Contains only references, observers not owned
       
   600     RPointerArray<MListBoxSelectionObserver> iSelectionObservers;
       
   601     // used in CEikListBox::HandlePointerEventL and
       
   602     // CEikListBox::OfferKeyEventL to enable multiselection with hash key
       
   603     TBool iShiftKeyPressed;
       
   604     // Last stuly down position
       
   605     TBool iIsDownOnItem;
       
   606 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   607     TBool iSelect;
       
   608     TInt iAnchor;
       
   609 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   610     TInt iSpeed;
       
   611     // Last pointer event pos
       
   612     TPoint iLastPoint;
       
   613 
       
   614     TInt iMaxSpeed;
       
   615     TInt iStepSpeed;
       
   616     TInt iInterval;
       
   617     CPeriodic* iHighlightTimer;    
       
   618     CAknPhysics *iPhysics;
       
   619     TPoint iDragStartPosition;
       
   620     TPoint iLastPointerPos;
       
   621     TBool iBackgroundDrawingSuppressed;
       
   622     TBool iClickEventsAllowed;
       
   623     TBool iScrolling;
       
   624     TSize iViewSize;
       
   625     TSize iWorldSize;
       
   626     TBool iItemDraggingReported;
       
   627     TTime iStartTime;
       
   628     TInt iItemsInSingleLine;
       
   629     TBool iEffectsEnabled;
       
   630     
       
   631     TPoint iViewPosition; // Current view position
       
   632     TInt iSelectedIndex;
       
   633     //Array of items need to handle point event everytime.
       
   634     RArray< TInt > iMutiTappingItems;
       
   635     // To calculate twice click interval  time on same item.
       
   636     TUint32 iListPointUpTime;
       
   637     TInt iLastItemIndex;
       
   638     
       
   639     // Used to disable list scrolling in certain list types.
       
   640     TBool iScrollingDisabled;
       
   641     
       
   642     // Whether or not pen down on item should be reported on highlight
       
   643     // timer callback.
       
   644     TBool iReportDelayedPenDown;
       
   645     
       
   646     // Whether or not multiselection should be done on highlight
       
   647     // timer callback.
       
   648     TBool iDelayedMultiselection;
       
   649     
       
   650     // Marking mode for multiselection lists is disabled when flicking.
       
   651     TBool iMarkingDisabled;
       
   652  
       
   653     // part of HandlePointerEventL for marking is moved to highlight timer with this flag
       
   654     TBool iMarkableListMarking;
       
   655     TBool iMarkableListShiftKeyPressed;
       
   656     TInt iMarkableListSelectionMode;
       
   657    
       
   658     // previous top item 
       
   659     TInt iPrevTopItemIndex;
       
   660     // is flick stopped by down event
       
   661     TBool iFlickStopped;
       
   662     
       
   663     TTouchLogicalFeedback iFeedbackType;
       
   664     
       
   665     /**
       
   666      * Pointer to item action menu.
       
   667      * Not own.
       
   668      */
       
   669     CAknItemActionMenu* iItemActionMenu;    
       
   670     
       
   671    /**
       
   672     * Long tap detector
       
   673     */
       
   674     CAknLongTapDetector* iLongTapDetector;
       
   675 
       
   676    /**
       
   677     * Single click mode enabled or not.
       
   678     */
       
   679     TBool iSingleClickEnabled;
       
   680 
       
   681    /**
       
   682     * Item that opened the item action menu
       
   683     */
       
   684     TInt iLongTappedItem;
       
   685     /**
       
   686      * Pointer event to be forwarded to the long tap detector upon
       
   687      * highlight timer completion.
       
   688      */
       
   689     TPointerEvent iDelayedPointerDownEvent;
       
   690     
       
   691 private:
       
   692     CMatchBuffer* iBuffer;
       
   693     CEikListBox& iListBox;
       
   694     CEikListBox::TReasonForFocusLost iReasonForFocusLost;
       
   695     TInt iFlags;
       
   696     // Contains only references, observers not owned
       
   697     RPointerArray<MListBoxItemChangeObserver> iItemChangeObservers;
       
   698 
       
   699     // For hash key selection.    
       
   700     CRepository* iCenRep;
       
   701     CCenRepNotifyHandler* iCenRepNotifyHandler;      
       
   702     CSubscriber* iQwertyModeStatusSubscriber;
       
   703     RProperty iQwertyModeStatusProperty;    
       
   704     MEikCommandObserver *iMSKCommandObserver; // this is for markable/multiselection list query
       
   705     /**
       
   706      * Pointer to the feedback object. Not owned.
       
   707      */    
       
   708     MTouchFeedback* iFeedback;
       
   709 
       
   710     /**
       
   711      * Is flick ongoing or not.
       
   712      */    
       
   713     TBool iFlickOngoing;
       
   714 
       
   715     /**
       
   716      * Is panning ongoing or not.
       
   717      */    
       
   718     TBool iPanningOngoing;
       
   719 
       
   720     /**
       
   721      * Height of the list in pixels.
       
   722      */    
       
   723     TInt iListBottomLimit;
       
   724     };
       
   725     
       
   726 // CEikListBoxExt    
       
   727 
       
   728 CListBoxExt* CListBoxExt::NewL( CEikListBox& aListBox )
       
   729     { // static
       
   730     _AKNTRACE_FUNC_ENTER;
       
   731     CListBoxExt* self = new (ELeave) CListBoxExt( aListBox );
       
   732     CleanupStack::PushL( self );
       
   733     self->ConstructL();
       
   734     CleanupStack::Pop( self );
       
   735     _AKNTRACE_FUNC_EXIT;
       
   736     return self;
       
   737     }
       
   738 
       
   739 CListBoxExt::CListBoxExt(CEikListBox& aListBox)
       
   740     : iLastDownTappedItem(KErrNotFound), iWesternVariant(ETrue), 
       
   741       iAknFepHashKeySelection(EFalse), 
       
   742       iQwertyMode(EFalse), iLongPressTimer(NULL), iSelectionModeEnabled(EFalse),
       
   743       iLastPoint(0,0), iMaxSpeed( KDefaultMaxSpeed ), iStepSpeed( KDefaultStepSpeed ),
       
   744       iInterval( KEikListBoxPointerRepeatInterval ),
       
   745       iClickEventsAllowed( ETrue ),
       
   746       iWorldSize(0,0),
       
   747       iSelectedIndex( KErrNotFound ),
       
   748       iListPointUpTime(0),
       
   749       iLastItemIndex(-1),
       
   750       iItemActionMenu( NULL ),
       
   751       iLongTapDetector( NULL ),
       
   752       iSingleClickEnabled( iAvkonAppUi->IsSingleClickCompatible() ),
       
   753       iLongTappedItem( KErrNotFound ),
       
   754       iListBox(aListBox)      
       
   755     {
       
   756     }
       
   757 
       
   758 CListBoxExt::~CListBoxExt()
       
   759     {
       
   760     _AKNTRACE_FUNC_ENTER;
       
   761     if ( iItemActionMenu )
       
   762         {
       
   763         iItemActionMenu->RemoveCollection( *this );
       
   764         }
       
   765     if ( iLongTapDetector )
       
   766         {
       
   767         delete iLongTapDetector;
       
   768         }
       
   769 
       
   770     delete iPhysics;
       
   771     delete iHighlightTimer;
       
   772     iMutiTappingItems.Close();
       
   773     delete iLongPressTimer;    
       
   774     FeatureManager::UnInitializeLib();
       
   775     iItemChangeObservers.Reset();
       
   776     iSelectionObservers.Reset();    
       
   777     delete iBuffer;
       
   778 
       
   779     // Stop listening CenRep.
       
   780     if (iCenRepNotifyHandler)
       
   781         {
       
   782         iCenRepNotifyHandler->StopListening();
       
   783         }
       
   784     delete iCenRepNotifyHandler;
       
   785     delete iCenRep; 
       
   786     
       
   787     // Stop subscribe in PubSub
       
   788     if (iQwertyModeStatusSubscriber)
       
   789         {
       
   790         iQwertyModeStatusSubscriber->StopSubscribe();
       
   791         }
       
   792     iQwertyModeStatusProperty.Close();
       
   793     delete iQwertyModeStatusSubscriber;   
       
   794     if (iMSKCommandObserver)
       
   795         {
       
   796         delete iMSKCommandObserver;
       
   797         iMSKCommandObserver = NULL;
       
   798         }
       
   799     _AKNTRACE_FUNC_EXIT;
       
   800     }
       
   801 
       
   802 void CListBoxExt::ConstructL()
       
   803     {
       
   804     _AKNTRACE_FUNC_ENTER;
       
   805     // Check the mode for hash key selection.
       
   806     // Eastern (short hash doesn't mark) == Chinese, Japanese or Vietnamese
       
   807     // Western (short hash marks) == All others.
       
   808     FeatureManager::InitializeLibL();
       
   809     if (FeatureManager::FeatureSupported(KFeatureIdChinese)  ||
       
   810         FeatureManager::FeatureSupported(KFeatureIdJapanese) || 
       
   811         (User::Language() & KAknLanguageMask) == ELangVietnamese)
       
   812         {
       
   813         iWesternVariant = EFalse;
       
   814         }
       
   815     
       
   816     // Start listening a CenRep key indicating whether hash key selection is active.
       
   817     TRAPD(err, iCenRep = CRepository::NewL(KCRUidAknFep));
       
   818     if (err == KErrNone)
       
   819         {
       
   820         iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this,
       
   821             *iCenRep,
       
   822             CCenRepNotifyHandler::EIntKey,
       
   823             KAknFepHashKeySelection);
       
   824 
       
   825         iCenRepNotifyHandler->StartListeningL();
       
   826         iCenRep->Get(KAknFepHashKeySelection, iAknFepHashKeySelection);
       
   827         } 
       
   828         
       
   829     // Start also listening qwerty mode status. Hash key selection is disabled when
       
   830     // qwerty mode is active.
       
   831     User::LeaveIfError(iQwertyModeStatusProperty.Attach(KCRUidAvkon, 
       
   832         KAknQwertyInputModeActive));
       
   833 
       
   834     iQwertyModeStatusSubscriber = new (ELeave) CSubscriber(
       
   835         TCallBack(QwertyModeChangeNotification, this), iQwertyModeStatusProperty);
       
   836         
       
   837     iQwertyModeStatusSubscriber->SubscribeL();       
       
   838     
       
   839     // Get the initial value.
       
   840     HandleQwertyModeChangeNotification();
       
   841     
       
   842     iMSKObserverEnabled = ETrue; // By default listbox handles MSK
       
   843     iShortHashMark = EFalse;
       
   844     
       
   845     iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard );    
       
   846 
       
   847     if ( CAknPhysics::FeatureEnabled() )
       
   848         {
       
   849         iPhysics = CAknPhysics::NewL( *this, &iListBox );
       
   850         iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   851         }
       
   852     iItemsInSingleLine = 1;
       
   853     iFeedback = MTouchFeedback::Instance();
       
   854 
       
   855     iItemActionMenu = CAknItemActionMenu::RegisterCollectionL( *this );
       
   856 
       
   857     if ( !( iListBox.iListBoxFlags & CEikListBox::EDisableItemSpecificMenu )
       
   858             && iItemActionMenu )
       
   859         {
       
   860         iLongTapDetector = CAknLongTapDetector::NewL( this );
       
   861         }
       
   862     if ( iSingleClickEnabled )
       
   863         {
       
   864         EnableHighlight( EFalse );
       
   865         }
       
   866     _AKNTRACE_FUNC_EXIT;
       
   867     } 
       
   868 
       
   869 
       
   870 void CListBoxExt::AddSelectionObserverL(
       
   871         MListBoxSelectionObserver* aObserver )
       
   872     {
       
   873     _AKNTRACE_FUNC_ENTER;
       
   874     iSelectionObservers.AppendL( aObserver );
       
   875     _AKNTRACE_FUNC_EXIT;
       
   876     }
       
   877 
       
   878 TBool CListBoxExt::RemoveSelectionObserver(
       
   879         MListBoxSelectionObserver* aObserver )
       
   880     {
       
   881     _AKNTRACE_FUNC_ENTER;
       
   882     TInt index = iSelectionObservers.Find( aObserver );
       
   883     if( KErrNotFound == index )
       
   884         {
       
   885         _AKNTRACE_FUNC_EXIT;
       
   886         return EFalse;
       
   887         }
       
   888 
       
   889     iSelectionObservers.Remove( index );
       
   890     _AKNTRACE_FUNC_EXIT;
       
   891     return ETrue;
       
   892     }
       
   893 
       
   894 TPoint CListBoxExt::ViewPosition() const
       
   895     {
       
   896     return iViewPosition;
       
   897     }
       
   898 
       
   899 
       
   900 // -----------------------------------------------------------------------------
       
   901 // CListBoxExt::CollectionState
       
   902 // -----------------------------------------------------------------------------
       
   903 //
       
   904 TUint CListBoxExt::CollectionState() const
       
   905     {
       
   906     _AKNTRACE_FUNC_ENTER;
       
   907     TUint state( 0 );
       
   908     if ( iListBox.IsVisible()
       
   909             && ( !iListBox.DrawableWindow()
       
   910             || !iListBox.DrawableWindow()->IsFaded() ) )
       
   911         {
       
   912         state |= MAknCollection::EStateCollectionVisible;
       
   913         }
       
   914     if ( iListBox.iItemDrawer )
       
   915         {
       
   916         TInt drawerFlags( iListBox.iItemDrawer->Flags() );
       
   917         if ( !( drawerFlags 
       
   918                 & CListItemDrawer::ESingleClickDisabledHighlight )
       
   919                 && !( iFlags & EHighlightEnabledByPointer ) )
       
   920             {
       
   921             state |=  MAknCollection::EStateHighlightVisible;
       
   922             }
       
   923         if ( drawerFlags & CListItemDrawer::EDisableHighlight )
       
   924             {
       
   925             state |= MAknCollection::EStateViewOnly;
       
   926             }
       
   927         }
       
   928     if ( iListBox.iListBoxFlags & CEikListBox::EMultipleSelection )
       
   929         {
       
   930         state |= MAknCollection::EStateMultipleSelection;
       
   931         }
       
   932     _AKNTRACE_FUNC_EXIT;
       
   933     return state;
       
   934     }
       
   935 
       
   936 
       
   937 // -----------------------------------------------------------------------------
       
   938 // CListBoxExt::ItemActionMenuClosed
       
   939 // -----------------------------------------------------------------------------
       
   940 //
       
   941 void CListBoxExt::ItemActionMenuClosed()
       
   942     {
       
   943     if ( iLongTappedItem != KErrNotFound )
       
   944         {
       
   945         EnableHighlight( EFalse );
       
   946         iListBox.iView->DrawItem( iLongTappedItem );
       
   947         iLongTappedItem = KErrNotFound;
       
   948         }
       
   949     }
       
   950 
       
   951 
       
   952 // -----------------------------------------------------------------------------
       
   953 // CListBoxExt::CollectionExtension
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 TInt CListBoxExt::CollectionExtension(
       
   957         TUint /*aExtensionId*/, TAny*& /*a0*/, TAny* /*a1*/ )
       
   958     {
       
   959     return KErrNone;
       
   960     }
       
   961 
       
   962 
       
   963 // ---------------------------------------------------------------------------
       
   964 // CListBoxExt::HandleLongTapEventL
       
   965 // ---------------------------------------------------------------------------
       
   966 //
       
   967 void CListBoxExt::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/, 
       
   968                                        const TPoint& aPenEventScreenLocation )
       
   969     {
       
   970     _AKNTRACE_FUNC_ENTER;
       
   971     iLongTappedItem = iLastDownTappedItem;
       
   972     iLastDownTappedItem = KErrNotFound;
       
   973     iItemActionMenu->ShowMenuL( aPenEventScreenLocation, 0 );
       
   974     _AKNTRACE_FUNC_EXIT;
       
   975     }
       
   976 
       
   977 
       
   978 // -----------------------------------------------------------------------------
       
   979 // CListBoxExt::ReportCollectionChangedEvent
       
   980 // -----------------------------------------------------------------------------
       
   981 //
       
   982 void CListBoxExt::ReportCollectionChangedEvent()
       
   983     {
       
   984     if ( iItemActionMenu )
       
   985         {
       
   986         iItemActionMenu->CollectionChanged( *this );
       
   987         }
       
   988     }
       
   989 
       
   990 
       
   991 // -----------------------------------------------------------------------------
       
   992 // CListBoxExt::EnableHighLight
       
   993 // -----------------------------------------------------------------------------
       
   994 //
       
   995 void CListBoxExt::EnableHighlight( TBool aEnabled, TBool aPointerEnabled )
       
   996     {
       
   997     _AKNTRACE_FUNC_ENTER;
       
   998     if ( iListBox.iItemDrawer && iSingleClickEnabled )
       
   999         {
       
  1000         TBool wasEnabled( !( iListBox.iItemDrawer->Flags()
       
  1001                 & CListItemDrawer::ESingleClickDisabledHighlight ) );
       
  1002         iFlags &= ( ~EHighlightEnabledByPointer );
       
  1003         if ( aEnabled )
       
  1004             {
       
  1005             iListBox.iItemDrawer->ClearFlags(
       
  1006                     CListItemDrawer::ESingleClickDisabledHighlight );
       
  1007             if ( aPointerEnabled )
       
  1008                 {
       
  1009                 iFlags |= EHighlightEnabledByPointer;
       
  1010                 }
       
  1011             }
       
  1012         else
       
  1013             {
       
  1014             iListBox.iItemDrawer->SetFlags(
       
  1015                     CListItemDrawer::ESingleClickDisabledHighlight );
       
  1016             }
       
  1017         if ( !aPointerEnabled
       
  1018                 && ( ( wasEnabled && !aEnabled )
       
  1019                         || ( !wasEnabled && aEnabled ) ) )
       
  1020             {
       
  1021             ReportCollectionChangedEvent();
       
  1022             }
       
  1023         }
       
  1024     _AKNTRACE_FUNC_EXIT;
       
  1025     }
       
  1026 
       
  1027 // -----------------------------------------------------------------------------
       
  1028 // CListBoxExt::DisableSingleClick
       
  1029 // -----------------------------------------------------------------------------
       
  1030 //
       
  1031 void CListBoxExt::DisableSingleClick()
       
  1032     {
       
  1033     _AKNTRACE_FUNC_ENTER;
       
  1034     EnableHighlight( ETrue );
       
  1035 	
       
  1036     if ( iListBox.iView->ViewRect() != TRect() )
       
  1037         {
       
  1038         TInt topItemIndex = iListBox.iView->TopItemIndex();
       
  1039         if ( iListBox.iView->ItemIsPartiallyVisible( topItemIndex) )
       
  1040             {
       
  1041             topItemIndex++; 
       
  1042             }    
       
  1043         TRAP_IGNORE( iListBox.UpdateHighlightL( topItemIndex ) );
       
  1044         }
       
  1045     
       
  1046     DisableItemSpecificMenu();
       
  1047     if ( iItemActionMenu )
       
  1048         {
       
  1049         iItemActionMenu->RemoveCollection( *this );
       
  1050         iItemActionMenu = NULL;
       
  1051         }
       
  1052     iSingleClickEnabled = EFalse;
       
  1053 
       
  1054     _AKNTRACE_FUNC_EXIT;
       
  1055     }
       
  1056 
       
  1057 
       
  1058 // -----------------------------------------------------------------------------
       
  1059 // CListBoxExt::DisableItemSpecificMenu
       
  1060 // -----------------------------------------------------------------------------
       
  1061 //
       
  1062 void CListBoxExt::DisableItemSpecificMenu()
       
  1063     {
       
  1064     _AKNTRACE_FUNC_ENTER;
       
  1065     
       
  1066     delete iLongTapDetector;
       
  1067     iLongTapDetector = NULL;
       
  1068 
       
  1069     iListBox.iListBoxFlags |= CEikListBox::EDisableItemSpecificMenu;
       
  1070 
       
  1071     _AKNTRACE_FUNC_EXIT;
       
  1072     }
       
  1073 
       
  1074 // -----------------------------------------------------------------------------
       
  1075 // CListBoxExt::LongTapPointerEventL
       
  1076 // -----------------------------------------------------------------------------
       
  1077 //
       
  1078 void CListBoxExt::LongTapPointerEventL( const TPointerEvent& aPointerEvent )
       
  1079     {
       
  1080     if ( iSingleClickEnabled && iLongTapDetector && iItemActionMenu  )
       
  1081         {
       
  1082         // Send event on down only if no marked items and item specific items
       
  1083         // were found
       
  1084         if ( aPointerEvent.iType != TPointerEvent::EButton1Down
       
  1085                 || ( !MarkedItems() && iItemActionMenu->InitMenuL() ) )
       
  1086             {
       
  1087             iLongTapDetector->PointerEventL ( aPointerEvent );
       
  1088             }
       
  1089         }
       
  1090     }
       
  1091 
       
  1092 
       
  1093 // -----------------------------------------------------------------------------
       
  1094 // CListBoxExt::CancelLongTapL
       
  1095 // -----------------------------------------------------------------------------
       
  1096 //
       
  1097 void CListBoxExt::CancelLongTapL()
       
  1098     {
       
  1099     if ( iLongTapDetector && iLongTapDetector->IsActive() )
       
  1100         {
       
  1101         iLongTapDetector->CancelAnimationL();
       
  1102         }
       
  1103     }
       
  1104 
       
  1105 
       
  1106 // -----------------------------------------------------------------------------
       
  1107 // CListBoxExt::EnableHighlightWithKeyEventL
       
  1108 // -----------------------------------------------------------------------------
       
  1109 //
       
  1110 TBool CListBoxExt::EnableHighlightWithKeyEventL(
       
  1111         TInt aTopItemIndex,
       
  1112         const TKeyEvent& aKeyEvent,
       
  1113         TEventCode aType )
       
  1114     {
       
  1115     _AKNTRACE_FUNC_ENTER;
       
  1116     _AKNTRACE( "aTopItemIndex is %d", aTopItemIndex );
       
  1117     _AKNTRACE( "aKeyEvent.iCode is %d", aKeyEvent.iCode );
       
  1118     _AKNTRACE( "aType is %d", aType );
       
  1119     TBool consumeKey( EFalse );
       
  1120     // With single click first key event enables highlight
       
  1121     if ( iListBox.iItemDrawer->Flags()
       
  1122             & CListItemDrawer::ESingleClickDisabledHighlight
       
  1123             && iSingleClickEnabled )
       
  1124         {
       
  1125         TBool enableHighlight( EFalse );
       
  1126         // Normal case: up, down, enter, msk pressed
       
  1127         if ( aKeyEvent.iCode == EKeyUpArrow
       
  1128                 || aKeyEvent.iCode == EKeyDownArrow
       
  1129                 || aKeyEvent.iCode == EKeyEnter 
       
  1130                 || aKeyEvent.iCode == EKeyOK )
       
  1131             {
       
  1132             consumeKey = ETrue;
       
  1133             enableHighlight = ETrue;
       
  1134             }
       
  1135         else if ( aType == EEventKeyDown
       
  1136                 && aKeyEvent.iScanCode == EStdKeyDevice3 )
       
  1137             {
       
  1138             iFlags |= EMSKKeyDownEventReceived;
       
  1139             }
       
  1140         // Msk pressed when MSK not visible
       
  1141         else if ( iFlags & EMSKKeyDownEventReceived
       
  1142                 && aType == EEventKeyUp
       
  1143                 && aKeyEvent.iScanCode == EStdKeyDevice3 )
       
  1144             {
       
  1145             iFlags &= ( ~EMSKKeyDownEventReceived );
       
  1146             enableHighlight = ETrue;
       
  1147             }
       
  1148         // Handle also left and right when grid in use.
       
  1149         else if ( iItemsInSingleLine > 1
       
  1150                 && ( aKeyEvent.iCode == EKeyLeftArrow 
       
  1151                 || aKeyEvent.iCode == EKeyRightArrow ) )
       
  1152             {
       
  1153             consumeKey = ETrue;
       
  1154             enableHighlight = ETrue;
       
  1155             }
       
  1156         if ( enableHighlight )
       
  1157             {
       
  1158             if ( iListBox.iView->ItemIsPartiallyVisible( aTopItemIndex ) )
       
  1159                 {
       
  1160                 aTopItemIndex++;
       
  1161                 }          
       
  1162             // Enable marquee
       
  1163             if ( iListBox.iItemDrawer->Flags() 
       
  1164                     & CListItemDrawer::EDisableMarquee )
       
  1165                 {
       
  1166                 iListBox.iItemDrawer->
       
  1167                     ClearFlags( CListItemDrawer::EDisableMarquee );
       
  1168                 }           
       
  1169             EnableHighlight( ETrue );
       
  1170             iListBox.UpdateHighlightL( aTopItemIndex );
       
  1171             }
       
  1172         }
       
  1173     _AKNTRACE_FUNC_EXIT;
       
  1174     return consumeKey;
       
  1175     }
       
  1176 
       
  1177 
       
  1178 // -----------------------------------------------------------------------------
       
  1179 // CListBoxExt::MarkedItems
       
  1180 // -----------------------------------------------------------------------------
       
  1181 //
       
  1182 TBool CListBoxExt::MarkedItems() const
       
  1183     {
       
  1184     return ( iListBox.iListBoxFlags & CEikListBox::ES60StyleMarkable
       
  1185             || iListBox.iListBoxFlags & CEikListBox::EMultipleSelection )
       
  1186             && iListBox.SelectionIndexes()->Count() > 0;
       
  1187     }
       
  1188 
       
  1189 
       
  1190 // -----------------------------------------------------------------------------
       
  1191 // CListBoxExt::StartLongPressTimerL
       
  1192 // -----------------------------------------------------------------------------
       
  1193 //
       
  1194 void CListBoxExt::StartLongPressTimerL()
       
  1195     {
       
  1196     _AKNTRACE_FUNC_ENTER;
       
  1197     if ( iLongPressTimer )
       
  1198         {
       
  1199         if ( iLongPressTimer->IsActive() )
       
  1200             {
       
  1201             iLongPressTimer->Cancel();
       
  1202             }
       
  1203 
       
  1204         iLongPressTimer->Start( KLongPressInterval, KLongPressInterval,
       
  1205             TCallBack( ReportLongPressL, this ) );
       
  1206         }
       
  1207     _AKNTRACE_FUNC_EXIT;
       
  1208     }
       
  1209 
       
  1210 // -----------------------------------------------------------------------------
       
  1211 // CListBoxExt::ReportLongPressL
       
  1212 // -----------------------------------------------------------------------------
       
  1213 //
       
  1214 TInt CListBoxExt::ReportLongPressL( TAny* aThis )
       
  1215     {
       
  1216     _AKNTRACE_FUNC_ENTER;
       
  1217     static_cast<CListBoxExt*>( aThis )->DoHandleLongPressL();
       
  1218     _AKNTRACE_FUNC_EXIT;
       
  1219     return 0;
       
  1220     }
       
  1221 
       
  1222 TBool CListBoxExt::IsInIgnoreRect( const TPoint& aPoint ) const
       
  1223     {
       
  1224     TInt offset = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW / 5;
       
  1225     TRect rect( iLastPoint.iX - offset, iLastPoint.iY - offset, 
       
  1226                 iLastPoint.iX + offset, iLastPoint.iY + offset ); 
       
  1227     return rect.Contains( aPoint );
       
  1228     }
       
  1229     
       
  1230 TBool CListBoxExt::IsInHandleAllPointEventArray(const TInt aIndex)  
       
  1231     {
       
  1232     return iMutiTappingItems.FindInOrder( aIndex ) != KErrNotFound;
       
  1233     }
       
  1234 
       
  1235 // -----------------------------------------------------------------------------
       
  1236 // CListBoxExt::DoHandleLongPressL
       
  1237 // -----------------------------------------------------------------------------
       
  1238 //
       
  1239 void CListBoxExt::DoHandleLongPressL()
       
  1240     {
       
  1241     _AKNTRACE_FUNC_ENTER;
       
  1242     iSelectionModeEnabled = ETrue;
       
  1243     if ( iLongPressTimer && iLongPressTimer->IsActive() )
       
  1244         {
       
  1245         iLongPressTimer->Cancel();
       
  1246         }
       
  1247     iListBox.ChangeSelectionMode( ETrue );
       
  1248     _AKNTRACE_FUNC_EXIT;
       
  1249     }
       
  1250 
       
  1251 
       
  1252 void CListBoxExt::CheckCreateBufferL()
       
  1253     {
       
  1254     if (!iBuffer)
       
  1255         iBuffer=CMatchBuffer::NewL(CMatchBuffer::EMinimal);
       
  1256     }
       
  1257 
       
  1258 CMatchBuffer* CListBoxExt::Buffer() const
       
  1259     {
       
  1260     return iBuffer;
       
  1261     }
       
  1262 
       
  1263 void CListBoxExt::CreateMatchBufferL()
       
  1264     {
       
  1265     _AKNTRACE_FUNC_ENTER;
       
  1266     if (iBuffer==NULL)
       
  1267         iBuffer=CMatchBuffer::NewL(CMatchBuffer::EFull);
       
  1268     else if (iBuffer->iMatchBuffer==NULL)
       
  1269         iBuffer->ConstructMatchBufferL();
       
  1270     _AKNTRACE_FUNC_EXIT;
       
  1271     }
       
  1272 
       
  1273 TBool CListBoxExt::IsVisible() const
       
  1274     {
       
  1275     return iListBox.IsVisible();
       
  1276     }
       
  1277 
       
  1278 TBool CListBoxExt::IsMatchBuffer() const
       
  1279     {
       
  1280     return (iBuffer && iBuffer->iMatchBuffer);
       
  1281     }
       
  1282 
       
  1283 void CListBoxExt::SetReasonForFocusLost(CEikListBox::TReasonForFocusLost aReasonForFocusLost)
       
  1284     {
       
  1285     iReasonForFocusLost = aReasonForFocusLost;
       
  1286     }
       
  1287  
       
  1288 TInt CListBoxExt::QwertyModeChangeNotification(TAny* aObj)
       
  1289     {
       
  1290     _AKNTRACE_FUNC_ENTER;
       
  1291     if (aObj != NULL)
       
  1292         {
       
  1293         static_cast<CListBoxExt*>(aObj)->HandleQwertyModeChangeNotification();
       
  1294         _AKNTRACE_FUNC_EXIT;
       
  1295         return KErrNone;
       
  1296         }
       
  1297     else
       
  1298         {
       
  1299         _AKNTRACE_FUNC_EXIT;
       
  1300         return KErrArgument;
       
  1301         }
       
  1302     }
       
  1303     
       
  1304 void CListBoxExt::HandleQwertyModeChangeNotification()
       
  1305     {
       
  1306     TInt value = 0;
       
  1307     iQwertyModeStatusProperty.Get(value);
       
  1308     iQwertyMode = value;
       
  1309     } 
       
  1310 
       
  1311 
       
  1312 void CListBoxExt::CreateMSKObserverL(CEikButtonGroupContainer *aCba, CEikListBox *aListBox)
       
  1313     {
       
  1314     _AKNTRACE_FUNC_ENTER;
       
  1315     RemoveMSKObserver(aListBox); // only one observer can be set at a time
       
  1316     iMSKCommandObserver = new(ELeave)CLBMSKCommandObserver(aCba, aListBox);
       
  1317     iMSKButtonGroupAlive = ETrue;
       
  1318     // if UpdateMSKCommandOpserver fails (there already is MSK observer set),
       
  1319     // iMSKButtonGroupAlive will be set EFalse
       
  1320     aCba->UpdateMSKCommandObserver(aListBox, iMSKCommandObserver);
       
  1321     _AKNTRACE_FUNC_EXIT;
       
  1322     }
       
  1323 
       
  1324 void CListBoxExt::RemoveMSKObserver(CEikListBox *aListBox)
       
  1325     {
       
  1326     _AKNTRACE_FUNC_ENTER;
       
  1327     if (iMSKCommandObserver)
       
  1328         {
       
  1329         if (iMSKButtonGroupAlive)
       
  1330             {
       
  1331             STATIC_CAST(CLBMSKCommandObserver*,iMSKCommandObserver)->iCba->UpdateMSKCommandObserver(aListBox, NULL);
       
  1332             }
       
  1333         delete iMSKCommandObserver;
       
  1334         iMSKCommandObserver = NULL;
       
  1335         }
       
  1336     _AKNTRACE_FUNC_EXIT;
       
  1337     }
       
  1338 
       
  1339 
       
  1340 // CEikListBoxExt::CSubscriber
       
  1341 
       
  1342 CListBoxExt::CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty)
       
  1343     : CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty)
       
  1344     {
       
  1345     CActiveScheduler::Add(this);
       
  1346     }
       
  1347 
       
  1348 CListBoxExt::CSubscriber::~CSubscriber()
       
  1349     {
       
  1350     Cancel();
       
  1351     }
       
  1352 
       
  1353 void CListBoxExt::CSubscriber::SubscribeL()
       
  1354     {
       
  1355     if (!IsActive())
       
  1356         {
       
  1357         iProperty.Subscribe(iStatus);
       
  1358         SetActive();
       
  1359         }
       
  1360     }
       
  1361 
       
  1362 void CListBoxExt::CSubscriber::StopSubscribe()
       
  1363     {
       
  1364     Cancel();
       
  1365     }
       
  1366     
       
  1367 void CListBoxExt::CSubscriber::RunL()
       
  1368     {
       
  1369     if (iStatus.Int() == KErrNone)
       
  1370         {
       
  1371         iCallBack.CallBack();
       
  1372         SubscribeL();
       
  1373         }
       
  1374     }
       
  1375     
       
  1376 void CListBoxExt::CSubscriber::DoCancel()
       
  1377     {
       
  1378     iProperty.Cancel();
       
  1379     }
       
  1380 
       
  1381 // CEikListBox
       
  1382 
       
  1383 CEikListBox::TReasonForFocusLost CListBoxExt::ReasonForFocusLost() const
       
  1384     {
       
  1385     return iReasonForFocusLost;
       
  1386     }
       
  1387 
       
  1388 void CListBoxExt::AddItemChangeObserverL(
       
  1389         MListBoxItemChangeObserver* aObserver )
       
  1390     {
       
  1391     iItemChangeObservers.AppendL( aObserver );
       
  1392     }
       
  1393 
       
  1394 TBool CListBoxExt::RemoveItemChangeObserver(
       
  1395         MListBoxItemChangeObserver* aObserver )
       
  1396     {
       
  1397     TInt index = iItemChangeObservers.Find( aObserver );
       
  1398     if( KErrNotFound == index )
       
  1399         {
       
  1400         return EFalse;
       
  1401         }
       
  1402 
       
  1403     iItemChangeObservers.Remove( index );
       
  1404     return ETrue;
       
  1405     }
       
  1406 
       
  1407 void CListBoxExt::FireItemChange(CEikListBox* aListBox)
       
  1408     {
       
  1409     TInt count = iItemChangeObservers.Count();
       
  1410     for( int i=0; i < count; i++ )
       
  1411         {
       
  1412         iItemChangeObservers[i]->ListBoxItemsChanged(aListBox);
       
  1413         }
       
  1414     }
       
  1415 
       
  1416 void CListBoxExt::SetUpdateScrollBarsColors(TBool aUpdate)
       
  1417     {
       
  1418     if (aUpdate)
       
  1419         iFlags |= EUpdateScrollBarsColors;
       
  1420     else
       
  1421         iFlags &= ~EUpdateScrollBarsColors;
       
  1422     }
       
  1423 
       
  1424 TBool CListBoxExt::UpdateScrollBarsColors() const
       
  1425     {
       
  1426     return (iFlags&EUpdateScrollBarsColors);
       
  1427     }
       
  1428 
       
  1429 void CListBoxExt::CheckScrollBarVisibility()
       
  1430     {
       
  1431     // Kinetic scrolling is disabled if scrollbar is not visible
       
  1432     if ( iListBox.iSBFrame )
       
  1433         {
       
  1434         TBool allowScrolling( iListBox.iSBFrame->ScrollBarVisibility(
       
  1435             CEikScrollBar::EVertical ) != CEikScrollBarFrame::EOff );
       
  1436                 
       
  1437         iScrollingDisabled = !allowScrolling;
       
  1438         }   
       
  1439     }
       
  1440     
       
  1441 void CListBoxExt::HandleNotifyInt(TUint32 aId, TInt aNewValue)
       
  1442     {
       
  1443     if (aId == KAknFepHashKeySelection)
       
  1444         {
       
  1445         iAknFepHashKeySelection = (TBool)aNewValue;
       
  1446         }
       
  1447     }
       
  1448 
       
  1449 
       
  1450 // ---------------------------------------------------------------------------
       
  1451 // Static callback function for the highlight timer. This should draw
       
  1452 // the highlight to the correct item and send the pen down event to the
       
  1453 // listbox observer.
       
  1454 // ---------------------------------------------------------------------------
       
  1455 //
       
  1456 TInt CListBoxExt::HighlightTimerCallback( TAny* aPtr )
       
  1457     {
       
  1458     _AKNTRACE_FUNC_ENTER;
       
  1459     CListBoxExt* me = static_cast<CListBoxExt*>( aPtr );
       
  1460 
       
  1461     if ( me )
       
  1462         {
       
  1463         if ( me->iSingleClickEnabled )
       
  1464             {
       
  1465             me->EnableHighlight( ETrue, ETrue );
       
  1466             }
       
  1467 
       
  1468         TRAP_IGNORE( me->iListBox.UpdateHighlightL(
       
  1469                          me->iLastDownTappedItem ) );
       
  1470         
       
  1471         me->ImmediateFeedback( me->iFeedbackType, 
       
  1472                                TTouchFeedbackType(ETouchFeedbackVibra | ETouchFeedbackAudio),
       
  1473                                TPointerEvent() ); 
       
  1474         
       
  1475         me->CancelHighlightTimer();
       
  1476         }
       
  1477     _AKNTRACE_FUNC_EXIT;
       
  1478     return 0;
       
  1479     }
       
  1480 
       
  1481 
       
  1482 // ---------------------------------------------------------------------------
       
  1483 // Starts the highlight timer.
       
  1484 // ---------------------------------------------------------------------------
       
  1485 //
       
  1486 void CListBoxExt::StartHighlightTimer()
       
  1487     {
       
  1488     _AKNTRACE_FUNC_ENTER;
       
  1489     CancelHighlightTimer();
       
  1490 
       
  1491     TTimeIntervalMicroSeconds32 timeout(
       
  1492         iPhysics->HighlightTimeout() * 1000 );
       
  1493     iHighlightTimer->Start( 
       
  1494         timeout,
       
  1495         timeout,
       
  1496         TCallBack( CListBoxExt::HighlightTimerCallback, this ) );
       
  1497     _AKNTRACE_FUNC_EXIT;
       
  1498     }
       
  1499 
       
  1500 
       
  1501 // ---------------------------------------------------------------------------
       
  1502 // Cancels the highlight timer and the delayed functions to be run upon
       
  1503 // its completion.
       
  1504 // ---------------------------------------------------------------------------
       
  1505 //
       
  1506 void CListBoxExt::CancelHighlightTimer()
       
  1507     {
       
  1508     _AKNTRACE_FUNC_ENTER;
       
  1509     if ( iHighlightTimer )
       
  1510         {
       
  1511         iHighlightTimer->Cancel();
       
  1512         }
       
  1513     iReportDelayedPenDown = EFalse;
       
  1514     iDelayedMultiselection = EFalse;
       
  1515     _AKNTRACE_FUNC_EXIT;
       
  1516     }
       
  1517 
       
  1518 
       
  1519 // ---------------------------------------------------------------------------
       
  1520 // Checks if the highlight timer is currently running.
       
  1521 // ---------------------------------------------------------------------------
       
  1522 //
       
  1523 TBool CListBoxExt::HighlightTimerActive() const
       
  1524     {
       
  1525     _AKNTRACE_FUNC_ENTER;
       
  1526     _AKNTRACE_FUNC_EXIT;
       
  1527     return ( iHighlightTimer && iHighlightTimer->IsActive() );
       
  1528     }
       
  1529 
       
  1530 
       
  1531 // ---------------------------------------------------------------------------
       
  1532 // CListBoxExt::ViewPositionChanged
       
  1533 // ---------------------------------------------------------------------------
       
  1534 //
       
  1535 void CListBoxExt::ViewPositionChanged( const TPoint& aNewPosition,
       
  1536                                        TBool aDrawNow,
       
  1537                                        TUint /*aFlags*/ )
       
  1538     {
       
  1539     _AKNTRACE_FUNC_ENTER;
       
  1540     TInt delta = iViewPosition.iY - aNewPosition.iY;
       
  1541 
       
  1542 #ifdef _DEBUG
       
  1543     _LIT( KDMsg, "CListBoxExt::ViewPositionChanged, delta = %d, aDrawNow = %d" );
       
  1544     RDebug::Print( KDMsg, delta, aDrawNow );
       
  1545 #endif // _DEBUG
       
  1546 
       
  1547     iListBox.ScrollView( delta, aDrawNow );
       
  1548     iViewPosition = aNewPosition;
       
  1549     _AKNTRACE_FUNC_EXIT;
       
  1550     }
       
  1551     
       
  1552 
       
  1553 // ---------------------------------------------------------------------------
       
  1554 // CListBoxExt::PhysicEmulationEnded
       
  1555 // ---------------------------------------------------------------------------
       
  1556 //
       
  1557 void CListBoxExt::PhysicEmulationEnded()
       
  1558     {
       
  1559     _AKNTRACE_FUNC_ENTER;    
       
  1560     if ( iScrolling )
       
  1561         {
       
  1562 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1563         iListBox.SuspendEffects( EFalse );
       
  1564 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1565         TRAP_IGNORE( iListBox.ReportListBoxEventL(
       
  1566                          MEikListBoxObserver::EEventFlickStopped ) );
       
  1567         }
       
  1568     
       
  1569     iScrolling = EFalse;
       
  1570     iListBox.iView->SetScrolling( iScrolling );
       
  1571     _AKNTRACE_FUNC_EXIT;
       
  1572     }
       
  1573 
       
  1574 
       
  1575 // ---------------------------------------------------------------------------
       
  1576 // CListBoxExt::InitPhysicsL
       
  1577 // ---------------------------------------------------------------------------
       
  1578 //
       
  1579 void CListBoxExt::InitPhysicsL()
       
  1580     {
       
  1581     _AKNTRACE_FUNC_ENTER;
       
  1582     if ( iPhysics )
       
  1583         {
       
  1584         // calculate view center based on CEikListBoxView::iTopItemIndex
       
  1585         TInt topItemIndex = iListBox.iView->TopItemIndex();
       
  1586         TInt itemHeight = iListBox.iView->ItemHeight();
       
  1587         TInt numberOfItems = iListBox.iModel->NumberOfItems();
       
  1588 
       
  1589         TSize viewSize( iListBox.iView->ViewRect().Size() );
       
  1590         TSize worldSize( viewSize.iWidth, itemHeight * numberOfItems );
       
  1591         
       
  1592         // grid has several items in one line
       
  1593         if ( iItemsInSingleLine > 1 )
       
  1594             {
       
  1595             worldSize.iHeight = 
       
  1596                 itemHeight * ( numberOfItems / iItemsInSingleLine );
       
  1597             
       
  1598             // handle non-full grid row
       
  1599             if ( numberOfItems % iItemsInSingleLine )
       
  1600                 {
       
  1601                 worldSize.iHeight += itemHeight;
       
  1602                 }
       
  1603             }
       
  1604             
       
  1605         // Reset offset if view's size has changed - this is needed if e.g.
       
  1606         // HandleResourceChange is overridden by a derived implementation.
       
  1607         if ( viewSize != iViewSize && iViewSize != TSize( 0, 0 ) )
       
  1608             {
       
  1609             iListBox.iView->SetItemOffsetInPixels( 0 );
       
  1610             }
       
  1611 
       
  1612         TPoint viewCenter( viewSize.iWidth / 2, ( topItemIndex / iItemsInSingleLine ) * itemHeight - iListBox.iView->ItemOffsetInPixels() + ( viewSize.iHeight / 2 ) );
       
  1613 
       
  1614         // Make sure that world's size is always at least view size.
       
  1615         worldSize.iHeight = Max( worldSize.iHeight, viewSize.iHeight );
       
  1616 
       
  1617         iPhysics->InitPhysicsL( worldSize, viewSize, EFalse );
       
  1618         
       
  1619         iWorldSize = worldSize;
       
  1620         iViewSize = viewSize;
       
  1621         iViewPosition = viewCenter;
       
  1622 
       
  1623 #ifdef _DEBUG
       
  1624         RDebug::Print( _L( "CListBox::InitPhysicsL, iViewSize = %d, %d" ), iViewSize.iWidth, iViewSize.iHeight );
       
  1625         RDebug::Print( _L( "CListBox::InitPhysicsL, iViewPosition = %d, %d" ), iViewPosition.iX, iViewPosition.iY );
       
  1626         RDebug::Print( _L( "CListBox::InitPhysicsL, verticalOffset = %d" ), iListBox.iView->ItemOffsetInPixels() );
       
  1627 #endif // _DEBUG
       
  1628         iPrevTopItemIndex = iListBox.iView->TopItemIndex();
       
  1629         iListBottomLimit = worldSize.iHeight;
       
  1630         }
       
  1631     _AKNTRACE_FUNC_EXIT;
       
  1632     }
       
  1633 
       
  1634 // ---------------------------------------------------------------------------
       
  1635 // CListBoxExt::MovePhysicsCursorL
       
  1636 // ---------------------------------------------------------------------------
       
  1637 //
       
  1638 TBool CListBoxExt::MovePhysicsCursorL(CListBoxView::TCursorMovement aCursorMovement, 
       
  1639 		                             CListBoxView::TSelectionMode aSelectionMode)
       
  1640     {
       
  1641     _AKNTRACE_FUNC_ENTER;
       
  1642     _AKNTRACE( "aCursorMovement = %d, aSelectionMode = %d", 
       
  1643          aCursorMovement, aSelectionMode );    
       
  1644     if ( !iPhysics || iScrollingDisabled )
       
  1645         {
       
  1646         _AKNTRACE_FUNC_EXIT;
       
  1647         return EFalse;
       
  1648         }
       
  1649                     
       
  1650     InitPhysicsL();
       
  1651     TInt curViewPosY = iViewPosition.iY;
       
  1652     TInt worldHeight = iWorldSize.iHeight;
       
  1653     TInt viewHeight = iViewSize.iHeight;
       
  1654     TInt offsetHeight = curViewPosY - ( viewHeight / 2 );
       
  1655     TInt deltaPixels = 0;
       
  1656     switch (aCursorMovement)
       
  1657         {
       
  1658         case CListBoxView::ECursorNextScreen:
       
  1659             {
       
  1660             if ( viewHeight > worldHeight - offsetHeight - viewHeight )
       
  1661                 {
       
  1662                 if ( worldHeight - offsetHeight - viewHeight > 0 )
       
  1663                     {
       
  1664                     iListBox.iView->MoveCursorL(CListBoxView::ECursorLastItem, aSelectionMode);
       
  1665                     }
       
  1666                 break;
       
  1667                 }
       
  1668             deltaPixels = viewHeight;
       
  1669             break;
       
  1670             }
       
  1671         case CListBoxView::ECursorPrevScreen:
       
  1672             {
       
  1673             if ( viewHeight > offsetHeight )
       
  1674                 {
       
  1675                 if ( offsetHeight > 0 )
       
  1676                     {
       
  1677                     iListBox.iView->MoveCursorL(CListBoxView::ECursorFirstItem, aSelectionMode);
       
  1678                     }
       
  1679                 break;
       
  1680                 }
       
  1681             deltaPixels = -viewHeight;
       
  1682             break;
       
  1683             }
       
  1684         default:
       
  1685             {
       
  1686             _AKNTRACE_FUNC_EXIT;
       
  1687             return EFalse;
       
  1688             }
       
  1689         }
       
  1690    
       
  1691     if ( deltaPixels != 0 )
       
  1692         {	
       
  1693         TPoint newPosition( iViewPosition.iX,
       
  1694                         deltaPixels + curViewPosY );
       
  1695         ViewPositionChanged( newPosition );
       
  1696         }
       
  1697     _AKNTRACE_FUNC_EXIT;
       
  1698     return ETrue;
       
  1699     }
       
  1700 
       
  1701 // ---------------------------------------------------------------------------
       
  1702 // CListBoxExt::ImmediateFeedback
       
  1703 // ---------------------------------------------------------------------------
       
  1704 //
       
  1705 void CListBoxExt::ImmediateFeedback( TTouchLogicalFeedback aFeedback,
       
  1706                                      TTouchFeedbackType aFeedbackType,
       
  1707                                      const TPointerEvent& aPointerEvent )
       
  1708     {
       
  1709     _AKNTRACE_FUNC_ENTER;
       
  1710     if ( iFeedback )
       
  1711         {
       
  1712         iFeedback->InstantFeedback( &iListBox, aFeedback, aFeedbackType, aPointerEvent );
       
  1713         }
       
  1714     _AKNTRACE_FUNC_EXIT;
       
  1715     }
       
  1716 
       
  1717 // ---------------------------------------------------------------------------
       
  1718 // CListBoxExt::FeedbackEnabledOnUpEvent
       
  1719 // ---------------------------------------------------------------------------
       
  1720 //
       
  1721 TBool CListBoxExt::FeedbackEnabledOnUpEvent()
       
  1722     {
       
  1723     _AKNTRACE_FUNC_ENTER;
       
  1724     TBool enabled( EFalse );
       
  1725     if ( ( iListBox.iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) &&
       
  1726          !iFlickStopped )
       
  1727         {
       
  1728         enabled = ETrue;
       
  1729         }
       
  1730     _AKNTRACE_FUNC_EXIT;
       
  1731     return enabled;
       
  1732     }
       
  1733 
       
  1734 // ---------------------------------------------------------------------------
       
  1735 // CListBoxExt::SetFlickOngoing
       
  1736 // ---------------------------------------------------------------------------
       
  1737 //
       
  1738 void CListBoxExt::SetFlickOngoing( TBool aFlickOngoing )
       
  1739     {
       
  1740     iFlickOngoing = aFlickOngoing;
       
  1741     }
       
  1742 
       
  1743 // ---------------------------------------------------------------------------
       
  1744 // CListBoxExt::SetPanningOngoing
       
  1745 // ---------------------------------------------------------------------------
       
  1746 //
       
  1747 void CListBoxExt::SetPanningOngoing( TBool aPanningOngoing )
       
  1748     {
       
  1749     iPanningOngoing = aPanningOngoing;
       
  1750     }
       
  1751 
       
  1752 // ---------------------------------------------------------------------------
       
  1753 // CListBoxExt::FlickOrPanningOngoing
       
  1754 // ---------------------------------------------------------------------------
       
  1755 //
       
  1756 TBool CListBoxExt::FlickOrPanningOngoing()
       
  1757     {
       
  1758     return ( iFlickOngoing | iPanningOngoing );
       
  1759     }
       
  1760 
       
  1761 // ---------------------------------------------------------------------------
       
  1762 // CListBoxExt::ListBottomLimit
       
  1763 // ---------------------------------------------------------------------------
       
  1764 //
       
  1765 TInt CListBoxExt::ListBottomLimit()
       
  1766     {
       
  1767     return iListBottomLimit;
       
  1768     }
       
  1769 
       
  1770 //
       
  1771 // class CEikListBox
       
  1772 //
       
  1773 
       
  1774 const TInt KEikListBoxHNudgeSizeAsFractionOfViewRectWidth = 20; 
       
  1775 // const TInt KEikListBoxBackgroundColor = 15;      later, this will be a data member of the listbox  
       
  1776 const TInt KEikListBoxItemVGap = 6; // to allow a box to be drawn around each item
       
  1777 const TInt KEikListBoxInterItemGap = 2;
       
  1778 
       
  1779 GLDEF_C void Panic(TEikListBoxPanic aPanic)
       
  1780     {
       
  1781     _LIT(KPanicCat,"EIKON-LISTBOX");
       
  1782     User::Panic(KPanicCat,aPanic);
       
  1783     }
       
  1784 
       
  1785 EXPORT_C CEikListBox::CEikListBox()
       
  1786 /*DFRD can setup 4 margins (top, bottom, left, right) by setting iHorizontalMargin
       
  1787 to KLafListboxUseLafHorizMargins and iVerticalMargin to KLafListboxUseLafVertMargins.
       
  1788 The DFRD can also use 3 margins by setting either of these 2 values (iHorizonatalMargin
       
  1789 or iVerticalMargin) to another integer.  The application developer can only set 2
       
  1790 margins; iHorizontalMargin and iVerticalMargin*/
       
  1791     :   iItemEditor(NULL)
       
  1792     {
       
  1793     _AKNTRACE_FUNC_ENTER;
       
  1794     LafListBox::GetDefaultBorder(iBorder);
       
  1795     iMargins = LafListBox::Margins();
       
  1796 
       
  1797     iItemHeight = iEikonEnv->NormalFont()->HeightInPixels() + KEikListBoxItemVGap;
       
  1798     iBackColor = iEikonEnv->Color(EColorControlBackground);
       
  1799 
       
  1800     SetComponentsToInheritVisibility(EFalse);
       
  1801     AKNTASHOOK_ADD( this, "CEikListBox" );
       
  1802     _AKNTRACE_FUNC_EXIT;
       
  1803     }
       
  1804 
       
  1805 EXPORT_C void CEikListBox::SetItemsInSingleLine( TInt aItems )
       
  1806     {
       
  1807     if ( iListBoxExt )
       
  1808         {
       
  1809         iListBoxExt->iItemsInSingleLine = aItems;
       
  1810         }
       
  1811     }
       
  1812 
       
  1813 EXPORT_C void CEikListBox::UpdateViewColors()
       
  1814     {
       
  1815     _AKNTRACE_FUNC_ENTER;
       
  1816     if(!iView)
       
  1817         {
       
  1818         _AKNTRACE_FUNC_EXIT;
       
  1819         return;
       
  1820         }
       
  1821 
       
  1822     if(IsDimmed())
       
  1823         {
       
  1824         iView->SetTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this));
       
  1825         iView->SetBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this));
       
  1826         iView->SetMatcherCursorColor(iEikonEnv->ControlColor(EColorControlHighlightBackground,*this));
       
  1827         }
       
  1828     else
       
  1829         {
       
  1830         iView->SetTextColor(iEikonEnv->ControlColor(EColorControlText,*this));
       
  1831         iView->SetBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this));
       
  1832         iView->SetMatcherCursorColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightBackground,*this));
       
  1833         }
       
  1834     _AKNTRACE_FUNC_EXIT;
       
  1835     }
       
  1836 
       
  1837 EXPORT_C void CEikListBox::UpdateItemDrawerColors()
       
  1838     {
       
  1839     _AKNTRACE_FUNC_ENTER;
       
  1840     if(!iItemDrawer)
       
  1841         {
       
  1842         _AKNTRACE_FUNC_EXIT;
       
  1843         return;
       
  1844         }
       
  1845 
       
  1846     if(IsDimmed())
       
  1847         {
       
  1848         iItemDrawer->SetTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this));
       
  1849         iItemDrawer->SetHighlightedTextColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightText,*this));
       
  1850         iItemDrawer->SetDimmedTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this));
       
  1851         iItemDrawer->SetBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this));
       
  1852         iItemDrawer->SetHighlightedBackColor(iEikonEnv->ControlColor(EColorControlDimmedHighlightBackground,*this));
       
  1853         iItemDrawer->SetDimmedBackColor(iEikonEnv->ControlColor(EColorControlDimmedBackground,*this));
       
  1854         }
       
  1855     else
       
  1856         {
       
  1857         iItemDrawer->SetTextColor(iEikonEnv->ControlColor(EColorControlText,*this));
       
  1858         iItemDrawer->SetHighlightedTextColor(iEikonEnv->ControlColor(EColorControlHighlightText,*this));
       
  1859         iItemDrawer->SetDimmedTextColor(iEikonEnv->ControlColor(EColorControlDimmedText,*this));
       
  1860         iItemDrawer->SetBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this));
       
  1861         iItemDrawer->SetHighlightedBackColor(iEikonEnv->ControlColor(EColorControlHighlightBackground,*this));
       
  1862         iItemDrawer->SetDimmedBackColor(iEikonEnv->ControlColor(EColorControlBackground,*this));
       
  1863         }
       
  1864     _AKNTRACE_FUNC_EXIT;
       
  1865     }
       
  1866 
       
  1867 EXPORT_C void CEikListBox::FireItemChange()
       
  1868     {
       
  1869     if( iListBoxExt )
       
  1870         {
       
  1871         iListBoxExt->FireItemChange( this );
       
  1872         }
       
  1873     }
       
  1874 
       
  1875 EXPORT_C CEikListBox::~CEikListBox()
       
  1876     {
       
  1877     _AKNTRACE_FUNC_ENTER;
       
  1878     AKNTASHOOK_REMOVE();
       
  1879     if (iCoeEnv && iEikonEnv && iAvkonEnv) 
       
  1880         iAvkonEnv->RemoveCbaObserver();
       
  1881 
       
  1882     if (iListBoxExt)
       
  1883         {
       
  1884         iListBoxExt->RemoveMSKObserver(this);    
       
  1885         delete iListBoxExt;
       
  1886         iListBoxExt = NULL;
       
  1887         }
       
  1888         
       
  1889     delete iSBFrame;
       
  1890     
       
  1891     if (!(iListBoxFlags & EKeepModel))
       
  1892         delete iModel;
       
  1893     
       
  1894     if (iView)
       
  1895         delete iView;
       
  1896     else
       
  1897         delete iItemDrawer;
       
  1898     
       
  1899     if (iLaunchingButton)
       
  1900         {
       
  1901         TPointerEvent event;
       
  1902         event.iType=TPointerEvent::EButton1Up;
       
  1903         event.iModifiers=0;
       
  1904         event.iPosition=iLaunchingButton->Position();
       
  1905         TRAP_IGNORE(iLaunchingButton->HandlePointerEventL(event));
       
  1906         }
       
  1907     
       
  1908     ResetItemEditor();
       
  1909     _AKNTRACE_FUNC_EXIT;
       
  1910     }
       
  1911 
       
  1912 void CEikListBox::InformMSKButtonGroupDeletion()
       
  1913     {
       
  1914     if (iListBoxExt)
       
  1915         {
       
  1916         iListBoxExt->iMSKButtonGroupAlive = EFalse;
       
  1917         }
       
  1918     }
       
  1919     
       
  1920 EXPORT_C TBool CEikListBox::ItemExists(TInt aItemIndex) const
       
  1921     {
       
  1922     return ((aItemIndex >= 0) && (aItemIndex < iModel->NumberOfItems()));
       
  1923     }
       
  1924 
       
  1925 EXPORT_C void CEikListBox::RestoreCommonListBoxPropertiesL(TResourceReader& aReader)
       
  1926     {
       
  1927     _AKNTRACE_FUNC_ENTER;
       
  1928     aReader.ReadInt8(); // version
       
  1929     iListBoxFlags = aReader.ReadInt32();  
       
  1930         
       
  1931     iRequiredHeightInNumOfItems = aReader.ReadInt16();
       
  1932 
       
  1933     if (! (iListBoxFlags & EPageAtOnceScrolling))
       
  1934         { // no loop scroll for viewers
       
  1935         iListBoxFlags |= ELoopScrolling; // All lists will have loop scrolling.
       
  1936         }
       
  1937 
       
  1938     if (iListBoxFlags & EIncrementalMatching)
       
  1939         CreateMatchBufferL();
       
  1940     _AKNTRACE_FUNC_EXIT;
       
  1941     }
       
  1942 
       
  1943 EXPORT_C MListBoxModel* CEikListBox::Model() const
       
  1944     {
       
  1945     return iModel;
       
  1946     }
       
  1947 
       
  1948 EXPORT_C CListBoxView* CEikListBox::View() const
       
  1949     {
       
  1950     return iView;
       
  1951     }
       
  1952 
       
  1953 EXPORT_C void CEikListBox::CreateMatchBufferL()
       
  1954     {
       
  1955     CheckCreateExtensionL();
       
  1956     iListBoxExt->CreateMatchBufferL();
       
  1957     }
       
  1958 
       
  1959 EXPORT_C void CEikListBox::SetItemHeightL(TInt aHeight)
       
  1960     {
       
  1961     _AKNTRACE_FUNC_ENTER;
       
  1962     _AKNTRACE( "aHeight = %d", aHeight );
       
  1963     // won't actually leave if the horizontal/vertical scrollbars have both been turned off
       
  1964     __ASSERT_ALWAYS((aHeight > 0), Panic(EEikPanicListBoxInvalidItemHeightSpecified));
       
  1965 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1966     TRect lastViewRect( iView->ViewRect() );
       
  1967 #endif
       
  1968     iItemHeight = aHeight;
       
  1969     TRect clientRect = iBorder.InnerRect(Rect());
       
  1970     iView->SetItemHeight(aHeight);
       
  1971     SetViewRectFromClientRect(clientRect);
       
  1972     HandleViewRectSizeChangeL();
       
  1973 
       
  1974 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1975     if( iView->ViewRect() != lastViewRect )
       
  1976         {
       
  1977         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  1978         if ( transApi )
       
  1979             {
       
  1980             transApi->Remove( MAknListBoxTfxInternal:: EListEverything );
       
  1981             }
       
  1982         }
       
  1983 #endif
       
  1984     _AKNTRACE_FUNC_EXIT;
       
  1985     }
       
  1986 
       
  1987 EXPORT_C TInt CEikListBox::ItemHeight() const
       
  1988     {
       
  1989     return iItemHeight;
       
  1990     }
       
  1991 
       
  1992 EXPORT_C TInt CEikListBox::CalcWidthBasedOnNumOfChars(TInt aNumOfChars) const
       
  1993     {
       
  1994     return CalcWidthBasedOnRequiredItemWidth(aNumOfChars * iEikonEnv->NormalFont()->MaxNormalCharWidthInPixels());
       
  1995     }
       
  1996 
       
  1997 EXPORT_C TInt CEikListBox::CalcWidthBasedOnRequiredItemWidth(TInt aTextWidthInPixels) const
       
  1998     {
       
  1999     _AKNTRACE_FUNC_ENTER;
       
  2000     _AKNTRACE("aTextWidthInPixels = %d", aTextWidthInPixels);    
       
  2001     TInt width = aTextWidthInPixels;
       
  2002     if (iItemDrawer->Flags()&CListItemDrawer::EDrawMarkSelection)
       
  2003         {
       
  2004         width += iItemDrawer->MarkColumn() + iItemDrawer->MarkGutter();
       
  2005         }
       
  2006     width += (LafListBox::InnerGutter() + ListBoxMargins().iLeft + ListBoxMargins().iRight);
       
  2007     width += iBorder.SizeDelta().iWidth;
       
  2008     if (iSBFrame)
       
  2009         {
       
  2010 #if COMMENTED_FOR_SERIES60_BECAUSE_SCROLLBAR_BREADTH_IS_NONZERO
       
  2011         if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  2012             width += CEikScrollBar::DefaultScrollBarBreadth();
       
  2013 #endif
       
  2014         }
       
  2015     _AKNTRACE( "width = %d", width );    
       
  2016     _AKNTRACE_FUNC_EXIT;
       
  2017     return width;
       
  2018     }
       
  2019 
       
  2020 EXPORT_C TInt CEikListBox::CalcHeightBasedOnNumOfItems(TInt aNumOfItems) const
       
  2021     {
       
  2022     _AKNTRACE_FUNC_ENTER;
       
  2023     _AKNTRACE( "aNumOfItems = %d", aNumOfItems );      
       
  2024     TInt height;
       
  2025     height = (aNumOfItems * iItemHeight);
       
  2026     height += (ListBoxMargins().iTop + ListBoxMargins().iBottom);
       
  2027     height += iBorder.SizeDelta().iHeight;
       
  2028     if (iSBFrame)
       
  2029         {
       
  2030         if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  2031             height += CEikScrollBar::DefaultScrollBarBreadth();
       
  2032         }
       
  2033     _AKNTRACE( "height = %d", height );  
       
  2034     _AKNTRACE_FUNC_EXIT;
       
  2035     return height;
       
  2036     }
       
  2037 
       
  2038 EXPORT_C TSize CEikListBox::MinimumSize()
       
  2039     {
       
  2040     _AKNTRACE_FUNC_ENTER;
       
  2041     TSize size;
       
  2042     TSize minCellSize(iItemDrawer->MinimumCellSize());
       
  2043     size.iWidth = minCellSize.iWidth + ListBoxMargins().iLeft + ListBoxMargins().iRight;
       
  2044     size.iHeight = (ListBoxMargins().iTop + ListBoxMargins().iBottom) + (iRequiredHeightInNumOfItems * minCellSize.iHeight);
       
  2045     if ((!(iListBoxFlags & EScrollBarSizeExcluded)) && iSBFrame)
       
  2046         {
       
  2047         if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  2048             size.iWidth += CEikScrollBar::DefaultScrollBarBreadth();
       
  2049         if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  2050             size.iHeight += CEikScrollBar::DefaultScrollBarBreadth();
       
  2051         }
       
  2052     size += iBorder.SizeDelta();
       
  2053     _AKNTRACE( "width = %d, height = %d", size.iWidth, size.iHeight ); 
       
  2054     _AKNTRACE_FUNC_EXIT;
       
  2055     return size;
       
  2056     }
       
  2057 
       
  2058 EXPORT_C TSize CEikListBox::CalcSizeInPixels(TInt aWidthAsNumOfChars, TInt aHeightAsNumOfItems) const
       
  2059     {
       
  2060     return TSize(CalcWidthBasedOnNumOfChars(aWidthAsNumOfChars), CalcHeightBasedOnNumOfItems(aHeightAsNumOfItems));
       
  2061     }
       
  2062 
       
  2063 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc)
       
  2064     {
       
  2065     return CreateScrollBarFrameL(aPreAlloc, EFalse);
       
  2066     }
       
  2067 
       
  2068 EXPORT_C void CEikListBox::HandleViewRectSizeChangeL()
       
  2069     {
       
  2070     _AKNTRACE_FUNC_ENTER;
       
  2071     iView->CalcBottomItemIndex();
       
  2072     iView->CalcDataWidth();
       
  2073     TInt currentItemIndex = iView->CurrentItemIndex();
       
  2074 
       
  2075     if ( ItemExists(currentItemIndex) )
       
  2076         {
       
  2077         TInt topItemIndex( iView->TopItemIndex() );
       
  2078         TInt numberOfItems = iView->NumberOfItemsThatFitInRect( iView->ViewRect() );    
       
  2079         TInt newTopItemIndex( KEikListBoxInvalidIndex ); 
       
  2080 
       
  2081         // Current item not visible or current item is the last item (not fully visible)
       
  2082         if ( !iView->ItemIsVisible(currentItemIndex)
       
  2083         	|| iListBoxExt && iListBoxExt->iPhysics 
       
  2084         	&& currentItemIndex == ( topItemIndex + numberOfItems - 1 ) )
       
  2085             {
       
  2086             newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( currentItemIndex );
       
  2087             }
       
  2088         else
       
  2089             {
       
  2090             // recalculates top index of list when mode be changed
       
  2091             TInt totalItems = iModel->NumberOfItems();
       
  2092             if ( (totalItems - topItemIndex) < numberOfItems )
       
  2093                 {
       
  2094                 newTopItemIndex = Max( 0, totalItems - numberOfItems );
       
  2095                 }
       
  2096             }
       
  2097 
       
  2098         if ( newTopItemIndex != KEikListBoxInvalidIndex )
       
  2099         	{
       
  2100         	iView->SetTopItemIndex( newTopItemIndex );
       
  2101         	if ( iListBoxExt && iListBoxExt->iPhysics )
       
  2102         		{
       
  2103         		iListBoxExt->InitPhysicsL();
       
  2104         		}
       
  2105             }
       
  2106         }
       
  2107     UpdateScrollBarsL();
       
  2108     _AKNTRACE_FUNC_EXIT;
       
  2109     }
       
  2110 
       
  2111 EXPORT_C void CEikListBox::SizeChanged()
       
  2112     {
       
  2113     _AKNTRACE_FUNC_ENTER;
       
  2114     TRect clientRect = iBorder.InnerRect(Rect());
       
  2115     SetViewRectFromClientRect(clientRect);
       
  2116     TRAP_IGNORE(HandleViewRectSizeChangeL());
       
  2117     _AKNTRACE_FUNC_EXIT;
       
  2118     }
       
  2119 
       
  2120 EXPORT_C TInt CEikListBox::CountComponentControls() const
       
  2121     {
       
  2122     TInt count=CEikBorderedControl::CountComponentControls();
       
  2123     if (iSBFrame && (iSBFrameOwned == ENotOwnedExternally))
       
  2124         {
       
  2125         if(iSBFrame->VerticalScrollBar()) 
       
  2126            { 
       
  2127            count+=iSBFrame->CountComponentControls(); 
       
  2128            }
       
  2129         }
       
  2130     return count;
       
  2131     }
       
  2132 
       
  2133 EXPORT_C CCoeControl* CEikListBox::ComponentControl(TInt aIndex) const
       
  2134     {
       
  2135     TInt baseCount=CEikBorderedControl::CountComponentControls();
       
  2136     if (aIndex<baseCount)
       
  2137         {
       
  2138         return CEikBorderedControl::ComponentControl(aIndex);
       
  2139         }
       
  2140     aIndex-=baseCount;
       
  2141     if( iSBFrame && iSBFrame->VerticalScrollBar() ) 
       
  2142         { 
       
  2143         return iSBFrame->ComponentControl(aIndex); 
       
  2144         } 
       
  2145     else
       
  2146         {
       
  2147         return NULL;
       
  2148         }
       
  2149     }
       
  2150 
       
  2151 EXPORT_C void CEikListBox::SetViewRectFromClientRect(const TRect& aClientRect)
       
  2152     {
       
  2153     _AKNTRACE_FUNC_ENTER;
       
  2154     TRect rect(aClientRect);
       
  2155     rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop,
       
  2156         rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom);
       
  2157 
       
  2158     if ( iListBoxExt && iListBoxExt->iPhysics )
       
  2159         {
       
  2160         iViewRectHeightAdjustment = 0;
       
  2161         iView->SetViewRect(rect);
       
  2162         }
       
  2163     else
       
  2164         {
       
  2165         iItemHeight = iView->ItemSize().iHeight;
       
  2166         iViewRectHeightAdjustment = AdjustRectHeightToWholeNumberOfItems(rect);
       
  2167         iView->SetViewRect(rect);
       
  2168         }
       
  2169         
       
  2170     if ( iListBoxExt && 
       
  2171          (iListBoxExt->iViewSize != rect.Size() ))
       
  2172         {
       
  2173         iListBoxExt->iViewSize = rect.Size();
       
  2174         }    
       
  2175     _AKNTRACE_FUNC_EXIT;
       
  2176     }
       
  2177 
       
  2178 EXPORT_C void CEikListBox::RestoreClientRectFromViewRect(TRect& aClientRect) const
       
  2179     {
       
  2180     _AKNTRACE_FUNC_ENTER;
       
  2181     aClientRect=iView->ViewRect();
       
  2182     aClientRect.SetRect(aClientRect.iTl.iX - ListBoxMargins().iLeft, aClientRect.iTl.iY - ListBoxMargins().iTop,
       
  2183         aClientRect.iBr.iX + ListBoxMargins().iRight, aClientRect.iBr.iY + ListBoxMargins().iBottom);
       
  2184     // height may have been rounded so correct it
       
  2185     if (!iViewRectHeightAdjustment)
       
  2186         return;
       
  2187 #ifdef ORIGINAL_UIKON_CODE
       
  2188     if (iViewRectHeightAdjustment % 2 !=0)
       
  2189         aClientRect.iBr.iY += 1;
       
  2190     aClientRect.Grow(0, iViewRectHeightAdjustment/2);
       
  2191 #else // Series60 code
       
  2192     aClientRect.iBr.iY += iViewRectHeightAdjustment;
       
  2193 #endif
       
  2194     _AKNTRACE_FUNC_EXIT;
       
  2195     // aClientRect.iBr.iY += iViewRectHeightAdjustment;
       
  2196     }
       
  2197 
       
  2198 EXPORT_C TInt CEikListBox::AdjustRectHeightToWholeNumberOfItems(TRect& aRect) const
       
  2199     {
       
  2200     _AKNTRACE_FUNC_ENTER;
       
  2201     // round down the height of aRect (if necessary) so that only a whole number of items can be displayed inside the listbox
       
  2202     // returns the number of pixels reduced.
       
  2203 #ifdef ORIGINAL_UIKON_CODE
       
  2204     TInt remainder = aRect.Height() % iItemHeight;
       
  2205     if (remainder != 0) 
       
  2206         {
       
  2207         // need to adjust viewRect 
       
  2208         aRect.Shrink(0, remainder/2);
       
  2209         if (remainder % 2 != 0)     
       
  2210             aRect.iBr.iY -= 1;
       
  2211         // aRect.iBr.iY -= remainder;
       
  2212         }
       
  2213 #else // Series 60 code
       
  2214     // To catch places which use this in series 60
       
  2215     // -- should use derived class version
       
  2216     // from CAknColumnList or CEikFormattedCellListBox or something else.
       
  2217     //__ASSERT_DEBUG(0, Panic(0));
       
  2218     // This is dead code, can be reverted to original once we've tested
       
  2219     // noone uses this.
       
  2220     TInt remainder = aRect.Height() % iItemHeight;
       
  2221     if (remainder != 0)
       
  2222     {
       
  2223         aRect.iBr.iY -= remainder;
       
  2224         }
       
  2225 #endif
       
  2226     _AKNTRACE_FUNC_EXIT;
       
  2227     return remainder;
       
  2228     }
       
  2229 
       
  2230 EXPORT_C void CEikListBox::CalculatePopoutRect(TInt aTargetItemIndex, TInt aTargetYPos, TRect& aListBoxRect, TInt aMinHeightInNumOfItems) 
       
  2231     {
       
  2232     _AKNTRACE_FUNC_ENTER;
       
  2233     /*controlling the maximum width, in pixels, of a choice list*/
       
  2234     if((LafListBox::MaxCellWidthInNumOfPixels() != KLafListBoxNoMaxCellWidth) && (aListBoxRect.Width() > LafListBox::MaxCellWidthInNumOfPixels()))
       
  2235         {
       
  2236         aListBoxRect.iBr.iX = aListBoxRect.iTl.iX + LafListBox::MaxCellWidthInNumOfPixels();
       
  2237         }
       
  2238     // this function is designed for use by the choice list control
       
  2239     TInt listBoxHeight = 0;
       
  2240     TInt listBoxYPos = 0;
       
  2241     TInt screenHeight = iAvkonAppUi->ApplicationRect().Height(); /*iCoeEnv->ScreenDevice()->SizeInPixels().iHeight;*/
       
  2242     TInt maxDisplayedItems = (screenHeight - (ListBoxMargins().iTop + ListBoxMargins().iBottom) - iBorder.SizeDelta().iHeight) / iItemHeight;
       
  2243 
       
  2244     /*controlling the maximum number of items displayed in a choice list*/
       
  2245     if(LafListBox::MaxHeightInNumOfItems() != KLafListBoxNoMaxHeightInNumOfItems)
       
  2246         {
       
  2247         maxDisplayedItems = Min(maxDisplayedItems,LafListBox::MaxHeightInNumOfItems());
       
  2248         }
       
  2249     TInt desiredHeightInNumOfItems = Max(iModel->NumberOfItems(), aMinHeightInNumOfItems);
       
  2250     if (desiredHeightInNumOfItems > maxDisplayedItems)
       
  2251         {
       
  2252         listBoxHeight = CalcHeightBasedOnNumOfItems(maxDisplayedItems);     
       
  2253         listBoxYPos = (screenHeight - listBoxHeight) / 2;
       
  2254         TInt numOfDisplayedItemsAboveTarget = (aTargetYPos-listBoxYPos-ListBoxMargins().iTop)/iItemHeight;
       
  2255         
       
  2256         TInt topItemOrdinal=Max(0, (aTargetItemIndex-numOfDisplayedItemsAboveTarget));
       
  2257         topItemOrdinal=Min(iModel->NumberOfItems()-maxDisplayedItems,topItemOrdinal);
       
  2258         iView->SetTopItemIndex(iView->TopItemIndex()+topItemOrdinal);
       
  2259         aListBoxRect.iTl.iY = listBoxYPos;
       
  2260         aListBoxRect.iBr.iY = listBoxYPos + listBoxHeight;
       
  2261         return;
       
  2262         }
       
  2263     listBoxHeight = CalcHeightBasedOnNumOfItems(desiredHeightInNumOfItems);
       
  2264     TInt numOfItemsAbove = aTargetItemIndex;
       
  2265     TInt potentialPixelsAboveTarget = 0;
       
  2266     if (numOfItemsAbove > 0)
       
  2267         {
       
  2268         potentialPixelsAboveTarget = numOfItemsAbove * iItemHeight + ListBoxMargins().iTop + iBorder.Margins().iTop;
       
  2269         }
       
  2270     listBoxYPos = aTargetYPos - potentialPixelsAboveTarget;
       
  2271     if ((listBoxYPos + listBoxHeight) >= screenHeight)
       
  2272         listBoxYPos = screenHeight - listBoxHeight;
       
  2273     if (potentialPixelsAboveTarget>aTargetYPos)
       
  2274         listBoxYPos = 0;
       
  2275     // find number of items below aTargetItemIndex
       
  2276     TInt numberOfItemsBelowTarget = 0;
       
  2277     TInt targetIndex = aTargetItemIndex;
       
  2278     while (ItemExists(++targetIndex))
       
  2279         ++numberOfItemsBelowTarget;
       
  2280     TInt potentialPixelsBelowTarget = 0;
       
  2281     if (numberOfItemsBelowTarget > 0)
       
  2282         {
       
  2283         potentialPixelsBelowTarget = numberOfItemsBelowTarget * iItemHeight + ListBoxMargins().iBottom + iBorder.Margins().iBottom;
       
  2284         }
       
  2285     if ((potentialPixelsBelowTarget + iItemHeight) > (screenHeight-aTargetYPos))
       
  2286         listBoxYPos = screenHeight - listBoxHeight;
       
  2287     aListBoxRect.iTl.iY = listBoxYPos;
       
  2288     aListBoxRect.iBr.iY = listBoxYPos + listBoxHeight;
       
  2289     _AKNTRACE_FUNC_EXIT;
       
  2290     }
       
  2291 
       
  2292 EXPORT_C TInt CEikListBox::TopItemIndex() const
       
  2293     {
       
  2294     _AKNTRACE( "iTopItemIndex = %d", iView->TopItemIndex() );
       
  2295     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  2296     return iView->TopItemIndex();
       
  2297     }
       
  2298 
       
  2299 EXPORT_C TInt CEikListBox::BottomItemIndex() const
       
  2300     {
       
  2301     _AKNTRACE( "iBottomItemIndex = %d", iView->BottomItemIndex() );
       
  2302     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  2303     return iView->BottomItemIndex();
       
  2304     }
       
  2305 
       
  2306 EXPORT_C void CEikListBox::SetTopItemIndex(TInt aItemIndex) const
       
  2307     {
       
  2308     _AKNTRACE( "aItemIndex = %d", aItemIndex );
       
  2309     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  2310     iView->SetTopItemIndex(aItemIndex);
       
  2311     UpdateScrollBarThumbs();
       
  2312     }
       
  2313 
       
  2314 EXPORT_C void CEikListBox::AdjustTopItemIndex() const
       
  2315     {
       
  2316     _AKNTRACE_FUNC_ENTER;
       
  2317     TInt maxTopItemIndex=iView->BottomItemIndex() - iView->NumberOfItemsThatFitInRect(iView->ViewRect()) +1;
       
  2318     maxTopItemIndex=Max(0, maxTopItemIndex);
       
  2319     if (iView->TopItemIndex() > maxTopItemIndex)
       
  2320         SetTopItemIndex(maxTopItemIndex);
       
  2321     _AKNTRACE_FUNC_EXIT;
       
  2322     }
       
  2323 
       
  2324 EXPORT_C TInt CEikListBox::CurrentItemIndex() const
       
  2325     {
       
  2326     _AKNTRACE( "iView->CurrentItemIndex() is %d", iView->CurrentItemIndex() );
       
  2327     __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView));
       
  2328     return iView->CurrentItemIndex();
       
  2329     }
       
  2330 
       
  2331 EXPORT_C void CEikListBox::UpdateCurrentItem(TInt aItemIndex) const
       
  2332     {
       
  2333     _AKNTRACE_FUNC_ENTER;
       
  2334     TInt oldCurrentItemIndex = iView->CurrentItemIndex();
       
  2335     iView->SetCurrentItemIndex(aItemIndex);
       
  2336     if ( IsReadyToDraw() )
       
  2337         {
       
  2338         iView->DrawItem(oldCurrentItemIndex);
       
  2339         }
       
  2340     if (!(iView->ItemIsVisible(aItemIndex)) || iView->ItemIsPartiallyVisible(aItemIndex) )
       
  2341         {
       
  2342         SetTopItemIndex(iView->CalcNewTopItemIndexSoItemIsVisible(aItemIndex));
       
  2343         
       
  2344         if ( !iView->RedrawDisabled() )
       
  2345             {           
       
  2346             DrawNow();
       
  2347             }
       
  2348         }
       
  2349 #if NOT_USED_IN_SERIES60
       
  2350 // This is not used in Series 60 because in FIND, we do not want
       
  2351 // selectionindexes to have a list of indexes...
       
  2352     if (!(iListBoxFlags & EMultipleSelection))
       
  2353         {
       
  2354         TRAPD(err,iView->UpdateSelectionL(CListBoxView::ESingleSelection));
       
  2355         if (err!=KErrNone)
       
  2356             iEikonEnv->NotifyIdleErrorWhileRedrawing(err);
       
  2357         }
       
  2358 #endif
       
  2359 
       
  2360     iView->DrawItem(aItemIndex);
       
  2361     TRAP_IGNORE(UpdateMarkUnmarkMSKL());
       
  2362     UpdateScrollBarThumbs();
       
  2363     _AKNTRACE_FUNC_EXIT;
       
  2364     }
       
  2365 
       
  2366 EXPORT_C void CEikListBox::SetCurrentItemIndex(TInt aItemIndex) const
       
  2367     {
       
  2368     _AKNTRACE_FUNC_ENTER;
       
  2369     _AKNTRACE( "aItemIndex = %d", aItemIndex );
       
  2370     __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView));
       
  2371     TBool redrawDisabled = iView->RedrawDisabled();
       
  2372     iView->SetDisableRedraw(ETrue);
       
  2373     UpdateCurrentItem(aItemIndex);
       
  2374     iView->SetDisableRedraw(redrawDisabled);
       
  2375     
       
  2376     if ( iListBoxExt && iListBoxExt->iPhysics && aItemIndex == 0 )
       
  2377         {
       
  2378         iView->SetItemOffsetInPixels( 0 );        
       
  2379         }
       
  2380     _AKNTRACE_FUNC_EXIT;
       
  2381     }
       
  2382 
       
  2383 EXPORT_C void CEikListBox::SetCurrentItemIndexAndDraw(TInt aItemIndex) const
       
  2384     {
       
  2385     __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView));
       
  2386     UpdateCurrentItem(aItemIndex);
       
  2387     }
       
  2388 
       
  2389 EXPORT_C void CEikListBox::ConstructL(const CCoeControl* aParent,TInt aFlags)
       
  2390     {
       
  2391     _AKNTRACE_FUNC_ENTER;
       
  2392     iListBoxFlags = aFlags;
       
  2393     if (! (iListBoxFlags & EPageAtOnceScrolling))
       
  2394         { // no loop scroll for viewers
       
  2395         iListBoxFlags |= ELoopScrolling; // All lists will have loop scrolling.
       
  2396         }
       
  2397     if (aParent)
       
  2398         SetContainerWindowL(*aParent);
       
  2399     else
       
  2400         {
       
  2401         CreateWindowL(aParent);
       
  2402 
       
  2403         if ( CAknEnv::Static()->TransparencyEnabled() )
       
  2404             {
       
  2405             Window().SetRequiredDisplayMode( EColor16MA );
       
  2406             TInt err = Window().SetTransparencyAlphaChannel();
       
  2407 
       
  2408             if ( err == KErrNone )
       
  2409                 {
       
  2410                 Window().SetBackgroundColor(~0);
       
  2411                 }
       
  2412             }
       
  2413 
       
  2414         EnableDragEvents();
       
  2415         Window().SetPointerGrab(ETrue);
       
  2416         }
       
  2417     if (iListBoxFlags & EPopout)
       
  2418         {
       
  2419         if (!LafListBox::FadeBehind())
       
  2420             DrawableWindow()->EnableBackup();
       
  2421         LafListBox::GetDefaultPopoutBorder(iBorder);
       
  2422         }
       
  2423     if (iListBoxFlags & EIncrementalMatching)
       
  2424         CreateMatchBufferL();
       
  2425     CreateViewL();
       
  2426     
       
  2427     if(iItemDrawer && (iItemDrawer->MinimumCellSize().iHeight != 0))
       
  2428         iItemHeight = iItemDrawer->MinimumCellSize().iHeight;
       
  2429 
       
  2430     CheckCreateExtensionL();
       
  2431     
       
  2432     if ( iListBoxExt->iLongTapDetector
       
  2433             && iListBoxFlags & EDisableItemSpecificMenu )
       
  2434         {
       
  2435         delete iListBoxExt->iLongTapDetector;
       
  2436         iListBoxExt->iLongTapDetector = NULL;
       
  2437         }
       
  2438     _AKNTRACE_FUNC_EXIT;
       
  2439     }
       
  2440 
       
  2441 EXPORT_C void CEikListBox::ConstructL(MListBoxModel* aListBoxModel,CListItemDrawer* aListItemDrawer,const CCoeControl* aParent,TInt aFlags)
       
  2442     {
       
  2443     _AKNTRACE_FUNC_ENTER;
       
  2444     __ASSERT_DEBUG(aListBoxModel!=NULL,Panic(EEikPanicListBoxInvalidModelSpecified));
       
  2445     __ASSERT_DEBUG(aListItemDrawer!=NULL,Panic(EEikPanicListBoxInvalidItemDrawerSpecified));
       
  2446     iModel = aListBoxModel;
       
  2447     iItemDrawer = aListItemDrawer;
       
  2448     ConstructL(aParent,aFlags);
       
  2449     _AKNTRACE_FUNC_EXIT;
       
  2450     }
       
  2451 
       
  2452 EXPORT_C void CEikListBox::ConstructL(MListBoxModel* aListBoxModel, CListItemDrawer* aListItemDrawer, const CCoeControl* aParent, TGulBorder aBorder, TInt aFlags)
       
  2453     {
       
  2454     _AKNTRACE_FUNC_ENTER;
       
  2455     iBorder = aBorder;
       
  2456     CEikListBox::ConstructL(aListBoxModel, aListItemDrawer, aParent, aFlags);
       
  2457     _AKNTRACE_FUNC_EXIT;
       
  2458     }
       
  2459 
       
  2460 EXPORT_C void CEikListBox::SetListBoxObserver(MEikListBoxObserver* aObserver)
       
  2461     {
       
  2462     iListBoxObserver = aObserver;
       
  2463     }
       
  2464 
       
  2465 EXPORT_C void CEikListBox::SetContainerWindowL(const CCoeControl& aParent)
       
  2466     {
       
  2467     _AKNTRACE_FUNC_ENTER;
       
  2468     if ((iListBoxFlags & ECreateOwnWindow) || (iListBoxFlags & EPopout))
       
  2469         {
       
  2470         CreateWindowL(&aParent);
       
  2471         if (iListBoxFlags & EPopout)
       
  2472             DrawableWindow()->EnableBackup();
       
  2473         }
       
  2474     else
       
  2475         CCoeControl::SetContainerWindowL(aParent);
       
  2476     EnableDragEvents();
       
  2477     Window().SetPointerGrab(ETrue);
       
  2478     
       
  2479     if ( iListBoxExt && iListBoxExt->iPhysics )
       
  2480         {
       
  2481         iListBoxExt->iPhysics->UpdateViewWindowControl();
       
  2482         }
       
  2483     _AKNTRACE_FUNC_EXIT;
       
  2484     }
       
  2485 
       
  2486 EXPORT_C CListBoxView* CEikListBox::MakeViewClassInstanceL()
       
  2487     {
       
  2488     return (new(ELeave) CListBoxView);
       
  2489     }
       
  2490 
       
  2491 EXPORT_C void CEikListBox::CreateViewL()
       
  2492     {
       
  2493     _AKNTRACE_FUNC_ENTER;
       
  2494     // assert that the model and item drawer aren't null
       
  2495     if (iView)
       
  2496         {
       
  2497         _AKNTRACE_FUNC_EXIT;
       
  2498         return;
       
  2499         }
       
  2500     iView = MakeViewClassInstanceL();
       
  2501     iView->ConstructL(iModel, iItemDrawer, iEikonEnv->ScreenDevice(), &(iEikonEnv->RootWin()), &Window(), Rect(), iItemHeight);
       
  2502     iView->iExtension->iListBox = this;    
       
  2503 
       
  2504 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2505     // LISTBOX EFFECTS IMPLEMENTATION
       
  2506     //
       
  2507     // Creates a CTfxGc and replaces the original CWindowGc with that gc.
       
  2508     //
       
  2509     CWindowGc* transGc = CAknListLoader::CreateTfxGc( *this );
       
  2510     if( transGc )
       
  2511         {
       
  2512         iView->iGc = transGc;
       
  2513         iView->ItemDrawer()->SetGc(transGc);
       
  2514         }
       
  2515     // END OF LISTBOX EFFECTS IMPLEMENTATION
       
  2516 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2517 
       
  2518     if (iListBoxFlags & EIncrementalMatching)
       
  2519         {
       
  2520         iView->SetMatcherCursor(ETrue);
       
  2521         if(IsDimmed())
       
  2522             iView->SetMatcherCursorColor(EColorControlHighlightBackground);
       
  2523         else
       
  2524             iView->SetMatcherCursorColor(EColorControlDimmedHighlightBackground);
       
  2525         }
       
  2526     iItemDrawer->SetVerticalInterItemGap(KEikListBoxItemVGap);
       
  2527     if (iListBoxFlags & EMultipleSelection) iItemDrawer->SetDrawMark(ETrue);
       
  2528     if (ItemExists(0))
       
  2529         SetCurrentItemIndex(0);
       
  2530     CheckCreateExtensionL();
       
  2531     
       
  2532     if ( iListBoxExt && iListBoxExt->iPhysics )
       
  2533         {
       
  2534         iView->iExtension->iScrollingDisabled = EFalse;
       
  2535         }
       
  2536     
       
  2537     iView->SetVisibilityObserver(iListBoxExt);
       
  2538     if ( iListBoxFlags & EPaintedSelection )
       
  2539         {
       
  2540         iView->SetPaintedSelection( ETrue );
       
  2541         iItemDrawer->SetDrawMark( EFalse );
       
  2542         iItemDrawer->SetFlags( CListItemDrawer::EPaintedSelection );
       
  2543         }
       
  2544     if (iListBoxFlags & EDisableHighlight)
       
  2545     {
       
  2546     iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight );
       
  2547     }
       
  2548 
       
  2549     if ( iListBoxExt && iListBoxExt->iSingleClickEnabled )
       
  2550         {
       
  2551         iListBoxExt->EnableHighlight( EFalse );
       
  2552         iListBoxExt->ReportCollectionChangedEvent();
       
  2553         }    
       
  2554         
       
  2555     UpdateViewColors();
       
  2556     UpdateItemDrawerColors();
       
  2557     _AKNTRACE_FUNC_EXIT;
       
  2558     }
       
  2559 
       
  2560 EXPORT_C void CEikListBox::DrawMatcherCursor() const
       
  2561     {
       
  2562     if (!IsMatchBuffer())
       
  2563         return;
       
  2564     TInt currentItemIndex = iView->CurrentItemIndex();
       
  2565     if (ItemExists(currentItemIndex)) 
       
  2566         {
       
  2567         if (! iView->ItemIsVisible(currentItemIndex))
       
  2568             ScrollToMakeItemVisible(currentItemIndex);
       
  2569         iView->DrawMatcherCursor();
       
  2570         }
       
  2571     }
       
  2572 
       
  2573 EXPORT_C TInt CEikListBox::InterItemGap()
       
  2574     { // static
       
  2575     return KEikListBoxInterItemGap;
       
  2576     }
       
  2577 
       
  2578 
       
  2579 EXPORT_C void CEikListBox::DrawItem( TInt aItemIndex ) const
       
  2580     {
       
  2581     _AKNTRACE_FUNC_ENTER;
       
  2582     if ( !IsReadyToDraw() )
       
  2583         {
       
  2584         _AKNTRACE_FUNC_EXIT;
       
  2585         return;
       
  2586         }
       
  2587 
       
  2588     __ASSERT_ALWAYS( iView, Panic( EEikPanicListBoxNoView ) );
       
  2589     
       
  2590     TBool viewScrolled = EFalse;
       
  2591     if ( iView->ItemIsPartiallyVisible( aItemIndex ) ||
       
  2592          !iView->ItemIsVisible( aItemIndex ) )
       
  2593         {
       
  2594         viewScrolled = iView->ScrollToMakeItemVisible( aItemIndex );
       
  2595         }
       
  2596 
       
  2597     if ( !viewScrolled )
       
  2598         {
       
  2599         iView->DrawItem( aItemIndex );
       
  2600         }
       
  2601     else
       
  2602         {
       
  2603         UpdateScrollBarThumbs();
       
  2604         }
       
  2605     _AKNTRACE_FUNC_EXIT;
       
  2606     }
       
  2607 
       
  2608 
       
  2609 EXPORT_C void CEikListBox::ScrollToMakeItemVisible(TInt aItemIndex) const 
       
  2610     {
       
  2611     _AKNTRACE_FUNC_ENTER;
       
  2612     __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView));
       
  2613     TBool scrollingTookPlace = iView->ScrollToMakeItemVisible(aItemIndex);
       
  2614     if (scrollingTookPlace)
       
  2615         UpdateScrollBarThumbs();
       
  2616     _AKNTRACE_FUNC_EXIT;
       
  2617     }
       
  2618 
       
  2619 EXPORT_C void CEikListBox::RedrawItem( TInt aItemIndex )
       
  2620     {
       
  2621     _AKNTRACE_FUNC_ENTER;
       
  2622     if (!IsReadyToDraw())
       
  2623         {
       
  2624         _AKNTRACE_FUNC_EXIT;        
       
  2625         return;
       
  2626         }
       
  2627     __ASSERT_ALWAYS(iView, Panic(EEikPanicListBoxNoView));
       
  2628     if ( iView->ItemIsVisible( aItemIndex ) )
       
  2629         {
       
  2630 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2631         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  2632 
       
  2633         TBool redraw = !IsBackedUp() && ( transApi == NULL || transApi->EffectsDisabled() );
       
  2634 #else
       
  2635         TBool redraw = !IsBackedUp();
       
  2636 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2637 
       
  2638         if ( redraw )
       
  2639             {
       
  2640             TRect redrawRect( 
       
  2641                 iView->ItemPos( aItemIndex ), 
       
  2642                 iItemDrawer->ItemCellSize() );
       
  2643             redrawRect.Intersection( iView->ViewRect() );
       
  2644 
       
  2645             Window().Invalidate( redrawRect );
       
  2646             Window().BeginRedraw( redrawRect );
       
  2647             }
       
  2648 
       
  2649         iView->DrawItem( aItemIndex );
       
  2650 
       
  2651         if ( redraw )
       
  2652             {
       
  2653             Window().EndRedraw();
       
  2654             }
       
  2655         }
       
  2656     _AKNTRACE_FUNC_EXIT;
       
  2657     }
       
  2658 
       
  2659 EXPORT_C void CEikListBox::ActivateL()
       
  2660     {
       
  2661     _AKNTRACE_FUNC_ENTER;
       
  2662     CCoeControl::ActivateL();
       
  2663     UpdateScrollBarThumbs();
       
  2664 
       
  2665     CEikButtonGroupContainer *cba;
       
  2666     MopGetObject(cba);
       
  2667     
       
  2668     if (!cba) 
       
  2669         {
       
  2670         _AKNTRACE_FUNC_EXIT;
       
  2671         return;
       
  2672         }
       
  2673     
       
  2674     if (iListBoxFlags & EEnterMarks)
       
  2675         {
       
  2676         // Unfortunately, we need to do this here. It belongs to 
       
  2677         // CAknSelectionListDialog, but we need this change also 
       
  2678         // to code that does not yet use CAknSelectionListDialog.
       
  2679         TRAP_IGNORE(iAvkonEnv->CreateCbaObserverL(cba, this));
       
  2680         }
       
  2681     if ( iListBoxExt && iListBoxExt->iMSKObserverEnabled &&
       
  2682         ( (iListBoxFlags & EShiftEnterMarks) ||
       
  2683           (iListBoxFlags & EEnterMarks) ) )
       
  2684         {
       
  2685         TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this));
       
  2686         TRAP_IGNORE(UpdateMarkUnmarkMSKL());
       
  2687         }
       
  2688     _AKNTRACE_FUNC_EXIT;
       
  2689     }
       
  2690 
       
  2691 
       
  2692 EXPORT_C void CEikListBox::Draw(const TRect& aRect) const
       
  2693     {
       
  2694     _AKNTRACE_FUNC_ENTER;
       
  2695     // If a parent has a custom gc, draw listbox using that gc
       
  2696     CWindowGc* replacedGc = ReplaceGcWithCustomGc( this );
       
  2697     
       
  2698     CWindowGc* gc = iItemDrawer->Gc();
       
  2699     TGulBorder::TColors borderColors;
       
  2700     iBorder.Draw(*gc, Rect(), borderColors);
       
  2701 
       
  2702 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2703     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  2704     if ( transApi )
       
  2705         {
       
  2706         transApi->BeginRedraw( MAknListBoxTfxInternal::EListView, View()->ViewRect() );
       
  2707         transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
  2708         }
       
  2709 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2710 
       
  2711 
       
  2712     ClearMargins(); 
       
  2713 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2714     if ( transApi )
       
  2715         {
       
  2716         transApi->StopDrawing();
       
  2717         }
       
  2718 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2719     iView->Draw(&aRect);
       
  2720 
       
  2721 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2722     if ( transApi )
       
  2723         {
       
  2724         transApi->EndViewRedraw( aRect );
       
  2725         }
       
  2726 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2727 
       
  2728     if ( replacedGc )
       
  2729         {
       
  2730         // Stop using the custom gc
       
  2731         iItemDrawer->SetGc( replacedGc );
       
  2732         }
       
  2733     _AKNTRACE_FUNC_EXIT;
       
  2734     }
       
  2735 
       
  2736 EXPORT_C void CEikListBox::ClearMargins() const
       
  2737     {
       
  2738      if (!iView->RedrawDisabled())
       
  2739          {
       
  2740          CWindowGc* gc = iItemDrawer->Gc();
       
  2741          if (gc)
       
  2742      {
       
  2743      TRect viewRect=iView->ViewRect();
       
  2744      TRect clientRect;
       
  2745      RestoreClientRectFromViewRect(clientRect);
       
  2746              gc->SetBrushColor(iBackColor);
       
  2747              DrawUtils::ClearBetweenRects(*gc, clientRect, viewRect);
       
  2748              }
       
  2749          }
       
  2750     }
       
  2751 
       
  2752 EXPORT_C void CEikListBox::UpdateScrollBarsL()
       
  2753     {
       
  2754     _AKNTRACE_FUNC_ENTER;
       
  2755     if (!iSBFrame)
       
  2756         {
       
  2757         _AKNTRACE_FUNC_EXIT;
       
  2758         return;
       
  2759         }
       
  2760     TEikScrollBarModel hSbarModel;
       
  2761     TEikScrollBarModel vSbarModel;
       
  2762     TRect rect=iView->ViewRect();
       
  2763 //#ifdef NOT_NEEDED_IN_SERIES60
       
  2764     if (!(iListBoxFlags & EScrollBarSizeExcluded))
       
  2765         {
       
  2766         // Ignore scrollbars presence to set the model, Scrollbar Frame will change it as required
       
  2767         rect = iBorder.InnerRect(Rect());
       
  2768         rect.SetRect(rect.iTl.iX + ListBoxMargins().iLeft, rect.iTl.iY + ListBoxMargins().iTop,
       
  2769             rect.iBr.iX - ListBoxMargins().iRight, rect.iBr.iY - ListBoxMargins().iBottom);
       
  2770         AdjustRectHeightToWholeNumberOfItems(rect);
       
  2771         // rect is now viewRect when ignoring scrollbars
       
  2772         }
       
  2773 //#endif
       
  2774     TInt itemHeight = iView->ItemHeight();
       
  2775     TSize viewSize( iView->ViewRect().Size() );
       
  2776     
       
  2777     if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  2778         {
       
  2779         if (!(iListBoxFlags & EPageAtOnceScrolling))
       
  2780             {
       
  2781             if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  2782                 {
       
  2783                 // For EDoubleSpan type scrollbar
       
  2784 				vSbarModel.iThumbPosition = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels();
       
  2785                 }
       
  2786             else
       
  2787                 {
       
  2788                 // For EArrowHead type scrollbar
       
  2789                 vSbarModel.iThumbPosition = iView->CurrentItemIndex();
       
  2790                 }
       
  2791             vSbarModel.iScrollSpan = iModel->NumberOfItems()*iView->ItemHeight();
       
  2792            }
       
  2793         else
       
  2794             { // Viewer
       
  2795 			vSbarModel.iThumbPosition = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels();
       
  2796 			vSbarModel.iScrollSpan = iModel->NumberOfItems()*iView->ItemHeight();
       
  2797             }
       
  2798         if ( vSbarModel.iScrollSpan == viewSize.iHeight )
       
  2799             {
       
  2800             vSbarModel.iThumbSpan = viewSize.iHeight;
       
  2801             }
       
  2802         else
       
  2803             {
       
  2804             vSbarModel.iThumbSpan = viewSize.iHeight - viewSize.iHeight % 2;            
       
  2805             }
       
  2806 //#ifdef NOT_NEEDED_IN_SERIES60
       
  2807         if ( IsActivated() )
       
  2808             {            
       
  2809             if (vSbarModel.iScrollSpan-vSbarModel.iThumbPosition<vSbarModel.iThumbSpan)
       
  2810                 {
       
  2811                 vSbarModel.iThumbPosition=Max(0,vSbarModel.iScrollSpan-vSbarModel.iThumbSpan);
       
  2812                 // This call causes redraw that should not be done in SizeChanged phase.
       
  2813                 iView->ScrollToMakeItemVisible(vSbarModel.iThumbPosition/iView->ItemHeight()); // force a scroll if neccessary
       
  2814                 }
       
  2815             }
       
  2816 //#endif
       
  2817         }
       
  2818     if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  2819         {
       
  2820         iView->CalcDataWidth();
       
  2821         hSbarModel.iThumbPosition = iView->HScrollOffset();
       
  2822         hSbarModel.iScrollSpan = iView->DataWidth();
       
  2823         hSbarModel.iThumbSpan = iView->VisibleWidth(rect);
       
  2824         }
       
  2825 
       
  2826     if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  2827         {
       
  2828         // For EDoubleSpan type scrollbar        
       
  2829         TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel );
       
  2830         TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel );
       
  2831               
       
  2832         TRect clientRect = Rect();      
       
  2833         TRect inclusiveRect = Rect();
       
  2834         TEikScrollBarFrameLayout layout;
       
  2835         layout.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant;
       
  2836         layout.SetClientMargin(0);
       
  2837         layout.SetInclusiveMargin(0);
       
  2838         if(iSBFrameOwned == EOwnedExternally)
       
  2839             iSBFrame->Tile(&hDsSbarModel, &vDsSbarModel);
       
  2840         else
       
  2841             {
       
  2842             TBool sizeChanged=EFalse;
       
  2843             sizeChanged=iSBFrame->TileL(&hDsSbarModel, &vDsSbarModel, clientRect, inclusiveRect, layout);
       
  2844             if (sizeChanged)
       
  2845                 {               
       
  2846                 iSBFrame->DrawScrollBarsDeferred();
       
  2847                 }
       
  2848             }
       
  2849         }
       
  2850     else
       
  2851         {
       
  2852         // For EArrowHead type scrollbar
       
  2853         TRect clientRect;
       
  2854         RestoreClientRectFromViewRect(clientRect);
       
  2855         TRect inclusiveRect=Rect();
       
  2856         TEikScrollBarFrameLayout layout;
       
  2857         CreateScrollBarFrameLayout(layout);
       
  2858         TBool sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout);
       
  2859         if (iListBoxExt->UpdateScrollBarsColors())
       
  2860             UpdateScrollBarsColors();
       
  2861         if (!sizeChanged)
       
  2862             return;
       
  2863         // else size of client/inclusive rect has changed
       
  2864         if (layout.iTilingMode==TEikScrollBarFrameLayout::EClientRectConstant)
       
  2865             SetSizeWithoutNotification(inclusiveRect.Size());
       
  2866         else
       
  2867             {
       
  2868             SetViewRectFromClientRect(clientRect);
       
  2869             ClearMargins();
       
  2870             }        
       
  2871         }
       
  2872     
       
  2873     if ( iListBoxExt )
       
  2874         {    
       
  2875         iListBoxExt->CheckScrollBarVisibility();
       
  2876         }
       
  2877     
       
  2878     AdjustTopItemIndex();
       
  2879     _AKNTRACE_FUNC_EXIT;
       
  2880     }
       
  2881                                                             
       
  2882 EXPORT_C void CEikListBox::CreateScrollBarFrameLayout(TEikScrollBarFrameLayout& aLayout)    const
       
  2883     {
       
  2884     _AKNTRACE_FUNC_ENTER;
       
  2885     aLayout.iInclusiveMargin=iBorder.Margins();
       
  2886 
       
  2887     aLayout.iClientMargin.iTop=ListBoxMargins().iTop;
       
  2888     aLayout.iClientMargin.iBottom=ListBoxMargins().iBottom;
       
  2889     aLayout.iClientMargin.iLeft=ListBoxMargins().iLeft;
       
  2890     aLayout.iClientMargin.iRight=ListBoxMargins().iRight;
       
  2891 
       
  2892     aLayout.iClientAreaGranularity=TSize(HorizScrollGranularityInPixels(), iItemHeight); 
       
  2893     aLayout.iTilingMode=(!(iListBoxFlags & EScrollBarSizeExcluded))? TEikScrollBarFrameLayout::EInclusiveRectConstant : TEikScrollBarFrameLayout::EClientRectConstant;
       
  2894     _AKNTRACE_FUNC_EXIT;
       
  2895     }
       
  2896 
       
  2897 EXPORT_C TInt CEikListBox::HorizScrollGranularityInPixels() const
       
  2898     {
       
  2899     return 1; // horiz scroll bar model set in pixels for standard listbox
       
  2900     }
       
  2901 
       
  2902 EXPORT_C void CEikListBox::Reset()
       
  2903     {
       
  2904     _AKNTRACE_FUNC_ENTER;
       
  2905 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  2906     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  2907     if ( transApi )
       
  2908         {
       
  2909         transApi->Remove( MAknListBoxTfxInternal:: EListEverything );
       
  2910         }
       
  2911 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  2912 
       
  2913     ((CListBoxView::CSelectionIndexArray*)iView->SelectionIndexes())->Reset();
       
  2914     iView->SetTopItemIndex(0);
       
  2915     iView->SetCurrentItemIndex(0);
       
  2916     iView->ClearSelectionAnchorAndActiveIndex();
       
  2917     iView->SetHScrollOffset(0);
       
  2918 
       
  2919     FireItemChange();
       
  2920     _AKNTRACE_FUNC_EXIT;
       
  2921     }
       
  2922 
       
  2923 EXPORT_C void CEikListBox::AddItemChangeObserverL(
       
  2924         MListBoxItemChangeObserver* aObserver )
       
  2925     {
       
  2926     _AKNTRACE_FUNC_ENTER;
       
  2927     if( !aObserver )
       
  2928         {
       
  2929         User::Leave( KErrArgument );
       
  2930         }
       
  2931 
       
  2932     CheckCreateExtensionL();
       
  2933     iListBoxExt->AddItemChangeObserverL( aObserver );
       
  2934     _AKNTRACE_FUNC_EXIT;
       
  2935     }
       
  2936 
       
  2937 EXPORT_C TBool CEikListBox::RemoveItemChangeObserver(
       
  2938         MListBoxItemChangeObserver* aObserver )
       
  2939     {
       
  2940     _AKNTRACE_FUNC_ENTER;
       
  2941     if( !iListBoxExt )
       
  2942         {
       
  2943         _AKNTRACE_FUNC_EXIT;
       
  2944         return EFalse;
       
  2945         }
       
  2946     _AKNTRACE_FUNC_EXIT;
       
  2947     return iListBoxExt->RemoveItemChangeObserver( aObserver );
       
  2948     }
       
  2949 
       
  2950 EXPORT_C void CEikListBox::AddSelectionObserverL( MListBoxSelectionObserver* aObserver )
       
  2951     {
       
  2952     _AKNTRACE_FUNC_ENTER;
       
  2953     if( !aObserver )
       
  2954         {
       
  2955         User::Leave( KErrArgument );
       
  2956         }
       
  2957 
       
  2958     CheckCreateExtensionL();
       
  2959     iListBoxExt->AddSelectionObserverL( aObserver );
       
  2960     _AKNTRACE_FUNC_EXIT;
       
  2961     }
       
  2962     
       
  2963 EXPORT_C void CEikListBox::RemoveSelectionObserver( MListBoxSelectionObserver* aObserver )
       
  2964     {
       
  2965     _AKNTRACE_FUNC_ENTER;
       
  2966     if( iListBoxExt )
       
  2967         {
       
  2968         iListBoxExt->RemoveSelectionObserver( aObserver );
       
  2969         }
       
  2970     _AKNTRACE_FUNC_EXIT;
       
  2971     }
       
  2972 
       
  2973 void CEikListBox::ChangeSelectionMode( TBool aEnable )
       
  2974     // Nonexported helper function.
       
  2975     {
       
  2976     _AKNTRACE_FUNC_ENTER;
       
  2977     // UI Spec does not mention this, but it is reasonable not to
       
  2978     // change selection mode on unmarkable item.
       
  2979     TInt index = CurrentItemIndex();
       
  2980     if ( index >= 0 && aEnable 
       
  2981          && iItemDrawer->Properties(index).IsSelectionHidden() )
       
  2982         {
       
  2983         _AKNTRACE_FUNC_EXIT;
       
  2984         return;
       
  2985         }
       
  2986     if( !iListBoxExt )
       
  2987         {
       
  2988         _AKNTRACE_FUNC_EXIT;
       
  2989         return;
       
  2990         }
       
  2991     CEikButtonGroupContainer *bgc;
       
  2992     CCoeControl* MSK( NULL );
       
  2993     CEikCba* cba( NULL );
       
  2994     CONST_CAST( CEikListBox*,this )->MopGetObject( bgc );
       
  2995     if ( !bgc )
       
  2996         {
       
  2997         _AKNTRACE_FUNC_EXIT;
       
  2998         return; // No bgc -> no cba -> nothing can be done here (and no need to inform observers)
       
  2999         }
       
  3000         
       
  3001     cba = ( static_cast<CEikCba*>( bgc->ButtonGroup() ) ); // downcast from MEikButtonGroup
       
  3002 
       
  3003     if ( !cba )
       
  3004         {
       
  3005         _AKNTRACE_FUNC_EXIT;
       
  3006         return; // No cba -> nothing can be done here (and no need to inform observers)
       
  3007         }
       
  3008 
       
  3009     MSK = cba->Control( 3 ); // MSK's position is 3
       
  3010 
       
  3011     TInt newResourceId( NULL );
       
  3012     if ( MSK && View()->ItemIsSelected( CurrentItemIndex() ) )
       
  3013         {
       
  3014         newResourceId = R_AVKON_SOFTKEY_UNMARK;
       
  3015         }
       
  3016     if ( MSK && !View()->ItemIsSelected( CurrentItemIndex() ) )
       
  3017         {
       
  3018         newResourceId = R_AVKON_SOFTKEY_MARK;
       
  3019         }
       
  3020 
       
  3021     if ( aEnable && newResourceId )
       
  3022         {
       
  3023         TRAPD( err, bgc->AddCommandToStackL( 3, newResourceId ) );
       
  3024         // in case of error, don't inform observers
       
  3025         // marking still works even MSK isn't changed
       
  3026         if ( err )
       
  3027             {
       
  3028             iListBoxExt->iSelectionModeEnabled = EFalse;
       
  3029             _AKNTRACE_FUNC_EXIT;
       
  3030             return;
       
  3031             }
       
  3032         cba->DrawNow();
       
  3033         iListBoxExt->iSelectionModeEnabled = ETrue;
       
  3034         }
       
  3035 
       
  3036     // remove stacked MSK
       
  3037     if( !aEnable && iListBoxExt->iSelectionModeEnabled )
       
  3038         {
       
  3039         if( ( MSK && cba->ControlId( MSK ) == EAknSoftkeyMark ) ||
       
  3040             ( MSK && cba->ControlId( MSK ) == EAknSoftkeyUnmark ) )
       
  3041             {
       
  3042             bgc->RemoveCommandFromStack( 3, cba->ControlId( MSK ) );
       
  3043             }
       
  3044         iListBoxExt->iSelectionModeEnabled = EFalse; // just in case
       
  3045         }
       
  3046         
       
  3047     TInt count = iListBoxExt->iSelectionObservers.Count();
       
  3048     for ( int i=0; i < count; i++ )
       
  3049         {
       
  3050         iListBoxExt->iSelectionObservers[i]->SelectionModeChanged( this, aEnable );
       
  3051         }
       
  3052     _AKNTRACE_FUNC_EXIT;
       
  3053     }
       
  3054 
       
  3055 
       
  3056 void CEikListBox::HandleItemRemovalWithoutSelectionsL()
       
  3057     // Nonexported helper function.
       
  3058     {
       
  3059     _AKNTRACE_FUNC_ENTER;
       
  3060     // this will force update of physics parameters next time when list is panned
       
  3061     iView->SetItemOffsetInPixels( 0 );
       
  3062     iView->SetFlags(CListBoxView::EItemCountModified);
       
  3063     iView->CalcDataWidth();
       
  3064     iView->CalcBottomItemIndex();
       
  3065     UpdateScrollBarsL();
       
  3066     UpdateScrollBarThumbs();
       
  3067     iView->ClearFlags(CListBoxView::EItemCountModified);
       
  3068 
       
  3069     FireItemChange();
       
  3070     
       
  3071     if ( iListBoxExt && iListBoxExt->iPhysics )
       
  3072         {
       
  3073         iListBoxExt->InitPhysicsL();
       
  3074         }    
       
  3075     _AKNTRACE_FUNC_EXIT;
       
  3076     }
       
  3077 
       
  3078 EXPORT_C void CEikListBox::HandleItemRemovalL(CArrayFix<TInt> &aArrayOfOldIndexes)
       
  3079     // NOTE, This algorithm cannot handle position of the list highlight
       
  3080     // nor can it update the topitemindex correctly.
       
  3081     {
       
  3082     _AKNTRACE_FUNC_ENTER;
       
  3083     TKeyArrayFix key(0,ECmpTInt);
       
  3084     aArrayOfOldIndexes.Sort(key);
       
  3085 
       
  3086     // remove removed items from selection index array
       
  3087     TInt changedcount = aArrayOfOldIndexes.Count();
       
  3088     for(TInt iii=0;iii<changedcount;iii++)
       
  3089         {
       
  3090         iView->DeselectItem(aArrayOfOldIndexes.At(iii));
       
  3091         }
       
  3092 
       
  3093     // decrease selectionindexes. Does not change their order, so resorting
       
  3094     // the array is not necessary
       
  3095     CListBoxView::CSelectionIndexArray* array = CONST_CAST(CListBoxView::CSelectionIndexArray*,iView->SelectionIndexes());
       
  3096     TInt selectioncount = array->Count();
       
  3097     TInt removedcount = aArrayOfOldIndexes.Count();
       
  3098     for(TInt ii = 0;ii<removedcount;ii++)
       
  3099         {
       
  3100         for(TInt i=0;i<selectioncount;i++)
       
  3101             {
       
  3102             // since we deselected the item, its not possible that
       
  3103             // the removed item is still in selectionindexes array.
       
  3104             __ASSERT_DEBUG(array->At(i) != aArrayOfOldIndexes.At(ii), Panic(EEikPanicOutOfRange));
       
  3105             if (array->At(i) > aArrayOfOldIndexes.At(ii))
       
  3106                 {
       
  3107                 (*array)[i]-=1;
       
  3108                 }
       
  3109             }
       
  3110         }
       
  3111  
       
  3112     HandleItemRemovalWithoutSelectionsL();
       
  3113     _AKNTRACE_FUNC_EXIT;
       
  3114     }
       
  3115 
       
  3116 EXPORT_C void CEikListBox::HandleItemAdditionL(CArrayFix<TInt> &aArrayOfNewIndexesAfterAddition)
       
  3117     // NOTE, This algorithm cannot handle position of the list highlight
       
  3118     // nor can it update the topitemindex correctly.
       
  3119     {
       
  3120     _AKNTRACE_FUNC_ENTER;
       
  3121     // Updates selectionindexes array
       
  3122 
       
  3123     // Sort indexes first
       
  3124     TKeyArrayFix key(0,ECmpTInt);
       
  3125     aArrayOfNewIndexesAfterAddition.Sort(key);
       
  3126     
       
  3127     // increase selectionindexes.
       
  3128     CListBoxView::CSelectionIndexArray* array = CONST_CAST(CListBoxView::CSelectionIndexArray*,iView->SelectionIndexes());
       
  3129     TInt selectioncount = array->Count();
       
  3130     TInt newindexcount = aArrayOfNewIndexesAfterAddition.Count();
       
  3131     for(TInt ii = 0;ii<newindexcount;ii++)
       
  3132         {
       
  3133         for(TInt i=0;i<selectioncount;i++)
       
  3134             {
       
  3135             if (array->At(i) >= aArrayOfNewIndexesAfterAddition.At(ii))
       
  3136                 {
       
  3137                 (*array)[i]+=1;
       
  3138                 }
       
  3139             }
       
  3140         }
       
  3141 
       
  3142     // other features that does not depend on the items added.
       
  3143     HandleItemAdditionL();
       
  3144     _AKNTRACE_FUNC_EXIT;
       
  3145     }
       
  3146 
       
  3147 EXPORT_C void CEikListBox::HandleItemAdditionL()
       
  3148     {
       
  3149     _AKNTRACE_FUNC_ENTER;
       
  3150      //fix the bug EGGO-7SQA4S and EVSG-7TD9WZ 
       
  3151     TInt curItemIndex = iView->CurrentItemIndex();
       
  3152     if(curItemIndex >= 0 && curItemIndex < iModel->NumberOfItems() )
       
  3153       {
       
  3154       TInt newTopItemIndex = iView->CalcNewTopItemIndexSoItemIsVisible( curItemIndex );
       
  3155       iView->SetTopItemIndex( newTopItemIndex );
       
  3156       }
       
  3157     iView->SetFlags(CListBoxView::EItemCountModified);
       
  3158     // following breaks lists in square layout, not needed in SERIES60?
       
  3159     //iView->CalcDataWidth();
       
  3160     iView->CalcBottomItemIndex();
       
  3161     UpdateScrollBarsL();
       
  3162     UpdateScrollBarThumbs();
       
  3163     if (IsReadyToDraw()) DrawDeferred();
       
  3164     iView->ClearFlags(CListBoxView::EItemCountModified);
       
  3165 
       
  3166     FireItemChange();
       
  3167     
       
  3168     if ( iListBoxExt )
       
  3169         {    
       
  3170         iListBoxExt->CheckScrollBarVisibility();
       
  3171         // Physics engine world size needs to be updated here, otherwise aknphysics 
       
  3172         // cone observer may block pointer events on new items. this can happen 
       
  3173         // when item addition inserts new row to taskswapper's grid and reuses list in Common Dialog
       
  3174         if ( iListBoxExt->iPhysics )
       
  3175             {
       
  3176             iListBoxExt->InitPhysicsL();
       
  3177             }
       
  3178         }     
       
  3179     _AKNTRACE_FUNC_EXIT;
       
  3180     }
       
  3181 
       
  3182 EXPORT_C void CEikListBox::HandleItemRemovalL()
       
  3183     {
       
  3184     // Should be called after one or more items have been removed from the model
       
  3185     // It is up to the application to then make sure that the current item index is set to an appropriate value and to redraw the listbox
       
  3186     _AKNTRACE_FUNC_ENTER;
       
  3187     ((CListBoxView::CSelectionIndexArray*)iView->SelectionIndexes())->Reset();
       
  3188     HandleItemRemovalWithoutSelectionsL();
       
  3189     _AKNTRACE_FUNC_EXIT;
       
  3190     // Please do not add anything here. Add them to the HandleItemRemovalWithoutSelectionsL().
       
  3191     }
       
  3192 
       
  3193 EXPORT_C const CArrayFix<TInt>* CEikListBox::SelectionIndexes() const
       
  3194     {
       
  3195     return iView->SelectionIndexes();
       
  3196     }
       
  3197 
       
  3198 EXPORT_C void CEikListBox::SetSelectionIndexesL(CListBoxView::CSelectionIndexArray* aArrayOfSelectionIndexes)
       
  3199     {
       
  3200     if (! aArrayOfSelectionIndexes)
       
  3201         iView->ClearSelection();
       
  3202     else
       
  3203         iView->SetSelectionIndexesL(aArrayOfSelectionIndexes);
       
  3204     }
       
  3205 
       
  3206 void CEikListBox::HorizontalScroll(TInt aScrollAmountInPixels)
       
  3207     {
       
  3208     iView->HScroll(aScrollAmountInPixels);
       
  3209     if (iSBFrame)
       
  3210         {
       
  3211         if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  3212             iSBFrame->MoveThumbsBy(aScrollAmountInPixels, 0);
       
  3213         }
       
  3214     }
       
  3215 
       
  3216 EXPORT_C void CEikListBox::HandleLeftArrowKeyL(CListBoxView::TSelectionMode /*aSelectionMode*/)
       
  3217     {
       
  3218     HorizontalScroll(-(iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth));
       
  3219     }
       
  3220 
       
  3221 
       
  3222 EXPORT_C void CEikListBox::HandleRightArrowKeyL(CListBoxView::TSelectionMode /*aSelectionMode*/)
       
  3223     {
       
  3224     HorizontalScroll((iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth));
       
  3225     }
       
  3226 //#define KEY_DEBUG
       
  3227 
       
  3228 #if defined(_DEBUG) && defined(KEY_DEBUG)
       
  3229 #define __KeyDebug(b,text) { _LIT(blah, "LbxKeys %d:%d:%c%c%c " ## L ## text); RDebug::Print(blah, aKeyEvent.iCode, aKeyEvent.iScanCode, shiftKeyPressed ? 's' : '_', enterKeyPressed ? 'e' : '_', aType == EEventKey ? 'K' : (aType == EEventKeyDown ? 'D' : (aType == EEventKeyUp ? 'U' : '_'))); }
       
  3230 #else
       
  3231 #define __KeyDebug(b,text)
       
  3232 #endif
       
  3233 
       
  3234 
       
  3235 EXPORT_C TKeyResponse CEikListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  3236     {
       
  3237     _AKNTRACE_FUNC_ENTER;
       
  3238     TKeyEvent keyEvent=aKeyEvent;
       
  3239     keyEvent.iCode=LafListBox::MapKeyCode(aKeyEvent,aType);
       
  3240     _AKNTRACE_FUNC_EXIT;
       
  3241     return DoOfferKeyEventL(keyEvent,aType);
       
  3242     }
       
  3243 
       
  3244 TBool IsSelectionMarkKeys(TInt aCode, TInt aScanCode, TBool aWesternVariant)
       
  3245     {
       
  3246     return aCode == EKeyUpArrow   || 
       
  3247            aCode == EKeyDownArrow ||
       
  3248            aCode == EKeyOK        ||
       
  3249         /* aCode == EKeyEnter     || */
       
  3250            (aCode == 0 && aScanCode == EStdKeyLeftShift)  ||
       
  3251            (aCode == 0 && aScanCode == EStdKeyRightShift) ||           
       
  3252            (aCode == 0 && aScanCode == EStdKeyRightCtrl)  ||
       
  3253            (!aWesternVariant && (aCode == 0 && aScanCode == EStdKeyHash));
       
  3254     }
       
  3255 
       
  3256 TKeyResponse CEikListBox::DoOfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  3257     {
       
  3258     _AKNTRACE_FUNC_ENTER;
       
  3259     TInt topItemIndex = iView->TopItemIndex();
       
  3260     if (ItemExists(topItemIndex) == EFalse)
       
  3261         {
       
  3262         return (aKeyEvent.iScanCode == EStdKeyYes ? EKeyWasNotConsumed:EKeyWasConsumed);
       
  3263         }
       
  3264         
       
  3265     TInt code = aKeyEvent.iCode;
       
  3266 
       
  3267     // With single click first key event enables highlight
       
  3268     if ( iListBoxExt && iListBoxExt->EnableHighlightWithKeyEventL(
       
  3269             topItemIndex, aKeyEvent, aType ) )
       
  3270         {
       
  3271         _AKNTRACE_FUNC_EXIT;
       
  3272         return EKeyWasConsumed;
       
  3273         }
       
  3274     
       
  3275     (void)aType; // to prevent a warning.
       
  3276 
       
  3277     TBool shiftKeyPressed = (aKeyEvent.iModifiers & EModifierShift) ||
       
  3278                             (aKeyEvent.iModifiers & EModifierLeftShift) ||
       
  3279                             (aKeyEvent.iModifiers & EModifierRightShift);
       
  3280 
       
  3281     // Downpressed hash key already generates shift modifier and
       
  3282     // in Chinese variant hash (shift) + movement/MSK should not mark
       
  3283     if ( iListBoxExt &&
       
  3284          iListBoxExt->iWesternVariant == EFalse &&
       
  3285          iListBoxExt->iAknFepHashKeySelection )
       
  3286         {
       
  3287         shiftKeyPressed = EFalse;
       
  3288         }
       
  3289 
       
  3290     TBool controlKeyPressed = (aKeyEvent.iModifiers & EModifierCtrl) || 
       
  3291                               (aKeyEvent.iModifiers & EModifierRightCtrl);  
       
  3292     TInt oldCurrentItemIndex = iView->CurrentItemIndex();
       
  3293     
       
  3294     TBool enterKeyPressed=EFalse;
       
  3295     TBool escapeKeyPressed=EFalse;
       
  3296     TBool sideBarKeyPressed=EFalse;
       
  3297     TBool switchMSK=EFalse; // for mark/unmark in selection lists
       
  3298     
       
  3299     // if we have markable list and either shift, ctrl or hash is long pressed
       
  3300     // down, we will enter selection (marking) mode, where MSK is Mark/Unmark
       
  3301     if( iListBoxExt && (iListBoxFlags & EMultipleSelection) &&
       
  3302         (iListBoxFlags & EShiftEnterMarks) &&
       
  3303          aType == EEventKeyDown &&
       
  3304          ( (iListBoxExt->iWesternVariant &&
       
  3305             iListBoxExt->iAknFepHashKeySelection && 
       
  3306             iListBoxExt->iQwertyMode == EFalse && 
       
  3307             aKeyEvent.iScanCode == EStdKeyHash)  ||
       
  3308          aKeyEvent.iScanCode == EStdKeyLeftShift ||
       
  3309          aKeyEvent.iScanCode == EStdKeyRightShift ||
       
  3310          aKeyEvent.iScanCode == EStdKeyLeftCtrl ||
       
  3311          aKeyEvent.iScanCode == EStdKeyRightCtrl ) )
       
  3312         {
       
  3313         iListBoxExt->StartLongPressTimerL();
       
  3314         iListBoxExt->iShortHashMark = ETrue;        
       
  3315         iListBoxExt->iShiftKeyPressed = ETrue;        
       
  3316         }
       
  3317 
       
  3318     if( iListBoxExt && (iListBoxFlags & EMultipleSelection) &&
       
  3319         (iListBoxFlags & EShiftEnterMarks) &&
       
  3320          aType == EEventKeyUp &&
       
  3321          ( (iListBoxExt->iWesternVariant &&
       
  3322             iListBoxExt->iAknFepHashKeySelection && 
       
  3323             iListBoxExt->iQwertyMode == EFalse && 
       
  3324             aKeyEvent.iScanCode == EStdKeyHash)  ||
       
  3325          aKeyEvent.iScanCode == EStdKeyLeftShift ||
       
  3326          aKeyEvent.iScanCode == EStdKeyRightShift ||
       
  3327          aKeyEvent.iScanCode == EStdKeyLeftCtrl ||
       
  3328          aKeyEvent.iScanCode == EStdKeyRightCtrl ) )
       
  3329         {
       
  3330         iListBoxExt->iShiftKeyPressed = EFalse;
       
  3331         if ( iListBoxExt->iLongPressTimer &&
       
  3332              iListBoxExt->iLongPressTimer->IsActive() )
       
  3333             {
       
  3334             iListBoxExt->iLongPressTimer->Cancel();
       
  3335             }
       
  3336         if( iListBoxExt->iSelectionModeEnabled )
       
  3337             {
       
  3338             ChangeSelectionMode( EFalse );
       
  3339             iListBoxExt->iSelectionModeEnabled = EFalse;
       
  3340             View()->ClearSelectionAnchorAndActiveIndex();
       
  3341             }
       
  3342         }
       
  3343 
       
  3344 
       
  3345     // SERIES60 LAF
       
  3346     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  3347     if (iListBoxFlags & EMultipleSelection)
       
  3348         {
       
  3349         if ((shiftKeyPressed || controlKeyPressed) && iListBoxFlags & EShiftEnterMarks && aType == EEventKey)
       
  3350             {
       
  3351             __KeyDebug(ETrue, "shift + enter marks");
       
  3352             View()->SetAnchor(View()->CurrentItemIndex());
       
  3353             selectionMode = CListBoxView::EDisjointMarkSelection;
       
  3354             }
       
  3355         else
       
  3356             {
       
  3357             selectionMode = CListBoxView::ENoSelection;
       
  3358             UpdateMarkUnmarkMSKL();
       
  3359             if (IsSelectionMarkKeys(code, aKeyEvent.iScanCode, iListBoxExt->iWesternVariant)) 
       
  3360                 {
       
  3361                 __KeyDebug(ETrue, "SelectionMarkKey")
       
  3362                 View()->ClearSelectionAnchorAndActiveIndex();
       
  3363                 }
       
  3364             }
       
  3365         }
       
  3366 
       
  3367 
       
  3368     // CAknGrid marking is implemeted in avkon.dll. But we still need to disable short
       
  3369     // hash mark in here.
       
  3370     if ( iListBoxFlags & EMultipleSelection && 
       
  3371          iListBoxFlags & EShiftEnterMarks && aType == EEventKeyUp )
       
  3372         {
       
  3373         if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ||
       
  3374              aKeyEvent.iScanCode == EStdKeyUpArrow ||
       
  3375              aKeyEvent.iScanCode == EStdKeyRightArrow ||
       
  3376              aKeyEvent.iScanCode == EStdKeyDownArrow )
       
  3377             {
       
  3378             iListBoxExt->iShortHashMark = EFalse;
       
  3379             }
       
  3380         // for some applications this is the only way to catch marking with MSK
       
  3381         if ( aKeyEvent.iScanCode == EStdKeyDevice3 )
       
  3382             {
       
  3383             iListBoxExt->iShortHashMark = EFalse;
       
  3384             }
       
  3385         }
       
  3386 
       
  3387 
       
  3388     TInt oldMatcherCursorPos = iView->MatcherCursorPos();
       
  3389 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3390     // LISTBOX EFFECTS IMPLEMENTATION
       
  3391     // 
       
  3392     // Fetch internal listbox transition API.
       
  3393     //
       
  3394     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  3395 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  3396     
       
  3397     switch (code)
       
  3398         {
       
  3399         case EKeyPrevious:
       
  3400             {
       
  3401             _AKNTRACE( "EKeyPrevious" );
       
  3402             const TBool disableRedraw = aKeyEvent.iRepeats;
       
  3403             
       
  3404             TBool redrawDisabled = iView->RedrawDisabled();
       
  3405             if ( disableRedraw )
       
  3406                 {
       
  3407                 iView->SetDisableRedraw(ETrue);
       
  3408                 }
       
  3409             
       
  3410             TInt count = 1 + aKeyEvent.iRepeats;
       
  3411             TInt currentItemIndex = iView->CurrentItemIndex();
       
  3412             if( ( currentItemIndex - count) < 0)
       
  3413                 {
       
  3414                 count = currentItemIndex;
       
  3415                 //  moveto = CListBoxView::ECursorLastItem;
       
  3416                 }
       
  3417             if ( !count )
       
  3418                 {
       
  3419                   count = 1;
       
  3420                 }  
       
  3421 
       
  3422 
       
  3423             for ( TInt ii = 0; ii < count; ii++ )
       
  3424                 {
       
  3425                 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorPreviousItem;
       
  3426                 if (iListBoxFlags & EPageAtOnceScrolling) 
       
  3427                     { 
       
  3428                     moveto = CListBoxView::ECursorPrevScreen; 
       
  3429                     }
       
  3430 
       
  3431                 TInt currentItemIndex = iView->CurrentItemIndex();
       
  3432                 if(!(iListBoxFlags & EPopout) && (currentItemIndex==0 || currentItemIndex==-1))
       
  3433                     {
       
  3434                     if (iListBoxFlags & ELoopScrolling)
       
  3435                         {
       
  3436                         moveto = CListBoxView::ECursorLastItem;
       
  3437                         }
       
  3438                     else
       
  3439                         {
       
  3440                         break;
       
  3441                         }
       
  3442                     }
       
  3443                 iView->MoveCursorL(moveto, selectionMode);
       
  3444                 ClearMatchBuffer();
       
  3445                 }
       
  3446 
       
  3447             if ( disableRedraw )
       
  3448                 {
       
  3449                 iView->SetDisableRedraw(redrawDisabled);
       
  3450                 if ( !redrawDisabled )
       
  3451                     {
       
  3452                     DrawNow();
       
  3453                     }
       
  3454                 }
       
  3455                 
       
  3456             if (iListBoxFlags & EMultipleSelection)
       
  3457                 {
       
  3458                 switchMSK = ETrue; // we need to check MSK later
       
  3459                 }
       
  3460             }
       
  3461             if(AknLayoutUtils::PenEnabled())
       
  3462                 {
       
  3463                 // update scroll bar thumbs here, because it is needed when scrolled.   
       
  3464                 UpdateScrollBarThumbs();
       
  3465                 }
       
  3466             break;
       
  3467         case EKeyNext:
       
  3468             {
       
  3469             _AKNTRACE( "EKeyNext" );
       
  3470             const TBool disableRedraw = aKeyEvent.iRepeats;
       
  3471             TBool redrawDisabled = iView->RedrawDisabled();
       
  3472             if ( disableRedraw )
       
  3473                 {
       
  3474                 iView->SetDisableRedraw(ETrue);
       
  3475                 }
       
  3476             
       
  3477             TInt count = 1 + aKeyEvent.iRepeats;
       
  3478             TInt currentItemIndex = iView->CurrentItemIndex();
       
  3479             if(currentItemIndex + count > Model()->NumberOfItems()-1 )
       
  3480                 {
       
  3481                 count = ( Model()->NumberOfItems() - 1 ) - currentItemIndex;
       
  3482                 }
       
  3483             if ( !count )
       
  3484                 {
       
  3485                   count = 1;
       
  3486                 }  
       
  3487 
       
  3488             
       
  3489             for ( TInt ii = 0; ii < count; ii++ )
       
  3490                 {
       
  3491                 CListBoxView::TCursorMovement moveto = CListBoxView::ECursorNextItem;
       
  3492                 if (iListBoxFlags & EPageAtOnceScrolling) 
       
  3493                     { 
       
  3494                     moveto = CListBoxView::ECursorNextScreen; 
       
  3495                     }
       
  3496                 
       
  3497                 TInt currentItemIndex = iView->CurrentItemIndex();
       
  3498                 if(!(iListBoxFlags & EPopout) && 
       
  3499                     (currentItemIndex==Model()->NumberOfItems()-1 || currentItemIndex==-1))
       
  3500                     {
       
  3501                     if (iListBoxFlags & ELoopScrolling)
       
  3502                         {
       
  3503                         moveto = CListBoxView::ECursorFirstItem;
       
  3504                         }
       
  3505                     else
       
  3506                         {
       
  3507                         break;
       
  3508                         }
       
  3509                     }
       
  3510                 iView->MoveCursorL(moveto, selectionMode);
       
  3511                 ClearMatchBuffer();
       
  3512                 }
       
  3513 
       
  3514             if ( disableRedraw )
       
  3515                 {
       
  3516                 iView->SetDisableRedraw(redrawDisabled);
       
  3517                 if ( !redrawDisabled )
       
  3518                     {
       
  3519                     DrawNow();
       
  3520                     }
       
  3521                 }
       
  3522                 
       
  3523             if (iListBoxFlags & EMultipleSelection)
       
  3524                 {
       
  3525                 switchMSK = ETrue; // we need to check MSK later
       
  3526                 }
       
  3527             }
       
  3528             if(AknLayoutUtils::PenEnabled())
       
  3529                 {
       
  3530                 // update scroll bar thumbs here, because it is needed when scrolled.   
       
  3531                 UpdateScrollBarThumbs();
       
  3532                 }
       
  3533             break;
       
  3534         case EKeyApplicationF:
       
  3535             // avkonenv can send these events to listbox.
       
  3536             // CR PKEA-4YSASZ
       
  3537             _AKNTRACE( "EKeyApplicationF" );
       
  3538             if (SelectionIndexes()->Count()==0)
       
  3539                 {
       
  3540                 TInt currentItem = View()->CurrentItemIndex();
       
  3541                 if (currentItem >= 0)
       
  3542                     {
       
  3543                     View()->SelectItemL(currentItem);
       
  3544                     }
       
  3545                 }
       
  3546             _AKNTRACE_FUNC_EXIT;
       
  3547             return EKeyWasConsumed;
       
  3548         case EKeyUpArrow:
       
  3549             {
       
  3550             _AKNTRACE( "EKeyUpArrow" );
       
  3551 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3552             // LISTBOX EFFECTS IMPLEMENTATION
       
  3553             // 
       
  3554             // Set type of momement
       
  3555             //
       
  3556             if ( transApi )
       
  3557                 {
       
  3558                 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveUp );
       
  3559                 }
       
  3560 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  3561 
       
  3562             // Note, in Series 60  we always eat uparrow and downarrow 
       
  3563             // in lists, even though it does not really change list state.
       
  3564             CListBoxView::TCursorMovement moveto = CListBoxView::ECursorPreviousItem;
       
  3565             if (iListBoxFlags & EPageAtOnceScrolling) 
       
  3566                 { 
       
  3567                 moveto = CListBoxView::ECursorPrevScreen; 
       
  3568                 }
       
  3569             if(!(iListBoxFlags & EPopout) && (oldCurrentItemIndex==0 || oldCurrentItemIndex==-1))
       
  3570                 {
       
  3571                 if (iListBoxFlags& ELoopScrolling)
       
  3572                     {
       
  3573                     moveto = CListBoxView::ECursorLastItem;
       
  3574                     }
       
  3575                 else if ( ScrollingDisabled() && topItemIndex == 0 )
       
  3576                     {
       
  3577                     _AKNTRACE_FUNC_EXIT;
       
  3578                     return( EKeyWasConsumed );
       
  3579                     }
       
  3580                 }
       
  3581 		
       
  3582             if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) )
       
  3583                 {
       
  3584                 iView->MoveCursorL(moveto, selectionMode);
       
  3585                 }
       
  3586             ClearMatchBuffer();
       
  3587             if( iListBoxFlags & EMultipleSelection )
       
  3588                 {
       
  3589                 switchMSK = ETrue; // we need to check MSK later
       
  3590                 }
       
  3591             }
       
  3592             if( AknLayoutUtils::PenEnabled() )
       
  3593                 {
       
  3594                 // update scroll bar thumbs here, because it is needed when scrolled.   
       
  3595                 UpdateScrollBarThumbs();
       
  3596                 }
       
  3597             break;
       
  3598         case EKeyDownArrow:
       
  3599             {
       
  3600             _AKNTRACE( "EKeyDownArrow" );
       
  3601 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  3602             // LISTBOX EFFECTS IMPLEMENTATION
       
  3603             // 
       
  3604             // Set type of momement
       
  3605             //
       
  3606             if ( transApi )
       
  3607                 {
       
  3608                 transApi->SetMoveType( MAknListBoxTfxInternal::EListMoveDown );
       
  3609                 }
       
  3610 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  3611             
       
  3612             CListBoxView::TCursorMovement moveto = CListBoxView::ECursorNextItem;
       
  3613             if (iListBoxFlags & EPageAtOnceScrolling)  
       
  3614                 { 
       
  3615                 moveto = CListBoxView::ECursorNextScreen; 
       
  3616                 }
       
  3617             if(!(iListBoxFlags & EPopout) && 
       
  3618                 (oldCurrentItemIndex==Model()->NumberOfItems()-1 || oldCurrentItemIndex==-1))
       
  3619                 {
       
  3620                 if (iListBoxFlags & ELoopScrolling)
       
  3621                     {
       
  3622                     moveto = CListBoxView::ECursorFirstItem;
       
  3623                     }
       
  3624                 else if ( ScrollingDisabled() && ( topItemIndex != 0 ) )
       
  3625                     {
       
  3626                     _AKNTRACE_FUNC_EXIT;
       
  3627                     return(EKeyWasConsumed);    
       
  3628                     }
       
  3629                 }
       
  3630 
       
  3631             if ( ScrollingDisabled() || ( !iListBoxExt->MovePhysicsCursorL( moveto, selectionMode ) ) )
       
  3632                 {
       
  3633                 iView->MoveCursorL(moveto, selectionMode);
       
  3634                 }
       
  3635             ClearMatchBuffer();
       
  3636             if (iListBoxFlags & EMultipleSelection)
       
  3637                 {
       
  3638                 switchMSK = ETrue; // we need to check MSK later
       
  3639                 }
       
  3640             }
       
  3641             if(AknLayoutUtils::PenEnabled())
       
  3642                 {
       
  3643                 // update scroll bar thumbs here, because it is needed when scrolled.   
       
  3644                 UpdateScrollBarThumbs();
       
  3645                 }
       
  3646             break;
       
  3647         case EKeyEnter:
       
  3648         case EKeyOK:
       
  3649             {
       
  3650             _AKNTRACE( "EKeyEnter or EKeyOK" );
       
  3651             if (aKeyEvent.iRepeats != 0) 
       
  3652                 {
       
  3653                 break;
       
  3654                 }
       
  3655             // Series 60  case where ok or shift+ok is pressed
       
  3656             if (iListBoxFlags & EMultipleSelection)
       
  3657                 {
       
  3658                 if ((shiftKeyPressed || controlKeyPressed) && iListBoxFlags & EShiftEnterMarks 
       
  3659                     || iListBoxFlags & EEnterMarks)
       
  3660                     {
       
  3661                     __KeyDebug(ETrue, "shift+ok or ok in markable/multiselection");
       
  3662 
       
  3663                     iView->UpdateSelectionL(CListBoxView::EDisjointSelection);
       
  3664                     iListBoxFlags |= EStateChanged;
       
  3665                     switchMSK = ETrue;
       
  3666                     break;
       
  3667                     }
       
  3668             
       
  3669                 // Markable list CR JLEO-4VQJ75
       
  3670                 if (!shiftKeyPressed && iListBoxFlags & EShiftEnterMarks)
       
  3671                     { 
       
  3672                     // enter key pressed on markable list without shift
       
  3673                     if (SelectionIndexes()->Count() > 0)
       
  3674                         { 
       
  3675                         // when there's marked items, should open options menu.
       
  3676                         __KeyDebug(ETrue, "ok without shift => ok options menu");
       
  3677 
       
  3678                         CEikMenuBar *bar;
       
  3679                         MopGetObject(bar);
       
  3680                         if (bar) 
       
  3681                             {
       
  3682                             bar->TryDisplayMenuBarL();
       
  3683                             }
       
  3684                         _AKNTRACE_FUNC_EXIT;
       
  3685                         return EKeyWasConsumed;
       
  3686                         }
       
  3687                     }
       
  3688                 }
       
  3689 
       
  3690             // Series 60  ok key
       
  3691             __KeyDebug(ETrue, "open item");
       
  3692             enterKeyPressed = ETrue;
       
  3693             }
       
  3694             break;
       
  3695         default:
       
  3696             if (iListBoxFlags & EIncrementalMatching) 
       
  3697                 {
       
  3698                 if (TChar(aKeyEvent.iCode).IsPrint())
       
  3699                     {
       
  3700                     MatchTypedCharL(aKeyEvent.iCode);
       
  3701                     }
       
  3702                 else
       
  3703                     {
       
  3704                     _AKNTRACE_FUNC_EXIT;
       
  3705                     return (aKeyEvent.iScanCode == EStdKeyYes ? 
       
  3706                         EKeyWasNotConsumed : EKeyWasConsumed);
       
  3707                     }
       
  3708                 }
       
  3709             break;
       
  3710         }
       
  3711     //
       
  3712     // Switch/case ends here
       
  3713     //
       
  3714     if(switchMSK)
       
  3715         {
       
  3716         if( selectionMode == CListBoxView::EDisjointMarkSelection )
       
  3717             {
       
  3718              // if hash and either up or down pressed -> no short marking
       
  3719             iListBoxExt->iShortHashMark = EFalse;
       
  3720             }
       
  3721         UpdateMarkUnmarkMSKL();
       
  3722         }
       
  3723 
       
  3724     if(!AknLayoutUtils::PenEnabled())
       
  3725         {
       
  3726         // do update only when needed and in correct place. (prevents flicker). 
       
  3727         // This place is called three times for every button event (down, key-event and up)     
       
  3728         UpdateScrollBarThumbs();
       
  3729         }
       
  3730 
       
  3731     if (oldCurrentItemIndex != iView->CurrentItemIndex())
       
  3732         {
       
  3733         iListBoxFlags |= EStateChanged;
       
  3734         DrawMatcherCursor();
       
  3735         }
       
  3736     else if (oldMatcherCursorPos != iView->MatcherCursorPos() && IsMatchBuffer())
       
  3737         {
       
  3738         DrawMatcherCursor();
       
  3739         }
       
  3740 
       
  3741     if (iListBoxFlags & EStateChanged)
       
  3742         {
       
  3743         ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  3744         iListBoxFlags &= (~EStateChanged);
       
  3745         }
       
  3746 
       
  3747     if (enterKeyPressed)
       
  3748         {
       
  3749         ReportListBoxEventL(MEikListBoxObserver::EEventEnterKeyPressed);
       
  3750         if (iListBoxFlags & EPopout)
       
  3751             {
       
  3752             ReportEventL(MCoeControlObserver::EEventRequestExit);
       
  3753             }
       
  3754         }
       
  3755 
       
  3756     if (escapeKeyPressed || sideBarKeyPressed)
       
  3757         {
       
  3758         if (iListBoxFlags & EPopout)
       
  3759             {
       
  3760             ReportEventL(MCoeControlObserver::EEventRequestCancel);
       
  3761             }
       
  3762         }
       
  3763 
       
  3764     if (sideBarKeyPressed)
       
  3765         {
       
  3766         _AKNTRACE_FUNC_EXIT;
       
  3767         return(EKeyWasNotConsumed);
       
  3768         }
       
  3769         
       
  3770     // This code block watches for hash key presses, and simulates shift + ok 
       
  3771     // if short hash key presses are used for selections. The events are simulated 
       
  3772     // only if a markable list is active, otherwise the simulated event might open 
       
  3773     // the selected item, which we don't want.    
       
  3774     if((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks) &&
       
  3775         iListBoxExt->iWesternVariant &&
       
  3776         iListBoxExt->iAknFepHashKeySelection && 
       
  3777         iListBoxExt->iQwertyMode == EFalse && 
       
  3778         aType == EEventKeyUp && aKeyEvent.iScanCode == EStdKeyHash &&
       
  3779         IsFocused() )
       
  3780         {
       
  3781         if( iListBoxExt->iShortHashMark )
       
  3782             {
       
  3783             TKeyEvent keyEvent;
       
  3784             keyEvent.iCode = EKeyDevice3;
       
  3785             keyEvent.iScanCode = EStdKeyDevice3;
       
  3786             keyEvent.iRepeats = 0;
       
  3787             keyEvent.iModifiers = EModifierShift;             
       
  3788             CCoeEnv::Static()->SimulateKeyEventL(keyEvent, EEventKey);
       
  3789             }
       
  3790         else
       
  3791             {
       
  3792             // some items has been un/marked with hash+up or down
       
  3793             // so don't do short hash mark - just clear selection mode
       
  3794             View()->ClearSelectionAnchorAndActiveIndex();
       
  3795             }
       
  3796         }
       
  3797     
       
  3798     if ( aKeyEvent.iScanCode == EStdKeyYes )
       
  3799         {
       
  3800         _AKNTRACE( "EStdKeyYes" );
       
  3801         _AKNTRACE_FUNC_EXIT;
       
  3802         return EKeyWasNotConsumed;
       
  3803         }
       
  3804     _AKNTRACE_FUNC_EXIT;    
       
  3805     return(EKeyWasConsumed);
       
  3806     }
       
  3807 
       
  3808 void CEikListBox::UpdateMarkUnmarkMSKL() const
       
  3809     {
       
  3810     // for markable lists if MSK is either mark/unmark
       
  3811     // and highlighted item has changed, try to switch
       
  3812     // MSK according to item's selection state
       
  3813     _AKNTRACE_FUNC_ENTER;
       
  3814     CEikButtonGroupContainer *bgc;
       
  3815     CCoeControl* MSK(NULL);
       
  3816     CEikCba* cba(NULL);
       
  3817     CONST_CAST(CEikListBox*,this)->MopGetObject(bgc);
       
  3818     if ( bgc )
       
  3819         {
       
  3820         cba = ( static_cast<CEikCba*>( bgc->ButtonGroup() ) ); // downcast from MEikButtonGroup
       
  3821         if ( cba )
       
  3822             {
       
  3823             MSK = cba->Control(3); // MSK's position is 3
       
  3824             }
       
  3825         }
       
  3826     TInt newResourceId(NULL);
       
  3827     if ( MSK && ( cba->ControlId( MSK ) == EAknSoftkeyMark ) &&
       
  3828         View()->ItemIsSelected( CurrentItemIndex() ) )
       
  3829         {
       
  3830         newResourceId = R_AVKON_SOFTKEY_UNMARK;
       
  3831         }
       
  3832     if ( MSK && ( cba->ControlId( MSK ) == EAknSoftkeyUnmark ) &&
       
  3833         !View()->ItemIsSelected( CurrentItemIndex() ) )
       
  3834         {
       
  3835         newResourceId = R_AVKON_SOFTKEY_MARK;
       
  3836         }
       
  3837 
       
  3838     if ( newResourceId )
       
  3839         {
       
  3840         bgc->SetCommandL( 3,newResourceId );
       
  3841         cba->DrawNow();
       
  3842         }
       
  3843     _AKNTRACE_FUNC_EXIT;
       
  3844     }
       
  3845 
       
  3846 EXPORT_C void CEikListBox::UpdateScrollBarThumbs() const
       
  3847     {
       
  3848     _AKNTRACE_FUNC_ENTER;
       
  3849     if (!iSBFrame)
       
  3850         {
       
  3851         _AKNTRACE_FUNC_EXIT;        
       
  3852         return;
       
  3853         }
       
  3854     TInt hThumbPos=iView->HScrollOffset();
       
  3855     TInt vThumbPos=iView->CurrentItemIndex();
       
  3856 
       
  3857     if ((iListBoxFlags & EPageAtOnceScrolling) || (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan))
       
  3858         {
       
  3859         TInt delta = iView->ItemHeight() + iView->ItemOffsetInPixels();
       
  3860         vThumbPos = iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels();
       
  3861         }
       
  3862 
       
  3863     iSBFrame->MoveHorizThumbTo(hThumbPos);
       
  3864     iSBFrame->MoveVertThumbTo(vThumbPos);
       
  3865     _AKNTRACE_FUNC_EXIT;
       
  3866     }
       
  3867 
       
  3868 EXPORT_C void CEikListBox::ReportListBoxEventL(MEikListBoxObserver::TListBoxEvent aEvent)
       
  3869     {
       
  3870     _AKNTRACE_FUNC_ENTER;
       
  3871     switch ( aEvent )
       
  3872         {
       
  3873         case MEikListBoxObserver::EEventFlickStarted:
       
  3874         case MEikListBoxObserver::EEventPanningStarted:
       
  3875             {
       
  3876             iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee );
       
  3877             if ( aEvent == MEikListBoxObserver::EEventFlickStarted )
       
  3878                 iListBoxExt->SetFlickOngoing( ETrue );
       
  3879             else            
       
  3880                 iListBoxExt->SetPanningOngoing( ETrue );
       
  3881             break;
       
  3882             }
       
  3883             
       
  3884         case MEikListBoxObserver::EEventFlickStopped:
       
  3885         case MEikListBoxObserver::EEventPanningStopped:
       
  3886             {
       
  3887             iItemDrawer->ClearFlags( CListItemDrawer::EDisableMarquee );
       
  3888             if ( aEvent == MEikListBoxObserver::EEventFlickStopped )
       
  3889                 {
       
  3890                 iListBoxExt->SetFlickOngoing( EFalse );
       
  3891                 }
       
  3892             else 
       
  3893                 {
       
  3894                 iListBoxExt->SetPanningOngoing( EFalse );
       
  3895                 }
       
  3896             
       
  3897             break;
       
  3898             }
       
  3899         }
       
  3900     
       
  3901     if ( iListBoxObserver )
       
  3902         {
       
  3903         TBool allowed = ETrue;
       
  3904 
       
  3905         if ( iListBoxExt && iListBoxExt->iPhysics
       
  3906              && aEvent != MEikListBoxObserver::EEventFlickStopped )
       
  3907             {
       
  3908             allowed = iListBoxExt->iClickEventsAllowed;
       
  3909             }
       
  3910         
       
  3911         if ( allowed )
       
  3912             {
       
  3913             iListBoxObserver->HandleListBoxEventL(this, aEvent);
       
  3914             }
       
  3915         }
       
  3916     _AKNTRACE_FUNC_EXIT;
       
  3917     }
       
  3918 
       
  3919 EXPORT_C TInt CEikListBox::HorizontalNudgeValue() const
       
  3920     {
       
  3921     return (iView->ViewRect().Width() / KEikListBoxHNudgeSizeAsFractionOfViewRectWidth);
       
  3922     }
       
  3923 
       
  3924 EXPORT_C CEikScrollBarFrame* const CEikListBox::ScrollBarFrame()
       
  3925     { 
       
  3926     return iSBFrame;
       
  3927     }
       
  3928 
       
  3929 EXPORT_C void CEikListBox::SetScrollBarFrame(CEikScrollBarFrame* aScrollBarFrame, TScrollBarOwnerShip aOwnerShip)
       
  3930     {
       
  3931     if (iSBFrameOwned == ENotOwnedExternally) { delete iSBFrame; iSBFrame = 0; }
       
  3932     iSBFrame = aScrollBarFrame; 
       
  3933     iSBFrameOwned = aOwnerShip;
       
  3934     }
       
  3935 
       
  3936 
       
  3937 // ---------------------------------------------------------------------------
       
  3938 // Scrolls the view by the given amount of pixels while keeping the
       
  3939 // physics parameters up-to-date.
       
  3940 // ---------------------------------------------------------------------------
       
  3941 //
       
  3942 EXPORT_C void CEikListBox::HandlePhysicsScrollEventL( TInt aDeltaPixels )
       
  3943     {    
       
  3944     _AKNTRACE_FUNC_ENTER;
       
  3945     if ( iListBoxExt->iPhysics )
       
  3946         {
       
  3947         iListBoxExt->InitPhysicsL();
       
  3948         
       
  3949         TPoint newPosition( iListBoxExt->iViewPosition.iX,
       
  3950                             aDeltaPixels + iListBoxExt->iViewPosition.iY );
       
  3951         iListBoxExt->ViewPositionChanged( newPosition );
       
  3952         }
       
  3953     _AKNTRACE_FUNC_EXIT;
       
  3954     }
       
  3955 
       
  3956 
       
  3957 EXPORT_C void CEikListBox::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType)
       
  3958     {
       
  3959     _AKNTRACE_FUNC_ENTER;
       
  3960     if ( iListBoxExt->iSingleClickEnabled )
       
  3961         {
       
  3962         iListBoxExt->EnableHighlight( EFalse );
       
  3963         iView->DrawItem( iView->CurrentItemIndex() );
       
  3964         }
       
  3965 
       
  3966     // When the scrollbar is scrolling, marquee will be disabled 
       
  3967     // temporarily for performance reason. And before leaving this function,
       
  3968     // this flag must be cleaned.
       
  3969     iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee );
       
  3970 
       
  3971     TInt oldThumbPos = (aEventType & KEikScrollEventBarMask) ? iView->HScrollOffset() : iView->TopItemIndex();
       
  3972     TInt newThumbPos = aScrollBar->ThumbPosition();
       
  3973     
       
  3974     TInt pageSize = 0;    
       
  3975     TInt maxThumbPos = 0;
       
  3976     
       
  3977     if ( aScrollBar->Model()->ScrollBarModelType() == 
       
  3978          TEikScrollBarModel::EAknDoubleSpanScrollBarModel )
       
  3979         {
       
  3980         const TAknDoubleSpanScrollBarModel* dblSpanModel = 
       
  3981             static_cast<const TAknDoubleSpanScrollBarModel*>( 
       
  3982                 aScrollBar->Model() );
       
  3983         pageSize = dblSpanModel->WindowSize();
       
  3984         maxThumbPos = dblSpanModel->ScrollSpan() - 
       
  3985             dblSpanModel->WindowSize();
       
  3986         }
       
  3987     else
       
  3988         {
       
  3989         pageSize = aScrollBar->Model()->iThumbSpan;
       
  3990         maxThumbPos = aScrollBar->Model()->MaxThumbPos();
       
  3991         }  
       
  3992     
       
  3993     TBool update = ETrue; // for the case EEikScrollThumbRelease so that after it there is now update.
       
  3994     TInt newThumbPosBeforeCorrecting = newThumbPos;
       
  3995 
       
  3996     switch (aEventType & KEikScrollEventBarMask)
       
  3997         { 
       
  3998     case KEikScrollEventFromHBar:
       
  3999         switch (aEventType)
       
  4000             {
       
  4001         case EEikScrollLeft:
       
  4002             newThumbPos -= HorizontalNudgeValue();
       
  4003             break;
       
  4004         case EEikScrollRight:
       
  4005             newThumbPos += HorizontalNudgeValue();
       
  4006             break;
       
  4007         case EEikScrollPageLeft:
       
  4008             newThumbPos -= pageSize;
       
  4009             break;
       
  4010         case EEikScrollPageRight:
       
  4011             newThumbPos += pageSize;
       
  4012             break;
       
  4013         case EEikScrollThumbDragHoriz:
       
  4014 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4015             SuspendEffects( ETrue );
       
  4016 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4017             if(AknLayoutUtils::PenEnabled())
       
  4018                 {
       
  4019                 break;
       
  4020                 }
       
  4021         case EEikScrollThumbReleaseHoriz:
       
  4022 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4023             SuspendEffects( EFalse );
       
  4024 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4025             // in the case of drag events, the scrollbar automatically updates its thumb pos...
       
  4026             if(AknLayoutUtils::PenEnabled())
       
  4027                 {
       
  4028                 update = EFalse;            
       
  4029                 }
       
  4030             break;
       
  4031         default:
       
  4032             break;
       
  4033             }
       
  4034         newThumbPos = Max(0, Min(newThumbPos, maxThumbPos));
       
  4035         iView->HScroll(newThumbPos - oldThumbPos);
       
  4036         if (aEventType != EEikScrollThumbDragHoriz)
       
  4037             aScrollBar->SetModelThumbPosition(iView->HScrollOffset());
       
  4038         break;
       
  4039         
       
  4040     case KEikScrollEventFromVBar:
       
  4041         switch (aEventType)
       
  4042             {
       
  4043         case EEikScrollUp:
       
  4044                 if ( oldThumbPos == 0  && (iListBoxFlags & ELoopScrolling))
       
  4045                     {
       
  4046                     newThumbPos = maxThumbPos;              
       
  4047                     }
       
  4048             break;
       
  4049                 
       
  4050         case EEikScrollDown:
       
  4051                 if ( oldThumbPos == maxThumbPos && (iListBoxFlags & ELoopScrolling) )
       
  4052                     {
       
  4053                     newThumbPos = 0;                
       
  4054                     }
       
  4055             break;
       
  4056                 
       
  4057         case EEikScrollPageUp:
       
  4058             break;
       
  4059                 
       
  4060         case EEikScrollPageDown:
       
  4061             break;
       
  4062                 
       
  4063         case EEikScrollThumbDragVert:
       
  4064 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4065             SuspendEffects( ETrue );
       
  4066 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4067             if(AknLayoutUtils::PenEnabled())
       
  4068                 {
       
  4069                 break;
       
  4070                 }
       
  4071         case EEikScrollThumbReleaseVert:
       
  4072 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4073             SuspendEffects( EFalse );
       
  4074 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4075             // in the case of drag events, the scrollbar automatically updates its thumb pos...
       
  4076             if(AknLayoutUtils::PenEnabled())
       
  4077                 {
       
  4078                 update = EFalse;            
       
  4079                 }
       
  4080             break;
       
  4081                 
       
  4082         default:
       
  4083             break;
       
  4084             }           
       
  4085             
       
  4086         newThumbPos = Max(0, Min(newThumbPos, maxThumbPos));
       
  4087         
       
  4088         if ( (!AknLayoutUtils::PenEnabled()) || update )
       
  4089             {
       
  4090 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4091             MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
  4092                                                                     iView->iGc );
       
  4093             TBool effects = transApi && !transApi->EffectsDisabled();
       
  4094 
       
  4095             if ( effects )
       
  4096                 {
       
  4097                 transApi->SetMoveType( newThumbPos < oldThumbPos ?
       
  4098                                        MAknListBoxTfxInternal::EListScrollUp :
       
  4099                                        MAknListBoxTfxInternal::EListScrollDown );
       
  4100                 }
       
  4101 #endif
       
  4102             
       
  4103         if ( iListBoxExt->iPhysics )
       
  4104             {
       
  4105             iListBoxExt->InitPhysicsL();
       
  4106             TInt deltaPixels = newThumbPos;
       
  4107     
       
  4108 #ifdef _DEBUG
       
  4109             RDebug::Print( _L( "CListBox::HandleScrollEventL, deltaPixels = %d" ), deltaPixels );
       
  4110 #endif // _DEBUG
       
  4111             
       
  4112             TPoint newPosition( iListBoxExt->iViewPosition.iX, deltaPixels + iView->ViewRect().Height() / 2 );
       
  4113             iListBoxExt->ViewPositionChanged( newPosition );
       
  4114             }
       
  4115         else
       
  4116             {
       
  4117             iView->VScrollTo(newThumbPos/iView->ItemHeight());
       
  4118             }
       
  4119 
       
  4120 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4121             if ( effects )
       
  4122                 {
       
  4123                 transApi->Draw( Rect() );
       
  4124                 }
       
  4125 #endif
       
  4126             if (aEventType != EEikScrollThumbDragVert)
       
  4127                 {               
       
  4128                 aScrollBar->SetModelThumbPosition(iView->TopItemIndex()*iView->ItemHeight() - iView->ItemOffsetInPixels());
       
  4129                 }
       
  4130             }
       
  4131         
       
  4132         // If the event has changed thumb position, then update scroll bar
       
  4133         // unless physics is used. In that case thumb is updated via 
       
  4134         // CEikListBox::ScrollView.
       
  4135         if ( AknLayoutUtils::PenEnabled() && newThumbPos != newThumbPosBeforeCorrecting && !iListBoxExt->iPhysics )
       
  4136             {
       
  4137             UpdateScrollBarThumbs();
       
  4138             }
       
  4139         }
       
  4140     iItemDrawer->ClearFlags(CListItemDrawer::EDisableMarquee);
       
  4141     _AKNTRACE_FUNC_EXIT;
       
  4142     }
       
  4143 
       
  4144 EXPORT_C void CEikListBox::HandleDragEventL(TPoint aPointerPos)
       
  4145     {
       
  4146     // return immediately if kinetic scrolling is enabled, this needs to be modified afterwards
       
  4147     _AKNTRACE_FUNC_ENTER;
       
  4148     if ( iListBoxExt && iListBoxExt->iPhysics )
       
  4149         {
       
  4150         _AKNTRACE_FUNC_EXIT;
       
  4151         return;
       
  4152         }
       
  4153     
       
  4154     CheckCreateExtensionL();
       
  4155     if (!(iListBoxFlags & ELeftDownInViewRect))
       
  4156         {
       
  4157         _AKNTRACE_FUNC_EXIT;
       
  4158         return;
       
  4159         }
       
  4160     
       
  4161     TRect viewRect(iView->ViewRect());
       
  4162     if( !AknLayoutUtils::PenEnabled() )
       
  4163         {
       
  4164         // We do not want highlight to move when dragged left/rightside of lists
       
  4165         if ((aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX))
       
  4166             {
       
  4167             aPointerPos.iX = viewRect.iTl.iX;
       
  4168             }
       
  4169         }
       
  4170     TInt itemIndex( 0 );
       
  4171     TBool pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex);
       
  4172     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  4173     TInt oldCurrentItemIndex = iView->CurrentItemIndex();
       
  4174     TInt oldTopItemIndex = iView->TopItemIndex();
       
  4175     TInt oldBottomItemIndex = iView->BottomItemIndex();
       
  4176     TInt topItemIndex ( oldTopItemIndex );
       
  4177     TInt bottomItemIndex( oldBottomItemIndex );
       
  4178     TInt interval = iListBoxExt->iInterval;
       
  4179     TInt speed = 0;
       
  4180     const TInt KBrakeL1 = 5;
       
  4181     const TInt KBrakeL2 = 10;
       
  4182     TInt lastItem = iModel->NumberOfItems() - 1;
       
  4183     TInt yDistance = aPointerPos.iY - iListBoxExt->iLastPoint.iY;
       
  4184     if(pointerIsOverAnItem && (itemIndex == oldBottomItemIndex) && yDistance > 0 )
       
  4185         {
       
  4186         speed = 1;
       
  4187         }
       
  4188     else if(pointerIsOverAnItem && (itemIndex == oldTopItemIndex) && yDistance < 0 )
       
  4189         {
       
  4190         speed = -1;
       
  4191         }
       
  4192     else if( pointerIsOverAnItem && 
       
  4193              oldTopItemIndex < itemIndex && 
       
  4194              oldBottomItemIndex > itemIndex )
       
  4195         {
       
  4196         // highlight the item
       
  4197         speed = 0;    
       
  4198         }
       
  4199     else if (aPointerPos.iY < viewRect.iTl.iY)
       
  4200         {
       
  4201         speed = - Min((( viewRect.iTl.iY + ItemHeight()) - aPointerPos.iY ) 
       
  4202                                     / ( ItemHeight() / 2 ) * iListBoxExt->iStepSpeed, 
       
  4203                                     iListBoxExt->iMaxSpeed );
       
  4204         if ( oldTopItemIndex <= KBrakeL1 )
       
  4205         {
       
  4206             speed = -1;
       
  4207         }
       
  4208         else if ( oldTopItemIndex + speed < KBrakeL1)
       
  4209         {
       
  4210             speed = KBrakeL1 - oldTopItemIndex;
       
  4211             }
       
  4212         }
       
  4213     else if (aPointerPos.iY > viewRect.iBr.iY)
       
  4214                 {
       
  4215         speed = Min(( aPointerPos.iY - ( viewRect.iBr.iY - ItemHeight())) 
       
  4216                                   / (ItemHeight() / 2) * iListBoxExt->iStepSpeed, 
       
  4217                                   iListBoxExt->iMaxSpeed );
       
  4218         if ( oldBottomItemIndex >= iModel->NumberOfItems() - 1 - KBrakeL1 )
       
  4219                     {
       
  4220             speed = 1;
       
  4221                 }
       
  4222         else if ( oldBottomItemIndex + speed > lastItem - KBrakeL1 )
       
  4223             {
       
  4224             speed = lastItem - oldBottomItemIndex - KBrakeL1;
       
  4225             }
       
  4226         }
       
  4227     // Brake level 2
       
  4228     if ( ( speed < 0 && oldTopItemIndex + speed < KBrakeL2 )
       
  4229          || ( speed > 0 && oldBottomItemIndex + speed > lastItem - KBrakeL2 ))
       
  4230         {
       
  4231         interval *= 2;        
       
  4232         }
       
  4233             
       
  4234 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4235     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
  4236                                                                 iView->iGc );
       
  4237     TBool effects = transApi && !transApi->EffectsDisabled();
       
  4238 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4239     TBool edge = EFalse;
       
  4240 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4241 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4242     if ( !ItemExists( oldTopItemIndex + speed ) ||
       
  4243          !ItemExists( oldBottomItemIndex + speed))
       
  4244         {
       
  4245         speed = 0;
       
  4246         }
       
  4247     iListBoxExt->iSpeed = speed;
       
  4248     if ( speed != 0 )
       
  4249         {
       
  4250         topItemIndex = oldTopItemIndex + speed;
       
  4251         
       
  4252 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4253         if ( !effects )
       
  4254             {
       
  4255 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4256         iView->SetTopItemIndex( topItemIndex );
       
  4257         UpdateScrollBarThumbs();
       
  4258 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4259             }
       
  4260 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4261         if ( pointerIsOverAnItem ) 
       
  4262             {
       
  4263             Window().RequestPointerRepeatEvent(interval, 
       
  4264                                                viewRect );
       
  4265             }
       
  4266         // Pointer outside of list
       
  4267         else
       
  4268             {
       
  4269             TRect screenRect(TPoint(-1000, -1000), TPoint(1000, 1000));
       
  4270             TRect ignoreDragRect;
       
  4271             
       
  4272             if ( AknLayoutUtils::PenEnabled() &&
       
  4273             ( (aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY) ) && 
       
  4274             !( (aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX) ) ) 
       
  4275                 {
       
  4276                 if (aPointerPos.iY < viewRect.iTl.iY)
       
  4277                     {
       
  4278                     ignoreDragRect.SetRect( screenRect.iTl, 
       
  4279                                             TPoint(screenRect.iBr.iX, viewRect.iTl.iY ));
       
  4280                     }
       
  4281                 else
       
  4282                     {
       
  4283                     ignoreDragRect.SetRect( TPoint( screenRect.iTl.iX, viewRect.iBr.iY), 
       
  4284                                             screenRect.iBr );
       
  4285                     }
       
  4286                 }
       
  4287             else if ( !AknLayoutUtils::PenEnabled() &&
       
  4288               ((aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY)) )
       
  4289                 {
       
  4290                 if (aPointerPos.iY < viewRect.iTl.iY)
       
  4291                     {
       
  4292                     ignoreDragRect.SetRect( screenRect.iTl, 
       
  4293                                             TPoint( screenRect.iBr.iX, viewRect.iTl.iY ));
       
  4294                     }
       
  4295                 else
       
  4296                     {
       
  4297                     ignoreDragRect.SetRect( TPoint( screenRect.iTl.iX, viewRect.iBr.iY), 
       
  4298                                             screenRect.iBr);
       
  4299                     }
       
  4300                 }
       
  4301             Window().RequestPointerRepeatEvent( interval, 
       
  4302                                                 ignoreDragRect );
       
  4303             }
       
  4304             
       
  4305         pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex);
       
  4306 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4307         if ( effects )
       
  4308             {
       
  4309             bottomItemIndex = topItemIndex + oldBottomItemIndex - oldTopItemIndex;
       
  4310             }
       
  4311         else
       
  4312             {
       
  4313 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4314             topItemIndex = iView->TopItemIndex();
       
  4315             bottomItemIndex = iView->BottomItemIndex();
       
  4316 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4317             }
       
  4318 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4319         // When scrolling don't focus first / last item unless it's really
       
  4320         // the first / last item of the list
       
  4321         if ( speed > 0 /*&& itemIndex == bottomItemIndex*/ )
       
  4322             {
       
  4323             if ( ItemExists ( bottomItemIndex +1 ) )
       
  4324                 {
       
  4325                 itemIndex = bottomItemIndex - 1;
       
  4326                 }
       
  4327                 else
       
  4328                 {
       
  4329                 itemIndex = bottomItemIndex;
       
  4330 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4331                 edge = ETrue;
       
  4332 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4333                 }
       
  4334             }
       
  4335         if ( speed < 0 /*&& itemIndex == topItemIndex*/ )
       
  4336             {
       
  4337             if ( ItemExists ( topItemIndex -1 ) )
       
  4338                 {
       
  4339                 itemIndex = topItemIndex + 1;
       
  4340                 }
       
  4341                 else
       
  4342                 {
       
  4343                 itemIndex = topItemIndex;                    
       
  4344 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4345                 edge = ETrue;
       
  4346 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4347                 }
       
  4348             }
       
  4349         
       
  4350 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4351         if ( speed != 0 && !effects )
       
  4352 #else
       
  4353         if(speed != 0)
       
  4354 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4355             {
       
  4356             SetCurrentItemIndex(itemIndex);
       
  4357             DrawNow();
       
  4358             }
       
  4359             
       
  4360         }
       
  4361     
       
  4362 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4363     if ( effects )
       
  4364         {
       
  4365         if ( AknLayoutUtils::PenEnabled() &&
       
  4366              ( iListBoxFlags & ES60StyleMultiselection || 
       
  4367                 ((iListBoxFlags & ES60StyleMarkable) && 
       
  4368                 ( (iListBoxExt->iEventModifiers & EModifierShift) ||
       
  4369                   (iListBoxExt->iEventModifiers & EModifierCtrl) ))))
       
  4370             {
       
  4371             if ( speed == 0 )
       
  4372                 {
       
  4373                 if ( itemIndex == oldCurrentItemIndex )
       
  4374                     {
       
  4375                     _AKNTRACE_FUNC_EXIT;
       
  4376                     return;
       
  4377                     }
       
  4378                 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag );
       
  4379                 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified,
       
  4380                                        viewRect );
       
  4381                 iView->SetTopItemIndex( topItemIndex );
       
  4382                 iView->SetItemIndex( itemIndex );
       
  4383                 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect );
       
  4384                 }
       
  4385 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4386             else if ( edge )
       
  4387                 {
       
  4388                 transApi->SetMoveType( MAknListBoxTfxInternal::EListHitBorder );
       
  4389                 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified,
       
  4390                                        viewRect );
       
  4391                 iView->SetTopItemIndex( topItemIndex );
       
  4392                 iView->SetItemIndex( itemIndex );
       
  4393                 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect );
       
  4394                 }
       
  4395 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4396             else
       
  4397                 {
       
  4398                 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag );
       
  4399                 transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified,
       
  4400                                        viewRect );
       
  4401                 iView->SetTopItemIndex( topItemIndex );
       
  4402                 iView->SetItemIndex( itemIndex );
       
  4403                 UpdateSelectionsL( iView, transApi, itemIndex, oldCurrentItemIndex, iListBoxExt->iAnchor, iListBoxExt->iSelect );
       
  4404                 }            
       
  4405             }
       
  4406 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4407         else if ( edge || iListBoxExt->iSpeed == 0 )
       
  4408 #else
       
  4409         else if ( iListBoxExt->iSpeed == 0 )
       
  4410 #endif
       
  4411             {
       
  4412 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4413             if ( iListBoxExt->iSpeed == 0 )
       
  4414                 {
       
  4415 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4416                 if ( itemIndex == oldCurrentItemIndex || itemIndex < 0 )
       
  4417                     {
       
  4418                     // If itemIndex didn't change or itemIndex doesn't
       
  4419                     // exist, just return
       
  4420                     _AKNTRACE_FUNC_EXIT;
       
  4421                     return;
       
  4422                     }
       
  4423                 transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag );
       
  4424 #ifdef RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4425                 }
       
  4426             else
       
  4427                 {
       
  4428                 transApi->SetMoveType( MAknListBoxTfxInternal::EListHitBorder );
       
  4429                 }
       
  4430 #endif // RD_UI_TRANSITION_EFFECTS_TOUCH_P2
       
  4431             transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified,
       
  4432                                    viewRect );
       
  4433             iView->SetTopItemIndex( topItemIndex );
       
  4434             iView->SetItemIndex( itemIndex );
       
  4435             iView->DrawItem( itemIndex );
       
  4436             iView->DrawItem( oldCurrentItemIndex );
       
  4437             for ( TInt i = iView->TopItemIndex(); i <= iView->BottomItemIndex(); i++ )
       
  4438                 {
       
  4439                 if ( i != itemIndex && i != oldCurrentItemIndex &&
       
  4440                      transApi->SetPosition( MAknListBoxTfxInternal::EListItem, iView->ItemPos( i ), i ) != KErrNone )
       
  4441                     {
       
  4442                     iView->DrawItem( i );
       
  4443                     }
       
  4444                 }
       
  4445             }
       
  4446         else
       
  4447             {
       
  4448             transApi->SetMoveType( MAknListBoxTfxInternal::EListDrag );
       
  4449             transApi->BeginRedraw( MAknListBoxTfxInternal::EListNotSpecified,
       
  4450                                    viewRect );
       
  4451             iView->SetItemIndex( itemIndex );
       
  4452                 iView->DrawItem( oldCurrentItemIndex );
       
  4453             iView->SetTopItemIndex( topItemIndex );
       
  4454             transApi->SetPosition( MAknListBoxTfxInternal::EListHighlight, iView->ItemPos( itemIndex ) );
       
  4455             for ( TInt i = iView->TopItemIndex(); i <= iView->BottomItemIndex(); i++ )
       
  4456                 {
       
  4457                 iView->DrawItem( i );
       
  4458                 }
       
  4459             }
       
  4460         transApi->SetPosition( MAknListBoxTfxInternal::EListHighlight, iView->ItemPos( itemIndex ) );
       
  4461         UpdateScrollBarThumbs();
       
  4462         if ( AknLayoutUtils::PenEnabled() )
       
  4463             {
       
  4464             MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  4465             // drag feedback, also for viewers
       
  4466             TBool feedbackNeeded = !(iListBoxFlags & EPageAtOnceScrolling) // editor case
       
  4467                                 || (oldTopItemIndex != topItemIndex || oldBottomItemIndex != bottomItemIndex); // viewer case
       
  4468             if ( feedback && feedbackNeeded )
       
  4469                 {
       
  4470                 feedback->InstantFeedback( ETouchFeedbackSensitive );
       
  4471                 }
       
  4472             ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned );
       
  4473             }
       
  4474 
       
  4475         transApi->EndRedraw( MAknListBoxTfxInternal::EListNotSpecified );
       
  4476         _AKNTRACE_FUNC_EXIT;
       
  4477         return;
       
  4478         }
       
  4479 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4480 
       
  4481     if (pointerIsOverAnItem)
       
  4482         {
       
  4483         // drag event occurred within the listbox
       
  4484         if ( itemIndex == oldCurrentItemIndex )
       
  4485             {
       
  4486             _AKNTRACE_FUNC_EXIT;
       
  4487             return;
       
  4488             }
       
  4489         if ( AknLayoutUtils::PenEnabled() &&
       
  4490              ( iListBoxFlags & ES60StyleMultiselection || 
       
  4491                 ((iListBoxFlags & ES60StyleMarkable) && 
       
  4492                 ( (iListBoxExt->iEventModifiers & EModifierShift) ||
       
  4493                   (iListBoxExt->iEventModifiers & EModifierCtrl) ))))
       
  4494             {
       
  4495             iView->VerticalMoveToItemL( itemIndex, CListBoxView::EPenMultiselection );
       
  4496             iListBoxFlags |= EStateChanged;
       
  4497             }
       
  4498         else               
       
  4499             {
       
  4500             iView->VerticalMoveToItemL( itemIndex, selectionMode );
       
  4501             UpdateMarkUnmarkMSKL(); 
       
  4502             }
       
  4503         UpdateScrollBarThumbs();
       
  4504         }
       
  4505     else if (viewRect.Contains(aPointerPos))
       
  4506         {
       
  4507         // find item nearest to the pointer pos and make that the current item
       
  4508         if( iListBoxExt->iIsDownOnItem )
       
  4509             {
       
  4510             if( yDistance>0 && itemIndex != oldBottomItemIndex )
       
  4511                 {
       
  4512                 iView->SetCurrentItemIndex( oldBottomItemIndex );
       
  4513                 }
       
  4514             else if( yDistance<0 && itemIndex != oldTopItemIndex )
       
  4515                 {
       
  4516                 iView->SetCurrentItemIndex( oldTopItemIndex );
       
  4517                 }
       
  4518             DrawDeferred();
       
  4519             }
       
  4520         }
       
  4521     else if ( AknLayoutUtils::PenEnabled() &&
       
  4522               ( (aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY) ) && 
       
  4523               !( (aPointerPos.iX > viewRect.iBr.iX) || (aPointerPos.iX < viewRect.iTl.iX) ) &&
       
  4524               // Scroll when stulying donw on item other than empty area.
       
  4525               iListBoxExt->iIsDownOnItem ) 
       
  4526         {
       
  4527         // drag event occurred outside the listbox's viewRect
       
  4528 
       
  4529         if ( iListBoxFlags & ES60StyleMultiselection || 
       
  4530             ((iListBoxFlags & ES60StyleMarkable) && 
       
  4531                 ( (iListBoxExt->iEventModifiers & EModifierShift) ||
       
  4532                   (iListBoxExt->iEventModifiers & EModifierCtrl) )))
       
  4533             {
       
  4534             iView->SetCurrentItemIndex(itemIndex);
       
  4535             iView->UpdateSelectionL(CListBoxView::EPenMultiselection);          
       
  4536             iListBoxFlags |= EStateChanged;
       
  4537             }
       
  4538         }
       
  4539     else if ( !AknLayoutUtils::PenEnabled() &&
       
  4540               ((aPointerPos.iY < viewRect.iTl.iY) || (aPointerPos.iY > viewRect.iBr.iY)) ) 
       
  4541         {
       
  4542         // drag event occurred outside the listbox's viewRect
       
  4543         TRect screenRect(TPoint(-1000, -1000), TPoint(1000, 1000));
       
  4544         TRect ignoreDragRect;
       
  4545         TInt oldTopItemIndex = iView->TopItemIndex();
       
  4546         TInt oldBottomItemIndex = iView->BottomItemIndex();
       
  4547         if (aPointerPos.iY < viewRect.iTl.iY)
       
  4548             {
       
  4549             ignoreDragRect.SetRect(screenRect.iTl, TPoint(screenRect.iBr.iX, viewRect.iTl.iY));
       
  4550             itemIndex = ItemExists(oldTopItemIndex-1) ? (oldTopItemIndex-1) : oldTopItemIndex;
       
  4551             }
       
  4552         else
       
  4553             {
       
  4554             ignoreDragRect.SetRect(TPoint(screenRect.iTl.iX, viewRect.iBr.iY), screenRect.iBr);
       
  4555             itemIndex = ItemExists(oldBottomItemIndex+1) ? (oldBottomItemIndex+1) : oldBottomItemIndex;
       
  4556             }
       
  4557  
       
  4558         SetCurrentItemIndexAndDraw(itemIndex);
       
  4559         UpdateScrollBarThumbs();
       
  4560         Window().RequestPointerRepeatEvent( interval, ignoreDragRect);
       
  4561         }
       
  4562 
       
  4563     if (itemIndex != oldCurrentItemIndex)
       
  4564         {
       
  4565         iView->UpdateSelectionL(selectionMode);
       
  4566  
       
  4567         if(AknLayoutUtils::PenEnabled())
       
  4568             {
       
  4569             MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  4570             // drag feedback, also for viewers
       
  4571             TBool feedbackNeeded = !(iListBoxFlags & EPageAtOnceScrolling) // editor case
       
  4572                                 || (oldTopItemIndex != topItemIndex || oldBottomItemIndex != bottomItemIndex); // viewer case
       
  4573             if ( feedback && feedbackNeeded )
       
  4574                 {
       
  4575                 feedback->InstantFeedback( ETouchFeedbackSensitive );
       
  4576                 }
       
  4577 
       
  4578             ReportListBoxEventL(MEikListBoxObserver::EEventItemDraggingActioned);
       
  4579             }
       
  4580  
       
  4581         iListBoxFlags |= EStateChanged;
       
  4582         if (IsMatchBuffer())
       
  4583             {
       
  4584             ClearMatchBuffer();
       
  4585             DrawMatcherCursor();
       
  4586             }
       
  4587         }
       
  4588     _AKNTRACE_FUNC_EXIT;
       
  4589     }
       
  4590 
       
  4591 // The function EnableRedraw was declared but never put to use.
       
  4592 //LOCAL_C void EnableRedraw(TAny* aPtr)
       
  4593 //    {
       
  4594 //    CListBoxView& lbv=*(CListBoxView*)aPtr;
       
  4595 //    lbv.SetDisableRedraw(EFalse);
       
  4596 //    }
       
  4597 
       
  4598 EXPORT_C void* CEikListBox::ExtensionInterface( TUid /*aInterface*/ )
       
  4599     {
       
  4600     return NULL;
       
  4601     }
       
  4602 
       
  4603 EXPORT_C void CEikListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  4604     {
       
  4605     _AKNTRACE_FUNC_ENTER;
       
  4606 
       
  4607     CheckCreateBufferL(); // don't need to create the full matching buffer here - only the iPressedIndex
       
  4608     TInt itemIndex( KErrNotFound );
       
  4609     TPoint pointerPos(aPointerEvent.iPosition);
       
  4610     TBool pointerIsOverAnItem = iView->XYPosToItemIndex(pointerPos, itemIndex);
       
  4611     TInt oldCurrentItemIndex;    
       
  4612     TBool listEmpty = !ItemExists( iView->TopItemIndex() );
       
  4613     
       
  4614     // Handle empty list area events
       
  4615     if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
  4616             !iListBoxExt->iScrolling && !iListBoxExt->iIsDownOnItem )
       
  4617         {
       
  4618         if ( listEmpty )
       
  4619             {
       
  4620             // No items, empty list was clicked
       
  4621             ReportListBoxEventL( MEikListBoxObserver::EEventEmptyListClicked );
       
  4622             _AKNTRACE_FUNC_EXIT;
       
  4623             return;
       
  4624             }
       
  4625         else if ( !pointerIsOverAnItem )
       
  4626             {
       
  4627             // Items exist, empty list area was clicked
       
  4628             ReportListBoxEventL( MEikListBoxObserver::EEventEmptyAreaClicked );
       
  4629             _AKNTRACE_FUNC_EXIT;
       
  4630             return;
       
  4631             }        
       
  4632         }     
       
  4633     else if ( listEmpty )
       
  4634         {
       
  4635         // Return always if list empty to avoid tactile feedback
       
  4636         _AKNTRACE_FUNC_EXIT;
       
  4637         return;
       
  4638         }
       
  4639 
       
  4640     
       
  4641     // When in marking mode, pointer events should not be forwarded to 
       
  4642     // long tap detector, this boolean indicates if marking mode is active
       
  4643     TBool markingMode( iListBoxExt->MarkedItems() );
       
  4644     
       
  4645     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  4646         {
       
  4647         if ( iListBoxExt->iSingleClickEnabled && 
       
  4648              itemIndex != iView->CurrentItemIndex() )
       
  4649             {
       
  4650             iListBoxExt->EnableHighlight( EFalse );
       
  4651             iView->DrawItem( iView->CurrentItemIndex() );
       
  4652             }
       
  4653 
       
  4654         iListBoxExt->iFeedbackType = ETouchFeedbackList;
       
  4655 
       
  4656         if ( itemIndex != iView->CurrentItemIndex() ||
       
  4657              iListBoxFlags & ES60StyleMultiselection )
       
  4658             {
       
  4659             iListBoxExt->iFeedbackType = ETouchFeedbackSensitiveList;
       
  4660             }
       
  4661 
       
  4662         if ( iListBoxExt->iPhysics &&
       
  4663              iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionFlicking )
       
  4664             {
       
  4665             iListBoxExt->iFeedbackType = ETouchFeedbackList;
       
  4666             }
       
  4667         
       
  4668         if ( !iListBoxExt->iPhysics || itemIndex == iView->CurrentItemIndex() )
       
  4669             {
       
  4670             iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType,
       
  4671                                             TTouchFeedbackType(ETouchFeedbackVibra | ETouchFeedbackAudio),
       
  4672                                             aPointerEvent );
       
  4673             }
       
  4674         }
       
  4675     iListBoxExt->iEventModifiers = aPointerEvent.iModifiers;
       
  4676     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  4677     TBool shiftKeyPressed = EFalse;
       
  4678     TBool controlKeyPressed = EFalse;
       
  4679 
       
  4680     if (iListBoxFlags & EMultipleSelection)
       
  4681         {
       
  4682         // determine selection mode
       
  4683         if ( iListBoxExt->iShiftKeyPressed )
       
  4684             {
       
  4685             shiftKeyPressed = ETrue;
       
  4686             }
       
  4687         else
       
  4688             {
       
  4689             shiftKeyPressed = (aPointerEvent.iModifiers) & EModifierShift;
       
  4690             }
       
  4691         controlKeyPressed = (aPointerEvent.iModifiers) & EModifierCtrl;
       
  4692         if (shiftKeyPressed)    
       
  4693             selectionMode = CListBoxView::EContiguousSelection;
       
  4694         else if (controlKeyPressed)
       
  4695             selectionMode = CListBoxView::EDisjointSelection;
       
  4696         }
       
  4697 
       
  4698     TBool s60StyleMultiselection = EFalse;
       
  4699     TBool s60StyleMarkable = EFalse;
       
  4700 
       
  4701     if (iListBoxFlags & ENoExtendedSelection)
       
  4702         {
       
  4703         controlKeyPressed = ETrue;
       
  4704         selectionMode = CListBoxView::EDisjointSelection;
       
  4705         }
       
  4706         
       
  4707     if (iListBoxFlags & ES60StyleMultiselection )
       
  4708         {
       
  4709         s60StyleMultiselection = ETrue;
       
  4710         selectionMode = CListBoxView::EDisjointSelection;
       
  4711         }
       
  4712     else if (iListBoxFlags & ES60StyleMarkable )
       
  4713         {
       
  4714         s60StyleMarkable = ETrue;
       
  4715         }
       
  4716         
       
  4717     if ( (aPointerEvent.iModifiers&EModifierDoubleClick)
       
  4718          && pointerIsOverAnItem && selectionMode == CListBoxView::ENoSelection
       
  4719          && ( !iListBoxExt->IsInHandleAllPointEventArray( itemIndex ) ))
       
  4720     {
       
  4721     // Do not return here if S60StyleMultiselection is used
       
  4722     if ( !(iListBoxFlags & ES60StyleMultiselection) &&
       
  4723           !(iListBoxFlags & ES60StyleMarkable) )
       
  4724         {
       
  4725         iListBoxExt->iEventModifiers = 0;
       
  4726         }
       
  4727     
       
  4728     if(Buffer()->iPressedIndex == itemIndex)
       
  4729         {
       
  4730         Buffer()->iPressedIndex = KEikListBoxInvalidIndex;
       
  4731         _AKNTRACE_FUNC_EXIT;
       
  4732         return;
       
  4733         }
       
  4734     }
       
  4735     
       
  4736     TBool simulateOkKey = EFalse;
       
  4737     
       
  4738     TBool hasPhysics = ( iListBoxExt && iListBoxExt->iPhysics );
       
  4739     TBool wasFlicking = EFalse;
       
  4740 
       
  4741     if ( hasPhysics )
       
  4742         {
       
  4743         if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  4744             {
       
  4745             wasFlicking = ( iListBoxExt->iPhysics
       
  4746                     && iListBoxExt->iPhysics->OngoingPhysicsAction() ==
       
  4747                     CAknPhysics::EAknPhysicsActionFlicking );
       
  4748             }
       
  4749         if ( HandlePhysicsPointerEventL( aPointerEvent ) )
       
  4750             {
       
  4751             _AKNTRACE_FUNC_EXIT;
       
  4752             return;
       
  4753             }
       
  4754         }
       
  4755                 
       
  4756     switch (aPointerEvent.iType)
       
  4757         {
       
  4758         case TPointerEvent::EButton1Down:
       
  4759             _AKNTRACE("TPointerEvent::EButton1Down");
       
  4760             // For drag outside listbox
       
  4761             iListBoxExt->iIsDownOnItem = pointerIsOverAnItem;
       
  4762             iListBoxExt->iLastPoint = pointerPos;
       
  4763 
       
  4764             // update index of the last down tapped item
       
  4765             iListBoxExt->iLastDownTappedItem = itemIndex;
       
  4766 
       
  4767             if ((! (Rect().Contains(aPointerEvent.iPosition))) && (iListBoxFlags & EPopout)) 
       
  4768                 {
       
  4769                 ReportEventL(MCoeControlObserver::EEventRequestCancel);
       
  4770                 iListBoxExt->iEventModifiers = 0;
       
  4771                 _AKNTRACE_FUNC_EXIT;
       
  4772                 return;
       
  4773                 }
       
  4774             if (iView->ViewRect().Contains(aPointerEvent.iPosition))
       
  4775                 iListBoxFlags|=ELeftDownInViewRect;
       
  4776             else
       
  4777                 {
       
  4778                 iListBoxExt->iEventModifiers = 0;
       
  4779                 _AKNTRACE_FUNC_EXIT;
       
  4780                 return;
       
  4781                 }
       
  4782         
       
  4783             oldCurrentItemIndex = iView->CurrentItemIndex();
       
  4784             Buffer()->iDragToAnotherItem = EFalse; 
       
  4785             if (pointerIsOverAnItem)
       
  4786                 {
       
  4787                 // check if pressed in the same position, if not reset pressed
       
  4788                 Buffer()->iPressedIndex = (itemIndex==oldCurrentItemIndex ? itemIndex : KEikListBoxInvalidIndex);
       
  4789 
       
  4790                 if ( !hasPhysics && !iListBoxExt->iSingleClickEnabled )
       
  4791                     {
       
  4792                     iItemDrawer->ClearFlags ( CListItemDrawer::EDisableHighlight );
       
  4793                     }
       
  4794 
       
  4795                 if ( !hasPhysics || !iListBoxExt->HighlightTimerActive() )
       
  4796                     {   
       
  4797                     // If single click mode is enabled and no physics enabled,
       
  4798                     // set highlight visible on pointer down.
       
  4799                     if ( iListBoxExt->iSingleClickEnabled )
       
  4800                         {
       
  4801                         // If flick was stopped - give only tactile feedback
       
  4802                         if ( !wasFlicking )
       
  4803                             {
       
  4804                             iListBoxExt->EnableHighlight( ETrue, ETrue );
       
  4805                             UpdateHighlightL( itemIndex );
       
  4806                             CCoeEnv::Static()->WsSession().Finish();
       
  4807                             }
       
  4808                         if ( itemIndex != oldCurrentItemIndex )
       
  4809                             {
       
  4810                         	iListBoxExt->ImmediateFeedback( 
       
  4811                                 iListBoxExt->iFeedbackType,
       
  4812                                 TTouchFeedbackType( ETouchFeedbackVibra | 
       
  4813                                 ETouchFeedbackAudio ),
       
  4814                                 aPointerEvent );
       
  4815                         	}
       
  4816                         if ( !wasFlicking )
       
  4817                             {
       
  4818                             ReportListBoxEventL( 
       
  4819                                     MEikListBoxObserver::EEventPenDownOnItem );
       
  4820                             iListBoxExt->LongTapPointerEventL( aPointerEvent );
       
  4821                             }
       
  4822                         }
       
  4823                     else
       
  4824                         {
       
  4825                         ReportListBoxEventL( 
       
  4826                                 MEikListBoxObserver::EEventPenDownOnItem );    
       
  4827                         }
       
  4828                     }
       
  4829                 else
       
  4830                     {
       
  4831                     iListBoxExt->iReportDelayedPenDown = ETrue;
       
  4832                     iListBoxExt->iDelayedPointerDownEvent = aPointerEvent;
       
  4833                     }
       
  4834  
       
  4835 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4836                     if ( itemIndex != oldCurrentItemIndex )
       
  4837                         {
       
  4838                         MAknListBoxTfxInternal* transApi =
       
  4839                                     CAknListLoader::TfxApiInternal( iView->iGc );
       
  4840                         if ( transApi && !transApi->EffectsDisabled() )
       
  4841                             {
       
  4842                             transApi->SetMoveType( MAknListBoxTfxInternal::EListTap );
       
  4843                             }
       
  4844                         }
       
  4845 #endif
       
  4846                 if (!(iListBoxFlags & EMultipleSelection))      // i.e. this is a single selection listbox
       
  4847                     {
       
  4848                     if (itemIndex == oldCurrentItemIndex)
       
  4849                         {
       
  4850                         iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  4851                         iView->DrawItem( itemIndex );
       
  4852 
       
  4853                         iListBoxExt->iEventModifiers = 0;
       
  4854                         _AKNTRACE_FUNC_EXIT;
       
  4855                         return;
       
  4856                         }
       
  4857                     
       
  4858                     if ( !hasPhysics )
       
  4859                         {
       
  4860                         iView->SetItemIndex(itemIndex);
       
  4861                         iView->DrawItem(oldCurrentItemIndex);
       
  4862                         iView->DrawItem(itemIndex);
       
  4863                         }
       
  4864                     
       
  4865                     iListBoxFlags |= EStateChanged;
       
  4866                     }
       
  4867                 else if ( s60StyleMultiselection )
       
  4868                     {
       
  4869                     if ( !hasPhysics || !iListBoxExt->HighlightTimerActive() )
       
  4870                         {
       
  4871                         iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  4872 
       
  4873                         iView->SetItemIndex(itemIndex);
       
  4874                         iView->DrawItem(oldCurrentItemIndex);
       
  4875                         iView->DrawItem(itemIndex);
       
  4876                         iListBoxFlags |= EStateChanged;
       
  4877                         Buffer()->iPressedIndex = itemIndex;
       
  4878 
       
  4879                         if ( !hasPhysics )
       
  4880                             {
       
  4881                             ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  4882                             }
       
  4883                         
       
  4884                         ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked);
       
  4885                         }
       
  4886                     else
       
  4887                         {
       
  4888                         iListBoxExt->iDelayedMultiselection = ETrue;
       
  4889                         }
       
  4890                     }
       
  4891                 else if ( s60StyleMarkable )
       
  4892                     {
       
  4893                     if ( !hasPhysics )
       
  4894                         {
       
  4895                         iView->SetItemIndex( itemIndex );
       
  4896                         }
       
  4897                     else
       
  4898                         { // shift key will be handled in highlight timer
       
  4899                         iListBoxExt->iMarkableListMarking = ETrue; 
       
  4900                         if ( shiftKeyPressed )
       
  4901                             {
       
  4902                             iListBoxExt->iMarkableListShiftKeyPressed = ETrue;
       
  4903                             // EPenMultiSelection moved to timer callback
       
  4904                             // CListBoxView::EPenMultiselection;
       
  4905                             selectionMode = CListBoxView::ENoSelection;
       
  4906                             }
       
  4907                         else
       
  4908                             {
       
  4909                             iListBoxExt->iMarkableListShiftKeyPressed = EFalse;
       
  4910                             }
       
  4911                         }
       
  4912 
       
  4913                     if ( itemIndex == oldCurrentItemIndex )
       
  4914                         {
       
  4915                         if ( shiftKeyPressed )
       
  4916                             {
       
  4917 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4918                             iListBoxExt->iAnchor = oldCurrentItemIndex;
       
  4919                             iListBoxExt->iSelect =
       
  4920                                 !iView->ItemIsSelected( iView->CurrentItemIndex() );
       
  4921 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4922 
       
  4923                             iView->SetAnchor( oldCurrentItemIndex );                      
       
  4924                             iView->UpdateSelectionL( CListBoxView::EChangeMarkMode );
       
  4925                             selectionMode = CListBoxView::EPenMultiselection;
       
  4926                             iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  4927                             }
       
  4928                         else
       
  4929                             {
       
  4930                             iView->SetAnchor( itemIndex - 1 );
       
  4931 
       
  4932 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  4933                             iListBoxExt->iAnchor = itemIndex - 1;
       
  4934 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  4935                             }
       
  4936                         }
       
  4937 
       
  4938                     if ( !hasPhysics )
       
  4939                         {
       
  4940                         iView->DrawItem( oldCurrentItemIndex );
       
  4941                         }
       
  4942 
       
  4943                     iView->UpdateSelectionL( selectionMode );
       
  4944                     iListBoxFlags |= EStateChanged;
       
  4945 
       
  4946                     if ( !hasPhysics )
       
  4947                         {
       
  4948                         iView->DrawItem( itemIndex );
       
  4949                         }
       
  4950                     }
       
  4951                 else    // multiple selection listbox
       
  4952                     {
       
  4953                     if ((itemIndex == oldCurrentItemIndex) && (iView->ItemIsSelected(itemIndex)) && (! controlKeyPressed))
       
  4954                         {
       
  4955                         iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  4956                         iView->DrawItem( itemIndex );
       
  4957                         iListBoxExt->iEventModifiers = 0;
       
  4958                         _AKNTRACE_FUNC_EXIT;
       
  4959                         return;
       
  4960                         }
       
  4961 
       
  4962                     if ( !hasPhysics )
       
  4963                         {
       
  4964                         iView->SetItemIndex(itemIndex);
       
  4965                         iView->DrawItem(oldCurrentItemIndex);
       
  4966                         }
       
  4967                     
       
  4968                     iView->UpdateSelectionL(selectionMode);
       
  4969                     iListBoxFlags |= EStateChanged;
       
  4970                     } 
       
  4971                 if (itemIndex != oldCurrentItemIndex)
       
  4972                     {
       
  4973                     iListBoxFlags |= EStateChanged;
       
  4974                     // Fixed for TSW error ETLN-7T2CSR.
       
  4975                     if ( !hasPhysics && IsMatchBuffer() )
       
  4976                         {
       
  4977                         ClearMatchBuffer();
       
  4978                         DrawMatcherCursor();
       
  4979                         }
       
  4980                     }
       
  4981                 else
       
  4982                     {
       
  4983                     iItemDrawer->SetFlags( 
       
  4984                         CListItemDrawer::EPressedDownState );
       
  4985                     iView->DrawItem( itemIndex ); 
       
  4986                     }
       
  4987                 }
       
  4988             break;
       
  4989             
       
  4990         case TPointerEvent::EButton1Up:
       
  4991             _AKNTRACE("TPointerEvent::EButton1Up");
       
  4992             if ( iListBoxExt->FeedbackEnabledOnUpEvent() && iListBoxExt->iClickEventsAllowed )
       
  4993                 {
       
  4994                 TTouchLogicalFeedback fbType = ETouchFeedbackList;
       
  4995                 if ( iListBoxFlags & ES60StyleMultiselection )
       
  4996                     {
       
  4997                     fbType = ETouchFeedbackCheckbox;
       
  4998                     }
       
  4999                 iListBoxExt->ImmediateFeedback( fbType,
       
  5000                                                 ETouchFeedbackVibra,
       
  5001                                                 aPointerEvent );
       
  5002                 }
       
  5003             if ((! (Rect().Contains(aPointerEvent.iPosition))) && (iListBoxFlags & EPopout)) 
       
  5004                 {
       
  5005                 ReportEventL(MCoeControlObserver::EEventRequestCancel);
       
  5006                 iListBoxExt->iEventModifiers = 0;
       
  5007                 _AKNTRACE_FUNC_EXIT;
       
  5008                 return;
       
  5009                 }
       
  5010             if (!(iListBoxFlags & ELeftDownInViewRect))
       
  5011                 {
       
  5012                 iListBoxExt->iEventModifiers = 0;
       
  5013                 _AKNTRACE_FUNC_EXIT;
       
  5014                 return;
       
  5015                 }
       
  5016                 
       
  5017             if (iListBoxFlags & EStateChanged)
       
  5018                 {
       
  5019                 iListBoxFlags &= (~EStateChanged);
       
  5020                 if ( !s60StyleMultiselection )
       
  5021                     {
       
  5022                     ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  5023                     UpdateMarkUnmarkMSKL();
       
  5024                     }
       
  5025                 }
       
  5026             iListBoxFlags&=(~ELeftDownInViewRect);
       
  5027             if (pointerIsOverAnItem)
       
  5028                 {
       
  5029                 TUint32 lastPointUpTime = iListBoxExt->iListPointUpTime;
       
  5030                 iListBoxExt->iListPointUpTime = User::NTickCount();
       
  5031 
       
  5032                 TInt lastItemIndex = iListBoxExt->iLastItemIndex;
       
  5033                 iListBoxExt->iLastItemIndex = itemIndex;
       
  5034 
       
  5035                 if ( ( iListBoxExt->iListPointUpTime - lastPointUpTime < KTwoPointerUpEventInterval )
       
  5036                      && lastItemIndex == itemIndex
       
  5037                      && ( !iListBoxExt->IsInHandleAllPointEventArray( itemIndex ) )
       
  5038                      && !hasPhysics )
       
  5039                 {
       
  5040                     iListBoxExt->iLastItemIndex = KEikListBoxInvalidIndex;
       
  5041                     _AKNTRACE_FUNC_EXIT;
       
  5042                     return;
       
  5043                 }
       
  5044 
       
  5045                 if ( !hasPhysics )
       
  5046                     {
       
  5047                     iListBoxExt->LongTapPointerEventL( aPointerEvent );
       
  5048                     }
       
  5049                 if ( !s60StyleMultiselection )
       
  5050                     {
       
  5051                     if ( !iListBoxExt->iSingleClickEnabled )
       
  5052                         {
       
  5053                         ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked);
       
  5054                         }
       
  5055                     else if ( itemIndex == iListBoxExt->iLastDownTappedItem )
       
  5056                         {
       
  5057                         // Single click item activation
       
  5058                         iListBoxExt->EnableHighlight( EFalse );
       
  5059                         UpdateHighlightL( itemIndex );
       
  5060                         ReportListBoxEventL( 
       
  5061                             MEikListBoxObserver::EEventItemSingleClicked );
       
  5062                         _AKNTRACE_FUNC_EXIT;
       
  5063                         return;
       
  5064                         }
       
  5065                     }
       
  5066                 else if ( s60StyleMultiselection && 
       
  5067                           iListBoxExt->iLastDownTappedItem == itemIndex &&
       
  5068                           !Buffer()->iDragToAnotherItem )
       
  5069                     {
       
  5070                     iListBoxFlags |= EStateChanged;
       
  5071                     Buffer()->iPressedIndex = itemIndex;
       
  5072                     iView->SetAnchor(itemIndex-1); // zero indexed
       
  5073                     iView->UpdateSelectionL(selectionMode);
       
  5074                     ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  5075 
       
  5076                     // Single click item activation
       
  5077                     if ( iListBoxExt->iSingleClickEnabled )
       
  5078                         {
       
  5079                         iListBoxExt->EnableHighlight( EFalse );
       
  5080                         UpdateHighlightL( itemIndex );
       
  5081                         ReportListBoxEventL( 
       
  5082                             MEikListBoxObserver::EEventItemSingleClicked );
       
  5083                         }
       
  5084                     else
       
  5085                         {
       
  5086                         ReportListBoxEventL(MEikListBoxObserver::EEventItemClicked);
       
  5087                         }
       
  5088 
       
  5089                     UpdateMarkUnmarkMSKL();
       
  5090                     }
       
  5091 
       
  5092                 if ((iListBoxFlags & EPopout) && (!(shiftKeyPressed || controlKeyPressed)))
       
  5093                     ReportEventL(MCoeControlObserver::EEventRequestExit);
       
  5094                 else if ((Buffer()->iPressedIndex != KEikListBoxInvalidIndex) &&
       
  5095                         (itemIndex==Buffer()->iPressedIndex) &&
       
  5096                         ( !Buffer()->iDragToAnotherItem ) && 
       
  5097                         (selectionMode == CListBoxView::ENoSelection))
       
  5098                     {
       
  5099                     if ( iAvkonAppUi->IsTouchCompatible() )
       
  5100                         {
       
  5101                         //In some cases, listbox will be blocked here for dialog(such as launch out a CAknQueryDialog).
       
  5102                         //And then, if App does not wait for dialog's back, and deletes container of listbox directly,
       
  5103                         //iListBoxExt will be a null point.
       
  5104                         iListBoxExt->iEventModifiers = 0;
       
  5105 
       
  5106                         // Clear pressed highlight and redraw item
       
  5107                         iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  5108                         UpdateHighlightL( itemIndex );
       
  5109 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5110                         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  5111                         if ( transApi && !transApi->EffectsDisabled() )
       
  5112                             {
       
  5113                             DrawNow();
       
  5114                             }
       
  5115 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  5116                         if ( !iListBoxExt->iSingleClickEnabled )
       
  5117                             {
       
  5118                             ReportListBoxEventL(MEikListBoxObserver::EEventItemDoubleClicked);
       
  5119                             }
       
  5120                         _AKNTRACE_FUNC_EXIT;
       
  5121                         return;
       
  5122                         }
       
  5123                     else
       
  5124                         {
       
  5125                         simulateOkKey = ETrue;
       
  5126                         }
       
  5127                     }
       
  5128                 else
       
  5129                     {
       
  5130                     Buffer()->iPressedIndex=KEikListBoxInvalidIndex;
       
  5131                     }
       
  5132                 }
       
  5133             iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  5134             iView->DrawItem( iView->CurrentItemIndex() );            
       
  5135             iListBoxExt->iIsDownOnItem = EFalse;         
       
  5136             break;
       
  5137             
       
  5138         case TPointerEvent::EDrag:
       
  5139             _AKNTRACE("TPointerEvent::EDrag");
       
  5140             // CAUTION: on hw, drag is too easy. Add a threshold for it.
       
  5141             if ( iListBoxExt->IsInIgnoreRect( pointerPos ) )
       
  5142                 {
       
  5143                 break;
       
  5144                 }
       
  5145 
       
  5146             if ( !hasPhysics && ( itemIndex != iView->CurrentItemIndex() ) )
       
  5147                 {
       
  5148                 // If single click mode is enabled, make sure that 
       
  5149                 // highlight is cleared when dragging to other item.
       
  5150                 if ( iListBoxExt->iSingleClickEnabled )
       
  5151                     {
       
  5152                     iListBoxExt->EnableHighlight( EFalse );
       
  5153                     iListBoxExt->iLastDownTappedItem = KErrNotFound;
       
  5154                     
       
  5155                     // Cancel long tap animation 
       
  5156                     iListBoxExt->CancelLongTapL();
       
  5157 
       
  5158                     }
       
  5159                 else
       
  5160                     {
       
  5161                     iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight );
       
  5162                     }
       
  5163                 ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned );
       
  5164                 }
       
  5165             
       
  5166             if( ( Buffer()->iPressedIndex != KEikListBoxInvalidIndex ) 
       
  5167                 && ( Buffer()->iPressedIndex != itemIndex)
       
  5168                 )
       
  5169                 {
       
  5170                 Buffer()->iDragToAnotherItem = ETrue;
       
  5171 
       
  5172                 if ( !hasPhysics && 
       
  5173                         ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState ) )
       
  5174                     {
       
  5175                     iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  5176                     iView->DrawItem( iView->CurrentItemIndex() );
       
  5177                     }
       
  5178                 }
       
  5179         
       
  5180             if( static_cast<CAknAppUi*>(iEikonEnv->EikAppUi())->IsFaded() && !IsFocused() )
       
  5181                 {
       
  5182                 iListBoxFlags&=(~ELeftDownInViewRect);
       
  5183                 _AKNTRACE_FUNC_EXIT;
       
  5184                 return;
       
  5185                 }
       
  5186             if ( !s60StyleMultiselection )
       
  5187                 {
       
  5188                 HandleDragEventL(pointerPos);
       
  5189                 }
       
  5190             else
       
  5191                 {
       
  5192                 // selection mode needs to be disabled in multiselection lists
       
  5193                 // since dragging is not supported
       
  5194                 iListBoxFlags &= ~ES60StyleMultiselection;
       
  5195                 HandleDragEventL( pointerPos );
       
  5196                 iListBoxFlags |= ES60StyleMultiselection;
       
  5197                 }            
       
  5198             break;
       
  5199             
       
  5200         case TPointerEvent::EButtonRepeat:
       
  5201             _AKNTRACE("TPointerEvent::EButtonRepeat");
       
  5202             // CAUTION: on hw, drag is too easy. Add a threshold for it.
       
  5203             if ( iListBoxExt->IsInIgnoreRect( pointerPos ) )
       
  5204                 {
       
  5205                 break;
       
  5206                 }
       
  5207             
       
  5208             // make sure that highlight is cleared when dragging to other item.
       
  5209             if ( !hasPhysics && itemIndex != iView->CurrentItemIndex() )
       
  5210                 {
       
  5211                 if ( iListBoxExt->iSingleClickEnabled )
       
  5212                     {
       
  5213                     iListBoxExt->EnableHighlight( EFalse );
       
  5214                     iListBoxExt->iLastDownTappedItem = KErrNotFound;
       
  5215                     }
       
  5216                 else
       
  5217                     {
       
  5218                     iItemDrawer->SetFlags( CListItemDrawer::EDisableHighlight );
       
  5219                     }
       
  5220                 }
       
  5221             
       
  5222             if (!(iListBoxFlags & ELeftDownInViewRect))
       
  5223                 {
       
  5224                 iListBoxExt->iEventModifiers = 0;
       
  5225                 _AKNTRACE_FUNC_EXIT;
       
  5226                 return;
       
  5227                 }
       
  5228 
       
  5229             if ( !s60StyleMultiselection )
       
  5230                 {
       
  5231                 HandleDragEventL(pointerPos);
       
  5232                 }
       
  5233             else
       
  5234                 {
       
  5235                 // selection mode needs to be disabled in multiselection lists
       
  5236                 // since dragging is not supported
       
  5237                 iListBoxFlags &= ~ES60StyleMultiselection;
       
  5238                 HandleDragEventL( pointerPos );
       
  5239                 iListBoxFlags |= ES60StyleMultiselection;
       
  5240                 }            
       
  5241             break;
       
  5242             
       
  5243         default:
       
  5244             break;
       
  5245         }
       
  5246         
       
  5247     iListBoxExt->iEventModifiers = 0;
       
  5248     
       
  5249     if ( simulateOkKey )
       
  5250         {
       
  5251         TKeyEvent keyEvent;
       
  5252         keyEvent.iCode = EKeyOK;
       
  5253         keyEvent.iScanCode = EStdKeyDevice3;// EStdKeyOK;
       
  5254         keyEvent.iRepeats = 0;
       
  5255         keyEvent.iModifiers = 0;
       
  5256         CCoeEnv::Static()->SimulateKeyEventL( keyEvent, EEventKey );
       
  5257         }
       
  5258     _AKNTRACE_FUNC_EXIT;
       
  5259     }
       
  5260 
       
  5261 EXPORT_C void CEikListBox::SimulateArrowKeyEventL(TKeyCode aKeyCode)
       
  5262     {
       
  5263     TKeyEvent keyEvent;
       
  5264     keyEvent.iCode = aKeyCode;
       
  5265     if (iListBoxFlags & EMultipleSelection)
       
  5266         keyEvent.iModifiers = EModifierShift;
       
  5267     OfferKeyEventL(keyEvent, EEventKey);
       
  5268     }
       
  5269 
       
  5270 EXPORT_C void CEikListBox::ClearSelection()
       
  5271     {
       
  5272     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  5273     iView->ClearSelection();
       
  5274     }
       
  5275 
       
  5276 EXPORT_C void CEikListBox::FocusChanged(TDrawNow aDrawNow)
       
  5277     {
       
  5278     _AKNTRACE_FUNC_ENTER;
       
  5279     if (iListBoxFlags & EEnterMarks || iListBoxFlags & EShiftEnterMarks )
       
  5280         {
       
  5281         CEikButtonGroupContainer *cba;
       
  5282         MopGetObject(cba);
       
  5283         // CR PKEA-4YSASZ
       
  5284         // Unfortunately, we need to do this here. It belongs to 
       
  5285         // CAknSelectionListDialog, but we need this change also 
       
  5286         // to code that does not yet use CAknSelectionListDialog.
       
  5287         if (cba && IsFocused())
       
  5288             {
       
  5289             if (iListBoxFlags & EEnterMarks)
       
  5290                 {
       
  5291                 TRAP_IGNORE(iAvkonEnv->CreateCbaObserverL(cba, this));
       
  5292                 }
       
  5293             if (iListBoxExt && iListBoxExt->iMSKObserverEnabled)
       
  5294                 {
       
  5295                 TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this));
       
  5296                 }
       
  5297             }
       
  5298         else
       
  5299             {
       
  5300             if (iListBoxFlags & EEnterMarks)
       
  5301                 {
       
  5302                 iAvkonEnv->RemoveCbaObserver();
       
  5303                 }
       
  5304             if (iListBoxExt)
       
  5305                 {
       
  5306                 iListBoxExt->RemoveMSKObserver(this);
       
  5307                 }
       
  5308             }
       
  5309         }
       
  5310         
       
  5311     if (IsFocused())
       
  5312         {
       
  5313         // Some client does not let list get button1up, so we do it there...
       
  5314         if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState )
       
  5315             {
       
  5316             iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  5317             DrawItem( iView->CurrentItemIndex() );
       
  5318             }        
       
  5319         iView->SetEmphasized(ETrue);
       
  5320         // This is needed or dialog pages do not work correctly.
       
  5321         // See for example multi-item fetch.
       
  5322         UpdateScrollBarThumbs();
       
  5323 
       
  5324         if (IsMatchBuffer())
       
  5325             iView->DrawMatcherCursor();
       
  5326         if ( iListBoxFlags & EPaintedSelection ) // added
       
  5327             {
       
  5328             TRAP_IGNORE(iView->SelectItemL(CurrentItemIndex()));
       
  5329             }
       
  5330         }
       
  5331     else
       
  5332         {
       
  5333         // switch off selection (marking) mode when we lose focus
       
  5334         // this also corrects situation, where FEP-menu is launched
       
  5335         // and thus listbox doesn't receive shift up event
       
  5336         if (NULL != iListBoxExt)
       
  5337             {
       
  5338             if ((iListBoxFlags & EMultipleSelection) && (iListBoxFlags & EShiftEnterMarks))
       
  5339                 {
       
  5340                 iListBoxExt->iShiftKeyPressed = EFalse;
       
  5341                 if (iListBoxExt->iLongPressTimer && iListBoxExt->iLongPressTimer->IsActive())
       
  5342                     {
       
  5343                     iListBoxExt->iLongPressTimer->Cancel();
       
  5344                     }
       
  5345                 ChangeSelectionMode(EFalse);
       
  5346                 iListBoxExt->iSelectionModeEnabled = EFalse;
       
  5347                 }
       
  5348             
       
  5349             // Cancel long tap detecting if focus is lost
       
  5350             iListBoxExt->CancelLongTapL();
       
  5351             }
       
  5352     
       
  5353         iView->SetEmphasized(EFalse);
       
  5354         iView->HideMatcherCursor();
       
  5355         
       
  5356         if (iItemEditor && 
       
  5357             (iListBoxFlags & EPaintedSelection) && 
       
  5358             (NULL != iListBoxExt && iListBoxExt->ReasonForFocusLost() == EFocusLostToExternalControl))
       
  5359             {
       
  5360             iView->DeselectItem(CurrentItemIndex());
       
  5361             }
       
  5362         }
       
  5363 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5364     // LISTBOX EFFECTS IMPLEMENTATION
       
  5365     if ( aDrawNow && !CAknListLoader::TfxApiInternal( iView->iGc ) )
       
  5366 #else
       
  5367     if (aDrawNow)
       
  5368 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
  5369         {
       
  5370         // redraw items affected by change in emphasis
       
  5371         TInt numOfSelectedItems = iView->SelectionIndexes()->Count();
       
  5372         TInt selectionIndex = 0;
       
  5373         for (TInt i = 0; i < numOfSelectedItems; i++)
       
  5374             {
       
  5375             selectionIndex = (*(iView->SelectionIndexes()))[i];
       
  5376             if (ItemExists(selectionIndex))
       
  5377                     iView->DrawItem(selectionIndex);
       
  5378             }
       
  5379        }
       
  5380     _AKNTRACE_FUNC_EXIT;
       
  5381     }
       
  5382 
       
  5383 EXPORT_C void CEikListBox::SetDimmed(TBool aDimmed)
       
  5384     {
       
  5385     // should panic if view does not exist
       
  5386     CCoeControl::SetDimmed(aDimmed);
       
  5387     iView->SetDimmed(aDimmed);
       
  5388     HandleResourceChange(KEikMessageColorSchemeChange);
       
  5389     }
       
  5390 
       
  5391 EXPORT_C void CEikListBox::ClearMatchBuffer() const
       
  5392     {
       
  5393     if(IsMatchBuffer())
       
  5394         {
       
  5395         iView->SetMatcherCursorPos(0);
       
  5396         MatchBuffer()->Clear();
       
  5397         }
       
  5398     }
       
  5399 
       
  5400 //
       
  5401 // Shortcut support functions (no default implementation available)
       
  5402 //
       
  5403 EXPORT_C TInt CEikListBox::ShortcutValueForNextList() 
       
  5404     { 
       
  5405     //__ASSERT_DEBUG(0,Panic(EEikPanicInvalidUseOfListBoxShortcuts)); 
       
  5406     return 0;
       
  5407     }
       
  5408 EXPORT_C void CEikListBox::SetShortcutValueFromPrevList(TInt /*aValue*/) 
       
  5409     {
       
  5410     //__ASSERT_DEBUG(0,Panic(EEikPanicInvalidUseOfListBoxShortcuts));
       
  5411     }
       
  5412 
       
  5413 // pop-up positioning support
       
  5414 EXPORT_C TRect CEikListBox::HighlightRect() const
       
  5415     {
       
  5416     TPoint topLeft( View()->ItemPos( CurrentItemIndex() ) );
       
  5417     topLeft += iAvkonAppUi->ClientRect().iTl;
       
  5418 
       
  5419     TRect rect( topLeft, iItemDrawer->ItemCellSize() );
       
  5420 
       
  5421     return rect;
       
  5422     }
       
  5423 
       
  5424 EXPORT_C TBool CEikListBox::BackgroundDrawingSuppressed() const
       
  5425     {
       
  5426     if ( iListBoxExt )
       
  5427         {
       
  5428         return iListBoxExt->iBackgroundDrawingSuppressed;
       
  5429         }
       
  5430         
       
  5431     return EFalse;
       
  5432     }
       
  5433 
       
  5434 // Series 60  needs this to control the state machine that determines how
       
  5435 // shortcuts work.
       
  5436 EXPORT_C TBool CEikListBox::LastCharMatched() const
       
  5437     {
       
  5438     return iLastCharMatched;
       
  5439     }
       
  5440 
       
  5441 EXPORT_C void CEikListBox::MatchTypedCharL(TUint aCode)
       
  5442     {
       
  5443     _AKNTRACE_FUNC_ENTER;
       
  5444     iLastCharMatched = EFalse;
       
  5445     if (iListBoxFlags&ENoFirstLetterMatching)
       
  5446         {
       
  5447         _AKNTRACE_FUNC_EXIT;
       
  5448         return;
       
  5449         }
       
  5450     const MDesCArray* matchableTextArray = iModel->MatchableTextArray();
       
  5451     if (! matchableTextArray)
       
  5452         {
       
  5453         _AKNTRACE_FUNC_EXIT;
       
  5454         return;
       
  5455         }
       
  5456     if (IsMatchBuffer())
       
  5457         {
       
  5458         TInt matcherCursorPos = iView->MatcherCursorPos();
       
  5459         if (MatchBuffer()->MatchLength() == KEikMaxMatchingBufferLength)
       
  5460             {
       
  5461             _AKNTRACE_FUNC_EXIT;
       
  5462             return;
       
  5463             }
       
  5464         MatchBuffer()->AppendChar(aCode);
       
  5465         TInt selectedItemIndex;
       
  5466         TInt ret = MatchBuffer()->FirstMatchingIndexF(selectedItemIndex, *matchableTextArray);
       
  5467         if (ret == KErrNone)
       
  5468             {
       
  5469             ++matcherCursorPos;
       
  5470 /*
       
  5471             if (matcherCursorPos >= matchableTextArray->MdcaPoint(selectedItemIndex).Length())
       
  5472                 {
       
  5473                 iListBoxExt->iBuffer->iMatchBuffer->DeleteLastChar();
       
  5474                 --matcherCursorPos;
       
  5475                 }
       
  5476 */
       
  5477             iView->VerticalMoveToItemL(selectedItemIndex, CListBoxView::ESingleSelection);
       
  5478             // SetCurrentItemIndexAndDraw(selectedItemIndex);
       
  5479             iView->SetMatcherCursorPos(matcherCursorPos);
       
  5480             iLastCharMatched = ETrue;
       
  5481             }
       
  5482         else   // No match with buf with new letter: discard new char
       
  5483             {       
       
  5484             iLastCharMatched = EFalse;      
       
  5485             MatchBuffer()->DeleteLastChar();
       
  5486             }
       
  5487         }
       
  5488     else
       
  5489         {
       
  5490         // do first later matching here
       
  5491         TChar matchCharacter(aCode);
       
  5492         matchCharacter.Fold();
       
  5493         TInt currentItemIndex = iView->CurrentItemIndex();   
       
  5494         TChar firstCharOfItem;
       
  5495         TBool foundMatch = EFalse;
       
  5496         TInt itemIndex = currentItemIndex + 1;
       
  5497         // look for match, starting at item below the current one
       
  5498         while ((itemIndex != currentItemIndex) && !foundMatch)
       
  5499             {
       
  5500             // if end of list reached, restart search from the beginning of the list
       
  5501             if (ItemExists(itemIndex) == EFalse)
       
  5502                 {
       
  5503                 itemIndex = 0;
       
  5504                 if (itemIndex == currentItemIndex)
       
  5505                     {
       
  5506                     foundMatch = ETrue;
       
  5507                     break;
       
  5508                     }
       
  5509                 }
       
  5510             TPtrC buf=matchableTextArray->MdcaPoint(itemIndex);
       
  5511             if (buf.Length())
       
  5512                 {
       
  5513                 firstCharOfItem = buf[0];
       
  5514                 firstCharOfItem.Fold();
       
  5515                 if (matchCharacter == firstCharOfItem)
       
  5516                     {
       
  5517                     foundMatch = ETrue;
       
  5518                     break;
       
  5519                     }
       
  5520                 }
       
  5521             ++itemIndex;
       
  5522             }
       
  5523         if (foundMatch)
       
  5524             {
       
  5525             iLastCharMatched = ETrue;
       
  5526             // SetCurrentItemIndexAndDraw(itemIndex);
       
  5527             iView->VerticalMoveToItemL(itemIndex, CListBoxView::ESingleSelection);
       
  5528         }
       
  5529         }
       
  5530     _AKNTRACE_FUNC_EXIT;
       
  5531     }
       
  5532 
       
  5533 EXPORT_C void CEikListBox::UndoLastChar()
       
  5534     {
       
  5535     __ASSERT_DEBUG(MatchBuffer(), Panic(EEikPanicListBoxNoMatchBuffer));
       
  5536     __ASSERT_DEBUG(iModel->MatchableTextArray(), Panic(EEikPanicListBoxNoMatchTextArray));
       
  5537     iView->SetMatcherCursorPos(iView->MatcherCursorPos() - 1);
       
  5538     MatchBuffer()->DeleteLastChar();
       
  5539     TInt selectedItemIndex;
       
  5540     const MDesCArray* matchableTextArray = iModel->MatchableTextArray(); 
       
  5541     TInt retcode = MatchBuffer()->FirstMatchingIndexF(selectedItemIndex, *matchableTextArray);
       
  5542     if (!retcode)
       
  5543         SetCurrentItemIndexAndDraw(selectedItemIndex);
       
  5544     }
       
  5545 
       
  5546 EXPORT_C void CEikListBox::SetLaunchingButton(CEikButtonBase* aButton)
       
  5547     {
       
  5548     iLaunchingButton=aButton;
       
  5549     }
       
  5550 
       
  5551 EXPORT_C TCoeInputCapabilities CEikListBox::InputCapabilities() const
       
  5552     {
       
  5553     if (iListBoxFlags&EIncrementalMatching)
       
  5554         return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation|TCoeInputCapabilities::EAllText);
       
  5555     if (iListBoxFlags&ENoFirstLetterMatching)
       
  5556         return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation);
       
  5557     return TCoeInputCapabilities(TCoeInputCapabilities::ENavigation|TCoeInputCapabilities::EAllText/*,1*/);
       
  5558     }
       
  5559 
       
  5560 /**
       
  5561 *   @ since uikon_1.2
       
  5562 *   A method which returns a TMargins object for the list box.
       
  5563 *   The TMargins object has 4 values, one for each side of the list box.
       
  5564 *   Depending on use of the Laf, the DFRD can program 2, 3 or 4 margins ...
       
  5565 *   ... but although the application developer can see up to 4 different margins ...
       
  5566 *   ... they can only set 2 (ie. iHorizontalMargin and iVerticalMargin)
       
  5567 */
       
  5568 EXPORT_C TMargins8 CEikListBox::ListBoxMargins() const
       
  5569     {
       
  5570     /*
       
  5571     TMargins margins;
       
  5572     if(iHorizontalMargin == KLafListBoxUseLafHorizMargins) // if the Laf is being used
       
  5573     {
       
  5574         margins.iLeft = LafListBox::LeftMargin();
       
  5575         margins.iRight = LafListBox::RightMargin();
       
  5576         }
       
  5577     else
       
  5578         {
       
  5579         // SERIES60 LAF
       
  5580         margins.iLeft=HorizontalMargin();
       
  5581         margins.iRight=0;
       
  5582         // END OF SERIES60 LAF
       
  5583         }
       
  5584     if(iVerticalMargin == KLafListBoxUseLafVertMargins) // if the Laf is being used
       
  5585         {
       
  5586         margins.iTop = LafListBox::TopMargin();
       
  5587         margins.iBottom = LafListBox::BottomMargin();
       
  5588     }
       
  5589     else
       
  5590         {
       
  5591         // SERIES60 LAF
       
  5592         margins.iTop=VerticalMargin();
       
  5593         margins.iBottom = 0;
       
  5594         // END OF SERIES60 LAF
       
  5595 
       
  5596         // Old implementation (not good for Series 60)
       
  5597         //margins.iTop=margins.iBottom=VerticalMargin();
       
  5598         //
       
  5599      
       
  5600         }
       
  5601     */
       
  5602     // SERIES60 LAF
       
  5603     TMargins8 margins = iMargins ;
       
  5604     margins.iTop=TInt8(VerticalMargin());
       
  5605     margins.iBottom = 0;
       
  5606     margins.iLeft=TInt8(HorizontalMargin());
       
  5607     margins.iRight = 0;
       
  5608     // END OF SERIES60 LAF
       
  5609     return margins;
       
  5610     }
       
  5611 
       
  5612 /**
       
  5613 *   @ deprecated
       
  5614 *   Use CEikListBox::ListBoxMargins() instead, to get more accurate values,
       
  5615 *   as use of this method may cause a single pixel error if the laf
       
  5616 *   is being used, due to the bit shifting involved
       
  5617 */
       
  5618 EXPORT_C TInt CEikListBox::HorizontalMargin() const
       
  5619     {
       
  5620     return ((iMargins.iLeft + iMargins.iRight) >> 1);
       
  5621     }
       
  5622 
       
  5623 /**
       
  5624 *   @ deprecated
       
  5625 *   Use CEikListBox::ListBoxMargins() instead, to get more accurate values,
       
  5626 *   as use of this method may cause a single pixel error if the laf
       
  5627 *   is being used, due to the bit shifting involved
       
  5628 */
       
  5629 EXPORT_C TInt CEikListBox::VerticalMargin() const
       
  5630     {
       
  5631     return ((iMargins.iTop + iMargins.iBottom) >> 1);
       
  5632     }
       
  5633 
       
  5634 EXPORT_C void CEikListBox::SetVerticalMargin(TInt aMargin)
       
  5635     {
       
  5636     iMargins.iTop = iMargins.iBottom = (TInt8) aMargin;
       
  5637     }
       
  5638 
       
  5639 EXPORT_C void CEikListBox::SetHorizontalMargin(TInt aMargin)
       
  5640     {
       
  5641     iMargins.iLeft = iMargins.iRight = (TInt8) aMargin;
       
  5642     }
       
  5643 
       
  5644 EXPORT_C RIncrMatcherBase* CEikListBox::MatchBuffer() const
       
  5645     {
       
  5646     if(CONST_CAST(CEikListBox*,this)->CheckCreateExtension() && Buffer())
       
  5647         return Buffer()->iMatchBuffer;
       
  5648     return NULL;
       
  5649     }
       
  5650 
       
  5651 EXPORT_C TInt CEikListBox::ViewRectHeightAdjustment() const
       
  5652     {
       
  5653     return iViewRectHeightAdjustment;
       
  5654     }
       
  5655 
       
  5656 EXPORT_C void CEikListBox::SetViewRectHeightAdjustment(TInt aAdjustment)
       
  5657     {
       
  5658     iViewRectHeightAdjustment = aAdjustment;
       
  5659     }
       
  5660 
       
  5661 EXPORT_C TRgb CEikListBox::BackColor() const
       
  5662     {
       
  5663     return iBackColor;
       
  5664     }
       
  5665 
       
  5666 EXPORT_C TInt CEikListBox::VerticalInterItemGap() const
       
  5667     {
       
  5668     return KEikListBoxItemVGap;
       
  5669 //  return ListBoxLaf()->LBxItemVGap();
       
  5670     }
       
  5671 
       
  5672 /**
       
  5673  * Gets the list of logical colors employed in the drawing of the control,
       
  5674  * paired with an explanation of how they are used. Appends the list to aColorUseList.
       
  5675  *
       
  5676  * @since ER5U 
       
  5677  */
       
  5678 EXPORT_C void CEikListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const
       
  5679     {
       
  5680     CEikBorderedControl::GetColorUseListL(aColorUseList);
       
  5681     LafListBox::GetColorUseListL(aColorUseList);
       
  5682     }
       
  5683 
       
  5684 /**
       
  5685  * Handles a change to the control's resources of type aType
       
  5686  * which are shared across the environment, e.g. colors or fonts.
       
  5687  *
       
  5688  * @since ER5U 
       
  5689  */
       
  5690 EXPORT_C void CEikListBox::HandleResourceChange(TInt aType)
       
  5691     {
       
  5692     _AKNTRACE_FUNC_ENTER;
       
  5693     _AKNTRACE( "aType = %d", aType );
       
  5694     CEikBorderedControl::HandleResourceChange(aType);
       
  5695     
       
  5696     if(aType==KEikDynamicLayoutVariantSwitch)
       
  5697         {    
       
  5698         if( iListBoxExt && iListBoxExt->iPhysics )
       
  5699             {
       
  5700             //stop flicking 
       
  5701             iListBoxExt->iPhysics->StopPhysics();
       
  5702 
       
  5703             //If touch down and hold view,
       
  5704             //kinetic scrolling should not be started after rotate screen.
       
  5705             iListBoxFlags &= ( ~ELeftDownInViewRect );
       
  5706             }
       
  5707         
       
  5708         if ( iView )
       
  5709             {
       
  5710             iView->SetItemOffsetInPixels( 0 );
       
  5711             }
       
  5712         
       
  5713         // make sure that highlight is removed and long tap is canceled 
       
  5714         // on layout switch, if single click is enabled and there is 
       
  5715         // pointer down on any item
       
  5716         if ( iListBoxExt && iListBoxExt->iSingleClickEnabled 
       
  5717              && iListBoxExt->iLastDownTappedItem != KErrNotFound )
       
  5718             {                   
       
  5719             iListBoxExt->EnableHighlight( EFalse );
       
  5720             iListBoxExt->CancelLongTapL();
       
  5721             }              
       
  5722                       
       
  5723         SizeChanged();
       
  5724 
       
  5725 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5726         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  5727         if ( transApi )
       
  5728             {
       
  5729             transApi->Remove( MAknListBoxTfxInternal:: EListEverything );
       
  5730             }
       
  5731 #endif
       
  5732         }
       
  5733 
       
  5734 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5735     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iView->iGc );
       
  5736 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  5737 
       
  5738     if ( aType == KEikMessageColorSchemeChange || aType == KAknsMessageSkinChange )
       
  5739         {
       
  5740         if ( !CAknEnv::Static()->TransparencyEnabled() && OwnsWindow())
       
  5741             {
       
  5742             Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorControlBackground,*this));
       
  5743             }
       
  5744         iBackColor=iEikonEnv->ControlColor(IsDimmed() ? 
       
  5745                                     EColorControlDimmedBackground : EColorControlBackground,*this);
       
  5746         UpdateViewColors();
       
  5747         UpdateItemDrawerColors();
       
  5748         
       
  5749         SizeChanged();
       
  5750         UpdateScrollBarsColors();
       
  5751         
       
  5752 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  5753         if ( transApi )
       
  5754             {
       
  5755             transApi->Remove( MAknListBoxTfxInternal:: EListEverything );
       
  5756             }
       
  5757         }
       
  5758     else if ( transApi && aType == KEikMessageUnfadeWindows && IsReadyToDraw() )
       
  5759         {
       
  5760         DrawDeferred();
       
  5761 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  5762         }
       
  5763         
       
  5764     switch ( aType )
       
  5765         {
       
  5766         case KEikMessageWindowsFadeChange:
       
  5767             {
       
  5768             if ( iListBoxExt )
       
  5769                 {
       
  5770                 iListBoxExt->ReportCollectionChangedEvent();
       
  5771                 }
       
  5772             } // fall through
       
  5773         case KEikMessageUnfadeWindows:
       
  5774         case KEikMessageFadeAllWindows:
       
  5775             {
       
  5776             // Some client does not let list get button1up, so we do it there...
       
  5777             iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  5778             TInt index = View()->CurrentItemIndex();
       
  5779             if ( index != KErrNotFound )
       
  5780             	{
       
  5781                 Window().Invalidate( TRect( View()->ItemPos(index), 
       
  5782             		                 View()->ItemSize() ) );
       
  5783             	}
       
  5784             break;
       
  5785             }
       
  5786         case KEikDynamicLayoutVariantSwitch:
       
  5787         case KEikMessageColorSchemeChange:
       
  5788         case KAknsMessageSkinChange:
       
  5789             DrawDeferred();
       
  5790             break;
       
  5791 
       
  5792         case KAknMessageFocusLost:
       
  5793             {
       
  5794             if ( iListBoxExt && iListBoxExt->iSingleClickEnabled )
       
  5795                 {
       
  5796                 TBool enabled( iItemDrawer && !( iItemDrawer->Flags()
       
  5797                     & CListItemDrawer::ESingleClickDisabledHighlight ) );
       
  5798                            
       
  5799                 if ( enabled )
       
  5800                     {
       
  5801                     iListBoxExt->EnableHighlight( EFalse );
       
  5802                     if ( iView && IsVisible() )
       
  5803                         {
       
  5804                         iView->DrawItem( CurrentItemIndex() );
       
  5805                         }
       
  5806                     }
       
  5807                 }
       
  5808             }
       
  5809             break;
       
  5810         }
       
  5811     _AKNTRACE_FUNC_EXIT;
       
  5812     }
       
  5813 
       
  5814 void CEikListBox::UpdateScrollBarsColors()
       
  5815     {
       
  5816     }
       
  5817 
       
  5818 void CEikListBox::UpdateScrollBarColors(CEikScrollBar* /*aScrollBar*/)
       
  5819     {
       
  5820     }
       
  5821 
       
  5822 //-----------------------------------------------------------
       
  5823 // CEikListBox::IsMultiselection()
       
  5824 // Returns true if ES60StyleMultiselection flag is on
       
  5825 //-----------------------------------------------------------
       
  5826 EXPORT_C TBool CEikListBox::IsMultiselection()
       
  5827     {
       
  5828     /* note, that this method is very misleading. To have this method
       
  5829     * return true, you need to construct your listbox with
       
  5830     * EAknListBoxPointerMultiselectionList flag, not with
       
  5831     * EAknListBoxMultipleSelection as ES60StyleMultiselection might
       
  5832     * suggest. However, to make multiselection work, you need
       
  5833     * to or those flags together...
       
  5834     */
       
  5835     return (iListBoxFlags & ES60StyleMultiselection );     
       
  5836     }
       
  5837   
       
  5838 //-----------------------------------------------------------
       
  5839 // CEikListBox::EventModifiers()
       
  5840 // Returns pointerevent modifiers.
       
  5841 //-----------------------------------------------------------  
       
  5842 EXPORT_C TInt CEikListBox::EventModifiers()
       
  5843     {
       
  5844     if (iListBoxExt)
       
  5845         {
       
  5846         return iListBoxExt->iEventModifiers;
       
  5847         }
       
  5848     return NULL;
       
  5849     }
       
  5850 
       
  5851 EXPORT_C void CEikListBox::CEikListBox_Reserved()
       
  5852     {}
       
  5853 
       
  5854 TBool CEikListBox::CheckCreateExtension()
       
  5855     {
       
  5856     TInt err=KErrNone;
       
  5857     if (!iListBoxExt)
       
  5858         {
       
  5859         TRAP(err,iListBoxExt=CListBoxExt::NewL(*this));
       
  5860         }
       
  5861     return err==KErrNone;
       
  5862     }
       
  5863 
       
  5864 void CEikListBox::CheckCreateExtensionL()
       
  5865     {
       
  5866     if (!iListBoxExt)
       
  5867         iListBoxExt=CListBoxExt::NewL(*this);
       
  5868     }
       
  5869 
       
  5870 void CEikListBox::CheckCreateBufferL()
       
  5871     {
       
  5872     CheckCreateExtensionL();
       
  5873     iListBoxExt->CheckCreateBufferL();
       
  5874     }
       
  5875 
       
  5876 CMatchBuffer* CEikListBox::Buffer() const
       
  5877     {
       
  5878     if(CONST_CAST(CEikListBox*,this)->CheckCreateExtension())
       
  5879         return iListBoxExt->Buffer();
       
  5880     return NULL;
       
  5881     }
       
  5882 
       
  5883 EXPORT_C TBool CEikListBox::IsMatchBuffer() const
       
  5884     {
       
  5885     return (CONST_CAST(CEikListBox*,this)->CheckCreateExtension() && iListBoxExt->IsMatchBuffer());
       
  5886     }
       
  5887 
       
  5888 EXPORT_C void CEikListBox::SetReasonForFocusLostL(TReasonForFocusLost aReasonForFocusLost)
       
  5889     {
       
  5890     CheckCreateExtensionL();
       
  5891     iListBoxExt->SetReasonForFocusLost(aReasonForFocusLost);
       
  5892     }
       
  5893 
       
  5894 EXPORT_C CEikListBox::TReasonForFocusLost CEikListBox::ReasonForFocusLostL()
       
  5895     {
       
  5896     CheckCreateExtensionL();
       
  5897     return iListBoxExt->ReasonForFocusLost();
       
  5898     }
       
  5899 
       
  5900 /**
       
  5901  * Sets the item editor to aEditor and transfers ownership.
       
  5902  *
       
  5903  * @since ER5U
       
  5904  */
       
  5905 EXPORT_C void CEikListBox::SetItemEditor(MEikListBoxEditor* aEditor)
       
  5906     {
       
  5907     if (iItemEditor)
       
  5908         iItemEditor->Release();
       
  5909     iItemEditor=aEditor;
       
  5910     }
       
  5911 
       
  5912 /**
       
  5913  * Deletes and NULLs the item editor.
       
  5914  *
       
  5915  * @since ER5U
       
  5916  */
       
  5917 EXPORT_C void CEikListBox::ResetItemEditor()
       
  5918     {
       
  5919     if (iItemEditor)
       
  5920         iItemEditor->Release();
       
  5921     iItemEditor=NULL;
       
  5922     }
       
  5923 
       
  5924 /**
       
  5925  * Returns a pointer to the item editor. Does not imply transfer of ownership.
       
  5926  *
       
  5927  * @since ER5U
       
  5928  */
       
  5929 EXPORT_C MEikListBoxEditor* CEikListBox::ItemEditor()
       
  5930     {
       
  5931     return iItemEditor;
       
  5932     }
       
  5933 
       
  5934 /**
       
  5935  * Creates an item editor, if one does not already exist, and starts editing the
       
  5936  * current item up to a maximum length of aMaxLength characters. Also reports an
       
  5937  * EEventEditingStarted event to any list box observer by default.
       
  5938  *
       
  5939  * @since ER5U
       
  5940  */
       
  5941 EXPORT_C void CEikListBox::EditItemL(TInt aMaxLength)
       
  5942     {
       
  5943     _AKNTRACE_FUNC_ENTER;
       
  5944     CEikListBoxTextEditor* itemEditor = STATIC_CAST(CEikListBoxTextEditor*,ItemEditor());
       
  5945     if ( !itemEditor || (itemEditor && !(itemEditor->Editor())) )
       
  5946         {
       
  5947         SetItemEditor(new(ELeave) CEikListBoxTextEditor(Model()));
       
  5948         itemEditor = STATIC_CAST(CEikListBoxTextEditor*,ItemEditor());
       
  5949         const TInt index = View()->CurrentItemIndex();
       
  5950         itemEditor->SetFont( ((CTextListItemDrawer*)iItemDrawer)->Font(index) );
       
  5951         TRect rect = TRect( View()->ItemPos( index ), View()->ItemSize() );
       
  5952         rect.iTl.iX += LafListBox::InnerGutter();
       
  5953         if (iItemDrawer->Flags()&CListItemDrawer::EDrawMarkSelection)
       
  5954             {
       
  5955             rect.iTl.iX += iItemDrawer->MarkColumn() + iItemDrawer->MarkGutter();
       
  5956             }
       
  5957         iListBoxExt->SetReasonForFocusLost(EFocusLostToInternalEditor);
       
  5958         itemEditor->StartEditingL(*this,rect,index,aMaxLength);
       
  5959         iListBoxExt->SetReasonForFocusLost(EFocusLostToExternalControl);
       
  5960         ReportListBoxEventL( MEikListBoxObserver::EEventEditingStarted );
       
  5961         }
       
  5962     _AKNTRACE_FUNC_EXIT;
       
  5963     }
       
  5964 
       
  5965 /**
       
  5966  * Stops editing and deletes the item editor, reporting an EEventEditingStopped event
       
  5967  * to any list box observer. Updates the list box model if aUpdateModel is ETrue.
       
  5968  *
       
  5969  * @since ER5U
       
  5970  */
       
  5971 EXPORT_C void CEikListBox::StopEditingL( TBool aUpdateModel )
       
  5972     {
       
  5973     MEikListBoxEditor* editor = ItemEditor();
       
  5974     if ( editor )
       
  5975         {
       
  5976         if ( aUpdateModel ) editor->UpdateModelL();
       
  5977         editor->StopEditingL();
       
  5978         ResetItemEditor();
       
  5979         ReportListBoxEventL( MEikListBoxObserver::EEventEditingStopped );
       
  5980         }
       
  5981     }
       
  5982 
       
  5983 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc, TBool aRemote)
       
  5984     {
       
  5985     // CEikListBox creates a window owning scroll bar by default. This causes
       
  5986     // scroll bar flicker during listbox open when transparency is enabled.
       
  5987     // With CAknPopupList the listbox and scroll bar are created outside of
       
  5988     // the CAknPopupList component. In order not to have to change source
       
  5989     // code of all CAknPopupList users to create a non window owning scroll
       
  5990     // bar, the default is changed for this case.
       
  5991     _AKNTRACE_FUNC_ENTER;
       
  5992     TBool windowOwning = ETrue;
       
  5993     if (Parent())
       
  5994         {
       
  5995         CAknPopupList* popupList;
       
  5996         Parent()->MopGetObjectNoChaining(popupList);
       
  5997         if (popupList)
       
  5998             {
       
  5999             windowOwning = EFalse;
       
  6000             }
       
  6001         }
       
  6002     _AKNTRACE_FUNC_EXIT;
       
  6003     return CreateScrollBarFrameL(aPreAlloc, aRemote, windowOwning);
       
  6004     }
       
  6005 
       
  6006 EXPORT_C CEikScrollBarFrame* CEikListBox::CreateScrollBarFrameL(TBool aPreAlloc, TBool aRemote, TBool aWindowOwning)
       
  6007     {
       
  6008     _AKNTRACE_FUNC_ENTER;
       
  6009     if (!iSBFrame)
       
  6010         {
       
  6011         iSBFrame=new(ELeave) CEikScrollBarFrame(this, this, aPreAlloc, ETrue); 
       
  6012         
       
  6013         // Check which type of scrollbar is to be shown
       
  6014         if (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan)
       
  6015             {
       
  6016             iSBFrame->CreateDoubleSpanScrollBarsL(aWindowOwning, aRemote, ETrue, EFalse);
       
  6017 
       
  6018             if ( CAknEnv::Static()->TransparencyEnabled() && iListBoxExt && iListBoxExt->iPhysics )
       
  6019                 {
       
  6020                 iSBFrame->DrawBackground(EFalse,EFalse);
       
  6021                 }
       
  6022             }
       
  6023 
       
  6024         if (CheckCreateExtension())
       
  6025             iListBoxExt->SetUpdateScrollBarsColors(ETrue);
       
  6026         if(aRemote)
       
  6027             iSBFrameOwned = EOwnedExternally;
       
  6028         else
       
  6029             iSBFrameOwned = ENotOwnedExternally;
       
  6030         }
       
  6031     _AKNTRACE_FUNC_EXIT;
       
  6032     return iSBFrame;
       
  6033     }
       
  6034 
       
  6035 EXPORT_C void CEikListBox::EnableMSKObserver(TBool aEnable)
       
  6036     {
       
  6037     _AKNTRACE_FUNC_ENTER;
       
  6038     if (iListBoxExt)
       
  6039         {
       
  6040         if (aEnable == EFalse)
       
  6041             {
       
  6042             iListBoxExt->RemoveMSKObserver(this); // remove disabled observer
       
  6043             }
       
  6044         else
       
  6045             {
       
  6046             if (iListBoxFlags & EEnterMarks || iListBoxFlags & EShiftEnterMarks)
       
  6047                 {
       
  6048                 CEikButtonGroupContainer *cba;
       
  6049                 MopGetObject(cba);
       
  6050                 if (cba)
       
  6051                     {
       
  6052                     TRAP_IGNORE(iListBoxExt->CreateMSKObserverL(cba, this));
       
  6053                     TRAP_IGNORE(UpdateMarkUnmarkMSKL());
       
  6054                     }
       
  6055                 }
       
  6056             }
       
  6057         iListBoxExt->iMSKObserverEnabled = aEnable;
       
  6058         }
       
  6059     _AKNTRACE_FUNC_EXIT;
       
  6060     }
       
  6061     
       
  6062 void CEikListBox::DoShiftMSKMarkingL()
       
  6063     {
       
  6064     _AKNTRACE_FUNC_ENTER;
       
  6065     if ( iListBoxExt && iListBoxExt->iWesternVariant &&
       
  6066         ( iListBoxFlags & EShiftEnterMarks || iListBoxFlags & EEnterMarks ) )
       
  6067         {
       
  6068         // if the user marks item with hash+MSK, releasing MSK should not
       
  6069         // do the marking again
       
  6070         iListBoxExt->iShortHashMark = EFalse;
       
  6071 
       
  6072         iView->UpdateSelectionL(CListBoxView::EDisjointSelection);
       
  6073         ReportEventL(MCoeControlObserver::EEventStateChanged);
       
  6074         UpdateMarkUnmarkMSKL();
       
  6075         }
       
  6076     _AKNTRACE_FUNC_EXIT;
       
  6077     }
       
  6078 
       
  6079 
       
  6080 // ---------------------------------------------------------------------------
       
  6081 // Disables the kinetic scrolling functionality in the list.
       
  6082 // ---------------------------------------------------------------------------
       
  6083 //
       
  6084 EXPORT_C void CEikListBox::DisableScrolling( TBool aDisabled )
       
  6085     {
       
  6086     _AKNTRACE_FUNC_ENTER;
       
  6087     iListBoxExt->iScrollingDisabled = aDisabled;
       
  6088     iView->iExtension->iScrollingDisabled = aDisabled;
       
  6089     
       
  6090     if ( aDisabled && iListBoxExt->iPhysics )
       
  6091         {
       
  6092         delete iListBoxExt->iPhysics;
       
  6093         iListBoxExt->iPhysics = NULL;
       
  6094         iView->SetItemOffsetInPixels( 0 );
       
  6095         }
       
  6096     else if ( !aDisabled && !iListBoxExt->iPhysics && CAknPhysics::FeatureEnabled() )
       
  6097         {
       
  6098         iListBoxExt->iPhysics = CAknPhysics::NewL( *iListBoxExt, this);      
       
  6099         }
       
  6100     _AKNTRACE_FUNC_EXIT;
       
  6101     }
       
  6102 
       
  6103 
       
  6104 // ---------------------------------------------------------------------------
       
  6105 // Checks if the kinetic scrolling functionality is disabled in the list.
       
  6106 // ---------------------------------------------------------------------------
       
  6107 //
       
  6108 EXPORT_C TBool CEikListBox::ScrollingDisabled()
       
  6109     {
       
  6110     return !iListBoxExt->iPhysics || iListBoxExt->iScrollingDisabled;
       
  6111     }
       
  6112 
       
  6113 
       
  6114 EXPORT_C void CEikListBox::SetPointerEventFilterDisabledL( const CArrayFix<TInt>& aItemIndexes )
       
  6115     {
       
  6116     _AKNTRACE_FUNC_ENTER;
       
  6117     iListBoxExt->iMutiTappingItems.Reset();
       
  6118 
       
  6119     for(TInt i=0; i<aItemIndexes.Count(); i++ )
       
  6120         {
       
  6121         iListBoxExt->iMutiTappingItems.InsertInOrderL( aItemIndexes.At(i) ); 
       
  6122         }   
       
  6123     _AKNTRACE_FUNC_EXIT;
       
  6124     }
       
  6125 
       
  6126 
       
  6127 // ---------------------------------------------------------------------------
       
  6128 // CEikListBox::SuspendEffects
       
  6129 // ---------------------------------------------------------------------------
       
  6130 //
       
  6131 EXPORT_C void CEikListBox::SuspendEffects( TBool aSuspend )
       
  6132     {
       
  6133     _AKNTRACE_FUNC_ENTER;
       
  6134     TBool effectsEnabled = EFalse;
       
  6135 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6136     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal(
       
  6137             iView->ItemDrawer()->Gc() );
       
  6138 
       
  6139     effectsEnabled = transApi && !transApi->EffectsDisabled();
       
  6140 #endif    
       
  6141     // Record effect's state before those are suspended so that calling this
       
  6142     // method doesn't turn effects on if they were disabled already.
       
  6143     if ( iListBoxExt )
       
  6144         {
       
  6145         if ( effectsEnabled && !iListBoxExt->iEffectsEnabled )
       
  6146             {
       
  6147             iListBoxExt->iEffectsEnabled = ETrue;
       
  6148             }
       
  6149         
       
  6150         if ( !aSuspend )
       
  6151             {
       
  6152             aSuspend = !iListBoxExt->iEffectsEnabled;
       
  6153             }
       
  6154         }
       
  6155 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6156     
       
  6157     MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iView->ItemDrawer()->Gc() );
       
  6158     
       
  6159     if (  aSuspend && effectsEnabled && tfxApi )
       
  6160         {
       
  6161         tfxApi->EnableEffects( EFalse );
       
  6162         }
       
  6163     else if ( !aSuspend && !effectsEnabled && tfxApi )
       
  6164         {
       
  6165         tfxApi->EnableEffects( ETrue );
       
  6166         }
       
  6167 #endif// RD_UI_TRANSITION_EFFECTS_LIST
       
  6168     _AKNTRACE_FUNC_EXIT;
       
  6169     }
       
  6170 
       
  6171 
       
  6172 // ---------------------------------------------------------------------------
       
  6173 // Disables the single click functionality in the list.
       
  6174 // ---------------------------------------------------------------------------
       
  6175 //
       
  6176 EXPORT_C void CEikListBox::DisableSingleClick( TBool aDisabled )
       
  6177     {
       
  6178     _AKNTRACE_FUNC_ENTER;
       
  6179     if ( aDisabled && iListBoxExt->iSingleClickEnabled )
       
  6180         {
       
  6181         iListBoxExt->DisableSingleClick(); 
       
  6182         }
       
  6183     _AKNTRACE_FUNC_EXIT;
       
  6184     }
       
  6185 
       
  6186 
       
  6187 // ---------------------------------------------------------------------------
       
  6188 // CEikListBox::DisableItemSpecificMenu
       
  6189 // ---------------------------------------------------------------------------
       
  6190 //
       
  6191 EXPORT_C void CEikListBox::DisableItemSpecificMenu()
       
  6192     {
       
  6193     if ( iListBoxExt )
       
  6194         {
       
  6195         iListBoxExt->DisableItemSpecificMenu();
       
  6196         }
       
  6197     }
       
  6198 
       
  6199 
       
  6200 void CEikListBox::ScrollView( const TInt aOffset, TBool aDrawNow )
       
  6201 	{
       
  6202 	_AKNTRACE_FUNC_ENTER;
       
  6203 #ifdef _DEBUG
       
  6204 	RDebug::Print( _L( "CEikListBox::ScrollView, aOffset = %d, aDrawNow = %d" ), aOffset, aDrawNow );
       
  6205 #endif // _DEBUG
       
  6206 
       
  6207 	if ( aOffset != 0 )
       
  6208 	    {
       
  6209         TInt itemHeight = iView->ItemHeight();
       
  6210         TInt viewHeight = iView->ViewRect().Size().iHeight;
       
  6211         TInt itemsInSingleLine = iListBoxExt->iItemsInSingleLine;
       
  6212         TInt oldListTopPos = ( iView->TopItemIndex() / itemsInSingleLine ) * itemHeight 
       
  6213             - iView->ItemOffsetInPixels();
       
  6214         TInt newListTopPos = oldListTopPos - aOffset;
       
  6215         
       
  6216         // calculate new top item index and offset
       
  6217         TInt newTopItemIndex = ( newListTopPos / itemHeight ) * itemsInSingleLine;
       
  6218         TInt newTopItemIndexBck = newTopItemIndex;
       
  6219         if ( newTopItemIndex >= Model()->NumberOfItems() )
       
  6220             {
       
  6221             newTopItemIndexBck = Model()->NumberOfItems() - 1;
       
  6222             newTopItemIndex = Model()->NumberOfItems();
       
  6223             }
       
  6224 
       
  6225         // feedback during flicking and panning
       
  6226         TInt newListBottomPos = newListTopPos + viewHeight;
       
  6227         
       
  6228         TInt newListLastItemPos = ( Model()->NumberOfItems()/itemsInSingleLine ) * itemHeight - newListTopPos;
       
  6229         if ( newTopItemIndex != iListBoxExt->iPrevTopItemIndex )
       
  6230             {
       
  6231             iListBoxExt->iPrevTopItemIndex = newTopItemIndex;
       
  6232             if( iListBoxExt->FlickOrPanningOngoing() )
       
  6233                 {
       
  6234                 if( ( newListBottomPos < iListBoxExt->ListBottomLimit() && newListTopPos > 0 ) || 
       
  6235                     ( newListBottomPos >= iListBoxExt->ListBottomLimit() ) ||
       
  6236                     ( newListTopPos <= 0 && newListTopPos + viewHeight >= 0 && newListLastItemPos > viewHeight ) )
       
  6237                     {
       
  6238                     if ( CAknPhysics::EAknPhysicsActionFlicking == iListBoxExt->iPhysics->OngoingPhysicsAction() || 
       
  6239                          CAknPhysics::EAknPhysicsActionBouncing == iListBoxExt->iPhysics->OngoingPhysicsAction() )
       
  6240                         {
       
  6241                         iListBoxExt->ImmediateFeedback( ETouchFeedbackSensitiveList,
       
  6242                                                         TTouchFeedbackType( ETouchFeedbackVibra ),
       
  6243                                                         TPointerEvent() );
       
  6244                         }
       
  6245                     else if ( CAknPhysics::EAknPhysicsActionDragging == iListBoxExt->iPhysics->OngoingPhysicsAction() )
       
  6246                         {
       
  6247                         iListBoxExt->ImmediateFeedback( iListBoxExt->iFeedbackType,
       
  6248                                                         TTouchFeedbackType( ETouchFeedbackVibra | ETouchFeedbackAudio ),
       
  6249                                                         TPointerEvent() );
       
  6250                         }
       
  6251                     }
       
  6252                 }
       
  6253             }
       
  6254         newTopItemIndex = newTopItemIndexBck;
       
  6255         if ( newTopItemIndex < 0 )
       
  6256             {
       
  6257             newTopItemIndex = 0;
       
  6258             }
       
  6259         
       
  6260         // Top item index should always be the first item index in a row.
       
  6261         TInt notFirstInRow = newTopItemIndex % itemsInSingleLine;
       
  6262     
       
  6263         if ( notFirstInRow > 0 )
       
  6264             {
       
  6265             newTopItemIndex -= notFirstInRow;
       
  6266             }
       
  6267         
       
  6268         TInt offset = ( newTopItemIndex / itemsInSingleLine ) * itemHeight - newListTopPos;
       
  6269     
       
  6270         iView->SetItemOffsetInPixels( offset );
       
  6271 #ifdef _DEBUG
       
  6272         RDebug::Print( _L( "CEikListBox::ScrollView, newTopItemIndex = %d" ), newTopItemIndex );
       
  6273 #endif // _DEBUG
       
  6274         iView->SetTopItemIndex( newTopItemIndex );
       
  6275         }
       
  6276     if ( aDrawNow )
       
  6277         {
       
  6278         TRect rect(Rect());
       
  6279         
       
  6280         // list position changed
       
  6281         iListBoxExt->iBackgroundDrawingSuppressed = ETrue;
       
  6282         UpdateScrollBarThumbs();
       
  6283         DrawNow();
       
  6284         if (iSBFrame && iSBFrame->VerticalScrollBar() && !iSBFrame->VerticalScrollBar()->OwnsWindow())
       
  6285             {
       
  6286             TRect srect( iSBFrame->VerticalScrollBar()->Rect() );
       
  6287             if ( !srect.Intersects( rect ))
       
  6288                 {
       
  6289                 iSBFrame->DrawScrollBarsNow();                
       
  6290                 }
       
  6291             }
       
  6292         iListBoxExt->iBackgroundDrawingSuppressed = EFalse;
       
  6293         }        
       
  6294     _AKNTRACE_FUNC_EXIT;
       
  6295 	}
       
  6296 
       
  6297 
       
  6298 // ---------------------------------------------------------------------------
       
  6299 // Handles pointer events if physics are enabled.
       
  6300 // ---------------------------------------------------------------------------
       
  6301 //
       
  6302 TBool CEikListBox::HandlePhysicsPointerEventL( const TPointerEvent& aPointerEvent )
       
  6303     {
       
  6304     _AKNTRACE_FUNC_ENTER;
       
  6305     _AKNTRACE( "aPointerEvent.iType = %d", aPointerEvent.iType );
       
  6306     if ( iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionBouncing )
       
  6307         { 
       
  6308         // Block scrolling events outside listbox area. Note that pointer
       
  6309         // event ignore must be done for the window-owning control or it
       
  6310         // doesn't have any effect!
       
  6311         CCoeControl* windowOwningControl = this;
       
  6312         
       
  6313         while ( windowOwningControl && !windowOwningControl->OwnsWindow() )
       
  6314             {
       
  6315             windowOwningControl = windowOwningControl->Parent();
       
  6316             }
       
  6317 
       
  6318         if ( windowOwningControl )
       
  6319             {
       
  6320             windowOwningControl->IgnoreEventsUntilNextPointerUp();
       
  6321             _AKNTRACE_FUNC_EXIT;
       
  6322             return ETrue;
       
  6323             }
       
  6324         }
       
  6325 
       
  6326     TBool blockEvent = EFalse;
       
  6327     
       
  6328     TBool allowDragEvent( ( iListBoxFlags & ELeftDownInViewRect ) && iSBFrame && !iListBoxExt->iScrollingDisabled );
       
  6329 
       
  6330     
       
  6331     switch ( aPointerEvent.iType )
       
  6332         {
       
  6333         case TPointerEvent::EButton1Down:
       
  6334             {
       
  6335             TInt tappedItemIndex = KErrNotFound;
       
  6336             iListBoxExt->iItemDraggingReported = EFalse;
       
  6337             
       
  6338             // If list is tapped while flicking then EEventItemClicked etc are not sent
       
  6339             if ( iListBoxExt->iPhysics->OngoingPhysicsAction() == CAknPhysics::EAknPhysicsActionFlicking )
       
  6340                 {
       
  6341                 iListBoxExt->iClickEventsAllowed = EFalse;
       
  6342                 if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState )
       
  6343                     {
       
  6344                     iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState ); 
       
  6345                     }
       
  6346                 
       
  6347                 // Multiselection list tapped while flicking.
       
  6348                 // Just move the highlight, pressed down highlight and
       
  6349                 // item marking are ignored.     
       
  6350                 if ( iListBoxFlags & ES60StyleMultiselection )
       
  6351                     {
       
  6352                     iListBoxExt->iIsDownOnItem =
       
  6353                         iView->XYPosToItemIndex( aPointerEvent.iPosition,
       
  6354                                                  tappedItemIndex );
       
  6355                     if ( iListBoxExt->iIsDownOnItem )
       
  6356                         {
       
  6357                         iListBoxExt->iLastDownTappedItem = tappedItemIndex;
       
  6358                         iListBoxExt->iMarkingDisabled = ETrue;
       
  6359                         iListBoxFlags|=ELeftDownInViewRect;                        
       
  6360                         blockEvent = ETrue;
       
  6361                         }
       
  6362                     }
       
  6363                 }
       
  6364             else
       
  6365                 {
       
  6366                 iListBoxExt->iClickEventsAllowed = ETrue;
       
  6367                 }
       
  6368             
       
  6369             if ( iView->XYPosToItemIndex( aPointerEvent.iPosition, tappedItemIndex ) )
       
  6370                 {
       
  6371                 // Start highlight timer if needed
       
  6372                 if ( tappedItemIndex != iView->CurrentItemIndex() ||
       
  6373                      iListBoxExt->iSingleClickEnabled )
       
  6374                     {                   
       
  6375                     if ( !iListBoxExt->iSingleClickEnabled )
       
  6376                         {
       
  6377                         iListBoxExt->StartHighlightTimer();
       
  6378                         }                    
       
  6379                     else if ( !( iItemDrawer->Flags() & CListItemDrawer::EDisableMarquee ) )
       
  6380                         {
       
  6381                         // Disable marquee
       
  6382                         iItemDrawer->SetFlags( CListItemDrawer::EDisableMarquee );
       
  6383                         }
       
  6384                     }
       
  6385                 }
       
  6386 
       
  6387             iListBoxExt->iPhysics->StopPhysics();
       
  6388             iListBoxExt->iPhysics->ResetFriction();
       
  6389             iListBoxExt->iDragStartPosition = aPointerEvent.iPosition;
       
  6390             iListBoxExt->iLastPointerPos = aPointerEvent.iPosition;
       
  6391             iListBoxExt->iScrolling = EFalse;
       
  6392             iListBoxExt->InitPhysicsL();
       
  6393             iListBoxExt->iStartTime.HomeTime();
       
  6394             }
       
  6395             break;
       
  6396         case TPointerEvent::EButtonRepeat: // fall through
       
  6397         case TPointerEvent::EDrag:
       
  6398             {
       
  6399             if ( allowDragEvent )
       
  6400                 {
       
  6401                 TPoint drag( iListBoxExt->iDragStartPosition - aPointerEvent.iPosition );
       
  6402 
       
  6403                 TInt currentItemIndex = iView->CurrentItemIndex();
       
  6404                 TInt touchedItemIndex( KErrNotFound );
       
  6405 
       
  6406                 if ( Abs( drag.iY ) > iListBoxExt->iPhysics->DragThreshold() &&
       
  6407                         !iListBoxExt->iScrolling )
       
  6408                     {
       
  6409 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6410                     SuspendEffects( ETrue );
       
  6411 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  6412                     iListBoxExt->iScrolling = ETrue;
       
  6413                     iListBoxExt->CancelHighlightTimer();
       
  6414 
       
  6415                     // Cancel long tap detecting
       
  6416                     iListBoxExt->CancelLongTapL();
       
  6417                     // Remove highlight if single click enabled
       
  6418                     if ( iListBoxExt->iSingleClickEnabled )
       
  6419                         {
       
  6420                         iListBoxExt->EnableHighlight( EFalse );
       
  6421                         iListBoxExt->iLastDownTappedItem = KErrNotFound;
       
  6422                         iView->SetItemIndex( 0 );
       
  6423                         }
       
  6424 
       
  6425                     if ( iView->ItemIsVisible( currentItemIndex ) )
       
  6426                         {
       
  6427                         iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  6428                         iView->DrawItem( currentItemIndex );
       
  6429                         }
       
  6430                     
       
  6431                     ReportListBoxEventL( MEikListBoxObserver::EEventPanningStarted );
       
  6432                     }
       
  6433                 else if ( !iListBoxExt->iScrolling &&
       
  6434                           iView->XYPosToItemIndex( aPointerEvent.iPosition, touchedItemIndex ) )
       
  6435                     {
       
  6436                     // Don't send the dragging actioned event if the
       
  6437                     // highlight timer hasn't yet completed as in that case
       
  6438                     // the current item index isn't updated yet.
       
  6439                     if ( currentItemIndex != touchedItemIndex &&
       
  6440                          !iListBoxExt->iItemDraggingReported &&
       
  6441                          !iListBoxExt->HighlightTimerActive() )
       
  6442                         {
       
  6443                         iListBoxExt->iItemDraggingReported = ETrue;
       
  6444                         ReportListBoxEventL( MEikListBoxObserver::EEventItemDraggingActioned );
       
  6445                         }
       
  6446                     }
       
  6447                 if ( iItemDrawer->Flags() & CListItemDrawer::EPressedDownState
       
  6448                           && !iView->ItemIsVisible( currentItemIndex ) )
       
  6449                     {
       
  6450                     iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  6451                     }
       
  6452                 
       
  6453                 if ( iListBoxExt->iScrolling )
       
  6454                     {
       
  6455                     iListBoxExt->iPhysics->RegisterPanningPosition( 
       
  6456                         TPoint( 0, iListBoxExt->iLastPointerPos.iY - aPointerEvent.iPosition.iY ) );
       
  6457 
       
  6458 #ifdef _DEBUG
       
  6459                     RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, newViewPosition.iX = %d, iY = %d" ), iListBoxExt->iViewPosition.iX, iListBoxExt->iViewPosition.iY );
       
  6460                     RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, iListBoxExt->iLastPointerPos.iY = %d" ), iListBoxExt->iLastPointerPos.iY );
       
  6461                     RDebug::Print( _L( "CEikListBox::HandlePhysicsPointerEventL, aPointerEvent.iPosition.iY = %d" ), aPointerEvent.iPosition.iY );
       
  6462 #endif // _DEBUG
       
  6463     
       
  6464                     blockEvent = ETrue;
       
  6465                     }
       
  6466     
       
  6467                 iListBoxExt->iLastPointerPos = aPointerEvent.iPosition;
       
  6468                 }
       
  6469             }
       
  6470             break;
       
  6471         
       
  6472         case TPointerEvent::EButton1Up:
       
  6473             {          
       
  6474             if ( iListBoxFlags & ES60StyleMultiselection 
       
  6475                  && iListBoxExt->iMarkingDisabled )
       
  6476                 {
       
  6477                 // Allow marking again on next up event.
       
  6478                 iListBoxExt->iMarkingDisabled = EFalse;
       
  6479                 blockEvent = ETrue;
       
  6480                 }
       
  6481             
       
  6482             // update selected item in case highlight timer is still running
       
  6483             if ( iListBoxExt->HighlightTimerActive() )
       
  6484                 {
       
  6485                 // Must cancel highlight timer directly instead of using
       
  6486                 // CListBoxExt::CancelHighlightTimer(), because it will
       
  6487                 // also clear the flags used in the highlight timer
       
  6488                 // callback function.
       
  6489                 iListBoxExt->iHighlightTimer->Cancel();
       
  6490                 CListBoxExt::HighlightTimerCallback( iListBoxExt );
       
  6491                 }
       
  6492                 
       
  6493             TPoint drag( iListBoxExt->iDragStartPosition - aPointerEvent.iPosition );
       
  6494 
       
  6495             iListBoxExt->LongTapPointerEventL( aPointerEvent );
       
  6496             
       
  6497             if (  allowDragEvent &&
       
  6498                  iListBoxExt->iPhysics->StartPhysics( drag, iListBoxExt->iStartTime ) )
       
  6499                 {
       
  6500                 iListBoxExt->CancelLongTapL();
       
  6501 
       
  6502                 if ( !iListBoxExt->iScrolling )
       
  6503                     {
       
  6504 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6505                     SuspendEffects( ETrue );
       
  6506 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  6507                     iItemDrawer->ClearFlags( CListItemDrawer::EPressedDownState );
       
  6508                     iView->DrawItem( iView->CurrentItemIndex() );
       
  6509                     iListBoxExt->iScrolling = ETrue;
       
  6510                     }
       
  6511                 else
       
  6512                     {
       
  6513                     ReportListBoxEventL( MEikListBoxObserver::EEventPanningStopped );
       
  6514                     }
       
  6515                 
       
  6516                 blockEvent = ETrue;
       
  6517 
       
  6518                 // Clearing ELeftDownInViewRect should be done by rest code in
       
  6519                 // CEikListBox::HandlePointerEventL, but since the event is 
       
  6520                 // blocked, do it here
       
  6521                 iListBoxFlags&=(~ELeftDownInViewRect);
       
  6522 
       
  6523                 ReportListBoxEventL( MEikListBoxObserver::EEventFlickStarted );
       
  6524                 }
       
  6525             else
       
  6526                 {
       
  6527                 iListBoxExt->iScrolling = EFalse;
       
  6528                 }
       
  6529 
       
  6530             if ( iListBoxExt->iSingleClickEnabled
       
  6531                      && iListBoxExt->iLongTappedItem == KErrNotFound ) 
       
  6532                 {
       
  6533                 iListBoxExt->EnableHighlight( EFalse );
       
  6534                 TInt itemIndex( 0 );
       
  6535                 if ( !iView->XYPosToItemIndex(
       
  6536                         aPointerEvent.iPosition, itemIndex ) )
       
  6537                     {
       
  6538                     iListBoxExt->iLastDownTappedItem = KErrNotFound;
       
  6539                     }
       
  6540                 }
       
  6541             }
       
  6542             iListBoxExt->iIsDownOnItem = EFalse;
       
  6543             break;
       
  6544             
       
  6545         default:
       
  6546             break;
       
  6547         }
       
  6548 
       
  6549     iView->SetScrolling( iListBoxExt->iScrolling );
       
  6550     _AKNTRACE_FUNC_EXIT;
       
  6551     return blockEvent;
       
  6552     }
       
  6553 
       
  6554 
       
  6555 // ---------------------------------------------------------------------------
       
  6556 // Draws the highlight to the current item.
       
  6557 // ---------------------------------------------------------------------------
       
  6558 //
       
  6559 void CEikListBox::UpdateHighlightL( TInt aItemIndex )
       
  6560     {
       
  6561     _AKNTRACE_FUNC_ENTER;
       
  6562     TInt oldCurrentItemIndex = iView->CurrentItemIndex();
       
  6563 
       
  6564     if ( iListBoxExt->iReportDelayedPenDown && !iListBoxExt->iScrolling )
       
  6565         {
       
  6566 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6567         if ( aItemIndex != oldCurrentItemIndex )
       
  6568             {
       
  6569             MAknListBoxTfxInternal* transApi =
       
  6570                         CAknListLoader::TfxApiInternal( iView->iGc );
       
  6571             if ( transApi && !transApi->EffectsDisabled() )
       
  6572                 {
       
  6573                 transApi->SetMoveType( MAknListBoxTfxInternal::EListTap );
       
  6574                 }
       
  6575             }
       
  6576 #endif
       
  6577         iView->SetItemIndex( aItemIndex );
       
  6578         ReportListBoxEventL(
       
  6579             MEikListBoxObserver::EEventPenDownOnItem );
       
  6580         
       
  6581         // The long tap animation should start after the highlight has
       
  6582         // been made visible.
       
  6583         iListBoxExt->LongTapPointerEventL(
       
  6584             iListBoxExt->iDelayedPointerDownEvent );
       
  6585         }
       
  6586 
       
  6587     if ( iListBoxExt->iDelayedMultiselection )
       
  6588         {
       
  6589         iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  6590         }
       
  6591     
       
  6592     iView->SetItemIndex( aItemIndex );
       
  6593 
       
  6594     if ( iListBoxExt->iMarkableListMarking )
       
  6595         {
       
  6596         if ( iListBoxExt->iMarkableListShiftKeyPressed )
       
  6597            {
       
  6598 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6599            iListBoxExt->iAnchor = oldCurrentItemIndex;
       
  6600            iListBoxExt->iSelect =
       
  6601                !iView->ItemIsSelected( iView->CurrentItemIndex() );
       
  6602 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  6603 
       
  6604            iView->SetAnchor( oldCurrentItemIndex );
       
  6605            iView->UpdateSelectionL( CListBoxView::EChangeMarkMode );
       
  6606            iItemDrawer->SetFlags( CListItemDrawer::EPressedDownState );
       
  6607            iView->UpdateSelectionL( CListBoxView::EPenMultiselection );
       
  6608            }
       
  6609       else
       
  6610            {
       
  6611            iView->SetAnchor( aItemIndex - 1 );
       
  6612 
       
  6613 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  6614            iListBoxExt->iAnchor = aItemIndex - 1;
       
  6615 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  6616            }
       
  6617 
       
  6618         iListBoxExt->iMarkableListMarking = EFalse;
       
  6619         }
       
  6620 
       
  6621     iView->DrawItem( oldCurrentItemIndex );
       
  6622     iView->DrawItem( aItemIndex );
       
  6623     
       
  6624     if ( iListBoxExt->iDelayedMultiselection )
       
  6625         {
       
  6626         iListBoxFlags |= EStateChanged;
       
  6627         Buffer()->iPressedIndex = aItemIndex;
       
  6628         }
       
  6629 
       
  6630     ReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6631     _AKNTRACE_FUNC_EXIT;
       
  6632     }
       
  6633 
       
  6634 
       
  6635 // ---------------------------------------------------------------------------
       
  6636 // Sets this control as visible or invisible.
       
  6637 // ---------------------------------------------------------------------------
       
  6638 //
       
  6639 EXPORT_C void CEikListBox::MakeVisible( TBool aVisible )
       
  6640     {
       
  6641     CEikBorderedControl::MakeVisible( aVisible );
       
  6642     if ( iListBoxExt )
       
  6643         {
       
  6644         if ( !aVisible )
       
  6645             {
       
  6646             iListBoxExt->EnableHighlight( EFalse );
       
  6647             }
       
  6648         else
       
  6649             {
       
  6650             iListBoxExt->ReportCollectionChangedEvent();
       
  6651             }
       
  6652         }
       
  6653     }
       
  6654 
       
  6655 //
       
  6656 // class CEikSnakingListBox
       
  6657 //
       
  6658 
       
  6659 EXPORT_C CEikSnakingListBox::CEikSnakingListBox()
       
  6660     {
       
  6661     AKNTASHOOK_ADD( this, "CEikSnakingListBox" );
       
  6662     }
       
  6663 
       
  6664 EXPORT_C CEikSnakingListBox::~CEikSnakingListBox()
       
  6665     {
       
  6666     AKNTASHOOK_REMOVE();
       
  6667     }
       
  6668 
       
  6669 EXPORT_C CListBoxView* CEikSnakingListBox::MakeViewClassInstanceL() 
       
  6670     {
       
  6671     return (new(ELeave) CSnakingListBoxView);
       
  6672     }
       
  6673 
       
  6674 EXPORT_C TInt CEikSnakingListBox::ColumnWidth() const
       
  6675     {
       
  6676     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  6677     return ((CSnakingListBoxView*)iView)->ColumnWidth();
       
  6678     }
       
  6679 
       
  6680 EXPORT_C void CEikSnakingListBox::SetColumnWidth(TInt aColumnWidth)
       
  6681     {
       
  6682     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  6683     ((CSnakingListBoxView*)iView)->SetColumnWidth(aColumnWidth);
       
  6684     }
       
  6685 
       
  6686 EXPORT_C void CEikSnakingListBox::HandleLeftArrowKeyL(CListBoxView::TSelectionMode aSelectionMode)
       
  6687     {
       
  6688     iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, aSelectionMode);
       
  6689     ClearMatchBuffer();
       
  6690     }
       
  6691 
       
  6692 EXPORT_C void CEikSnakingListBox::HandleRightArrowKeyL(CListBoxView::TSelectionMode aSelectionMode)
       
  6693     {
       
  6694     iView->MoveCursorL(CListBoxView::ECursorNextColumn, aSelectionMode);
       
  6695     ClearMatchBuffer();
       
  6696     }
       
  6697 
       
  6698 EXPORT_C TInt CEikSnakingListBox::HorizontalNudgeValue() const
       
  6699     {
       
  6700     return 1;   // scroll horizontal by one column when the left/right scroll arrows (i.e. the nudge buttons) are tapped
       
  6701     }
       
  6702 
       
  6703 EXPORT_C TInt CEikSnakingListBox::HorizScrollGranularityInPixels() const
       
  6704     {
       
  6705     return ColumnWidth(); // horiz scrollbar model set in columns for snaking list box
       
  6706     }
       
  6707 
       
  6708 EXPORT_C void CEikSnakingListBox::SetTopItemIndex(TInt aItemIndex) const
       
  6709     {
       
  6710     __ASSERT_DEBUG(iView, Panic(EEikPanicListBoxNoView));
       
  6711     iView->SetTopItemIndex(aItemIndex);
       
  6712     }
       
  6713 
       
  6714 EXPORT_C void CEikSnakingListBox::HandleViewRectSizeChangeL()
       
  6715     {
       
  6716     _AKNTRACE_FUNC_ENTER;
       
  6717     iView->CalcBottomItemIndex();
       
  6718     TInt oldTopItemIndex = TopItemIndex();
       
  6719     TInt newTopItemIndex = TopItemIndex();
       
  6720     TInt currentItemIndex = CurrentItemIndex();
       
  6721     TInt numOfItemsPerColumn = 0;   
       
  6722     UpdateScrollBarsL();
       
  6723     numOfItemsPerColumn = iView->ViewRect().Height() / iItemHeight;
       
  6724     numOfItemsPerColumn = Max(1, numOfItemsPerColumn);
       
  6725     if (currentItemIndex != oldTopItemIndex)
       
  6726         {
       
  6727         TInt colIndexOfTargetItem = currentItemIndex / numOfItemsPerColumn;
       
  6728         TInt numOfColsThatFitInViewRect = iView->VisibleWidth(iView->ViewRect());
       
  6729         TInt adjustment = newTopItemIndex % numOfItemsPerColumn;
       
  6730         if (adjustment != 0)
       
  6731             // adjust newTopItemIndex till it refers to the index of an item at the top of a column
       
  6732             newTopItemIndex -= adjustment;
       
  6733         TInt newBottomItemIndex = newTopItemIndex + (numOfColsThatFitInViewRect * numOfItemsPerColumn) - 1;
       
  6734         if (currentItemIndex < newTopItemIndex)
       
  6735             newTopItemIndex = colIndexOfTargetItem * numOfItemsPerColumn;
       
  6736         else if (currentItemIndex > newBottomItemIndex)
       
  6737             {
       
  6738             TInt colIndexOfNewBottomItem = colIndexOfTargetItem;
       
  6739             TInt colIndexOfNewTopItem = colIndexOfNewBottomItem - (numOfColsThatFitInViewRect - 1);
       
  6740             newTopItemIndex = colIndexOfNewTopItem * numOfItemsPerColumn;
       
  6741             }
       
  6742         }
       
  6743     else if ((newTopItemIndex != 0) && (numOfItemsPerColumn != 0))
       
  6744         {
       
  6745         TInt adjustment = newTopItemIndex % numOfItemsPerColumn;
       
  6746         if (adjustment != 0)
       
  6747             // adjust newTopItemIndex till it refers to the index of an item at the top of a column
       
  6748             newTopItemIndex -= adjustment;
       
  6749         }
       
  6750     SetTopItemIndex(newTopItemIndex);
       
  6751     iView->CalcDataWidth();
       
  6752     UpdateScrollBarsL();
       
  6753     iView->CalcBottomItemIndex();
       
  6754     _AKNTRACE_FUNC_EXIT;
       
  6755     }
       
  6756 
       
  6757 EXPORT_C void CEikSnakingListBox::SizeChanged()
       
  6758     {
       
  6759     TRect clientRect = iBorder.InnerRect(Rect());
       
  6760     SetViewRectFromClientRect(clientRect);
       
  6761     TRAP_IGNORE(HandleViewRectSizeChangeL());
       
  6762     }
       
  6763 
       
  6764 EXPORT_C void CEikSnakingListBox::AdjustTopItemIndex() const
       
  6765     {
       
  6766     _AKNTRACE_FUNC_ENTER;
       
  6767     // assumes we know # of items in the model
       
  6768     TInt numOfItemsPerCol = iView->ViewRect().Height() / iItemHeight;
       
  6769     numOfItemsPerCol = Max(1, numOfItemsPerCol);
       
  6770     TInt numOfVisCols = iView->VisibleWidth(iView->ViewRect());
       
  6771     TInt numOfItems = iModel->NumberOfItems();
       
  6772     TInt colIndexOfRightmostCol = numOfItems / numOfItemsPerCol;
       
  6773     TInt maxTopItemIndex = Max (0, (colIndexOfRightmostCol - (numOfVisCols - 1)) * numOfItemsPerCol);
       
  6774     if (iView->TopItemIndex() > maxTopItemIndex)
       
  6775         SetTopItemIndex(maxTopItemIndex);
       
  6776     _AKNTRACE_FUNC_EXIT;
       
  6777     }
       
  6778 
       
  6779 EXPORT_C void CEikSnakingListBox::HandleDragEventL(TPoint aPointerPos)
       
  6780     {
       
  6781     _AKNTRACE_FUNC_ENTER;
       
  6782     if (!(iListBoxFlags & ELeftDownInViewRect))
       
  6783         {
       
  6784         _AKNTRACE_FUNC_EXIT;
       
  6785         return;
       
  6786         }
       
  6787     TRect ignoreDragRect(TPoint(aPointerPos.iX-20, aPointerPos.iY-20), TPoint(aPointerPos.iX+20, aPointerPos.iY+20));
       
  6788     TRect viewRect(iView->ViewRect());
       
  6789     TInt itemIndex;
       
  6790     TBool pointerIsOverAnItem = iView->XYPosToItemIndex(aPointerPos, itemIndex);
       
  6791     // SERIES60 LAF
       
  6792 #if 1 
       
  6793     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  6794 #else
       
  6795     CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection;
       
  6796 #endif
       
  6797     // END OF SERIES60 LAF
       
  6798     TInt oldCurrentItemIndex = iView->CurrentItemIndex();
       
  6799     TRect currentItemRect(iView->ItemPos(oldCurrentItemIndex), iView->ItemSize(oldCurrentItemIndex));
       
  6800     if (pointerIsOverAnItem)
       
  6801         {
       
  6802         // drag event occurred within the listbox
       
  6803         iView->SetCurrentItemIndex(itemIndex);
       
  6804         if (itemIndex != oldCurrentItemIndex) 
       
  6805             {
       
  6806             iView->SetCurrentItemIndex(itemIndex);
       
  6807             iView->DrawItem(oldCurrentItemIndex);
       
  6808             iView->UpdateSelectionL(selectionMode);
       
  6809             iView->DrawItem(itemIndex);
       
  6810             }
       
  6811         }
       
  6812     else if ((aPointerPos.iX < viewRect.iTl.iX) || (aPointerPos.iX > viewRect.iBr.iX))
       
  6813         {
       
  6814         // drag event occurred outside the listbox's viewRect
       
  6815         if (aPointerPos.iX < viewRect.iTl.iX)
       
  6816             iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode);
       
  6817         else if (aPointerPos.iX > viewRect.iBr.iX)
       
  6818             iView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode);
       
  6819         MoveToNextOrPreviousItemL(aPointerPos);     
       
  6820         UpdateScrollBarThumbs();
       
  6821         Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  6822 //      Window().RequestPointerRepeatEvent(ListBoxLaf()->LBxPointerRepeatInterval(), ignoreDragRect);
       
  6823         }
       
  6824     else
       
  6825         {
       
  6826         // find item nearest to the pointer pos and make that the current item
       
  6827         if (viewRect.Contains(aPointerPos))
       
  6828             {
       
  6829             }
       
  6830         else
       
  6831             {
       
  6832             if (aPointerPos.iX > currentItemRect.iBr.iX)
       
  6833                 iView->MoveCursorL(CListBoxView::ECursorNextColumn, selectionMode);
       
  6834             else if (aPointerPos.iX < currentItemRect.iTl.iX)
       
  6835                 iView->MoveCursorL(CListBoxView::ECursorPreviousColumn, selectionMode);
       
  6836             MoveToNextOrPreviousItemL(aPointerPos);
       
  6837             UpdateScrollBarThumbs();
       
  6838             Window().RequestPointerRepeatEvent(KEikListBoxPointerRepeatInterval, ignoreDragRect);
       
  6839 //          Window().RequestPointerRepeatEvent(ListBoxLaf()->LBxPointerRepeatInterval(), ignoreDragRect);
       
  6840             }
       
  6841         }
       
  6842     if (iView->CurrentItemIndex() != oldCurrentItemIndex)
       
  6843         {
       
  6844         iListBoxFlags |= EStateChanged;
       
  6845         if (IsMatchBuffer())
       
  6846             {
       
  6847             ClearMatchBuffer();
       
  6848             DrawMatcherCursor();
       
  6849             }
       
  6850         }
       
  6851     }
       
  6852 
       
  6853 EXPORT_C void CEikSnakingListBox::MoveToNextOrPreviousItemL(TPoint aPointerPos)
       
  6854     {
       
  6855     // AVKON LAF
       
  6856 #if 1
       
  6857     CListBoxView::TSelectionMode selectionMode = CListBoxView::ENoSelection;
       
  6858 #else
       
  6859     CListBoxView::TSelectionMode selectionMode = (iListBoxFlags & EMultipleSelection) ? CListBoxView::EContiguousSelection : CListBoxView::ESingleSelection;
       
  6860 #endif
       
  6861     // END OF AVKON LAF
       
  6862     TInt cix = iView->CurrentItemIndex();
       
  6863     TRect currentItemRect(iView->ItemPos(cix), iView->ItemSize(cix));
       
  6864     TInt numOfRows =  ((CSnakingListBoxView*)iView)->NumberOfItemsPerColumn();
       
  6865     TBool currItemIsInLastRow = ((cix % numOfRows) == (numOfRows-1));
       
  6866     TBool currItemIsLastItem = (cix == (iModel->NumberOfItems()-1));
       
  6867     TBool currItemIsInFirstRow = ((cix % numOfRows) == 0);
       
  6868     if ((aPointerPos.iY > currentItemRect.iBr.iY) && (! (currItemIsInLastRow || currItemIsLastItem)))
       
  6869         iView->MoveCursorL(CListBoxView::ECursorNextItem, selectionMode);
       
  6870     else if ((aPointerPos.iY < currentItemRect.iTl.iY) && (! currItemIsInFirstRow))
       
  6871         iView->MoveCursorL(CListBoxView::ECursorPreviousItem, selectionMode);
       
  6872     _AKNTRACE_FUNC_EXIT;
       
  6873     }
       
  6874 
       
  6875 EXPORT_C void CEikSnakingListBox::RestoreClientRectFromViewRect(TRect& aClientRect) const
       
  6876     {
       
  6877     aClientRect=iView->ViewRect();
       
  6878     aClientRect.SetRect(aClientRect.iTl.iX - ListBoxMargins().iLeft, aClientRect.iTl.iY - ListBoxMargins().iTop,
       
  6879         aClientRect.iBr.iX + ListBoxMargins().iRight, aClientRect.iBr.iY + ListBoxMargins().iBottom);
       
  6880     if (!ViewRectHeightAdjustment())
       
  6881         return;
       
  6882     aClientRect.iBr.iY += ViewRectHeightAdjustment();
       
  6883     }
       
  6884 
       
  6885 EXPORT_C TInt CEikSnakingListBox::AdjustRectHeightToWholeNumberOfItems(TRect& aRect) const
       
  6886     {
       
  6887     TInt remainder = aRect.Height() % iItemHeight;
       
  6888     if (remainder != 0) 
       
  6889         aRect.iBr.iY -= remainder;
       
  6890     return remainder;
       
  6891     }
       
  6892 
       
  6893 /**
       
  6894  * Gets the list of logical colors employed in the drawing of the control,
       
  6895  * paired with an explanation of how they are used. Appends the list to aColorUseList.
       
  6896  *
       
  6897  * @since ER5U 
       
  6898  */
       
  6899 EXPORT_C void CEikSnakingListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& /*aColorUseList*/) const
       
  6900     {
       
  6901     }
       
  6902 
       
  6903 /**
       
  6904  * Handles a change to the control's resources of type aType
       
  6905  * which are shared across the environment, e.g. colors or fonts.
       
  6906  *
       
  6907  * @since ER5U 
       
  6908  */
       
  6909 EXPORT_C void CEikSnakingListBox::HandleResourceChange(TInt aType)
       
  6910     {
       
  6911     CCoeControl::HandleResourceChange(aType);
       
  6912     }
       
  6913 
       
  6914 EXPORT_C void CEikSnakingListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent) 
       
  6915     { 
       
  6916     CEikListBox::HandlePointerEventL(aPointerEvent); 
       
  6917     }
       
  6918 
       
  6919 EXPORT_C void* CEikSnakingListBox::ExtensionInterface( TUid /*aInterface*/ )
       
  6920     {
       
  6921     return NULL;
       
  6922     }
       
  6923 
       
  6924 EXPORT_C void CEikSnakingListBox::Reserved_1()
       
  6925     {}
       
  6926 
       
  6927 EXPORT_C void CEikSnakingListBox::Reserved_2()
       
  6928     {}
       
  6929 
       
  6930 EXPORT_C void CEikSnakingListBox::CEikListBox_Reserved()
       
  6931     {}