/*
* 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