emailcontacts/contactactionmenu/src/cfsccontactactionmenulist.cpp
changeset 0 8466d47a6819
child 13 8592a65ad3fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailcontacts/contactactionmenu/src/cfsccontactactionmenulist.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,917 @@
+/*
+* Copyright (c) 2008 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:  Implementation of the class CFscContactActionMenuList.
+*
+*/
+//<cmail> Layout changes
+
+
+// INCUDES
+#include "emailtrace.h"
+#include <e32std.h>
+#include <e32base.h>
+#include <eikclbd.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <gulicon.h>
+#include <coeaui.h>
+#include <coefontprovider.h>
+#include <gulfont.h>
+#include <AknBidiTextUtils.h> 
+#include <AknLayoutFont.h> 
+#include <AknLayout2ScalableDataDef.h>
+#include <AknLayout2ScalableDef.h>
+#include <layoutmetadata.cdl.h>
+#include <CdlEngine.h>
+#include <coemain.h>
+#include <AknsListBoxBackgroundControlContext.h> 
+
+#include <aknlayoutscalable_apps.cdl.h>
+#include <layoutmetadata.cdl.h>
+
+#include "cfsccontactactionmenulist.h"
+#include "mfsccontactactionmenulistobserver.h"
+#include "mfsccontactactionmenumodel.h"
+#include "cfsccontactactionmenuitem.h"
+#include "cfsccontactactionmenulistbox.h"
+#include "fsccontactactionmenuuidefines.h"
+
+//_LIT( KListItemTextFormat, "%d\t%S" );
+_LIT( KListItemTextFormat, "\t%d\t\t%S" );
+
+const TInt KPeriodicDelay = 0; // immediately
+const TInt KPeriodicInterval = 20*1000; // 20ms
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::NewL
+// ---------------------------------------------------------------------------
+//
+CFscContactActionMenuList* CFscContactActionMenuList::NewL(
+    MFscContactActionMenuListObserver* aObserver, 
+    MFscContactActionMenuModel* aModel,
+    TBool aAiMode, 
+    MFsActionMenuPositionGiver* aPositionGiver,
+    TBool aOpenedFromMR )
+    {
+    FUNC_LOG;
+
+    CFscContactActionMenuList* self = new (ELeave) CFscContactActionMenuList( 
+            aObserver, aModel, aAiMode, aPositionGiver, aOpenedFromMR );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+        
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::~CFscContactActionMenuList
+// ---------------------------------------------------------------------------
+//
+CFscContactActionMenuList::~CFscContactActionMenuList()
+    {
+    FUNC_LOG;
+    Hide( EFalse );
+    delete iPeriodic;
+    ClearControls();
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CFscContactActionMenuList::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    FUNC_LOG;
+
+    TKeyResponse ret = ( EKeyWasConsumed );
+    
+    if ( iObserver->IsOperationCompleted() )
+        {
+        ret = EKeyWasNotConsumed;
+        TInt closeKey = AknLayoutUtils::LayoutMirrored() ? 
+            EStdKeyRightArrow : EStdKeyLeftArrow;
+        if ( aType == EEventKey && aKeyEvent.iScanCode == closeKey )
+            {
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventCloseKey );
+            ret = EKeyWasConsumed;
+            }
+        else if ( aType == EEventKey && aKeyEvent.iCode == EKeyEscape )
+            {
+            ret = EKeyWasConsumed;
+            // Handle application exit
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventExitKey );
+            }
+        else if ( aType == EEventKey && aKeyEvent.iCode == EKeyYes )
+        	{
+        	// Send key is not active in the action menu
+        	ret = EKeyWasConsumed;
+        	}
+        else if ( !iAiMode ||
+                  aKeyEvent.iScanCode == EStdKeyRightArrow || 
+                  aKeyEvent.iScanCode == EStdKeyUpArrow || 
+                  aKeyEvent.iScanCode == EStdKeyDownArrow ||  
+                  aKeyEvent.iScanCode == EStdKeyEnter ||
+                  aKeyEvent.iScanCode == EStdKeyDevice0 || //RSK 
+                  aKeyEvent.iScanCode == EStdKeyDevice1 || //LSK
+                  aKeyEvent.iScanCode == EStdKeyDevice3  ) //
+            {
+            ret = iListBox->OfferKeyEventL( aKeyEvent, aType );
+            }
+        else if ( aType == EEventKey )
+            {
+            // iAiMode == ETrue && some special key pressed
+            // Inform observer and remove menu from stack
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventExitKey );
+            }    
+        }
+    
+    return ret;     
+    }
+
+// ---------------------------------------------------------------------------
+// <cmail> Touch
+// CFscContactActionMenuList::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+    {
+    iListHasConsumedPointed = EFalse;
+    iListBox->HandlePointerEventL(aPointerEvent);
+    if (!iListHasConsumedPointed && aPointerEvent.iType == TPointerEvent::EButton1Up)
+        {
+        Hide(ETrue);
+        }
+    }
+
+// </cmail>
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::HandleResourceChange
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandleResourceChange( TInt aType )
+    {
+    FUNC_LOG;
+    CCoeControl::HandleResourceChange( aType );
+    if ( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        //This code was commented out because of ELLO-7PDHT2
+        //but perhaps error related to switching layout may be fixed, so
+        //code is left here for future use
+        if ( iOpenedFromMR )
+            {
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuLayoutChanged );
+            }
+        else
+            {
+            LayoutPopupWindow( ETrue );
+            }
+        }
+    else if ( aType == KAknsMessageSkinChange ||
+              aType == KEikMessageColorSchemeChange )
+        {
+        UpdateColors();
+        DrawDeferred();
+        }
+           
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::CountComponentControls
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::CountComponentControls() const
+    {
+    FUNC_LOG;
+    TInt result = 1;
+    return result;
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ComponentControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CFscContactActionMenuList::ComponentControl( TInt aIndex ) const
+    {
+    FUNC_LOG;
+    CCoeControl* control = NULL;
+
+    if ( aIndex == 0 && iListBox != NULL )
+        {
+        control = iListBox;
+        } // No need for else block  
+
+    return control;
+    }
+    
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::HandleListBoxEventL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandleListBoxEventL(
+    CEikListBox* aListBox, TListBoxEvent aEventType )
+    {
+    FUNC_LOG;
+    if( aListBox == iListBox )
+        {
+// <cmail> Touch
+    // Handle pointer events
+       TBool executeAction = EFalse;
+       if ( aEventType == EEventItemDraggingActioned )
+           {
+           iHasBeenDragged = ETrue;
+           }
+       else if ( aEventType == EEventItemClicked )
+           {
+           if (!iHasBeenDragged)
+               {
+               executeAction = ETrue;
+               }
+           else
+               {
+               iHasBeenDragged = EFalse;
+               }
+           }
+       else if ( aEventType == EEventEnterKeyPressed)
+           {
+           executeAction = ETrue;
+           iHasBeenDragged = EFalse;
+           }
+       iListHasConsumedPointed = ETrue;
+       if ( executeAction )
+           {
+           iObserver->HandleListEvent( 
+                           MFscContactActionMenuListObserver::EFscMenuEventItemClicked 
+                           );
+           }
+        
+        /*
+        if ( aEventType == EEventItemClicked || 
+            aEventType == EEventEnterKeyPressed )
+            {
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventItemClicked 
+                );
+            }*/
+// </cmail>
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ShowL
+// ---------------------------------------------------------------------------
+//
+// <cmail> Touch
+void CFscContactActionMenuList::ShowL( 
+    TFscContactActionMenuPosition aPosition,
+    TInt aIndex )
+    {
+    FUNC_LOG;
+      
+    iPosition = aPosition;
+// </cmail>    
+
+    //UpdateListContentL();
+    //UpdateWindowL();
+    UpdateColors();
+    
+    DrawableWindow()->SetOrdinalPosition( KZero, KZero );
+    SetupMenuOffset();
+    iState = ESlidingIn;
+    iMenuOffset.SetWithSpeed( KZero, KMenuSlideSpeed );
+    if ( iMenuOffset.Interpolating() && !iPeriodic->IsActive() )
+        {
+        TCallBack callback( UpdateWindowPosition, this );
+        iPeriodic->Start( KPeriodicDelay, KPeriodicInterval, callback );
+        }
+    
+    iEikonEnv->EikAppUi()->AddToStackL( this, ECoeStackPriorityDialog );
+    MakeVisible( ETrue );
+    SetFocus( ETrue, EDrawNow ); 
+    iListBox->SetCurrentItemIndex( aIndex );
+        
+    DrawDeferred();
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::Hide
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::Hide( TBool aSlide )
+    {
+    FUNC_LOG;
+    
+    if ( aSlide && ( iState == EIn || iState == ESlidingIn ) )
+        {
+        // Start sliding out when menu is fully or partialy shown
+        iState = ESlidingOut;
+        const TInt windowWidth( Rect().Width() );
+        TInt newPos = 
+            AknLayoutUtils::LayoutMirrored() ? 
+                -windowWidth : windowWidth;
+        iMenuOffset.SetWithSpeed( newPos, KMenuSlideSpeed );
+        if ( iMenuOffset.Interpolating() && !iPeriodic->IsActive() )
+            {
+            TCallBack callback( UpdateWindowPosition, this );
+            iPeriodic->Start( KPeriodicDelay, KPeriodicInterval, callback );
+            }
+        }
+    else
+        {
+        // Hide menu now
+        SetFocus( EFalse );
+        MakeVisible( EFalse );
+        iEikonEnv->EikAppUi()->RemoveFromStack( this );
+        
+        // If periodic running, stop it
+        iPeriodic->Cancel();  
+        
+        if ( iState != EOut )
+            {
+            iState = EOut;
+            // Inform observer         
+            iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventMenuHidden
+                );  
+            }
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SelectedItemIndex
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::SelectedItemIndex()
+    {
+    FUNC_LOG;
+    return iListBox->CurrentItemIndex();
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ItemCount
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::ItemCount()
+    {
+    FUNC_LOG;
+    return iListBox->Model()->ItemTextArray()->MdcaCount();
+    }   
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::CFscContactActionMenuList
+// ---------------------------------------------------------------------------
+//
+// <cmail>
+CFscContactActionMenuList::CFscContactActionMenuList(
+    MFscContactActionMenuListObserver* aObserver, 
+    MFscContactActionMenuModel* aModel,
+    TBool aAiMode,
+    MFsActionMenuPositionGiver* aPositionGiver,
+    TBool aOpenedFromMR )
+    : iState( EOut ), iObserver( aObserver ), iModel( aModel ),
+      iAiMode( aAiMode ), iPositionGiver(aPositionGiver),
+      iOpenedFromMR( aOpenedFromMR )
+    {
+// </cmail>
+    FUNC_LOG;
+    ASSERT( aObserver != NULL && aModel != NULL);
+    
+    iListItemId = KAknsIIDQgnFsGrafContactsContent;
+    iListBottomId = KAknsIIDQsnBgColumnA;  
+    iHighlightId = KAknsIIDQgnFsList;
+    iHighlightCenterId = KAknsIIDQgnFsListCenter;   
+    
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ConstructL()
+    {
+    FUNC_LOG;
+    
+    iPeriodic = CPeriodic::NewL( CActive::EPriorityUserInput );
+    
+    CreateWindowL();
+
+    SetNonFocusing();
+    SetBlank();    // This control need not draw
+#ifndef FF_CMAIL_INTEGRATION
+    EnableWindowTransparency(); //Needed to draw background correctly Not supported in 5.0
+#endif
+    
+    // <cmail> Touch
+    Window().SetPointerCapture(RWindowBase::TCaptureFlagEnabled | RWindowBase::TCaptureFlagAllGroups);
+    // </cmail>
+    
+    //InitializeLayoutL();    
+    ConstructControlsL();    
+    
+    // Finalize construct
+    MakeVisible(ETrue);
+    ActivateL();
+
+    }   
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutList
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::LayoutList()
+    {
+    FUNC_LOG;
+    TRAPD( error, LayoutListL() );
+    return error;
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutListL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::LayoutListL()
+    {
+    FUNC_LOG;
+
+    const TRect menuPaneRect( Rect() );
+
+    // Menu list pane
+    TAknLayoutRect menuListPane;
+    menuListPane.LayoutRect( menuPaneRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_pane( 
+                    Max( 0, iModel->ItemCount() - 1 ) ) );
+    const TRect menuPaneListRect( menuListPane.Rect() );
+
+    // Menu gene pane
+    TAknLayoutRect menuGenePane;
+    menuGenePane.LayoutRect( menuPaneListRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane( 0 ) );
+    const TRect menuGenePaneRect( menuGenePane.Rect() );
+           
+    // Menu gene pane g1
+    TAknLayoutRect menuGenePaneG1;
+    menuGenePaneG1.LayoutRect( menuGenePaneRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_g1( 0 ) );
+    const TRect menuGenePaneG1Rect( menuGenePaneG1.Rect() );
+
+    // Menu gene pane t1
+    TAknLayoutText menuGenePaneT1;
+    menuGenePaneT1.LayoutText( menuGenePaneRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_t1( 0 ) );
+    const TRect menuGenePaneT1Rect( menuGenePaneT1.TextRect() );
+    iFont = menuGenePaneT1.Font();
+
+    iListBox->SetRect( menuPaneListRect );
+   
+    // Setup listbox columns
+    CColumnListBoxData& columnData( *iListBox->ItemDrawer()->ColumnData() );
+    columnData.SetColumnWidthPixelL( ELeftMarginColumn, 
+            LeftMargin( menuGenePaneRect, menuGenePaneG1Rect ) );        
+    columnData.SetColumnWidthPixelL( EIconColumn, menuGenePaneG1Rect.Width() );
+    columnData.SetColumnWidthPixelL( EMidleMarginColumn, 
+            MiddleMargin( menuGenePaneG1Rect, menuGenePaneT1Rect ) );
+    columnData.SetColumnWidthPixelL( ETextColumn, menuGenePaneT1Rect.Width() );    
+    columnData.SetGraphicsColumnL( EIconColumn, ETrue );
+    columnData.SetColumnFontL( ETextColumn, iFont );         
+    columnData.SetColumnBaselinePosL( ETextColumn,
+            iFont->HeightInPixels() + 
+            (menuGenePaneRect.Height() - iFont->HeightInPixels() - iFont->FontMaxDescent()) / 2 );
+        
+    AknLayoutUtils::LayoutMirrored() ? 
+        columnData.SetColumnAlignmentL( ETextColumn, CGraphicsContext::ERight ) : 
+        columnData.SetColumnAlignmentL( ETextColumn, CGraphicsContext::ELeft );
+
+    // Setup item height
+    columnData.SetItemCellSize( menuGenePaneRect.Size() );    
+    iListBox->SetItemHeightL( menuGenePaneRect.Height() );    
+    iListBox->SetBackgroundRect( menuPaneRect );  
+
+    UpdateListContentL( menuGenePaneG1Rect.Size() );
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LeftMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::LeftMargin( const TRect& aMenuPane, 
+        const TRect& aG1 ) const
+    {
+    FUNC_LOG;
+    if ( AknLayoutUtils::LayoutMirrored() )
+        {
+        return Abs( aMenuPane.iBr.iX - aG1.iBr.iX );
+        }
+    return Abs( aG1.iTl.iX - aMenuPane.iTl.iX );
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::MiddleMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::MiddleMargin( const TRect& aG1, 
+        const TRect& aT1 ) const
+    {
+    FUNC_LOG;
+    if ( AknLayoutUtils::LayoutMirrored() )
+        {
+        return Abs( aG1.iTl.iX - aT1.iBr.iX );
+        }
+    return Abs( aG1.iBr.iX - aT1.iTl.iX );
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::RightMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::RightMargin( const TRect& aMenuPane, 
+        const TRect& aT1 ) const
+    {
+    FUNC_LOG;
+    if ( AknLayoutUtils::LayoutMirrored() )
+        {
+        return Abs( aT1.iTl.iX - aMenuPane.iTl.iX );
+        }
+    return Abs( aMenuPane.iBr.iX - aT1.iBr.iX );    
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ConstructControlsL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ConstructControlsL()
+    {
+    FUNC_LOG;
+        
+    // Create list control
+    iListBox = new ( ELeave ) CFscContactActionMenuListBox();
+    iListBox->ConstructL( this );
+    iListBox->HandleItemAdditionL();
+    iListBox->SetFocus( ETrue );
+    iListBox->SetContainerWindowL( *this );
+    iListBox->SetListBoxObserver( this );           
+    // Set icon array
+    CArrayPtrFlat<CGulIcon>* iconArray = 
+        new (ELeave) CArrayPtrFlat<CGulIcon>( KGranularity );
+    iListBox->ItemDrawer()->ColumnData()->SetIconArray( iconArray );
+    LayoutPopupWindow();
+    }   
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ClearControls
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ClearControls()
+    {
+    FUNC_LOG;
+    
+    if ( iListBox )
+        {
+        delete iListBox;
+        iListBox = NULL;
+        }
+
+    }  
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateListL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::UpdateListContentL( const TSize& aIconSize )
+    {
+    FUNC_LOG;
+
+    CDesCArray* desArray =
+        static_cast<CDesCArray*>( iListBox->Model()->ItemTextArray() );
+    desArray->Reset();
+
+    CArrayPtr<CGulIcon>* iconArray = 
+        iListBox->ItemDrawer()->ColumnData()->IconArray();
+    iconArray->ResetAndDestroy(); // Remove old icons  
+    
+    TInt itemCount = iModel->VisibleItemCount();
+    for ( TInt i = 0; i < itemCount; i++ )
+        {
+        CFscContactActionMenuItem& item = iModel->VisibleItemL( i );
+        
+        const CGulIcon* origIcon = item.Icon();
+        ASSERT( origIcon != NULL );
+        
+        CGulIcon* icon = CGulIcon::NewL( 
+            origIcon->Bitmap(), origIcon->Mask() );
+        CleanupStack::PushL( icon );
+        icon->SetBitmapsOwnedExternally( ETrue );
+            
+        AknIconUtils::SetSize( icon->Bitmap(), aIconSize );
+        AknIconUtils::SetSize( icon->Mask(), aIconSize );
+        iconArray->AppendL(icon);
+        CleanupStack::Pop( icon );  
+        
+        const TDesC& text = item.MenuText();
+        HBufC* tempDes = HBufC::NewLC( 
+                text.Length() + KListItemTextFormat().Length() );
+        tempDes->Des().Format( KListItemTextFormat, i, &text );
+        desArray->AppendL( *tempDes );
+        CleanupStack::PopAndDestroy( tempDes );         
+        }
+                
+    iListBox->HandleItemAdditionL();
+    iListBox->UpdateScrollBarsL();
+
+    }
+   
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SetupMenuOffset
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::SetupMenuOffset()
+    {
+    FUNC_LOG;
+
+    switch( iState )
+        {
+        case EOut:
+        case ESlidingOut:
+            {
+            const TInt windowWidth( Rect().Width() );
+            // Menu is out of the screen
+            TInt newPos = 
+            AknLayoutUtils::LayoutMirrored() ? 
+                -windowWidth : windowWidth;
+            iMenuOffset.Set( newPos );    
+            }
+            break;
+        case EIn:
+        case ESlidingIn:
+            {
+            // Menu is visible
+            iMenuOffset.Set( 0 );
+            }
+            break;    
+        default:
+            {
+            //Nothing to do
+            break;
+            }  
+        }
+    
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateColors
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::UpdateColors()
+    {
+    FUNC_LOG;
+    
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance(); 
+    TRgb color;    
+        
+    // Highlight text color    
+    TInt error = AknsUtils::GetCachedColor( 
+        skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10 );    
+    if ( !error )
+        {
+        iListBox->ItemDrawer()->SetHighlightedTextColor( color );
+        }
+    else
+        {
+        error = AknsUtils::GetCachedColor( 
+            skin, color, KAknsIIDFsHighlightColors, EAknsCIFsHighlightColorsCG1 );
+        if ( !error )
+            {
+            iListBox->ItemDrawer()->SetHighlightedTextColor( color );
+            }
+        }
+        
+    // Text color
+    error = AknsUtils::GetCachedColor( 
+        skin, color, KAknsIIDFsTextColors, EAknsCIQsnTextColorsCG19 ); 
+    if ( !error )
+        { 
+        iListBox->ItemDrawer()->SetTextColor( color );
+        }
+    else
+        {
+        // if colors are not found from the skins, set the default values
+        error = AknsUtils::GetCachedColor( 
+            skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 );
+        if ( !error )
+            {
+            iListBox->ItemDrawer()->SetTextColor( color );
+            }
+        }
+               
+    }    
+    
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::MaxListTextWidth
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::MaxListTextWidth()
+    {
+    FUNC_LOG;
+    TPtrC itemText;
+    TInt maxLength( 0 );
+    for ( TInt i = 0; i < iModel->VisibleItemCount(); i++ )
+        {
+        TRAPD( error, itemText.Set( iModel->VisibleItemL( i ).MenuText() ) );
+        if ( !error )
+            {
+            TInt offset( itemText.LocateReverse( TChar('\t') ) );        
+            if ( offset != KErrNotFound && ++offset < itemText.Length() )
+                {
+                itemText.Set( itemText.Mid( offset ) );            
+                }        
+            const TInt length( AknBidiTextUtils::MeasureTextBoundsWidth(
+                *iFont, itemText, CFont::TMeasureTextInput::EFVisualOrder ) );
+            maxLength = length > maxLength ? length : maxLength;
+            }
+        }
+    return maxLength;
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateWindowPosition
+// ---------------------------------------------------------------------------
+//   
+TInt CFscContactActionMenuList::UpdateWindowPosition( TAny *aPtr )
+    {
+    FUNC_LOG;
+    CFscContactActionMenuList* list = 
+        static_cast<CFscContactActionMenuList*>( aPtr );
+    
+    TRect newRect( list->iOrigMenuRect ); 
+    newRect.Move( list->iMenuOffset.Now(), 0 ); 
+    list->SetPosition( newRect.iTl );
+
+    if ( !list->iMenuOffset.Interpolating() )
+        {
+        // Stop timer
+        list->iPeriodic->Cancel();
+        if ( list->iState == ESlidingOut )
+            { 
+            // Hide window totally
+            list->iState = EOut;
+            list->SetFocus( EFalse );
+            list->MakeVisible( EFalse );
+            static_cast< CEikonEnv* >
+                ( list->iCoeEnv )->EikAppUi()->RemoveFromStack( list );
+                
+            // Inform observer        
+            list->iObserver->HandleListEvent( 
+                MFscContactActionMenuListObserver::EFscMenuEventMenuHidden 
+                );        
+            }
+        else if ( list->iState == ESlidingIn )
+            {
+            list->iState = EIn;
+            }
+        }  
+              
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutPopupWindow
+// ---------------------------------------------------------------------------
+//   
+void CFscContactActionMenuList::LayoutPopupWindow( const TBool aLayoutChange )
+    {
+    FUNC_LOG;
+    // Application window
+    TRect applicationRect;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow,
+        applicationRect );
+
+    // Main 2 pane. This is the main pane that is used as parent layout
+    // for the popup menup pane in the layout data, but using this would
+    // make popup to overlap with the cba area.
+    TAknLayoutRect main2Pane;
+    main2Pane.LayoutRect( applicationRect, AknLayoutScalable_Apps::main2_pane(
+        Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 3 ) );
+    TRect main2PaneRect = main2Pane.Rect();
+
+    // Main pane
+    TRect mainPaneRect;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
+
+    // Menu pane
+    TAknLayoutRect menuPane;
+    menuPane.LayoutRect( mainPaneRect,
+        AknLayoutScalable_Apps::popup_sp_fs_action_menu_pane(
+            iModel->ItemCount() + 1 ) );
+
+    iOrigMenuRect = menuPane.Rect();
+    AdjustByContent( iOrigMenuRect );
+    if ( iPositionGiver )
+        {
+        TPoint customPos = iPositionGiver->ActionMenuPosition();
+        iOrigMenuRect.Move( 0, -iOrigMenuRect.iTl.iY + mainPaneRect.iTl.iY
+            + customPos.iY );
+        }
+
+    // Adjust menu pane position to keep it fully visible. The main2pane is
+    // used here to enable menu pane to overlap with status pane area.
+    if ( iOrigMenuRect.iTl.iY < main2PaneRect.iTl.iY )
+        {
+        iOrigMenuRect.Move( 0, main2PaneRect.iTl.iY - iOrigMenuRect.iTl.iY );
+        }
+    else if ( iOrigMenuRect.iBr.iY > main2PaneRect.iBr.iY )
+        {
+        iOrigMenuRect.Move( 0, main2PaneRect.iBr.iY - iOrigMenuRect.iBr.iY );
+        }
+
+    SetRect( iOrigMenuRect );
+
+    if ( !aLayoutChange )
+        {
+        const TInt width( iOrigMenuRect.Width() );
+        TPoint tl( iOrigMenuRect.iTl );
+        tl.iX += AknLayoutUtils::LayoutMirrored() ? -width : width;
+        SetPosition( tl );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::AdjustByContent
+// ---------------------------------------------------------------------------
+//   
+void CFscContactActionMenuList::AdjustByContent( TRect& aRect )
+    {
+    FUNC_LOG;
+    // Menu list pane
+    TAknLayoutRect menuListPane;
+    menuListPane.LayoutRect( aRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_pane( 
+                    Max( 0, iModel->ItemCount() - 1 ) ) );
+    const TRect menuPaneListRect( menuListPane.Rect() );
+
+    // Menu gene pane
+    TAknLayoutRect menuGenePane;
+    menuGenePane.LayoutRect( menuPaneListRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane( 0 ) );
+    const TRect menuGenePaneRect( menuGenePane.Rect() );
+           
+    // Menu gene pane g1
+    TAknLayoutRect menuGenePaneG1;
+    menuGenePaneG1.LayoutRect( menuGenePaneRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_g1( 0 ) );
+    const TRect menuGenePaneG1Rect( menuGenePaneG1.Rect() );
+    
+    // Menu gene pane t1
+    TAknLayoutText menuGenePaneT1;
+    menuGenePaneT1.LayoutText( menuGenePaneRect, 
+            AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_t1( 0 ) );
+    const TRect menuGenePaneT1Rect( menuGenePaneT1.TextRect() );
+    iFont = menuGenePaneT1.Font();
+
+    const TInt textColumnWidth( menuGenePaneT1Rect.Width() );    
+    const TInt maxTextWidth( MaxListTextWidth() + 
+            RightMargin( menuGenePaneRect, menuGenePaneT1Rect ) );
+
+    if ( maxTextWidth < textColumnWidth )
+        {
+        const TInt widthAdjustment( textColumnWidth - maxTextWidth );
+        if ( !AknLayoutUtils::LayoutMirrored() )
+            {
+            aRect.Move( widthAdjustment, 0 );
+            }
+        aRect.Resize( -widthAdjustment, 0 );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SizeChanged
+// ---------------------------------------------------------------------------
+//   
+void CFscContactActionMenuList::SizeChanged()
+    {
+    FUNC_LOG;
+    LayoutList();
+    }
+
+//</cmail>
+