emailuis/emailui/src/ncspopuplistbox.cpp
branchRCL_3
changeset 25 3533d4323edc
equal deleted inserted replaced
24:d189ee25cf9d 25:3533d4323edc
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: This file implements classes CNcsPopupListBox, CNcsListItemDrawer. 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "emailtrace.h"
       
    21 #include <eikclbd.h>
       
    22 #include <AknsFrameBackgroundControlContext.h>
       
    23 #include <FreestyleEmailUi.rsg>						// R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH
       
    24 #include <StringLoader.h>						// StringLoader
       
    25 #include <CPbkContactEngine.h>
       
    26 #include <AknsDrawUtils.h>
       
    27 #include <AknsUtils.h>
       
    28 #include <aknlayoutscalable_apps.cdl.h>
       
    29 #include <aknlayoutscalable_avkon.cdl.h>
       
    30 
       
    31 #include "ncspopuplistbox.h"
       
    32 #include "ncsemailaddressobject.h"					// CNcsEmailAddressObject
       
    33 #include "ncsconstants.h"
       
    34 #include "ncsheadercontainer.h"						// CNcsHeaderContainer
       
    35 #include "FreestyleEmailUiContactHandler.h"		// CFSEmailUiClsListsHandler
       
    36 #include "ncsutility.h"
       
    37 #include "FreestyleEmailUiUtilities.h"
       
    38 #include "FreestyleEmailUiAppui.h"
       
    39 #include "FreestyleEmailUiLayoutHandler.h"
       
    40 #include "FSDelayedLoader.h"
       
    41 #include "FreestyleEmailUiCLSItem.h"
       
    42 
       
    43 const TInt KHighlightFrameWidth = 2;
       
    44 
       
    45 // ========================= MEMBER FUNCTIONS ==================================
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CNcsPopupListBox::NewL
       
    49 // -----------------------------------------------------------------------------
       
    50 CNcsPopupListBox* CNcsPopupListBox::NewL( const CCoeControl* aParent, 
       
    51                                           CFSMailBox& aMailBox, 
       
    52                                           CNcsHeaderContainer& aHeaderContainer, 
       
    53                                           TBool aRemoteLookupSupported  )
       
    54     {
       
    55     FUNC_LOG;
       
    56     CNcsPopupListBox* self =  new (ELeave) CNcsPopupListBox( aHeaderContainer,
       
    57         aRemoteLookupSupported, aMailBox );
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL( aParent );
       
    60     CleanupStack::Pop( self );
       
    61     return self;
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CNcsPopupListBox::CNcsPopupListBox
       
    66 // -----------------------------------------------------------------------------
       
    67 CNcsPopupListBox::CNcsPopupListBox( CNcsHeaderContainer& aHeaderContainer, 
       
    68                                     TBool aRemoteLookupSupported, 
       
    69                                     CFSMailBox& aMailBox)
       
    70     : iHeaderContainer( aHeaderContainer ),
       
    71       iMailBox( aMailBox ),
       
    72       iRemoteLookupSupported( aRemoteLookupSupported ),
       
    73       iCachingInProgress( EFalse ),
       
    74       iAppUi( static_cast<CFreestyleEmailUiAppUi*>( iEikonEnv->AppUi() ) )
       
    75     {
       
    76     FUNC_LOG;
       
    77     iPopupMaxRect = TRect( 100, 100, 100, 100 );
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CNcsPopupListBox::ConstructL
       
    82 // -----------------------------------------------------------------------------
       
    83 void CNcsPopupListBox::ConstructL( const CCoeControl* aParent )
       
    84     {
       
    85     FUNC_LOG;
       
    86     CEikTextListBox::ConstructL( NULL, CEikListBox::EPopout );
       
    87     SetMopParent( const_cast<CCoeControl*>( aParent ) );
       
    88     User::LeaveIfError( SetParent( const_cast<CCoeControl*>( aParent ) ) );
       
    89 
       
    90     CEikScrollBarFrame* frame = CreateScrollBarFrameL( EFalse, EFalse, ETrue );
       
    91 
       
    92     CEikTextListBox::SetBorder( TGulBorder::ENone );
       
    93 
       
    94     const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
       
    95     CEikTextListBox::SetItemHeightL( font->FontMaxHeight() + 12 );
       
    96 
       
    97     iBackgroundContext = CAknsFrameBackgroundControlContext::NewL(
       
    98         KAknsIIDQsnFrPopupSub, Rect(), Rect(), EFalse );
       
    99     UpdateTextColors();
       
   100 
       
   101     iContactHandler = CFsDelayedLoader::InstanceL()->GetContactHandlerL();
       
   102     if ( !iContactHandler->IsLanguageSupportedL() )
       
   103         {
       
   104         iContactHandler = NULL;
       
   105         }
       
   106 
       
   107     SetListBoxObserver( this );
       
   108     }
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // CNcsPopupListBox::InitAndSearchL
       
   112 // -----------------------------------------------------------------------------
       
   113 void CNcsPopupListBox::InitAndSearchL( const TDesC& aText, TInt aMode )
       
   114     {
       
   115     FUNC_LOG;
       
   116     SetSearchTextL( aText, aMode );
       
   117     RPointerArray<CFSEmailUiClsItem> emptyArray;
       
   118     CleanupClosePushL( emptyArray );
       
   119     OperationCompleteL( ESearchContacts, emptyArray );
       
   120     CleanupStack::PopAndDestroy( &emptyArray );
       
   121     }
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // CNcsPopupListBox::~CNcsPopupListBox
       
   125 // ---------------------------------------------------------------------------
       
   126 CNcsPopupListBox::~CNcsPopupListBox()
       
   127     {
       
   128     FUNC_LOG;
       
   129     delete iBackgroundContext;
       
   130     delete iItemTextsArray;
       
   131     delete iCurrentSearchText;
       
   132     iMatchingItems.ResetAndDestroy();
       
   133     }
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CNcsPopupListBox::CreateItemDrawerL
       
   137 // -----------------------------------------------------------------------------
       
   138 void CNcsPopupListBox::CreateItemDrawerL()
       
   139     {
       
   140     FUNC_LOG;
       
   141     iItemDrawer = new (ELeave) CNcsListItemDrawer( *this );
       
   142     }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // CNcsPopupListBox::MopSupplyObject
       
   146 // -----------------------------------------------------------------------------
       
   147 TTypeUid::Ptr CNcsPopupListBox::MopSupplyObject(TTypeUid aId)
       
   148     {
       
   149     FUNC_LOG;
       
   150     if ( aId.iUid == MAknsControlContext::ETypeId )
       
   151         {
       
   152         return MAknsControlContext::SupplyMopObject( aId, iBackgroundContext );
       
   153         }
       
   154     return CCoeControl::MopSupplyObject( aId );
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CNcsPopupListBox::SizeChanged
       
   159 // -----------------------------------------------------------------------------
       
   160 void CNcsPopupListBox::SizeChanged()
       
   161     {
       
   162     FUNC_LOG;
       
   163     const TRect outerRect = Rect();
       
   164 
       
   165     TAknLayoutRect subpane;
       
   166     subpane.LayoutRect( outerRect, 
       
   167         AknLayoutScalable_Avkon::bg_popup_sub_pane_g1() );
       
   168     const TRect innerRect = subpane.Rect();
       
   169 
       
   170     iBackgroundContext->SetFrameRects( outerRect, innerRect );
       
   171 
       
   172     SetViewRectFromClientRect( innerRect );
       
   173     TRAP_IGNORE( HandleViewRectSizeChangeL() );
       
   174     }
       
   175 
       
   176 void CNcsPopupListBox::HandleResourceChange( TInt aType )
       
   177     {
       
   178     FUNC_LOG;
       
   179     if ( aType == KAknsMessageSkinChange )
       
   180         {
       
   181         UpdateTextColors();
       
   182         }
       
   183     }
       
   184 
       
   185 void CNcsPopupListBox::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   186     {
       
   187     CEikTextListBox::HandlePointerEventL( aPointerEvent );
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CNcsPopupListBox::OfferKeyEventL
       
   192 // -----------------------------------------------------------------------------
       
   193 //    
       
   194 TKeyResponse CNcsPopupListBox::OfferKeyEventL( const TKeyEvent& aKeyEvent,
       
   195     TEventCode aType )
       
   196     {
       
   197     FUNC_LOG;
       
   198     TKeyResponse ret( EKeyWasNotConsumed );
       
   199     if( aKeyEvent.iCode == EKeyDownArrow )
       
   200         {
       
   201         MoveRemoteLookupItemL( ERemoteLookupItemDown );
       
   202         iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection );
       
   203 		ret = EKeyWasConsumed;
       
   204         } 
       
   205     else if( aKeyEvent.iCode == EKeyUpArrow )
       
   206         {
       
   207 		TBool stay = EFalse;
       
   208         // Move cursor separator line over
       
   209 		if ( CurrentItemIndex() - 1 > 0 && CurrentItemIndex() - 1 == iRemoteLookupItemPos )
       
   210 			{
       
   211 	        MoveRemoteLookupItemL( ERemoteLookupItemUp );
       
   212 	        iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection );
       
   213 			stay = ETrue;
       
   214 			}
       
   215 
       
   216         MoveRemoteLookupItemL( ERemoteLookupItemUp );
       
   217         iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection );
       
   218 	    if( stay )
       
   219 			{
       
   220 	        MoveRemoteLookupItemL( ERemoteLookupItemDown );
       
   221 
       
   222 			iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection );
       
   223 			}
       
   224 
       
   225 
       
   226     	ret = EKeyWasConsumed;
       
   227         }
       
   228        
       
   229     if( ret == EKeyWasNotConsumed )
       
   230         {
       
   231         ret = CEikListBox::OfferKeyEventL( aKeyEvent, aType );
       
   232         }
       
   233 	// call HandleItemAdditionL just in case. There might be changes on remote lookup item place.
       
   234 	// The call is here, because we don't want to have extra redraw events when the popuplist
       
   235 	// is not fully updated.
       
   236 	HandleItemAdditionL(); 
       
   237     return ret;
       
   238     }
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // CNcsPopupListBox::HandleListBoxEventL
       
   242 // ---------------------------------------------------------------------------
       
   243 //      
       
   244 void CNcsPopupListBox::HandleListBoxEventL( CEikListBox* /*aListBox*/,
       
   245     TListBoxEvent aEventType )
       
   246     {
       
   247     if ( aEventType == EEventItemClicked || 
       
   248          aEventType == EEventItemSingleClicked )
       
   249         {
       
   250         iHeaderContainer.DoPopupSelectL();
       
   251         }
       
   252     }
       
   253 
       
   254 // -----------------------------------------------------------------------------
       
   255 // CNcsPopupListBox::OperationComplete
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 void CNcsPopupListBox::OperationCompleteL( TContactHandlerCmd /*aCmd*/,
       
   259     const RPointerArray<CFSEmailUiClsItem>& aMatchingItems )
       
   260     {
       
   261     FUNC_LOG;
       
   262     iMatchingItems.ResetAndDestroy();
       
   263     // Replace old matcing items.
       
   264 
       
   265     for ( TInt ii = 0; ii < aMatchingItems.Count(); ++ii )
       
   266     	{
       
   267     	if ( aMatchingItems[ii] )
       
   268     		{
       
   269     		CFSEmailUiClsItem* item = aMatchingItems[ii]->CloneLC();  		
       
   270     		iMatchingItems.AppendL( item );
       
   271     		CleanupStack::Pop( item );
       
   272     		}
       
   273     	}
       
   274     
       
   275     UpdateListL();
       
   276     }
       
   277 
       
   278 void CNcsPopupListBox::OperationErrorL( TContactHandlerCmd aCmd, TInt aError )
       
   279 	{
       
   280     FUNC_LOG;
       
   281 	
       
   282 	if ( aCmd == ESearchContacts )
       
   283 		{
       
   284 		// KerrNotReady --> caching in progress, KErrNotFound --> caching not started yet
       
   285 		if ( (aError == KErrNotReady) || (aError == KErrNotFound) )
       
   286 			{
       
   287 			if(!iAppUi->AppUiExitOngoing()) //<cmail>
       
   288 			    TFsEmailUiUtility::ShowInfoNoteL( R_FSE_EDITOR_INFO_BUILDING_CACHE );
       
   289 			iCachingInProgress = ETrue;
       
   290 			}
       
   291 		if ( aError == KErrNone && iCachingInProgress )
       
   292 			{
       
   293 			if(!iAppUi->AppUiExitOngoing()) //<cmail>
       
   294 			    TFsEmailUiUtility::ShowInfoNoteL( R_FSE_EDITOR_INFO_CACHING_COMPLETED );
       
   295 			iCachingInProgress = EFalse;
       
   296 			}
       
   297 		}
       
   298 	}
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CNcsPopupListBox::SetSearchTextL
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 void CNcsPopupListBox::SetSearchTextL( const TDesC& aText, TInt aMode )
       
   305     {
       
   306     FUNC_LOG;
       
   307     delete iCurrentSearchText;
       
   308     iCurrentSearchText = NULL;
       
   309     iCurrentSearchText = aText.AllocL();
       
   310     if ( !iCachingInProgress  )
       
   311         {
       
   312         if ( iContactHandler  )
       
   313             {
       
   314             iContactHandler->SearchMatchesL( aText, this, &iMailBox, aMode );
       
   315             }
       
   316         }
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CNcsPopupListBox::ReturnCurrentEmailAddressLC
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 CNcsEmailAddressObject* CNcsPopupListBox::ReturnCurrentEmailAddressLC()
       
   324     {
       
   325     FUNC_LOG;
       
   326     CNcsEmailAddressObject* addressObject = NULL;
       
   327 
       
   328     if ( iMatchingItems.Count() )
       
   329         {
       
   330         CFSEmailUiClsItem* clsItem = NULL;
       
   331         if ( iRemoteLookupSupported )
       
   332             {
       
   333             // calculate index of item
       
   334             TInt index = (CurrentItemIndex() > iRemoteLookupItemPos ? CurrentItemIndex() - 1 : CurrentItemIndex());
       
   335             clsItem = iMatchingItems[index];
       
   336             }
       
   337         else
       
   338             {
       
   339             clsItem = iMatchingItems[CurrentItemIndex()]; // no iRemoteLookupItemPos
       
   340             }
       
   341 
       
   342         addressObject= CNcsEmailAddressObject::NewL( clsItem->DisplayName(), clsItem->EmailAddress() );
       
   343         CleanupStack::PushL( addressObject );
       
   344         if ( clsItem->MultipleEmails() )
       
   345             {
       
   346             addressObject->SetDisplayFull( ETrue );
       
   347             }
       
   348         }
       
   349 
       
   350     return addressObject;
       
   351     }
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CNcsPopupListBox::SetPopupMaxRect
       
   355 // -----------------------------------------------------------------------------
       
   356 void CNcsPopupListBox::SetPopupMaxRect( const TRect& aPopupMaxRect )
       
   357     {
       
   358     FUNC_LOG;
       
   359     iPopupMaxRect = aPopupMaxRect;
       
   360 
       
   361     SetPopupRect();
       
   362     TRAP_IGNORE( UpdateScrollBarsL() );
       
   363     TRAP_IGNORE( SetScrollBarVisibilityL() );
       
   364     }
       
   365 
       
   366 // -----------------------------------------------------------------------------
       
   367 // CNcsPopupListBox::IsPopupEmpty
       
   368 // -----------------------------------------------------------------------------
       
   369 TBool CNcsPopupListBox::IsPopupEmpty() const
       
   370     {
       
   371     FUNC_LOG;
       
   372     if ( Model()->NumberOfItems() > 0 )
       
   373         return EFalse;
       
   374     else
       
   375         return ETrue;
       
   376     }
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // CNcsPopupListBox::IsRemoteLookupItemSelected
       
   380 // -----------------------------------------------------------------------------
       
   381 TBool CNcsPopupListBox::IsRemoteLookupItemSelected() const
       
   382     {
       
   383     FUNC_LOG;
       
   384     if ( CurrentItemIndex() == iRemoteLookupItemPos && iRemoteLookupSupported )
       
   385         return ETrue;
       
   386     else
       
   387         return EFalse;
       
   388     }
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // CNcsPopupListBox::CurrentPopupClsItemsArray
       
   392 // -----------------------------------------------------------------------------
       
   393 const RPointerArray<CFSEmailUiClsItem>& CNcsPopupListBox::CurrentPopupClsItemsArray() const
       
   394     {
       
   395     return iMatchingItems;
       
   396     }
       
   397 
       
   398 // -----------------------------------------------------------------------------
       
   399 // CNcsPopupListBox::RemoteLookupItemPos
       
   400 // -----------------------------------------------------------------------------
       
   401 TInt CNcsPopupListBox::RemoteLookupItemPos() const
       
   402     {
       
   403     FUNC_LOG;
       
   404     return iRemoteLookupItemPos;
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CNcsPopupListBox::LayoutHandler
       
   409 // -----------------------------------------------------------------------------
       
   410 CFSEmailUiLayoutHandler& CNcsPopupListBox::LayoutHandler() const
       
   411     {
       
   412     FUNC_LOG;
       
   413     return *iAppUi->LayoutHandler();
       
   414     }
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // CNcsPopupListBox::SetListItemsFromArrayL
       
   418 // -----------------------------------------------------------------------------
       
   419 void CNcsPopupListBox::SetListItemsFromArrayL()
       
   420 	{
       
   421     FUNC_LOG;
       
   422 	// reset the cursor to point to the first item
       
   423     //iView->MoveCursorL( CListBoxView::ECursorFirstItem, CListBoxView::ENoSelection);
       
   424 	Reset();
       
   425 	
       
   426 	// Create totally new text array
       
   427 	CreateTextArrayAndSetToTheListboxL( ETrue );
       
   428 
       
   429 	// append texts to text array
       
   430 	for( TInt i=0; i < iMatchingItems.Count(); i++ )
       
   431 		{
       
   432 		iItemTextsArray->AppendL( iMatchingItems[i]->FullTextL() );
       
   433 		}
       
   434 
       
   435 	// Update rmlu item
       
   436 	SetRemoteLookupItemFirstToTheListL();
       
   437 	
       
   438 	SetPopupRect();
       
   439 	SetScrollBarVisibilityL();
       
   440 	HandleItemAdditionL();
       
   441 
       
   442     if ( iItemTextsArray && iItemTextsArray->Count() > 0 )
       
   443         {
       
   444         SetCurrentItemIndex( 0 );
       
   445         }
       
   446 
       
   447     if ( IsVisible() )
       
   448         {
       
   449         DrawDeferred();
       
   450         }
       
   451     }
       
   452 
       
   453 // -----------------------------------------------------------------------------
       
   454 // CNcsPopupListBox::RoundToItemHeight
       
   455 // -----------------------------------------------------------------------------
       
   456 TInt CNcsPopupListBox::RoundToItemHeight(const TInt aPopupHeight) const
       
   457     {
       
   458     TReal fullItems; // number of full visible items in window
       
   459     TInt err = Math::Round(fullItems, (aPopupHeight / ItemHeight()), 0);
       
   460     if (err == KErrNone)
       
   461         {
       
   462         return (TInt)(fullItems * ItemHeight()); 
       
   463         }
       
   464     return aPopupHeight; // in case of error
       
   465     }
       
   466 
       
   467 // -----------------------------------------------------------------------------
       
   468 // CNcsPopupListBox::SetPopupRect
       
   469 // -----------------------------------------------------------------------------
       
   470 void CNcsPopupListBox::SetPopupRect()
       
   471     {
       
   472     FUNC_LOG;
       
   473     // The popup width and horizontal position is adjusted so that it
       
   474     // will be within the area specified in both layout data and the set
       
   475     // maximum rect.
       
   476     TAknLayoutRect editorPane;
       
   477     editorPane.LayoutRect( iAppUi->ClientRect(),
       
   478         TAknWindowComponentLayout::Compose(
       
   479             TAknWindowComponentLayout::Compose(
       
   480                 AknLayoutScalable_Apps::list_cmail_pane(),
       
   481                 AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0 ) ),
       
   482             AknLayoutScalable_Apps::list_single_cmail_header_editor_pane_bg( 4 ) ) );
       
   483     TRect editorPaneRect = editorPane.Rect();
       
   484 
       
   485     TRect newRect = iPopupMaxRect;
       
   486     newRect.iTl.iX = Max( iPopupMaxRect.iTl.iX, editorPaneRect.iTl.iX );
       
   487     newRect.iBr.iX = Min( iPopupMaxRect.iBr.iX, editorPaneRect.iBr.iX );
       
   488 
       
   489     // Thhe popup height and vertical position is adjusted based on the
       
   490     // available space below and above the cursor and the number of items
       
   491     // in the list.
       
   492     const TRect rect = iPopupMaxRect;
       
   493     TAknLayoutRect subpane;
       
   494     subpane.LayoutRect( rect, AknLayoutScalable_Avkon::bg_popup_sub_pane_g1() );
       
   495     const TRect subpaneRect = subpane.Rect();
       
   496 
       
   497     const TInt frameHeights = iPopupMaxRect.Height() - subpaneRect.Height();
       
   498 
       
   499     // This is the total height in pixels needed to show all items
       
   500     TInt minimumHeight = frameHeights + 
       
   501         CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() );
       
   502 
       
   503     CCoeControl* container = Parent()->Parent();
       
   504     TInt containerTop = container->PositionRelativeToScreen().iY;
       
   505     TInt containerHeight = container->Rect().Height();
       
   506     TInt containerCenter = containerTop + containerHeight / 2;
       
   507 
       
   508     // Get height of one line in Address field
       
   509     CNcsHeaderContainer* headerObj = static_cast<CNcsHeaderContainer* >(Parent());
       
   510     TInt toLineHeight = headerObj->GetToLineHeight(); // height of one line height
       
   511     if ( toLineHeight == 0 )
       
   512         {
       
   513         toLineHeight = ItemHeight();
       
   514         }
       
   515 
       
   516     TInt newHeight = minimumHeight; // default window height
       
   517 
       
   518     // latch listbox on the bottom of the editor field
       
   519     if ( newRect.iTl.iY <= containerCenter ) 
       
   520         {
       
   521         TInt maxHeight = containerHeight - ( newRect.iTl.iY - containerTop ); 
       
   522         newHeight = RoundToItemHeight( maxHeight - frameHeights ) + frameHeights;
       
   523         if ( newHeight > minimumHeight )
       
   524             {
       
   525             newHeight = minimumHeight; // shrink window (if needed)
       
   526             }
       
   527         }
       
   528     // latch listbox on the top of the editor field
       
   529     else
       
   530         {
       
   531         TInt yOffset = -minimumHeight - toLineHeight; // how much up
       
   532         TInt newTlY = newRect.iTl.iY + yOffset;       // new Top Left Y coordinate
       
   533         if ( newTlY >= containerTop )
       
   534             {
       
   535             newRect.Move( 0, yOffset );
       
   536             }
       
   537         else
       
   538             {
       
   539             // shrink height to visible area and move
       
   540             TInt maxHeight = newRect.iTl.iY - toLineHeight - containerTop;
       
   541             newHeight = RoundToItemHeight( maxHeight - frameHeights ) + frameHeights;
       
   542             newRect.Move( 0, -newHeight - toLineHeight );
       
   543             }
       
   544         }
       
   545     newRect.SetHeight( newHeight ); // set new height
       
   546     SetRect( newRect );
       
   547     }
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // CNcsPopupListBox::SetScrollBarVisibilityL
       
   551 // -----------------------------------------------------------------------------
       
   552 void CNcsPopupListBox::SetScrollBarVisibilityL()
       
   553 	{
       
   554     FUNC_LOG;
       
   555 	// This is the total height in pixels needed to show all items
       
   556 	TInt minimumHeight = CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() );
       
   557 
       
   558 	// Show scroll bar if there is more items we can show at once.
       
   559 	if( iPopupMaxRect.Height() > minimumHeight ) 
       
   560 		{
       
   561 		ScrollBarFrame()->SetScrollBarVisibilityL(
       
   562 			CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff ); 
       
   563 		}
       
   564 	else 
       
   565 		{
       
   566 		ScrollBarFrame()->SetScrollBarVisibilityL(
       
   567 			CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn ); 
       
   568 		}
       
   569 	}
       
   570 
       
   571 
       
   572 // -----------------------------------------------------------------------------
       
   573 // CNcsPopupListBox::SetRemoteLookupItemFirstToTheListL
       
   574 // -----------------------------------------------------------------------------
       
   575 void CNcsPopupListBox::SetRemoteLookupItemFirstToTheListL()
       
   576 	{
       
   577     FUNC_LOG;
       
   578 	if( iRemoteLookupSupported )
       
   579 		{
       
   580 		HBufC* rmluText = StringLoader::LoadLC( 
       
   581 		    R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
       
   582 		
       
   583 		iItemTextsArray->InsertL( 0, *rmluText );
       
   584 		CleanupStack::PopAndDestroy( rmluText );
       
   585 		iRemoteLookupItemPos = 0;
       
   586 		}
       
   587 	else
       
   588 		{
       
   589 		iRemoteLookupItemPos = -1;
       
   590 		}
       
   591 	}
       
   592 
       
   593 // -----------------------------------------------------------------------------
       
   594 // CNcsPopupListBox::MoveRemoteLookupItemL
       
   595 // -----------------------------------------------------------------------------
       
   596 void CNcsPopupListBox::MoveRemoteLookupItemL( TRemoteLookupItemMoveDirection aDirection )
       
   597 	{
       
   598     FUNC_LOG;
       
   599 	if( iRemoteLookupSupported )
       
   600 		{
       
   601 		TInt newRMLUItemIndex = -1;
       
   602 		TInt newCurrentItem = -1;
       
   603 		if( aDirection == ERemoteLookupItemUp &&
       
   604 			 iView->CurrentItemIndex() == iView->TopItemIndex() )
       
   605 			{
       
   606 			newRMLUItemIndex = iRemoteLookupItemPos - 1;
       
   607 			newCurrentItem = CurrentItemIndex() - 1;
       
   608 			}
       
   609 		else if( aDirection == ERemoteLookupItemDown &&
       
   610 				 iView->CurrentItemIndex() == iView->BottomItemIndex() )
       
   611 			{
       
   612 			newRMLUItemIndex = iRemoteLookupItemPos + 1;
       
   613 			newCurrentItem = CurrentItemIndex() + 1;
       
   614 			}
       
   615 
       
   616 
       
   617 		if( ItemExists ( newCurrentItem ) && newRMLUItemIndex != -1 )
       
   618 			{
       
   619 			iItemTextsArray->Delete( iRemoteLookupItemPos );
       
   620 
       
   621 			HBufC* rmluText = StringLoader::LoadLC( R_FSE_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText );
       
   622 			
       
   623 			iItemTextsArray->InsertL( newRMLUItemIndex, *rmluText );
       
   624 			CleanupStack::PopAndDestroy( rmluText );
       
   625 			iRemoteLookupItemPos = newRMLUItemIndex;
       
   626 			}
       
   627 		}
       
   628 	}
       
   629 
       
   630 
       
   631 // -----------------------------------------------------------------------------
       
   632 // CNcsPopupListBox::CreateTextArrayAndSetToTheListboxL
       
   633 // -----------------------------------------------------------------------------
       
   634 void CNcsPopupListBox::CreateTextArrayAndSetToTheListboxL( const TBool& aResetIfExists )
       
   635 	{
       
   636     FUNC_LOG;
       
   637 	if( !iItemTextsArray )
       
   638 		{
       
   639 		iItemTextsArray = new ( ELeave ) CDesCArraySeg( 8 );
       
   640 		// Set the popup list data
       
   641 		Model()->SetItemTextArray( iItemTextsArray );
       
   642 		Model()->SetOwnershipType( ELbmDoesNotOwnItemArray  );
       
   643 		}
       
   644 		
       
   645 	if( aResetIfExists )
       
   646 		{
       
   647 		delete iItemTextsArray;
       
   648 		iItemTextsArray = NULL;
       
   649 		CreateTextArrayAndSetToTheListboxL( EFalse );
       
   650 		}
       
   651 	}
       
   652 
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CNcsListItemDrawer::CNcsListItemDrawer
       
   656 // -----------------------------------------------------------------------------
       
   657 CNcsListItemDrawer::CNcsListItemDrawer( const CNcsPopupListBox& aListBox )
       
   658 :CListItemDrawer(), iListBox( aListBox )
       
   659     {
       
   660     FUNC_LOG;
       
   661     // Store a GC for later use
       
   662     iGc = &CCoeEnv::Static()->SystemGc();
       
   663     SetGc(iGc);
       
   664     }
       
   665 
       
   666 // -----------------------------------------------------------------------------
       
   667 // CNcsListItemDrawer::DrawActualItem
       
   668 // -----------------------------------------------------------------------------
       
   669 void CNcsListItemDrawer::DrawActualItem(TInt aItemIndex,
       
   670     const TRect& aActualItemRect, TBool aItemIsCurrent,
       
   671     TBool /*aViewIsEmphasized*/, TBool /*aViewIsDimmed*/,
       
   672     TBool /*aItemIsSelected*/) const
       
   673     {
       
   674     FUNC_LOG;
       
   675     iGc->DiscardFont();
       
   676 
       
   677     // Get reference to curren popup cls item list.
       
   678     const RPointerArray<CFSEmailUiClsItem>& clsItemArray =
       
   679         iListBox.CurrentPopupClsItemsArray();
       
   680     TInt rmluPosition = iListBox.RemoteLookupItemPos();
       
   681 
       
   682     // Sets all the attributes, like font, text color and background color.
       
   683     const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont );
       
   684     iGc->UseFont( font );
       
   685     iGc->SetPenStyle( CGraphicsContext::ESolidPen );
       
   686     iGc->SetBrushStyle( CGraphicsContext::ENullBrush );
       
   687 
       
   688     TRect itemRect = aActualItemRect;
       
   689     { 
       
   690     // temporary const_cast to get the scrollbar width
       
   691     CNcsPopupListBox& tmpListBox = const_cast<CNcsPopupListBox&>( iListBox );
       
   692     const TInt scrollbarBreadth = tmpListBox.ScrollBarFrame()->
       
   693         ScrollBarBreadth( CEikScrollBar::EVertical );
       
   694     if ( scrollbarBreadth > 0 )
       
   695         {
       
   696         if ( AknLayoutUtils::LayoutMirrored() )
       
   697             {
       
   698             itemRect.iTl.iX = iListBox.Rect().iTl.iX + scrollbarBreadth;
       
   699             }
       
   700         else
       
   701             {
       
   702             itemRect.iBr.iX = iListBox.Rect().iBr.iX - scrollbarBreadth;
       
   703             }
       
   704         }
       
   705     }
       
   706 
       
   707     TRect textRect = itemRect;
       
   708     textRect.Shrink( KHighlightFrameWidth, KHighlightFrameWidth );
       
   709 
       
   710     // Get skin instance.
       
   711     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   712 
       
   713     // Draw background using the control context from the list box.
       
   714     MAknsControlContext* cc = AknsDrawUtils::ControlContext( &iListBox );
       
   715     if ( cc )
       
   716         {
       
   717         AknsDrawUtils::Background( skin, cc, *iGc, aActualItemRect );
       
   718         }
       
   719     else
       
   720         {
       
   721         iGc->Clear( aActualItemRect );
       
   722         }
       
   723 
       
   724     // Draw the highlight, when necessary.
       
   725     if ( aItemIsCurrent ) 
       
   726         {
       
   727         AknsDrawUtils::DrawFrame( skin, *iGc, itemRect, textRect,
       
   728             KAknsIIDQsnFrList, KAknsIIDQsnFrListCenter );
       
   729         }
       
   730 
       
   731     // Get text color.
       
   732     TRgb textColor = TextColor();
       
   733     if ( aItemIsCurrent )
       
   734         {
       
   735         textColor = HighlightedTextColor();
       
   736         }
       
   737 
       
   738     iGc->SetPenColor( textColor );
       
   739     TInt topToBaseline = ( textRect.Height() - font->FontMaxHeight() ) / 2
       
   740         + font->FontMaxAscent();
       
   741 
       
   742     TPtrC itemText = iListBox.Model()->ItemText( aItemIndex );
       
   743 
       
   744 	// Construct bidirectional text object
       
   745 	// <cmail> Removed leave from non-leaving function.
       
   746 	TBidiText* bidiText = NULL;
       
   747 	TRAPD( err, bidiText = TBidiText::NewL( itemText, 1 ) );
       
   748 	if ( err == KErrNone )
       
   749 		{
       
   750 		bidiText->WrapText( textRect.Width(), *font, NULL );
       
   751 		}
       
   752 		
       
   753 	TPoint leftBase = textRect.iTl + TPoint( 0, topToBaseline );
       
   754 
       
   755     if ( err != KErrNone )
       
   756         {
       
   757         bidiText = NULL; // to be on the safe side
       
   758         }
       
   759 
       
   760 	// check if we are drawing remote lookup item or contact match
       
   761 	else if ( rmluPosition == aItemIndex )
       
   762 		{
       
   763 		iGc->SetUnderlineStyle( EUnderlineOff );
       
   764 		bidiText->DrawText( *iGc, leftBase );
       
   765 		}
       
   766 	else
       
   767 		{
       
   768 		// if list has rmlu item change item index right
       
   769 		if ( rmluPosition >= 0 && aItemIndex > rmluPosition )
       
   770 			{
       
   771 			aItemIndex--;
       
   772 			}
       
   773 
       
   774     // Change text transparency if match doesn't have email address.
       
   775     if ( clsItemArray[aItemIndex]->EmailAddress().Compare( KNullDesC ) == 0 )
       
   776         {
       
   777         const TInt KTransparency = 
       
   778             iListBox.LayoutHandler().PcsPopupDimmedFontTransparency();
       
   779         textColor.SetAlpha( KTransparency );
       
   780         iGc->SetPenColor( textColor );
       
   781         }
       
   782 
       
   783 		// For now, we support underlining the matching part only if the
       
   784 		//       text is written completely with left-to-right script
       
   785 		
       
   786 		// We know the text contains RTL script if the display string is not just
       
   787 		// truncated version of the original string.
       
   788 		TPtrC dispText = bidiText->DisplayText();
       
   789 		TInt compLength = dispText.Length() - 1; // -1 to omit the truncation character
       
   790 		TBool textContainsRtl = 
       
   791             ( itemText.Left(compLength) != dispText.Left(compLength) );
       
   792 		
       
   793         const RArray<TPsMatchLocation>& underlines = clsItemArray[aItemIndex]->Highlights();
       
   794         
       
   795 		if ( underlines.Count() > 0 && !textContainsRtl )
       
   796 			{
       
   797 			TInt i = 0;
       
   798 			TBool partsLeft = ETrue;
       
   799 			TInt currentTextStart = 0;
       
   800 			TInt currentTextLength = 0;
       
   801 
       
   802 			while ( partsLeft )
       
   803 				{
       
   804 				if ( currentTextStart < underlines[i].index )
       
   805 					{
       
   806 					// draw letters to the start of the underlined part
       
   807 					currentTextLength = underlines[i].index - currentTextStart;
       
   808 					DrawPartOfItem( textRect, *font, currentTextStart, currentTextLength, itemText,
       
   809 									EFalse, topToBaseline );
       
   810 					}
       
   811 				else if ( currentTextStart == underlines[i].index )
       
   812 					{
       
   813 					// draw underlined letters
       
   814 					currentTextLength = underlines[i].length;
       
   815 					
       
   816 					DrawPartOfItem( textRect, *font, currentTextStart, currentTextLength, itemText,
       
   817 									ETrue, topToBaseline );
       
   818 					i++;
       
   819 					}
       
   820 				else 
       
   821 					{
       
   822 					// This is here, because PCS Engine might give you duplicate match entries,
       
   823 					// in this case we're not advancing text but we'll skip that match
       
   824 					currentTextLength = 0;
       
   825 					i++;
       
   826 					}
       
   827 					// update text start point
       
   828 					currentTextStart += currentTextLength;
       
   829 				
       
   830 				if ( i >= underlines.Count() )
       
   831 					{
       
   832 					partsLeft = EFalse;
       
   833 					// draw rest of the letters, if there are any after the last underlined part
       
   834 					if ( currentTextStart < itemText.Length() )
       
   835 						{
       
   836 						currentTextLength = itemText.Length() - currentTextStart;
       
   837 						DrawPartOfItem( textRect, *font, currentTextStart, currentTextLength, itemText,
       
   838 										EFalse, topToBaseline );
       
   839 						}
       
   840 					}
       
   841 				
       
   842 				}
       
   843 			}
       
   844 		else
       
   845 			{
       
   846 			iGc->SetUnderlineStyle( EUnderlineOff );
       
   847 			bidiText->DrawText( *iGc, leftBase );
       
   848 			}		
       
   849 		}
       
   850 		
       
   851 	delete bidiText;
       
   852 	bidiText = NULL;
       
   853 	}
       
   854 
       
   855 // -----------------------------------------------------------------------------
       
   856 // CNcsListItemDrawer::DrawPartOfItem
       
   857 // -----------------------------------------------------------------------------
       
   858 void CNcsListItemDrawer::DrawPartOfItem( const TRect& aItemRect, const CFont& aFont,
       
   859 						 TInt aStartPos, TInt aLength, const TDesC& aDes,
       
   860 						 TBool aUnderlined, TInt aBaselineOffsetFromTop  ) const
       
   861 	{
       
   862     FUNC_LOG;
       
   863 	if( aUnderlined )
       
   864 		{
       
   865 		iGc->SetUnderlineStyle( EUnderlineOn );
       
   866 		}
       
   867 	else
       
   868 		{
       
   869 		iGc->SetUnderlineStyle( EUnderlineOff );
       
   870 		}
       
   871 	TRect currentTextRect( aItemRect );
       
   872 	TInt pixels = aFont.TextWidthInPixels( aDes.Left( aStartPos ) );
       
   873 	currentTextRect.iTl.iX = currentTextRect.iTl.iX + pixels;
       
   874 	iGc->DrawText( aDes.Mid( aStartPos, aLength ), 
       
   875 	        currentTextRect, aBaselineOffsetFromTop );
       
   876 	}
       
   877 
       
   878 
       
   879 void CNcsPopupListBox::UpdateListL()
       
   880     {
       
   881     FUNC_LOG;
       
   882     SetListItemsFromArrayL();
       
   883 
       
   884     // Close the popup if it's empty and make sure it's visible if it's not empty.
       
   885     if ( IsPopupEmpty() )
       
   886         {
       
   887         iHeaderContainer.ClosePopupContactListL();
       
   888         }
       
   889     else
       
   890         {
       
   891         MakeVisible( ETrue );
       
   892         UpdateScrollBarsL();
       
   893         iHeaderContainer.ShowPopupMenuBarL( ETrue );
       
   894         }
       
   895     }
       
   896 
       
   897 void CNcsPopupListBox::UpdateTextColors()
       
   898     {
       
   899     if ( iItemDrawer )
       
   900         {
       
   901         // Get skin instance.
       
   902         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   903 
       
   904         // Get color for popup text from current skin.
       
   905         TRgb textColor = KRgbBlack;
       
   906         AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors,
       
   907             EAknsCIQsnTextColorsCG20 );
       
   908         iItemDrawer->SetTextColor( textColor );
       
   909 
       
   910         // Get text color for highlighted list item from current skin.
       
   911         AknsUtils::GetCachedColor( skin, textColor, KAknsIIDQsnTextColors,
       
   912             EAknsCIQsnTextColorsCG10 );
       
   913         iItemDrawer->SetHighlightedTextColor( textColor );
       
   914         }
       
   915     }
       
   916 
       
   917 void CNcsPopupListBox::Draw( const TRect& /*aRect*/ ) const
       
   918     {
       
   919     CWindowGc& gc = SystemGc();
       
   920     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   921     if ( iBackgroundContext )
       
   922         {
       
   923         AknsDrawUtils::DrawBackground( skin, iBackgroundContext, this, gc,
       
   924             Rect().iTl, Rect(), KAknsDrawParamNoClearUnderImage );
       
   925         }
       
   926     else
       
   927         {
       
   928         gc.Clear( Rect() );
       
   929         }
       
   930     CEikListBox::Draw( Rect() );
       
   931     }
       
   932 
       
   933 // End of File
       
   934