phonebookui/Phonebook2/UIControls/src/CPbk2ContactViewListBox.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 85 38bb213f60ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2ContactViewListBox.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,797 @@
+/*
+* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Phonebook 2 contact view list box.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbk2ContactViewListBox.h"
+
+// Phonebook 2
+#include "MPbk2ContactViewListBoxModel.h"
+#include "CPbk2IconArray.h"
+#include "MPbk2NamesListState.h"
+#include "cpbk2contactviewdoublelistboxmodel.h"
+#include <CPbk2UIExtensionManager.h>
+#include <MPbk2UIExtensionIconSupport.h>
+#include <MPbk2UIExtensionFactory.h>
+#include <MPbk2ContactUiControlExtension.h>
+#include "CPbk2ListboxModelCmdDecorator.h"
+#include <CPbk2ContactIconsUtils.h>
+#include <Pbk2UIControls.hrh>
+
+// Virtual Phonebook
+#include <CVPbkContactManager.h>
+
+// System includes
+#include <barsread.h>
+#include <eikclbd.h>
+
+#include <aknappui.h>
+#include <aknViewAppUi.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+#include <featmgr.h>
+
+#include <skinlayout.cdl.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include "cpbk2contactviewcustomlistboxitemdrawer.h"
+#include "cpbk2contactviewcustomlistboxdata.h"
+#include "CPbk2NamesListControl.h"
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL FUNCTIONS
+
+_LIT( KTabChar, "\t" );
+const TInt KCheckboxMargin = 1; // Checkbox margin pixels
+
+/**
+ * Returns icon array from given list box.
+ *
+ * @param aListBox  List box.
+ * @return  Icon array in Phonebook 2 format.
+ */
+inline CPbk2IconArray* IconArray( CEikColumnListBox& aListBox )
+    {
+    return static_cast<CPbk2IconArray*>(
+        aListBox.ItemDrawer()->ColumnData()->IconArray() );
+    }
+
+/**
+ * Sets given icon array as given listbox's icon array.
+ *
+ * @param aListBox      List box.
+ * @param aIconArray    Icon array.
+ */
+inline void SetIconArray( CEikColumnListBox& aListBox,
+        CPbk2IconArray* aIconArray )
+    {
+    aListBox.ItemDrawer()->ColumnData()->SetIconArray( aIconArray );
+    }
+
+#ifdef _DEBUG
+enum TPanicCode
+    {
+    EPanicPreCond_CreateListBoxModelL = 1
+    };
+
+void Panic(TInt aReason)
+    {
+    _LIT(KPanicText, "CPbk2ContactViewListBox");
+    User::Panic(KPanicText, aReason);
+    }
+#endif // _DEBUG
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::CPbk2ContactViewListBox
+// --------------------------------------------------------------------------
+//
+CPbk2ContactViewListBox::CPbk2ContactViewListBox
+            (   CCoeControl& aContainer,
+                MPbk2ContactUiControlExtension* aUiExtension,
+                CPbk2PredictiveSearchFilter &aSearchFilter ) :
+                iContainer(aContainer), 
+                iChangedIndexes( 1 ), // allocation granularity
+                iUiExtension( aUiExtension ),
+                iSearchFilter( aSearchFilter ),
+                iMarkingModeOn( EFalse )
+    {
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::~CPbk2ContactViewListBox
+// --------------------------------------------------------------------------
+//
+CPbk2ContactViewListBox::~CPbk2ContactViewListBox()
+    {
+    delete iListboxModelDecorator;
+    delete iModel;
+    FeatureManager::UnInitializeLib();
+    CCoeEnv::Static()->RemoveForegroundObserver( *this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::ConstructL(
+        CCoeControl& aContainer, TResourceReader& aResourceReader,
+        const CVPbkContactManager& aManager, MVPbkContactViewBase& aView,
+        MPbk2ContactNameFormatter& aNameFormatter,
+        CPbk2StorePropertyArray& aStoreProperties )
+    {
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2ContactViewListBox::ConstructL"));
+
+    FeatureManager::InitializeLibL();
+
+    // Preallocate space for the one required integer
+    iChangedIndexes.AppendL( KErrNotFound );
+
+    // Read flags from resources
+    iResourceData.iFlags = aResourceReader.ReadUint32();    // flags
+
+    SetContainerWindowL( aContainer );
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2ContactViewListBox::ConstructL about to resource construct"));
+
+    // Let Avkon read it's share of the resources
+    ConstructFromResourceL( aResourceReader );
+
+    // Remove the platform default "No data" text
+    View()->SetListEmptyTextL( KNullDesC );
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2ContactViewListBox::ConstructL about to create icon array"));
+
+    CPbk2IconArray* iconArray =
+        CPbk2ContactIconsUtils::CreateListboxIconArrayL(
+                aResourceReader.ReadInt32());
+
+    SetIconArray( *this, iconArray );
+
+    iResourceData.iEmptyIconId =
+        TPbk2IconId( aResourceReader ); // empty icon
+    iResourceData.iDefaultIconId =
+        TPbk2IconId( aResourceReader ); // default icon
+
+    CreateScrollBarFrameL( ETrue );
+    ScrollBarFrame()->SetScrollBarVisibilityL(
+        CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+
+    MakeVisible( EFalse );
+
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2ContactViewListBox::ConstructL about to create model"));
+
+    CreateListBoxModelL( aManager, aView,
+        aNameFormatter, aStoreProperties );
+    
+    CCoeEnv::Static()->AddForegroundObserverL( *this );
+    PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+        ("CPbk2ContactViewListBox::ConstructL end"));
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2ContactViewListBox* CPbk2ContactViewListBox::NewL(
+        CCoeControl& aContainer, TResourceReader& aResourceReader,
+        const CVPbkContactManager& aManager, MVPbkContactViewBase& aView,
+        MPbk2ContactNameFormatter& aNameFormatter,
+        CPbk2StorePropertyArray& aStoreProperties,
+        MPbk2ContactUiControlExtension* aUiExtension,
+        CPbk2PredictiveSearchFilter &aSearchFilter )
+    {
+    CPbk2ContactViewListBox* self =
+        new ( ELeave ) CPbk2ContactViewListBox( aContainer, aUiExtension, aSearchFilter );
+    CleanupStack::PushL( self );
+    self->ConstructL( aContainer, aResourceReader, aManager,
+        aView, aNameFormatter, aStoreProperties );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::NumberOfItems
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactViewListBox::NumberOfItems() const
+    {
+    TInt result = 0;
+    if ( iListboxModelDecorator )
+        {
+        result = iListboxModelDecorator->MdcaCount();
+        }
+    return result;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::ContactsMarked
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::ContactsMarked() const
+    {
+    const CListBoxView::CSelectionIndexArray* selections =
+        View()->SelectionIndexes();
+    TBool notEmpty = selections && selections->Count() > 0;
+    TBool containsContacts = EFalse;
+    for (TInt n = 0; notEmpty && n < selections->Count() && !containsContacts; ++n )
+        {
+        const TInt index = selections->At( n );
+        // The item is either a contact or a command.
+        containsContacts = IsContact( index );
+        }
+    return containsContacts;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandleContactViewEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandleEventL
+        ( TInt aEvent, TInt aIndex )
+    {
+    switch ( aEvent )
+        {
+        case MPbk2NamesListState::EItemAdded:
+            {
+            iChangedIndexes[0] = aIndex;
+            HandleItemAdditionL( iChangedIndexes );
+            break;
+            }
+        case MPbk2NamesListState::EItemRemoved:
+            {
+            // Deselect item
+            CListBoxView& listBoxView = *View();
+            listBoxView.SetDisableRedraw( ETrue );
+            listBoxView.DeselectItem( aIndex );
+            listBoxView.SetDisableRedraw( EFalse );
+
+            TInt focusIndex = CurrentItemIndex();
+            TInt topIndex = TopItemIndex();
+            iChangedIndexes[0] = aIndex;
+            HandleItemRemovalL( iChangedIndexes );
+
+            // The deduction of 1 is for adapting with the different bases
+            const TInt lastIndex = Model()->NumberOfItems() - 1;
+            if ( lastIndex == KErrNotFound )
+                {
+                Reset();
+                }
+            else
+                {
+                if ( aIndex < focusIndex )
+                    {
+                    // If item was removed above focused item, maintain
+                    // focus by moving it up by one
+                    --focusIndex;
+                    }
+                if ( focusIndex > lastIndex || focusIndex < 0 )
+                    {
+                    focusIndex = lastIndex;
+                    }
+                const TInt numVisibleItems =
+                    View()->NumberOfItemsThatFitInRect(
+                        View()->ViewRect() );
+                if ( topIndex + numVisibleItems > lastIndex )
+                    {
+                    topIndex = Max( lastIndex - numVisibleItems + 1, 0 );
+                    }
+                if ( topIndex >= 0 )
+                    {
+                    SetTopItemIndex( topIndex );
+                    }
+                if ( focusIndex >= 0 )
+                    {
+                    SetCurrentItemIndex( focusIndex );
+                    }
+                }
+            break;
+            }
+        default:
+            {
+            // Do nothing
+            break;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::FixTopItemIndex
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::FixTopItemIndex()
+    {
+    TInt index = TopItemIndex();
+    const TInt height = View()->NumberOfItemsThatFitInRect(
+        View()->ViewRect() );
+    const TInt numItems = Model()->NumberOfItems();
+    if ( index + height > numItems )
+        {
+        index += numItems - ( height + index );
+        if ( index < 0 )
+            {
+            index = 0;
+            }
+        if ( index != TopItemIndex() )
+            {
+            SetTopItemIndex( index );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::CheckFocusIndex
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::CheckFocusIndex()
+    {
+    if ( CurrentItemIndex() == KErrNotFound )
+        {
+        SetCurrentItemIndex( 0 );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandlePointerEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandlePointerEventL
+        ( const TPointerEvent& aPointerEvent )
+    {
+    TInt oldIndex = CurrentItemIndex();
+
+    // Base class handles the pointer event
+    CAknSingleGraphicStyleListBox::HandlePointerEventL( aPointerEvent );
+
+    switch( aPointerEvent.iType )
+        {
+        case TPointerEvent::EButton1Down:
+            {
+            TInt pointedItemIndex;
+            iFocusableContactPointed = View()->XYPosToItemIndex(
+                aPointerEvent.iPosition, pointedItemIndex );
+            
+            //no prior focus needed
+            iFocusedContactPointed = iFocusableContactPointed;
+            break;
+            }
+        default:
+            {
+            // Do nothing
+            break;
+            }
+        };
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::Flags
+// --------------------------------------------------------------------------
+//
+TUint CPbk2ContactViewListBox::Flags() const
+    {
+    return iResourceData.iFlags;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::SetScrollEventObserver
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::SetScrollEventObserver(MEikScrollBarObserver* aObserver)
+    {
+    iScrollEventObserver = aObserver;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::IsSelectionListBox
+// This function is non const because IsMultiselection is non const.
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::IsSelectionListBox()
+    {
+    // Try firs the CEikListBox method for multiselection
+    TBool result = IsMultiselection();
+
+    if ( !result )
+        {
+        // Then try other flags
+        TUint32 markableFlags =
+            EAknListBoxStylusMarkableList |
+            EAknListBoxStylusMultiselectionList |
+            EAknListBoxMarkableList |
+            EAknListBoxMultiselectionList;
+
+        // Compare CEikListBox flags to Avkon markable list flags
+        result = iListBoxFlags & markableFlags;
+        }
+    return result;
+    }
+
+void CPbk2ContactViewListBox::SetListCommands(
+    const RPointerArray<MPbk2UiControlCmdItem>* aCommands )
+    {
+    iListboxModelDecorator->SetListCommands( aCommands );
+    if( iColumnData )
+        {
+        iColumnData->SetListCommands( aCommands );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::ClipFromBeginning
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::ClipFromBeginning
+        ( TDes& aBuffer, TInt aItemIndex, TInt aSubCellNumber )
+    {
+    CColumnListBoxData *data = ItemDrawer()->ColumnData();
+    const CFont *font =
+        data->Font(ItemDrawer()->Properties(aItemIndex), aSubCellNumber);
+    // The width of the subcell displaying the characters.
+    TInt cellWidth = data->ColumnWidthPixel(aSubCellNumber);
+    // The margin of the subcell.
+    TMargins margin = data->ColumnMargins(aSubCellNumber);
+    // The valid width width displaying the characters.
+    TInt width = cellWidth - margin.iLeft - margin.iRight;
+    // If Marking mode is active, recalculate the valid width displaying characters.
+    // contact entry of name list view in marking mode
+    //
+    // |checkbox|Icon|name  |
+    // |        |    |number|
+    if( iMarkingModeOn )
+        {
+        RecalcWidthInMarkingMode(width, *font, aBuffer[0]);
+        }
+    TInt clipGap = data->ColumnTextClipGap(aSubCellNumber);
+    
+    return AknTextUtils::ClipToFit(
+        aBuffer, *font, width, AknTextUtils::EClipFromBeginning, width + clipGap);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::FocusedItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::FocusedItemPointed()
+    {
+    return iFocusedContactPointed;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::FocusableItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::FocusableItemPointed()
+    {
+    return iFocusableContactPointed;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::SearchFieldPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::SearchFieldPointed()
+    {
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandleScrollEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandleScrollEventL(CEikScrollBar* aScrollBar, TEikScrollEvent aEventType)
+    {   
+    // Handle showing of popupcharacter when user scrolls list using using scroll bar
+    TBool prevState = iShowPopupChar;
+
+    iShowPopupChar = ( aEventType == EEikScrollThumbDragHoriz || aEventType == EEikScrollThumbDragVert );
+    
+    if( prevState != iShowPopupChar )
+        {
+        DrawDeferred();
+        }
+
+    CAknSingleGraphicStyleListBox::HandleScrollEventL( aScrollBar, aEventType );
+    if( iScrollEventObserver )
+        {
+        iScrollEventObserver->HandleScrollEventL( aScrollBar, aEventType );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::CreateListBoxModelL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::CreateListBoxModelL
+        ( const CVPbkContactManager& aManager, MVPbkContactViewBase& aView,
+        MPbk2ContactNameFormatter& aNameFormatter,
+        CPbk2StorePropertyArray& aStoreProperties )
+    {
+    __ASSERT_DEBUG( !iModel && !iListboxModelDecorator,
+        Panic( EPanicPreCond_CreateListBoxModelL ) );
+
+    // Set up listbox model
+    CPbk2ContactViewListBoxModel::TParams params;
+    params.iContactManager = &aManager;
+    params.iView = &aView;
+    params.iStoreProperties = &aStoreProperties;
+    params.iNameFormatter = &aNameFormatter;
+    params.iIconArray = IconArray( *this );
+    params.iEmptyId = iResourceData.iEmptyIconId;
+    params.iDefaultId = iResourceData.iDefaultIconId;
+    params.iClipListBoxText = this;
+    params.iUiExtension = iUiExtension;
+    params.iMultiselection = IsMultiselection();
+    CPbk2ContactViewListBoxModel* model = DoCreateModelL( params );
+    model->SetUnnamedText( iResourceData.iUnnamedText );
+    iModel = model;
+
+    if( iColumnData )
+        {
+        iColumnData->SetDataModel( iModel );
+        }
+    // Wrap the original model.
+    iListboxModelDecorator = DoCreateDecoratorL( 
+            *IconArray( *this ),
+            iResourceData.iEmptyIconId,
+            iResourceData.iDefaultIconId );
+    
+    
+    iListboxModelDecorator->SetDecoratedModel( *iModel );
+    Model()->SetItemTextArray( iListboxModelDecorator );
+    Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::DoCreateModelL
+// --------------------------------------------------------------------------
+//
+CPbk2ContactViewListBoxModel* CPbk2ContactViewListBox::DoCreateModelL(
+                CPbk2ContactViewListBoxModel::TParams params )
+    {
+    return CPbk2ContactViewListBoxModel::NewL( params );
+    }
+
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::DoCreateDecoratorL
+// --------------------------------------------------------------------------
+//
+CPbk2ListboxModelCmdDecorator* CPbk2ContactViewListBox::DoCreateDecoratorL( 
+                const CPbk2IconArray& aIconArray,
+                TPbk2IconId aEmptyIconId,
+                TPbk2IconId aDefaultIconId )
+    {
+    return CPbk2ListboxModelCmdDecorator::NewL(
+                aIconArray,
+                aEmptyIconId,
+                aDefaultIconId );
+    }
+
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::IsContact
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactViewListBox::IsContact( TInt aIndex ) const
+    {
+    // The command items are always at the top of the list.
+    return aIndex >= iListboxModelDecorator->NumberOfEnabledCommands();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::Draw
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::Draw( const TRect& aRect ) const
+    {
+    CAknSingleGraphicStyleListBox::Draw(aRect);
+    HandlePopupCharacter(NULL, Rect());
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::CreateItemDrawerL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::CreateItemDrawerL()
+    {
+    // Use custom drawer only if predictive search is enabled
+    if( FeatureManager::FeatureSupported(KFeatureIdFfContactsPredictiveSearch) )
+        {
+        CPbk2ContactViewCustomListBoxData* columnData =
+                        CPbk2ContactViewCustomListBoxData::NewL( iSearchFilter );
+    
+        CleanupStack::PushL( columnData );
+    
+        iItemDrawer=new(ELeave) CPbk2ContactViewCustomListBoxItemDrawer(
+                static_cast<MTextListBoxModel*>(Model()), iCoeEnv->NormalFont(),
+                columnData);
+        CleanupStack::Pop( columnData );
+    
+        //Ownership has been transferred to iItemDrawer
+        iColumnData = columnData;
+        }
+    else
+        {
+        CAknSingleGraphicStyleListBox::CreateItemDrawerL();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandleGainingForeground
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandleGainingForeground()
+    {
+    DrawDeferred();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandleLosingForeground
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandleLosingForeground()
+    {
+    if ( iShowPopupChar )
+        {
+        //Simulate an EButton1Up event to force a DrawDeferred() calling
+        //in case of the scrollbar¡¯s at the background that can¡¯t receive the EButton1Up event.
+        TPointerEvent PointEvent;
+        PointEvent.iType = TPointerEvent::EButton1Up ;
+        TRAP_IGNORE( ScrollBarFrame()->VerticalScrollBar()->HandlePointerEventL( PointEvent ) );
+        DrawDeferred();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::HandlePopupCharacter
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::HandlePopupCharacter( CWindowGc* aGc, const TRect& aRectOfListBoxItem ) const
+    {
+    CPbk2NamesListControl& listControl = static_cast<CPbk2NamesListControl&>(iContainer);
+    TInt itemIndex = TopItemIndex() - listControl.CommandItemCount();
+   
+    // itemIndex >= 0 filter out command item
+    if ( itemIndex >= 0 && iShowPopupChar )
+        {
+        TAknLayoutRect layout;
+        layout.LayoutRect(Rect(), AknLayoutScalable_Apps::popup_navstr_preview_pane(0));
+        
+        if (!layout.Rect().Intersects(aRectOfListBoxItem))
+            {
+            // If the rect of PopupCharacter not overlapped
+            // with aRectOfListBoxItem, do nothing.
+            return;
+            }
+
+        // Handle showing of popupcharacter when user scrolls list using using scroll bar
+        CWindowGc* gc = aGc;
+        if (!gc)
+            {
+            gc = &SystemGc();
+            }
+
+        TRgb normal;
+        AknsUtils::GetCachedColor(AknsUtils::SkinInstance(),
+                normal,
+                KAknsIIDQsnTextColors,
+                EAknsCIQsnTextColorsCG6 );
+
+        TAknLayoutRect cornerRect;
+        // skinned draw uses submenu popup window skin (skinned border)
+        cornerRect.LayoutRect(
+            layout.Rect(),
+            SkinLayout::Submenu_skin_placing_Line_2() );
+
+        TRect innerRect( layout.Rect() );
+        innerRect.Shrink( cornerRect.Rect().Width(), cornerRect.Rect().Height() );
+
+        if ( !AknsDrawUtils::DrawFrame(
+                AknsUtils::SkinInstance(),
+                *gc,
+                layout.Rect(),
+                innerRect,
+                KAknsIIDQsnFrPopupSub,
+                KAknsIIDQsnFrPopupCenterSubmenu ) )
+            {
+            // skinned border failed -> black border
+            gc->SetPenStyle( CGraphicsContext::ESolidPen );
+            gc->SetBrushColor( KRgbBlack );
+            gc->DrawRect( layout.Rect() );
+            }
+
+        TAknLayoutText textLayout;
+        textLayout.LayoutText(layout.Rect(), AknLayoutScalable_Apps::popup_navstr_preview_pane_t1(0).LayoutLine());
+
+        TPtrC desc(Model()->ItemTextArray()->MdcaPoint(View()->TopItemIndex()));
+        
+        //Add "if-clause" to avaid the error that argument of Mid() out of range.
+        TInt index = desc.Find( KTabChar );
+        if ( index != KErrNotFound && index < desc.Length()-1 )
+            {
+            HBufC* buf = desc.Mid( index + 1, 1 ).AllocL();           
+
+            TPtr textPtr = buf->Des();
+            textPtr.UpperCase();
+
+            textLayout.DrawText( *gc, textPtr, ETrue, normal );
+
+            delete buf;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactViewListBox::RecalcWidthInMarkingMode
+// Recalculate the width of space displaying the third column of the schema
+// below when Marking Mode is active.
+// contact entry of name list view in marking mode
+// The schema:
+// |checkbox|Icon|name  |
+// |        |    |number|
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactViewListBox::RecalcWidthInMarkingMode(
+                              TInt& aWidth,
+                              const CFont& aFont,
+                              TChar aChar )
+    {
+    if( aWidth > 0 )
+        {
+        aWidth -= KCheckboxMargin;
+        // Get the coordinate for the right margin of the checkbox.
+        TInt checkBoxRight = AknLayoutScalable_Avkon::list_single_graphic_pane_t1( 0 ).r();
+        // Get the coordinate for the left margin of the checkbox.
+        TInt checkBoxLeft = AknLayoutScalable_Avkon::list_single_graphic_pane_t1( 0 ).l();
+        // The width to display one char.
+        TInt charWidth = aFont.CharWidthInPixels(aChar);
+        TInt checkBoxWidth = checkBoxRight - checkBoxLeft;
+        if( 0 > checkBoxWidth )
+            {
+            checkBoxWidth *= -1; // To make sure the value is positive.
+            }
+        if( charWidth > 0 && checkBoxWidth > 0 )
+            {
+            // The width of the characters which should be dropped, when marking
+            // mode is active.
+            TInt width;
+            if( 0 == checkBoxWidth%charWidth )
+                {
+                width = checkBoxWidth;
+                }
+            else
+                {
+                // The width should be divisible by charWidth.
+                width = ( checkBoxWidth/charWidth + 1 ) * charWidth;
+                }
+            // When marking mode is on,
+            // the width should minus the part of checkbox in the front of
+            // a listbox item.
+            aWidth -= width;
+            }
+        }
+    }
+
+// End of File