emailuis/emailui/src/ncspopuplistbox.cpp
branchRCL_3
changeset 64 3533d4323edc
child 73 c8382f7b54ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncspopuplistbox.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,934 @@
+/*
+* Copyright (c) 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: This file implements classes CNcsPopupListBox, CNcsListItemDrawer. 
+*
+*/
+
+
+// INCLUDE FILES
+#include "emailtrace.h"
+#include <eikclbd.h>
+#include <AknsFrameBackgroundControlContext.h>
+#include <FreestyleEmailUi.rsg>						// R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH
+#include <StringLoader.h>						// StringLoader
+#include <CPbkContactEngine.h>
+#include <AknsDrawUtils.h>
+#include <AknsUtils.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+#include "ncspopuplistbox.h"
+#include "ncsemailaddressobject.h"					// CNcsEmailAddressObject
+#include "ncsconstants.h"
+#include "ncsheadercontainer.h"						// CNcsHeaderContainer
+#include "FreestyleEmailUiContactHandler.h"		// CFSEmailUiClsListsHandler
+#include "ncsutility.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "FreestyleEmailUiAppui.h"
+#include "FreestyleEmailUiLayoutHandler.h"
+#include "FSDelayedLoader.h"
+#include "FreestyleEmailUiCLSItem.h"
+
+const TInt KHighlightFrameWidth = 2;
+
+// ========================= MEMBER FUNCTIONS ==================================
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::NewL
+// -----------------------------------------------------------------------------
+CNcsPopupListBox* CNcsPopupListBox::NewL( const CCoeControl* aParent, 
+                                          CFSMailBox& aMailBox, 
+                                          CNcsHeaderContainer& aHeaderContainer, 
+                                          TBool aRemoteLookupSupported  )
+    {
+    FUNC_LOG;
+    CNcsPopupListBox* self =  new (ELeave) CNcsPopupListBox( aHeaderContainer,
+        aRemoteLookupSupported, aMailBox );
+    CleanupStack::PushL( self );
+    self->ConstructL( aParent );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::CNcsPopupListBox
+// -----------------------------------------------------------------------------
+CNcsPopupListBox::CNcsPopupListBox( CNcsHeaderContainer& aHeaderContainer, 
+                                    TBool aRemoteLookupSupported, 
+                                    CFSMailBox& aMailBox)
+    : iHeaderContainer( aHeaderContainer ),
+      iMailBox( aMailBox ),
+      iRemoteLookupSupported( aRemoteLookupSupported ),
+      iCachingInProgress( EFalse ),
+      iAppUi( static_cast<CFreestyleEmailUiAppUi*>( iEikonEnv->AppUi() ) )
+    {
+    FUNC_LOG;
+    iPopupMaxRect = TRect( 100, 100, 100, 100 );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::ConstructL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::ConstructL( const CCoeControl* aParent )
+    {
+    FUNC_LOG;
+    CEikTextListBox::ConstructL( NULL, CEikListBox::EPopout );
+    SetMopParent( const_cast<CCoeControl*>( aParent ) );
+    User::LeaveIfError( SetParent( const_cast<CCoeControl*>( aParent ) ) );
+
+    CEikScrollBarFrame* frame = CreateScrollBarFrameL( EFalse, EFalse, ETrue );
+
+    CEikTextListBox::SetBorder( TGulBorder::ENone );
+
+    const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
+    CEikTextListBox::SetItemHeightL( font->FontMaxHeight() + 12 );
+
+    iBackgroundContext = CAknsFrameBackgroundControlContext::NewL(
+        KAknsIIDQsnFrPopupSub, Rect(), Rect(), EFalse );
+    UpdateTextColors();
+
+    iContactHandler = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
+    if ( !iContactHandler->IsLanguageSupportedL() )
+        {
+        iContactHandler = NULL;
+        }
+
+    SetListBoxObserver( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::InitAndSearchL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::InitAndSearchL( const TDesC& aText, TInt aMode )
+    {
+    FUNC_LOG;
+    SetSearchTextL( aText, aMode );
+    RPointerArray<CFSEmailUiClsItem> emptyArray;
+    CleanupClosePushL( emptyArray );
+    OperationCompleteL( ESearchContacts, emptyArray );
+    CleanupStack::PopAndDestroy( &emptyArray );
+    }
+
+// ---------------------------------------------------------------------------
+// CNcsPopupListBox::~CNcsPopupListBox
+// ---------------------------------------------------------------------------
+CNcsPopupListBox::~CNcsPopupListBox()
+    {
+    FUNC_LOG;
+    delete iBackgroundContext;
+    delete iItemTextsArray;
+    delete iCurrentSearchText;
+    iMatchingItems.ResetAndDestroy();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::CreateItemDrawerL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::CreateItemDrawerL()
+    {
+    FUNC_LOG;
+    iItemDrawer = new (ELeave) CNcsListItemDrawer( *this );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::MopSupplyObject
+// -----------------------------------------------------------------------------
+TTypeUid::Ptr CNcsPopupListBox::MopSupplyObject(TTypeUid aId)
+    {
+    FUNC_LOG;
+    if ( aId.iUid == MAknsControlContext::ETypeId )
+        {
+        return MAknsControlContext::SupplyMopObject( aId, iBackgroundContext );
+        }
+    return CCoeControl::MopSupplyObject( aId );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SizeChanged
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SizeChanged()
+    {
+    FUNC_LOG;
+    const TRect outerRect = Rect();
+
+    TAknLayoutRect subpane;
+    subpane.LayoutRect( outerRect, 
+        AknLayoutScalable_Avkon::bg_popup_sub_pane_g1() );
+    const TRect innerRect = subpane.Rect();
+
+    iBackgroundContext->SetFrameRects( outerRect, innerRect );
+
+    SetViewRectFromClientRect( innerRect );
+    TRAP_IGNORE( HandleViewRectSizeChangeL() );
+    }
+
+void CNcsPopupListBox::HandleResourceChange( TInt aType )
+    {
+    FUNC_LOG;
+    if ( aType == KAknsMessageSkinChange )
+        {
+        UpdateTextColors();
+        }
+    }
+
+void CNcsPopupListBox::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    CEikTextListBox::HandlePointerEventL( aPointerEvent );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//    
+TKeyResponse CNcsPopupListBox::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 == iRemoteLookupItemPos )
+			{
+	        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;
+    }
+
+// ---------------------------------------------------------------------------
+// CNcsPopupListBox::HandleListBoxEventL
+// ---------------------------------------------------------------------------
+//      
+void CNcsPopupListBox::HandleListBoxEventL( CEikListBox* /*aListBox*/,
+    TListBoxEvent aEventType )
+    {
+    if ( aEventType == EEventItemClicked || 
+         aEventType == EEventItemSingleClicked )
+        {
+        iHeaderContainer.DoPopupSelectL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::OperationComplete
+// -----------------------------------------------------------------------------
+//
+void CNcsPopupListBox::OperationCompleteL( TContactHandlerCmd /*aCmd*/,
+    const RPointerArray<CFSEmailUiClsItem>& aMatchingItems )
+    {
+    FUNC_LOG;
+    iMatchingItems.ResetAndDestroy();
+    // Replace old matcing items.
+
+    for ( TInt ii = 0; ii < aMatchingItems.Count(); ++ii )
+    	{
+    	if ( aMatchingItems[ii] )
+    		{
+    		CFSEmailUiClsItem* item = aMatchingItems[ii]->CloneLC();  		
+    		iMatchingItems.AppendL( item );
+    		CleanupStack::Pop( item );
+    		}
+    	}
+    
+    UpdateListL();
+    }
+
+void CNcsPopupListBox::OperationErrorL( TContactHandlerCmd aCmd, TInt aError )
+	{
+    FUNC_LOG;
+	
+	if ( aCmd == ESearchContacts )
+		{
+		// KerrNotReady --> caching in progress, KErrNotFound --> caching not started yet
+		if ( (aError == KErrNotReady) || (aError == KErrNotFound) )
+			{
+			if(!iAppUi->AppUiExitOngoing()) //<cmail>
+			    TFsEmailUiUtility::ShowInfoNoteL( R_FSE_EDITOR_INFO_BUILDING_CACHE );
+			iCachingInProgress = ETrue;
+			}
+		if ( aError == KErrNone && iCachingInProgress )
+			{
+			if(!iAppUi->AppUiExitOngoing()) //<cmail>
+			    TFsEmailUiUtility::ShowInfoNoteL( R_FSE_EDITOR_INFO_CACHING_COMPLETED );
+			iCachingInProgress = EFalse;
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetSearchTextL
+// -----------------------------------------------------------------------------
+//
+void CNcsPopupListBox::SetSearchTextL( const TDesC& aText, TInt aMode )
+    {
+    FUNC_LOG;
+    delete iCurrentSearchText;
+    iCurrentSearchText = NULL;
+    iCurrentSearchText = aText.AllocL();
+    if ( !iCachingInProgress  )
+        {
+        if ( iContactHandler  )
+            {
+            iContactHandler->SearchMatchesL( aText, this, &iMailBox, aMode );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::ReturnCurrentEmailAddressLC
+// -----------------------------------------------------------------------------
+//
+CNcsEmailAddressObject* CNcsPopupListBox::ReturnCurrentEmailAddressLC()
+    {
+    FUNC_LOG;
+    CNcsEmailAddressObject* addressObject = NULL;
+
+    if ( iMatchingItems.Count() )
+        {
+        CFSEmailUiClsItem* clsItem = NULL;
+        if ( iRemoteLookupSupported )
+            {
+            // calculate index of item
+            TInt index = (CurrentItemIndex() > iRemoteLookupItemPos ? CurrentItemIndex() - 1 : CurrentItemIndex());
+            clsItem = iMatchingItems[index];
+            }
+        else
+            {
+            clsItem = iMatchingItems[CurrentItemIndex()]; // no iRemoteLookupItemPos
+            }
+
+        addressObject= CNcsEmailAddressObject::NewL( clsItem->DisplayName(), clsItem->EmailAddress() );
+        CleanupStack::PushL( addressObject );
+        if ( clsItem->MultipleEmails() )
+            {
+            addressObject->SetDisplayFull( ETrue );
+            }
+        }
+
+    return addressObject;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetPopupMaxRect
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SetPopupMaxRect( const TRect& aPopupMaxRect )
+    {
+    FUNC_LOG;
+    iPopupMaxRect = aPopupMaxRect;
+
+    SetPopupRect();
+    TRAP_IGNORE( UpdateScrollBarsL() );
+    TRAP_IGNORE( SetScrollBarVisibilityL() );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::IsPopupEmpty
+// -----------------------------------------------------------------------------
+TBool CNcsPopupListBox::IsPopupEmpty() const
+    {
+    FUNC_LOG;
+    if ( Model()->NumberOfItems() > 0 )
+        return EFalse;
+    else
+        return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::IsRemoteLookupItemSelected
+// -----------------------------------------------------------------------------
+TBool CNcsPopupListBox::IsRemoteLookupItemSelected() const
+    {
+    FUNC_LOG;
+    if ( CurrentItemIndex() == iRemoteLookupItemPos && iRemoteLookupSupported )
+        return ETrue;
+    else
+        return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::CurrentPopupClsItemsArray
+// -----------------------------------------------------------------------------
+const RPointerArray<CFSEmailUiClsItem>& CNcsPopupListBox::CurrentPopupClsItemsArray() const
+    {
+    return iMatchingItems;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::RemoteLookupItemPos
+// -----------------------------------------------------------------------------
+TInt CNcsPopupListBox::RemoteLookupItemPos() const
+    {
+    FUNC_LOG;
+    return iRemoteLookupItemPos;
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::LayoutHandler
+// -----------------------------------------------------------------------------
+CFSEmailUiLayoutHandler& CNcsPopupListBox::LayoutHandler() const
+    {
+    FUNC_LOG;
+    return *iAppUi->LayoutHandler();
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetListItemsFromArrayL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SetListItemsFromArrayL()
+	{
+    FUNC_LOG;
+	// reset the cursor to point to the first item
+    //iView->MoveCursorL( CListBoxView::ECursorFirstItem, CListBoxView::ENoSelection);
+	Reset();
+	
+	// Create totally new text array
+	CreateTextArrayAndSetToTheListboxL( ETrue );
+
+	// append texts to text array
+	for( TInt i=0; i < iMatchingItems.Count(); i++ )
+		{
+		iItemTextsArray->AppendL( iMatchingItems[i]->FullTextL() );
+		}
+
+	// Update rmlu item
+	SetRemoteLookupItemFirstToTheListL();
+	
+	SetPopupRect();
+	SetScrollBarVisibilityL();
+	HandleItemAdditionL();
+
+    if ( iItemTextsArray && iItemTextsArray->Count() > 0 )
+        {
+        SetCurrentItemIndex( 0 );
+        }
+
+    if ( IsVisible() )
+        {
+        DrawDeferred();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::RoundToItemHeight
+// -----------------------------------------------------------------------------
+TInt CNcsPopupListBox::RoundToItemHeight(const TInt aPopupHeight) const
+    {
+    TReal fullItems; // number of full visible items in window
+    TInt err = Math::Round(fullItems, (aPopupHeight / ItemHeight()), 0);
+    if (err == KErrNone)
+        {
+        return (TInt)(fullItems * ItemHeight()); 
+        }
+    return aPopupHeight; // in case of error
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetPopupRect
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SetPopupRect()
+    {
+    FUNC_LOG;
+    // The popup width and horizontal position is adjusted so that it
+    // will be within the area specified in both layout data and the set
+    // maximum rect.
+    TAknLayoutRect editorPane;
+    editorPane.LayoutRect( iAppUi->ClientRect(),
+        TAknWindowComponentLayout::Compose(
+            TAknWindowComponentLayout::Compose(
+                AknLayoutScalable_Apps::list_cmail_pane(),
+                AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0 ) ),
+            AknLayoutScalable_Apps::list_single_cmail_header_editor_pane_bg( 4 ) ) );
+    TRect editorPaneRect = editorPane.Rect();
+
+    TRect newRect = iPopupMaxRect;
+    newRect.iTl.iX = Max( iPopupMaxRect.iTl.iX, editorPaneRect.iTl.iX );
+    newRect.iBr.iX = Min( iPopupMaxRect.iBr.iX, editorPaneRect.iBr.iX );
+
+    // Thhe popup height and vertical position is adjusted based on the
+    // available space below and above the cursor and the number of items
+    // in the list.
+    const TRect rect = iPopupMaxRect;
+    TAknLayoutRect subpane;
+    subpane.LayoutRect( rect, AknLayoutScalable_Avkon::bg_popup_sub_pane_g1() );
+    const TRect subpaneRect = subpane.Rect();
+
+    const TInt frameHeights = iPopupMaxRect.Height() - subpaneRect.Height();
+
+    // This is the total height in pixels needed to show all items
+    TInt minimumHeight = frameHeights + 
+        CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() );
+
+    CCoeControl* container = Parent()->Parent();
+    TInt containerTop = container->PositionRelativeToScreen().iY;
+    TInt containerHeight = container->Rect().Height();
+    TInt containerCenter = containerTop + containerHeight / 2;
+
+    // Get height of one line in Address field
+    CNcsHeaderContainer* headerObj = static_cast<CNcsHeaderContainer* >(Parent());
+    TInt toLineHeight = headerObj->GetToLineHeight(); // height of one line height
+    if ( toLineHeight == 0 )
+        {
+        toLineHeight = ItemHeight();
+        }
+
+    TInt newHeight = minimumHeight; // default window height
+
+    // latch listbox on the bottom of the editor field
+    if ( newRect.iTl.iY <= containerCenter ) 
+        {
+        TInt maxHeight = containerHeight - ( newRect.iTl.iY - containerTop ); 
+        newHeight = RoundToItemHeight( maxHeight - frameHeights ) + frameHeights;
+        if ( newHeight > minimumHeight )
+            {
+            newHeight = minimumHeight; // shrink window (if needed)
+            }
+        }
+    // latch listbox on the top of the editor field
+    else
+        {
+        TInt yOffset = -minimumHeight - toLineHeight; // how much up
+        TInt newTlY = newRect.iTl.iY + yOffset;       // new Top Left Y coordinate
+        if ( newTlY >= containerTop )
+            {
+            newRect.Move( 0, yOffset );
+            }
+        else
+            {
+            // shrink height to visible area and move
+            TInt maxHeight = newRect.iTl.iY - toLineHeight - containerTop;
+            newHeight = RoundToItemHeight( maxHeight - frameHeights ) + frameHeights;
+            newRect.Move( 0, -newHeight - toLineHeight );
+            }
+        }
+    newRect.SetHeight( newHeight ); // set new height
+    SetRect( newRect );
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetScrollBarVisibilityL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SetScrollBarVisibilityL()
+	{
+    FUNC_LOG;
+	// This is the total height in pixels needed to show all items
+	TInt minimumHeight = CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() );
+
+	// Show scroll bar if there is more items we can show at once.
+	if( iPopupMaxRect.Height() > minimumHeight ) 
+		{
+		ScrollBarFrame()->SetScrollBarVisibilityL(
+			CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff ); 
+		}
+	else 
+		{
+		ScrollBarFrame()->SetScrollBarVisibilityL(
+			CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn ); 
+		}
+	}
+
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::SetRemoteLookupItemFirstToTheListL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::SetRemoteLookupItemFirstToTheListL()
+	{
+    FUNC_LOG;
+	if( iRemoteLookupSupported )
+		{
+		HBufC* rmluText = StringLoader::LoadLC( 
+		    R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
+		
+		iItemTextsArray->InsertL( 0, *rmluText );
+		CleanupStack::PopAndDestroy( rmluText );
+		iRemoteLookupItemPos = 0;
+		}
+	else
+		{
+		iRemoteLookupItemPos = -1;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::MoveRemoteLookupItemL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::MoveRemoteLookupItemL( TRemoteLookupItemMoveDirection aDirection )
+	{
+    FUNC_LOG;
+	if( iRemoteLookupSupported )
+		{
+		TInt newRMLUItemIndex = -1;
+		TInt newCurrentItem = -1;
+		if( aDirection == ERemoteLookupItemUp &&
+			 iView->CurrentItemIndex() == iView->TopItemIndex() )
+			{
+			newRMLUItemIndex = iRemoteLookupItemPos - 1;
+			newCurrentItem = CurrentItemIndex() - 1;
+			}
+		else if( aDirection == ERemoteLookupItemDown &&
+				 iView->CurrentItemIndex() == iView->BottomItemIndex() )
+			{
+			newRMLUItemIndex = iRemoteLookupItemPos + 1;
+			newCurrentItem = CurrentItemIndex() + 1;
+			}
+
+
+		if( ItemExists ( newCurrentItem ) && newRMLUItemIndex != -1 )
+			{
+			iItemTextsArray->Delete( iRemoteLookupItemPos );
+
+			HBufC* rmluText = StringLoader::LoadLC( R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
+			
+			iItemTextsArray->InsertL( newRMLUItemIndex, *rmluText );
+			CleanupStack::PopAndDestroy( rmluText );
+			iRemoteLookupItemPos = newRMLUItemIndex;
+			}
+		}
+	}
+
+
+// -----------------------------------------------------------------------------
+// CNcsPopupListBox::CreateTextArrayAndSetToTheListboxL
+// -----------------------------------------------------------------------------
+void CNcsPopupListBox::CreateTextArrayAndSetToTheListboxL( const TBool& aResetIfExists )
+	{
+    FUNC_LOG;
+	if( !iItemTextsArray )
+		{
+		iItemTextsArray = new ( ELeave ) CDesCArraySeg( 8 );
+		// Set the popup list data
+		Model()->SetItemTextArray( iItemTextsArray );
+		Model()->SetOwnershipType( ELbmDoesNotOwnItemArray  );
+		}
+		
+	if( aResetIfExists )
+		{
+		delete iItemTextsArray;
+		iItemTextsArray = NULL;
+		CreateTextArrayAndSetToTheListboxL( EFalse );
+		}
+	}
+
+
+// -----------------------------------------------------------------------------
+// CNcsListItemDrawer::CNcsListItemDrawer
+// -----------------------------------------------------------------------------
+CNcsListItemDrawer::CNcsListItemDrawer( const CNcsPopupListBox& aListBox )
+:CListItemDrawer(), iListBox( aListBox )
+    {
+    FUNC_LOG;
+    // Store a GC for later use
+    iGc = &CCoeEnv::Static()->SystemGc();
+    SetGc(iGc);
+    }
+
+// -----------------------------------------------------------------------------
+// CNcsListItemDrawer::DrawActualItem
+// -----------------------------------------------------------------------------
+void CNcsListItemDrawer::DrawActualItem(TInt aItemIndex,
+    const TRect& aActualItemRect, TBool aItemIsCurrent,
+    TBool /*aViewIsEmphasized*/, TBool /*aViewIsDimmed*/,
+    TBool /*aItemIsSelected*/) const
+    {
+    FUNC_LOG;
+    iGc->DiscardFont();
+
+    // Get reference to curren popup cls item list.
+    const RPointerArray<CFSEmailUiClsItem>& clsItemArray =
+        iListBox.CurrentPopupClsItemsArray();
+    TInt rmluPosition = iListBox.RemoteLookupItemPos();
+
+    // Sets all the attributes, like font, text color and background color.
+    const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
+    iGc->UseFont( font );
+    iGc->SetPenStyle( CGraphicsContext::ESolidPen );
+    iGc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+    TRect itemRect = aActualItemRect;
+    { 
+    // temporary const_cast to get the scrollbar width
+    CNcsPopupListBox& tmpListBox = const_cast<CNcsPopupListBox&>( iListBox );
+    const TInt scrollbarBreadth = tmpListBox.ScrollBarFrame()->
+        ScrollBarBreadth( CEikScrollBar::EVertical );
+    if ( scrollbarBreadth > 0 )
+        {
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            itemRect.iTl.iX = iListBox.Rect().iTl.iX + scrollbarBreadth;
+            }
+        else
+            {
+            itemRect.iBr.iX = iListBox.Rect().iBr.iX - scrollbarBreadth;
+            }
+        }
+    }
+
+    TRect textRect = itemRect;
+    textRect.Shrink( KHighlightFrameWidth, KHighlightFrameWidth );
+
+    // Get skin instance.
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+    // Draw background using the control context from the list box.
+    MAknsControlContext* cc = AknsDrawUtils::ControlContext( &iListBox );
+    if ( cc )
+        {
+        AknsDrawUtils::Background( skin, cc, *iGc, aActualItemRect );
+        }
+    else
+        {
+        iGc->Clear( aActualItemRect );
+        }
+
+    // Draw the highlight, when necessary.
+    if ( aItemIsCurrent ) 
+        {
+        AknsDrawUtils::DrawFrame( skin, *iGc, itemRect, textRect,
+            KAknsIIDQsnFrList, KAknsIIDQsnFrListCenter );
+        }
+
+    // Get text color.
+    TRgb textColor = TextColor();
+    if ( aItemIsCurrent )
+        {
+        textColor = HighlightedTextColor();
+        }
+
+    iGc->SetPenColor( textColor );
+    TInt topToBaseline = ( textRect.Height() - font->FontMaxHeight() ) / 2
+        + font->FontMaxAscent();
+
+    TPtrC itemText = iListBox.Model()->ItemText( aItemIndex );
+
+	// Construct bidirectional text object
+	// <cmail> Removed leave from non-leaving function.
+	TBidiText* bidiText = NULL;
+	TRAPD( err, bidiText = TBidiText::NewL( itemText, 1 ) );
+	if ( err == KErrNone )
+		{
+		bidiText->WrapText( textRect.Width(), *font, NULL );
+		}
+		
+	TPoint leftBase = textRect.iTl + TPoint( 0, topToBaseline );
+
+    if ( err != KErrNone )
+        {
+        bidiText = NULL; // to be on the safe side
+        }
+
+	// check if we are drawing remote lookup item or contact match
+	else if ( rmluPosition == aItemIndex )
+		{
+		iGc->SetUnderlineStyle( EUnderlineOff );
+		bidiText->DrawText( *iGc, leftBase );
+		}
+	else
+		{
+		// if list has rmlu item change item index right
+		if ( rmluPosition >= 0 && aItemIndex > rmluPosition )
+			{
+			aItemIndex--;
+			}
+
+    // Change text transparency if match doesn't have email address.
+    if ( clsItemArray[aItemIndex]->EmailAddress().Compare( KNullDesC ) == 0 )
+        {
+        const TInt KTransparency = 
+            iListBox.LayoutHandler().PcsPopupDimmedFontTransparency();
+        textColor.SetAlpha( KTransparency );
+        iGc->SetPenColor( textColor );
+        }
+
+		// For now, we support underlining the matching part only if the
+		//       text is written completely with left-to-right script
+		
+		// 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( textRect, *font, currentTextStart, currentTextLength, itemText,
+									EFalse, topToBaseline );
+					}
+				else if ( currentTextStart == underlines[i].index )
+					{
+					// draw underlined letters
+					currentTextLength = underlines[i].length;
+					
+					DrawPartOfItem( textRect, *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( textRect, *font, currentTextStart, currentTextLength, itemText,
+										EFalse, topToBaseline );
+						}
+					}
+				
+				}
+			}
+		else
+			{
+			iGc->SetUnderlineStyle( EUnderlineOff );
+			bidiText->DrawText( *iGc, leftBase );
+			}		
+		}
+		
+	delete bidiText;
+	bidiText = NULL;
+	}
+
+// -----------------------------------------------------------------------------
+// CNcsListItemDrawer::DrawPartOfItem
+// -----------------------------------------------------------------------------
+void CNcsListItemDrawer::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;
+	iGc->DrawText( aDes.Mid( aStartPos, aLength ), 
+	        currentTextRect, aBaselineOffsetFromTop );
+	}
+
+
+void CNcsPopupListBox::UpdateListL()
+    {
+    FUNC_LOG;
+    SetListItemsFromArrayL();
+
+    // Close the popup if it's empty and make sure it's visible if it's not empty.
+    if ( IsPopupEmpty() )
+        {
+        iHeaderContainer.ClosePopupContactListL();
+        }
+    else
+        {
+        MakeVisible( ETrue );
+        UpdateScrollBarsL();
+        iHeaderContainer.ShowPopupMenuBarL( ETrue );
+        }
+    }
+
+void CNcsPopupListBox::UpdateTextColors()
+    {
+    if ( iItemDrawer )
+        {
+        // Get skin instance.
+        MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+        // Get color for popup text from current skin.
+        TRgb textColor = KRgbBlack;
+        AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors,
+            EAknsCIQsnTextColorsCG20 );
+        iItemDrawer->SetTextColor( textColor );
+
+        // Get text color for highlighted list item from current skin.
+        AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors,
+            EAknsCIQsnTextColorsCG10 );
+        iItemDrawer->SetHighlightedTextColor( textColor );
+        }
+    }
+
+void CNcsPopupListBox::Draw( const TRect& /*aRect*/ ) const
+    {
+    CWindowGc& gc = SystemGc();
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    if ( iBackgroundContext )
+        {
+        AknsDrawUtils::DrawBackground( skin, iBackgroundContext, this, gc,
+            Rect().iTl, Rect(), KAknsDrawParamNoClearUnderImage );
+        }
+    else
+        {
+        gc.Clear( Rect() );
+        }
+    CEikListBox::Draw( Rect() );
+    }
+
+// End of File
+