--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuilderpluginextension/src/cesmrncspopuplistbox.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,848 @@
+/*
+* Copyright (c) 2007-2009 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: Definition of the class CESMRNcsPopupListBox
+*
+*/
+
+#include "emailtrace.h"
+#include "cesmrncspopuplistbox.h"
+
+#include <eikclbd.h>
+#include <AknsLayeredBackgroundControlContext.h>
+#include <StringLoader.h> // StringLoader
+#include <ct/rcpointerarray.h>
+
+//text truncation
+#include <AknBidiTextUtils.h>//line wrapping and mirroring
+#include <aknlayoutscalable_apps.cdl.h> //xml layout data for applications
+#include <aknlayoutscalable_avkon.cdl.h> //xml layout data of avkon components
+
+#include <esmrgui.rsg>
+
+#include "cesmrncsemailaddressobject.h"
+#include "cesmrcontacthandler.h"
+#include "cesmrlayoutmgr.h"
+
+namespace { // codescanner::namespace
+const TInt KItemExtraHeight = 8;
+const TInt KEdge (8);
+const TInt KScrollbarWidth (6);
+const TInt KListBoxDrawMargin (4);
+//drop down list colors since we have no official LAF
+#define KWhite TRgb( 255,255,255 )
+#define KGraySelectable TRgb( 30,30,30 )
+#define KGrayNoEmail TRgb( 215,215,215 )
+#define KGrayBackground TRgb( 140,140,140 )
+#define KSelectorFallbackColor TRgb( 0,200,200 )
+}
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::NewL
+// -----------------------------------------------------------------------------
+//
+CESMRNcsPopupListBox* CESMRNcsPopupListBox::NewL( const CCoeControl* aParent,
+ CESMRContactHandler& aContactHandler )
+ {
+ FUNC_LOG;
+ CESMRNcsPopupListBox* self = new (ELeave) CESMRNcsPopupListBox( aContactHandler );
+ CleanupStack::PushL(self);
+ self->ConstructL( aParent );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::CESMRNcsPopupListBox
+// -----------------------------------------------------------------------------
+//
+CESMRNcsPopupListBox::CESMRNcsPopupListBox( CESMRContactHandler& aContactHandler )
+ :
+ iContactHandler( aContactHandler )
+ {
+ FUNC_LOG;
+ //do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::ConstructL( const CCoeControl* aParent )
+ {
+ FUNC_LOG;
+ CEikTextListBox::ConstructL( aParent, CEikListBox::EPopout );
+
+ CEikTextListBox::SetBorder( TGulBorder::EWithOutline|
+ TGulBorder::EAddTwoPixels|
+ TGulBorder::EAddOneRoundingPixel );
+
+ CreateScrollBarFrameL();
+
+ const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
+ CEikTextListBox::SetItemHeightL( font->HeightInPixels() + KItemExtraHeight );
+
+ iBaseBackroundContext = CAknsBasicBackgroundControlContext::NewL(
+ KAknsIIDQgnFsGrafEmailContent,
+ Rect(),
+ EFalse );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::InitAndSearchL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::InitAndSearchL( const TDesC& aText )
+ {
+ FUNC_LOG;
+ RCPointerArray<CESMRClsItem> matchingArray; // Empty array
+ CleanupClosePushL( matchingArray );
+ SetSearchTextL( aText );
+ OperationCompleteL( ESearchContacts, &matchingArray );
+ CleanupStack::PopAndDestroy( &matchingArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRNcsPopupListBox::~CESMRNcsPopupListBox
+// ---------------------------------------------------------------------------
+//
+CESMRNcsPopupListBox::~CESMRNcsPopupListBox()
+ {
+ FUNC_LOG;
+ delete iBaseBackroundContext;
+ iMatchingArray.ResetAndDestroy();
+
+ delete iItemTextsArray;
+ delete iCurrentSearchText;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::CreateItemDrawerL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::CreateItemDrawerL()
+ {
+ FUNC_LOG;
+ CESMRNcsListItemDrawer* drawer = new (ELeave) CESMRNcsListItemDrawer( *this );
+ iItemDrawer = drawer;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::MopSupplyObject
+// -----------------------------------------------------------------------------
+//
+TTypeUid::Ptr CESMRNcsPopupListBox::MopSupplyObject(TTypeUid aId)
+ {
+ FUNC_LOG;
+ if ( aId.iUid == MAknsControlContext::ETypeId )
+ {
+ return MAknsControlContext::SupplyMopObject( aId, iBaseBackroundContext );
+ }
+ return CCoeControl::MopSupplyObject( aId );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SizeChanged
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SizeChanged()
+ {
+ FUNC_LOG;
+ CEikTextListBox::SizeChanged();
+ iBaseBackroundContext->SetRect( Rect() );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CESMRNcsPopupListBox::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ FUNC_LOG;
+ TKeyResponse ret( EKeyWasNotConsumed );
+ if( aKeyEvent.iCode == EKeyDownArrow )
+ {
+ MoveRemoteLookupItemL( ERemoteLookupItemDown );
+ iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection );
+ ret = EKeyWasConsumed;
+ }
+ else if( aKeyEvent.iCode == EKeyUpArrow )
+ {
+ TBool stay = EFalse;
+ // Move cursor separator line over
+ if( CurrentItemIndex() - 1 > 0 && CurrentItemIndex() - 1 == iRMLUItemPosition )
+ {
+ MoveRemoteLookupItemL( ERemoteLookupItemUp );
+ iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection );
+ stay = ETrue;
+ }
+
+ MoveRemoteLookupItemL( ERemoteLookupItemUp );
+ iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection );
+ if( stay )
+ {
+ MoveRemoteLookupItemL( ERemoteLookupItemDown );
+
+ iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection );
+ }
+
+
+ ret = EKeyWasConsumed;
+ }
+
+ if( ret == EKeyWasNotConsumed )
+ {
+ ret = CEikListBox::OfferKeyEventL( aKeyEvent, aType );
+ }
+ // call HandleItemAdditionL just in case. There might be changes on remote lookup item place.
+ // The call is here, because we don't want to have extra redraw events when the popuplist
+ // is not fully updated.
+ HandleItemAdditionL();
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRNcsPopupListBox::OperationCompleteL
+// ---------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::OperationCompleteL(
+ TContactHandlerCmd /*aCmd*/,
+ const RPointerArray<CESMRClsItem>* aMatchingItems )
+ {
+ FUNC_LOG;
+ if ( aMatchingItems )
+ {
+ iMatchingArray.ResetAndDestroy();
+ // Replace old matcing items.
+
+ for ( TInt ii = 0; ii < aMatchingItems->Count(); ++ii )
+ {
+ if ( (*aMatchingItems)[ii] )
+ {
+ CESMRClsItem* item = (*aMatchingItems)[ii]->CloneLC();
+ iMatchingArray.AppendL( item );
+ CleanupStack::Pop( item );
+ }
+ }
+ SetListItemsFromArrayL();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRNcsPopupListBox::OperationErrorL
+// ---------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::OperationErrorL( TContactHandlerCmd /*aCmd*/,
+ TInt /*aError*/ )
+ {
+ FUNC_LOG;
+ //no errors handled here
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SetSearchTextL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SetSearchTextL( const TDesC& aText )
+ {
+ FUNC_LOG;
+ delete iCurrentSearchText;
+ iCurrentSearchText = NULL; // to remove code scanner warning
+ iCurrentSearchText = aText.AllocL();
+ iContactHandler.SearchMatchesL( aText, this );
+
+ if(!iRemoteLookupSupported)
+ {
+ iRemoteLookupSupported = iContactHandler.RemoteLookupSupportedL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::ReturnCurrentEmailAddressLC
+// -----------------------------------------------------------------------------
+//
+CESMRNcsEmailAddressObject* CESMRNcsPopupListBox::ReturnCurrentEmailAddressLC()
+ {
+ FUNC_LOG;
+ CESMRNcsEmailAddressObject* addressObject = NULL;
+
+ if( iMatchingArray.Count() > 0 )
+ {
+ CESMRClsItem* clsItem = NULL;
+ if( iRemoteLookupSupported )
+ {
+ clsItem =iMatchingArray[CurrentItemIndex()-1]; // -1 because of iRMLUItemPosition
+ }
+ else
+ {
+ clsItem =iMatchingArray[CurrentItemIndex()]; // no iRMLUItemPosition
+ }
+ addressObject= CESMRNcsEmailAddressObject::NewL( clsItem->DisplayName(), clsItem->EmailAddress() );
+ CleanupStack::PushL( addressObject );
+ if ( clsItem->MultipleEmails() )
+ {
+ addressObject->SetDisplayFull( ETrue );
+ }
+ }
+
+ return addressObject;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SetPopupMaxRectL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SetPopupMaxRectL( const TRect& aPopupMaxRect )
+ {
+ FUNC_LOG;
+ iPopupMaxRect = aPopupMaxRect;
+ SetPopupHeightL();
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::IsPopupEmpty
+// -----------------------------------------------------------------------------
+//
+TBool CESMRNcsPopupListBox::IsPopupEmpty() const
+ {
+ FUNC_LOG;
+ if( Model()->NumberOfItems() > 0 )
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::IsRemoteLookupItemSelected
+// -----------------------------------------------------------------------------
+//
+TBool CESMRNcsPopupListBox::IsRemoteLookupItemSelected() const
+ {
+ FUNC_LOG;
+ if( CurrentItemIndex() == iRMLUItemPosition && iRemoteLookupSupported )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::CurrentPopupClsItemsArray
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CESMRClsItem>& CESMRNcsPopupListBox::CurrentPopupClsItemsArray() const
+ {
+ return iMatchingArray;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::RMLUItemPosition
+// -----------------------------------------------------------------------------
+//
+TInt CESMRNcsPopupListBox::RMLUItemPosition() const
+ {
+ FUNC_LOG;
+ return iRMLUItemPosition;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SetListItemsFromArrayL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SetListItemsFromArrayL()
+ {
+ FUNC_LOG;
+ // Create totally new text array
+ Reset();
+ CreateTextArrayAndSetToTheListboxL();
+
+ // append texts to text array
+ for( TInt i=0; i < iMatchingArray.Count(); i++ )
+ {
+ iItemTextsArray->AppendL( iMatchingArray[i]->FullTextL() );
+ }
+
+ // Update rmlu item
+ SetRemoteLookupItemFirstToTheListL();
+
+ HandleItemAdditionL();
+
+ if( iItemTextsArray && iItemTextsArray->Count() > 0 )
+ {
+ SetCurrentItemIndex( 0 );
+ }
+
+ if ( Observer() )
+ {
+ Observer()->HandleControlEventL( this,
+ MCoeControlObserver::EEventStateChanged );
+ }
+
+ if( IsVisible() )
+ {
+ SetPopupHeightL();
+ DrawDeferred();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SetPopupHeightL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SetPopupHeightL()
+ {
+ FUNC_LOG;
+ TInt totalHeight = CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() );
+ TRect rect = iPopupMaxRect;
+
+ ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn );
+
+ //shrink listbox if less than max area needed to show items
+ if( rect.Height() >= totalHeight )
+ {
+ ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff );
+
+ //latch listbox on top of the editorfield
+ TRect fieldArea = Parent()->Rect();
+
+ if ( rect.iBr.iY < fieldArea.iBr.iY )
+ {
+ rect.Move(0, (rect.Height() - totalHeight) );
+ }
+
+ rect.SetHeight( totalHeight );
+ }
+
+ UpdateScrollBarsL();
+ SetRect( rect );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::SetRemoteLookupItemFirstToTheListL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::SetRemoteLookupItemFirstToTheListL()
+ {
+ FUNC_LOG;
+ if( iRemoteLookupSupported )
+ {
+ HBufC* rmluText = StringLoader::LoadLC( R_MEET_REQ_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
+
+ iItemTextsArray->InsertL( 0, *rmluText );
+ CleanupStack::PopAndDestroy( rmluText );
+ iRMLUItemPosition = 0;
+ }
+ else
+ {
+ iRMLUItemPosition = -1;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::MoveRemoteLookupItemL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::MoveRemoteLookupItemL( TRemoteLookupItemMoveDirection aDirection )
+ {
+ FUNC_LOG;
+ if( iRemoteLookupSupported )
+ {
+ TInt newRMLUItemIndex = -1;
+ TInt newCurrentItem = -1;
+ if( aDirection == ERemoteLookupItemUp &&
+ iView->CurrentItemIndex() == iView->TopItemIndex() )
+ {
+ newRMLUItemIndex = iRMLUItemPosition - 1;
+ newCurrentItem = CurrentItemIndex() - 1;
+ }
+ else if( aDirection == ERemoteLookupItemDown &&
+ iView->CurrentItemIndex() == iView->BottomItemIndex() )
+ {
+ newRMLUItemIndex = iRMLUItemPosition + 1;
+ newCurrentItem = CurrentItemIndex() + 1;
+ }
+
+
+ if( ItemExists ( newCurrentItem ) )
+ {
+ iItemTextsArray->Delete( iRMLUItemPosition );
+
+ HBufC* rmluText = StringLoader::LoadLC( R_MEET_REQ_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
+
+ iItemTextsArray->InsertL( newRMLUItemIndex, *rmluText );
+ CleanupStack::PopAndDestroy( rmluText );
+ iRMLUItemPosition = newRMLUItemIndex;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::CreateTextArrayAndSetToTheListboxL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::CreateTextArrayAndSetToTheListboxL()
+ {
+ FUNC_LOG;
+ if( iItemTextsArray )
+ {
+ delete iItemTextsArray;
+ iItemTextsArray = NULL;
+ }
+
+ const TInt KItemTextArrayLen = 8;
+
+ if( !iItemTextsArray )
+ {
+ iItemTextsArray = new ( ELeave ) CDesCArraySeg( KItemTextArrayLen );
+ // Set the popup list data
+ Model()->SetItemTextArray( iItemTextsArray );
+ Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsPopupListBox::InitialiseL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsPopupListBox::Initialise(CESMRLayoutManager* aLayout)
+ {
+ FUNC_LOG;
+ static_cast<CESMRNcsListItemDrawer*>( iItemDrawer )->SetLayoutManager(aLayout);
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsListItemDrawer::CESMRNcsListItemDrawer
+// -----------------------------------------------------------------------------
+//
+CESMRNcsListItemDrawer::CESMRNcsListItemDrawer( CESMRNcsPopupListBox& aListBox )
+:CListItemDrawer(),
+iListBox(aListBox)
+ {
+ FUNC_LOG;
+ // Store a GC for later use
+ iGc = &CCoeEnv::Static()->SystemGc();
+ SetGc(iGc);
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsListItemDrawer::DrawActualItemL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsListItemDrawer::DrawActualItem( TInt aItemIndex,
+ const TRect& aActualItemRect, TBool aItemIsCurrent,
+ TBool aViewIsEmphasized, TBool aViewIsDimmed,
+ TBool aItemIsSelected ) const
+ {
+ FUNC_LOG;
+ TRAP_IGNORE( DoDrawActualItemL( aItemIndex,
+ aActualItemRect,
+ aItemIsCurrent,
+ aViewIsEmphasized,
+ aViewIsDimmed,
+ aItemIsSelected ) )
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsListItemDrawer::SetLayoutManager
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsListItemDrawer::SetLayoutManager(CESMRLayoutManager* aLayout)
+ {
+ FUNC_LOG;
+ iLayout = aLayout;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsListItemDrawer::DoDrawActualItemL
+// -----------------------------------------------------------------------------
+//
+void CESMRNcsListItemDrawer::DoDrawActualItemL( TInt aItemIndex,
+ const TRect& aActualItemRect, TBool aItemIsCurrent,
+ TBool /*aViewIsEmphasized*/, TBool /*aViewIsDimmed*/,
+ TBool /*aItemIsSelected*/ ) const
+ {
+ FUNC_LOG;
+ // Get reference to curren popup cls item list.
+ const RPointerArray<CESMRClsItem>& clsItemArray = iListBox.CurrentPopupClsItemsArray();
+ TInt rmluPosition = iListBox.RMLUItemPosition();
+
+ // Sets all the attributes, like font, text color and background color.
+ const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
+ iGc->UseFont(font);
+
+ // We have to draw the item in layered fashion in order to do the skin
+ // First clear the backround by drawing a solid rect.
+ iGc->SetPenColor( KGrayBackground );
+ iGc->SetBrushColor( KGrayBackground );
+ iGc->SetPenStyle(CGraphicsContext::ESolidPen);
+ iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+
+ // Now draw the highlight
+ if( aItemIsCurrent )
+ {
+ if (iLayout)
+ {
+ CFbsBitmap* selector = NULL;
+ CFbsBitmap* selectorMask = NULL;
+
+ // highlight bitmap target rect:
+ TRect rect( aActualItemRect );
+
+ TSize corner(KEdge, KEdge);
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListCornerTl, selector, selectorMask, corner );
+
+ //adjust selector size for if scrollbar is on screen
+ if (iListBox.ScrollBarFrame()->ScrollBarVisibility(CEikScrollBar::EVertical) ==
+ CEikScrollBarFrame::EOn)
+ {
+ rect.SetWidth( (rect.Width() - KScrollbarWidth) );
+ }
+
+ if( selector && selectorMask)
+ {
+ //corner TL
+ iGc->BitBltMasked(
+ rect.iTl, selector, corner, selectorMask, EFalse );
+
+ //side L
+ TSize side(KEdge, (rect.Height() - 2 * KEdge) );
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListSideL, selector, selectorMask, side );
+ iGc->BitBltMasked( TPoint(rect.iTl.iX, rect.iTl.iY + KEdge),
+ selector, side, selectorMask, EFalse );
+
+ //corner BL
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListCornerBl, selector, selectorMask, corner );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX, rect.iTl.iY + KEdge + side.iHeight),
+ selector, corner, selectorMask, EFalse );
+
+ //top
+ TSize top( (rect.Width() - 2 * KEdge) , KEdge);
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListSideT, selector, selectorMask, top );
+ iGc->BitBltMasked( TPoint(rect.iTl.iX + KEdge, rect.iTl.iY),
+ selector, top, selectorMask, EFalse );
+
+ //center
+ TSize center( top.iWidth, side.iHeight);
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListCenter, selector, selectorMask, center );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX + KEdge, rect.iTl.iY + KEdge),
+ selector, center, selectorMask, EFalse );
+
+ //bottom
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListSideB, selector, selectorMask, top );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX + KEdge, rect.iTl.iY + side.iHeight + KEdge),
+ selector, top, selectorMask, EFalse );
+
+ //corner TR
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListCornerTr, selector, selectorMask, corner );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX + KEdge + top.iWidth, rect.iTl.iY),
+ selector, corner, selectorMask, EFalse );
+
+ //side R
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListSideR, selector, selectorMask, side );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX + KEdge + top.iWidth, rect.iTl.iY + KEdge),
+ selector, side, selectorMask, EFalse );
+
+ //corner Br
+ iLayout->GetSkinBasedBitmap(
+ KAknsIIDQgnFsListCornerBr, selector, selectorMask, corner );
+ iGc->BitBltMasked(
+ TPoint(rect.iTl.iX + KEdge + top.iWidth,
+ rect.iTl.iY + KEdge + side.iHeight),
+ selector, corner, selectorMask, EFalse );
+ }
+ else
+ {
+ iGc->SetBrushColor( KSelectorFallbackColor );
+ }
+
+ delete selector;
+ delete selectorMask;
+ }
+ else
+ {
+ iGc->SetBrushColor( KSelectorFallbackColor );
+ }
+ }
+ else
+ {
+ iGc->DrawRect(aActualItemRect);
+ }
+
+ if(aItemIsCurrent)
+ {
+ iGc->SetPenColor( KWhite );
+ }
+ else
+ {
+ iGc->SetPenColor( KGraySelectable );
+ }
+
+ iGc->SetPenStyle(CGraphicsContext::ESolidPen);
+ iGc->SetBrushStyle(CGraphicsContext::ENullBrush);
+ TInt topToBaseline = ( aActualItemRect.Height() - font->HeightInPixels() ) / 2
+ + font->AscentInPixels();
+
+ TPtrC itemText = iListBox.Model()->ItemText( aItemIndex );
+
+ // Construct bidirectional text object
+ TBidiText* bidiText = TBidiText::NewL( itemText, 1 );
+ CleanupStack::PushL( bidiText );
+ bidiText->WrapText( aActualItemRect.Width(), *font, NULL );
+ TPoint leftBase = aActualItemRect.iTl + TPoint( 0, topToBaseline );
+ leftBase.iX += KListBoxDrawMargin;
+
+ // check if we are drawing remote lookup item or contact match
+ if ( rmluPosition == aItemIndex )
+ {
+ iGc->SetUnderlineStyle( EUnderlineOff );
+ bidiText->DrawText( *iGc, leftBase );
+ }
+ else
+ {
+ // if list has rmlu item change item index right
+ if ( rmluPosition >= 0 )
+ {
+ --aItemIndex;
+ aItemIndex = Max( 0, aItemIndex );
+ }
+
+ // change color to gray if match doesn't have email address.
+ if ( clsItemArray[aItemIndex]->EmailAddress().Compare( KNullDesC ) == 0 )
+ {
+ iGc->SetPenColor( KGrayNoEmail );
+ iGc->SetBrushColor( KGrayNoEmail );
+ }
+
+ // We know the text contains RTL script if the display string is not just
+ // truncated version of the original string.
+ TPtrC dispText = bidiText->DisplayText();
+ TInt compLength = dispText.Length() - 1; // -1 to omit the truncation character
+ TBool textContainsRtl =
+ ( itemText.Left(compLength) != dispText.Left(compLength) );
+
+ const RArray<TPsMatchLocation>& underlines = clsItemArray[aItemIndex]->Highlights();
+
+ if ( underlines.Count() > 0 && !textContainsRtl )
+ {
+ TInt i = 0;
+ TBool partsLeft = ETrue;
+ TInt currentTextStart = 0;
+ TInt currentTextLength = 0;
+
+ while ( partsLeft )
+ {
+ if ( currentTextStart < underlines[i].index )
+ {
+ // draw letters to the start of the underlined part
+ currentTextLength = underlines[i].index - currentTextStart;
+ DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText,
+ EFalse, topToBaseline );
+ }
+ else if ( currentTextStart == underlines[i].index )
+ {
+ // draw underlined letters
+ currentTextLength = underlines[i].length;
+
+ DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText,
+ ETrue, topToBaseline );
+ i++;
+ }
+ else
+ {
+ // This is here, because PCS Engine might give you duplicate match entries,
+ // in this case we're not advancing text but we'll skip that match
+ currentTextLength = 0;
+ i++;
+ }
+ // update text start point
+ currentTextStart += currentTextLength;
+
+ if ( i >= underlines.Count() )
+ {
+ partsLeft = EFalse;
+ // draw rest of the letters, if there are any after the last underlined part
+ if ( currentTextStart < itemText.Length() )
+ {
+ currentTextLength = itemText.Length() - currentTextStart;
+ DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText,
+ EFalse, topToBaseline );
+ }
+ }
+ }
+ }
+ else
+ {
+ iGc->SetUnderlineStyle( EUnderlineOff );
+ bidiText->DrawText( *iGc, leftBase );
+ }
+ }
+ CleanupStack::PopAndDestroy( bidiText );
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRNcsListItemDrawer::DrawPartOfItem
+// -----------------------------------------------------------------------------
+void CESMRNcsListItemDrawer::DrawPartOfItem( const TRect& aItemRect, const CFont& aFont,
+ TInt aStartPos, TInt aLength, const TDesC& aDes,
+ TBool aUnderlined, TInt aBaselineOffsetFromTop ) const
+ {
+ FUNC_LOG;
+ if( aUnderlined )
+ {
+ iGc->SetUnderlineStyle( EUnderlineOn );
+ }
+ else
+ {
+ iGc->SetUnderlineStyle( EUnderlineOff );
+ }
+ TRect currentTextRect( aItemRect );
+ TInt pixels = aFont.TextWidthInPixels( aDes.Left( aStartPos ) );
+ currentTextRect.iTl.iX = currentTextRect.iTl.iX + pixels + KListBoxDrawMargin;
+
+ //adjust selector size for if scrollbar is on screen
+ if (iListBox.ScrollBarFrame()->ScrollBarVisibility(CEikScrollBar::EVertical) ==
+ CEikScrollBarFrame::EOn)
+ {
+ currentTextRect.iBr.iX = currentTextRect.iBr.iX - KListBoxDrawMargin - KScrollbarWidth;
+ }
+ else
+ {
+ currentTextRect.iBr.iX = currentTextRect.iBr.iX - KListBoxDrawMargin;
+ }
+
+ iGc->DrawText( aDes.Mid( aStartPos, aLength ), currentTextRect, aBaselineOffsetFromTop );
+
+ }
+
+
+
+// End of File
+