emailuis/emailui/src/FreestyleMessageHeaderURLEventHandler.cpp
branchRCL_3
changeset 25 3533d4323edc
child 26 968773a0b6ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/FreestyleMessageHeaderURLEventHandler.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,692 @@
+/*
+* Copyright (c) 2007-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:  Message header URL event handler
+*
+*/
+
+#include "FreestyleMessageHeaderURLEventHandler.h"
+#include "FreestyleMessageHeaderURL.h"
+#include "FreestyleEmailUiConstants.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "cfsmailmessage.h"
+#include "FreestyleEmailUiAppui.h"
+#include "FreestyleEmailUiHtmlViewerView.h"
+#include "FreestyleEmailUi.hrh"
+#include "FreestyleEmailUi.rsg"
+#include "FSHtmlReloadAO.h"
+
+#include <aknnotewrappers.h>
+#include <aknstyluspopupmenu.h>
+#include <brctldefs.h>
+#include <e32std.h>
+#include <eikmobs.h>
+#include <coemain.h>
+#include <schemehandler.h>
+
+EXPORT_C CFreestyleMessageHeaderURLEventHandler* CFreestyleMessageHeaderURLEventHandler::NewL(
+        CFreestyleEmailUiAppUi& aAppUi,
+        CFsEmailUiHtmlViewerView& aView )
+    {
+    CFreestyleMessageHeaderURLEventHandler* obj = new (ELeave) CFreestyleMessageHeaderURLEventHandler( aAppUi, aView );
+    CleanupStack::PushL( obj );
+    obj->ConstructL();
+    CleanupStack::Pop( obj );
+    return obj;
+    }
+
+CFreestyleMessageHeaderURLEventHandler::CFreestyleMessageHeaderURLEventHandler(
+        CFreestyleEmailUiAppUi& aAppUi,
+        CFsEmailUiHtmlViewerView& aView )
+    : iAppUi( aAppUi ),
+    iView( aView ),
+    iMailMessage( NULL ),
+    iAttachmentsListModel( NULL )
+    {
+    }
+
+void CFreestyleMessageHeaderURLEventHandler::ConstructL()
+    {
+    iMessageHeaderURL = CFreestyleMessageHeaderURL::NewL();
+    iHTMLReloadAO = CFSHtmlReloadAO::NewL(iView);
+
+    }
+
+CFreestyleMessageHeaderURLEventHandler::~CFreestyleMessageHeaderURLEventHandler ()
+    {
+    delete iMessageHeaderURL;
+    delete iHTMLReloadAO;
+    if( iEmailAddressStylusPopup )
+        {
+        delete iEmailAddressStylusPopup;
+        }
+
+    if( iAttachmentStylusPopup )
+        {
+        delete iAttachmentStylusPopup;
+        }
+
+    if( iWebAddressStylusPopup )
+        {
+        delete iWebAddressStylusPopup;
+        }
+
+    delete iUrl;
+    }
+
+EXPORT_C TBool CFreestyleMessageHeaderURLEventHandler::HandleEventL( const TDesC& aUri )
+    {
+    iMailMessage = iView.CurrentMessage();
+    iAttachmentsListModel = iView.CurrentAttachmentsListModel();
+
+    if ( ! CFreestyleMessageHeaderURL::IsMessageHeaderURL( aUri ) )
+        {
+        //Handle http and https links
+        if( ( aUri.FindF( KURLHttpPrefix ) ) == 0
+                ||( aUri.FindF( KURLHttpsPrefix ) ) == 0 )
+            {
+            if ( iUrl )
+                {
+                delete iUrl;
+                iUrl = NULL;
+                }
+            iUrl = aUri.AllocL();
+            LaunchWebAddressMenuL( );
+            return ETrue;
+            }
+        //Link wasn't handled
+        return EFalse;
+        }
+    else
+        {
+        //URL is of the message header format, hence parse it
+        iMessageHeaderURL->InternalizeL( aUri );
+        iMenuVisible = ETrue;
+        if ( ( iMessageHeaderURL->Type()->CompareF( KURLTypeTo ) == 0 )
+             || ( iMessageHeaderURL->Type()->CompareF( KURLTypeFrom ) == 0 )
+             || ( iMessageHeaderURL->Type()->CompareF( KURLTypeCc ) == 0 ) )
+            {
+            LaunchEmailAddressMenuL( );
+            }
+
+        else if ( ( iMessageHeaderURL->Type()->CompareF( KURLTypeAttachment ) == 0 ) )
+            {
+            LaunchAttachmentMenuL( FindAttachmentL( *iMessageHeaderURL ) );
+            }
+        else if ( iMessageHeaderURL->Type()->CompareF( KURLTypeSubject ) )
+            {
+            CSchemeHandler* handler = CSchemeHandler::NewL( aUri );
+            CleanupStack::PushL( handler );
+            handler->HandleUrlStandaloneL();
+            CleanupStack::PopAndDestroy( handler );
+            }
+        iMenuVisible=EFalse;
+        if( iPendingReload )
+            {
+            //Load web page aysnchronously
+            iHTMLReloadAO->ReloadPageAysnc();
+            iPendingReload=EFalse;
+            }
+        return ETrue;
+        }
+    }
+
+/*
+ * Launches the avkon stylus popup and dims the inappropriate menu items and handles the user
+ * menu item selection.
+ * @param aType the type of the link the user selected
+ */
+void CFreestyleMessageHeaderURLEventHandler::LaunchEmailAddressMenuL()
+    {
+    if ( LaunchEmailAddressMenuHWKeyL() )
+        {
+        return;
+        }
+    
+    //Change the creation of the stylus menu here to avoid crash when calling SetItemDimmed(ETrue) multiple times
+    //on same instance of the menu (if created only once in constructor).
+    //Creating the menu everytime the user clicks on the link avoids this crash however performance is affected.
+    if( iEmailAddressStylusPopup)
+       {
+       delete iEmailAddressStylusPopup;
+       iEmailAddressStylusPopup = NULL;
+       }
+
+    TPoint point( 0, 0 );
+    iEmailAddressStylusPopup = CAknStylusPopUpMenu::NewL( this , point );
+    TResourceReader reader;
+    CCoeEnv::Static()->CreateResourceReaderLC( reader, R_STYLUS_POPUP_MENU_HTML_VIEW_EMAIL_ADDRESS );
+    iEmailAddressStylusPopup->ConstructFromResourceL( reader );
+    CleanupStack::PopAndDestroy(); //resource reader
+
+    iEmailAddressStylusPopup->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup,
+                                             !iView.IsRemoteLookupSupportedL() );
+    iEmailAddressStylusPopup->SetPosition( iAppUi.LastSeenPointerPosition(),
+                                           CAknStylusPopUpMenu::EPositionTypeRightBottom );
+    iEmailAddressStylusPopup->ShowMenu();
+    }
+
+
+TBool CFreestyleMessageHeaderURLEventHandler::LaunchEmailAddressMenuHWKeyL()
+    {
+    TInt wsEventType = iAppUi.LastSeenWsEventType();
+    if ( wsEventType != EEventKey )
+        {
+        return EFalse; // only hw key event handled here
+        }
+
+    CFreestylePopupMenu* popup = CFreestylePopupMenu::NewL( R_STYLUS_POPUP_MENU_HTML_VIEW_EMAIL_ADDRESS );
+    CleanupStack::PushL( popup );
+
+    popup->SetDimmed( EFsEmailUiCmdActionsRemoteLookup, 
+                     !iView.IsRemoteLookupSupportedL() );
+
+    TInt commandId = popup->LaunchPopupMenuL();
+
+    CleanupStack::PopAndDestroy( popup );
+   
+    if ( commandId != KErrCancel )
+        {
+        ProcessCommandL( commandId );
+        }
+    
+    return ETrue;
+    }
+
+
+//From MEikMenuObserver
+void CFreestyleMessageHeaderURLEventHandler::ProcessCommandL( TInt aCommand )
+    {
+
+    switch ( aCommand )
+        {
+        case EFsEmailUiCmdActionsReply:
+        case EFsEmailUiCmdActionsAddContact:
+        case EFsEmailUiCmdActionsRemoteLookup:
+        case EFsEmailUiCmdActionsCopyToClipboard:
+        case EFsEmailUiCmdActionsContactDetails:
+            {
+            iView.HandleEmailAddressCommandL( aCommand, *iMessageHeaderURL->ItemId() );
+            break;
+            }
+
+        case EFsEmailUiCmdCancelDownload:
+            {
+            iView.CancelAttachmentL( FindAttachmentL( *iMessageHeaderURL ) );
+            break;
+            }
+
+        case EFsEmailUiCmdCancelAllDownloads:
+            {
+            iView.CancelAllAttachmentsL();
+            break;
+            }
+
+        case EFsEmailUiCmdOpenAttachment:
+            {
+            iView.OpenAttachmentL( FindAttachmentL( *iMessageHeaderURL ) );
+            break;
+            }
+
+        case EFsEmailUiCmdSave:
+            {
+            iView.SaveAttachmentL( FindAttachmentL( *iMessageHeaderURL ) );
+            break;
+            }
+
+        case EFsEmailUiCmdSaveAll:
+            {
+            iView.SaveAllAttachmentsL( );
+            break;
+            }
+
+        case EFsEmailUiCmdActionsOpenWeb:
+        case EFsEmailUiCmdActionsAddBookmark:
+        case EFsEmailUiCmdActionsCopyWWWAddressToClipboard:
+            {
+            iView.HandleWebAddressCommandL( aCommand, *iUrl );
+            break;
+            }
+
+        }
+    }
+
+const TAttachmentData& CFreestyleMessageHeaderURLEventHandler::FindAttachmentL(
+        const CFreestyleMessageHeaderURL& aAttachmentUrl )
+    {
+    User::LeaveIfNull( iAttachmentsListModel );
+    TUint id;
+    TLex parser( *aAttachmentUrl.ItemId() );
+    parser.Val( id );
+
+    TInt found = KErrNotFound;
+    for (TInt i=0; i<iAttachmentsListModel->GetModel().Count(); i++)
+        {
+        if ( iAttachmentsListModel->GetModel()[i].partData.iMessagePartId.Id() == id )
+            {
+            found = i;
+            break;
+            }
+        }
+
+    if ( found == KErrNotFound )
+        {
+        // Probably, only the headers were downloaded. Check if attachments
+        // were downloaded later.
+        if( iMailMessage )
+            {
+            iAttachmentsListModel->UpdateListL( iMailMessage );
+            }
+        for (TInt i=0; i<iAttachmentsListModel->GetModel().Count(); i++)
+            {
+            if ( iAttachmentsListModel->GetModel()[i].partData.iMessagePartId.Id() == id )
+                {
+                found = i;
+                break;
+                }
+            }
+
+        if ( found == KErrNotFound )
+            {
+            User::Leave( KErrNotFound );
+            }
+        }
+
+    return iAttachmentsListModel->GetModel()[found];
+    }
+
+void CFreestyleMessageHeaderURLEventHandler::LaunchAttachmentMenuL(
+        const TAttachmentData& aAttachment )
+    {
+    ASSERT( iAppUi.DownloadInfoMediator() );
+    
+    if ( LaunchAttachmentMenuHWKeyL( aAttachment ) )
+        {
+        return;
+        }
+    
+    
+    //Change the creation of the stylus menu here to avoid crash when calling SetItemDimmed(ETrue) multiple times 
+    //on same instance of the menu (if created only once in constructor).
+    //Creating the menu everytime the user clicks on the link avoids this crash however performance is affected.
+    if( iAttachmentStylusPopup )
+       {
+       delete iAttachmentStylusPopup;
+       iAttachmentStylusPopup = NULL;
+       }
+    TPoint point( 0, 0 );
+    iAttachmentStylusPopup = CAknStylusPopUpMenu::NewL( this , point );
+    TResourceReader reader;
+    CCoeEnv::Static()->CreateResourceReaderLC( reader, R_STYLUS_POPUP_MENU_HTML_VIEW_ATTACHMENT );
+    iAttachmentStylusPopup->ConstructFromResourceL( reader );
+    CleanupStack::PopAndDestroy(); //resource reader
+
+
+    //Dim all item by default
+    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdOpenAttachment, ETrue );
+    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, ETrue );
+    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSaveAll, ETrue );
+    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelDownload, ETrue );
+    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelAllDownloads, ETrue );
+
+    const TBool isMessage( iAttachmentsListModel->IsMessage( aAttachment ) );
+
+    if ( iAppUi.DownloadInfoMediator()->IsDownloading( aAttachment.partData.iMessagePartId ) )
+        {
+        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelDownload, EFalse );
+        }
+    else if ( aAttachment.downloadProgress == KComplete )
+        {
+        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+
+        // block saving of embedded messages if needed.
+        if ( iView.IsEmbeddedMsgView() )
+            {
+            if ( iView.IsEmbeddedMsgSavingAllowed() || !isMessage )
+                {
+                iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, EFalse );
+                }
+            }
+        else
+            {
+            iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, isMessage && !iView.IsEmbeddedMsgSavingAllowed() );
+            }
+
+        if ( iAttachmentsListModel->GetModel().Count() > 1 )
+            {
+            // Save all cannot be shown if there is one message attachment and saving is not supported
+            if ( !( iAttachmentsListModel->IsThereAnyMessageAttachments() && !iView.IsEmbeddedMsgSavingAllowed() ) )
+                {
+                // In embedded message mode, save all needs to be blocked if there
+                // are any message type attachments. This is due to limitations of Activesync plugin.
+                if( !(iView.IsEmbeddedMsgView() && iAttachmentsListModel->IsThereAnyMessageAttachments()) )
+                    {
+                    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSaveAll, EFalse );
+                    }
+                }
+            }
+        }
+    else
+        {
+        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, isMessage );
+        if ( iAttachmentsListModel->GetModel().Count() > 1 )
+            {
+            iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSaveAll,
+                    iAttachmentsListModel->IsThereAnyMessageAttachments() && !iView.IsEmbeddedMsgSavingAllowed() );
+            }
+        }
+
+    if ( iAttachmentsListModel->IsMultiplyDownloadsOngoing() )
+        {
+        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelAllDownloads, EFalse );
+        }
+
+    iAttachmentStylusPopup->SetPosition( iAppUi.LastSeenPointerPosition(),
+                                         CAknStylusPopUpMenu::EPositionTypeRightBottom );
+    iAttachmentStylusPopup->ShowMenu();
+    }
+
+
+TBool CFreestyleMessageHeaderURLEventHandler::LaunchAttachmentMenuHWKeyL( 
+        const TAttachmentData& aAttachment )
+    {
+    ASSERT( iAppUi.DownloadInfoMediator() );
+    
+    TInt wsEventType = iAppUi.LastSeenWsEventType();
+    if ( wsEventType != EEventKey )
+        {
+        return EFalse; // only hw key event handled here
+        }
+
+    CFreestylePopupMenu* popup = CFreestylePopupMenu::NewL( R_STYLUS_POPUP_MENU_HTML_VIEW_ATTACHMENT );
+    CleanupStack::PushL( popup );
+    
+    //Dim all item by default
+    popup->SetDimmed( EFsEmailUiCmdOpenAttachment, ETrue );
+    popup->SetDimmed( EFsEmailUiCmdSave, ETrue );
+    popup->SetDimmed( EFsEmailUiCmdSaveAll, ETrue );
+    popup->SetDimmed( EFsEmailUiCmdCancelDownload, ETrue );   
+    popup->SetDimmed( EFsEmailUiCmdCancelAllDownloads, ETrue );
+
+    const TBool isMessage( iAttachmentsListModel->IsMessage( aAttachment ) );
+    
+    if ( iAppUi.DownloadInfoMediator()->IsDownloading( aAttachment.partData.iMessagePartId ) )
+        {        
+        popup->SetDimmed( EFsEmailUiCmdCancelDownload, EFalse );  
+        }
+    else if ( aAttachment.downloadProgress == KComplete )
+        {
+        popup->SetDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+        
+        // block saving of embedded messages if needed.
+        if ( iView.IsEmbeddedMsgView() )
+            {
+            if ( iView.IsEmbeddedMsgSavingAllowed() || !isMessage )
+                {
+                popup->SetDimmed( EFsEmailUiCmdSave, EFalse );    
+                }              
+            }
+        else
+            {
+            popup->SetDimmed( EFsEmailUiCmdSave, isMessage && !iView.IsEmbeddedMsgSavingAllowed() );
+            }
+        
+        if ( iAttachmentsListModel->GetModel().Count() > 1 )
+            {
+            // Save all cannot be shown if there is one message attachment and saving is not supported
+            if ( !( iAttachmentsListModel->IsThereAnyMessageAttachments() && !iView.IsEmbeddedMsgSavingAllowed() ) )
+                {
+                // In embedded message mode, save all needs to be blocked if there
+                // are any message type attachments. This is due to limitations of Activesync plugin.
+                if( !(iView.IsEmbeddedMsgView() && iAttachmentsListModel->IsThereAnyMessageAttachments()) )
+                    {
+                    popup->SetDimmed( EFsEmailUiCmdSaveAll, EFalse );    
+                    }
+                }
+            }         
+        }
+    else
+        {
+        popup->SetDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+        popup->SetDimmed( EFsEmailUiCmdSave, isMessage ); 
+        if ( iAttachmentsListModel->GetModel().Count() > 1 )
+            {
+            popup->SetDimmed( EFsEmailUiCmdSaveAll,
+                    iAttachmentsListModel->IsThereAnyMessageAttachments() && !iView.IsEmbeddedMsgSavingAllowed() );
+            }         
+        }
+
+    if ( iAttachmentsListModel->IsMultiplyDownloadsOngoing() )
+        {
+        popup->SetDimmed( EFsEmailUiCmdCancelAllDownloads, EFalse );
+        }
+    
+    TInt commandId = popup->LaunchPopupMenuL();
+
+    CleanupStack::PopAndDestroy( popup );
+       
+    if ( commandId != KErrCancel )
+        {
+        ProcessCommandL( commandId );
+        }
+    
+    return ETrue;    
+    }
+
+//Open the Avkon stylus popup when a web address link was pressed
+void CFreestyleMessageHeaderURLEventHandler::LaunchWebAddressMenuL()
+    {
+    if ( LaunchWebAddressMenuHWKeyL() )
+        {
+        return;
+        }
+        
+    //Change the creation of the stylus menu here to avoid crash when calling SetItemDimmed(ETrue) multiple times
+    //on same instance of the menu (if created only once in constructor).
+    //Creating the menu everytime the user clicks on the link avoids this crash however performance is affected.
+    if( iWebAddressStylusPopup )
+        {
+        delete iWebAddressStylusPopup;
+        iWebAddressStylusPopup = NULL;
+        }
+
+    TPoint point( 0, 0 );
+    iWebAddressStylusPopup = CAknStylusPopUpMenu::NewL( this , point );
+    TResourceReader reader;
+    CCoeEnv::Static()->CreateResourceReaderLC( reader, R_STYLUS_POPUP_MENU_HTML_VIEW_WEB_ADDRESS );
+    iWebAddressStylusPopup->ConstructFromResourceL( reader );
+    CleanupStack::PopAndDestroy(); //resource reader
+
+    iWebAddressStylusPopup->SetPosition( iAppUi.LastSeenPointerPosition(),
+                                           CAknStylusPopUpMenu::EPositionTypeRightBottom );
+    iWebAddressStylusPopup->ShowMenu();
+    }
+
+
+TBool CFreestyleMessageHeaderURLEventHandler::LaunchWebAddressMenuHWKeyL()
+    {
+    TInt wsEventType = iAppUi.LastSeenWsEventType();
+    if ( wsEventType != EEventKey )
+        {
+        return EFalse; // only hw key event handled here
+        }
+
+    CFreestylePopupMenu* popup = CFreestylePopupMenu::NewL( R_STYLUS_POPUP_MENU_HTML_VIEW_WEB_ADDRESS );
+    CleanupStack::PushL( popup );
+
+    TInt commandId = popup->LaunchPopupMenuL();
+
+    CleanupStack::PopAndDestroy( popup );
+       
+    if ( commandId != KErrCancel )
+        {
+        ProcessCommandL( commandId );
+        }
+        
+    return ETrue;
+    }
+
+
+//From MEikMenuObserver
+void CFreestyleMessageHeaderURLEventHandler::SetEmphasis(CCoeControl* /*aMenuControl*/,TBool /*aEmphasis*/)
+    {
+    }
+
+void CFreestyleMessageHeaderURLEventHandler::DismissMenuAndReload()
+    {
+        CFSEmailUiActionMenu::Dismiss(ETrue);
+        iPendingReload=ETrue;
+    }
+TBool CFreestyleMessageHeaderURLEventHandler::IsMenuVisible()
+    {
+    return iMenuVisible;
+    }
+/******************************************************************************
+ * class CFreestylePopupMenu
+ ******************************************************************************/
+
+
+CFreestylePopupMenu* CFreestylePopupMenu::NewL( TInt aResourceId )
+    {
+    CFreestylePopupMenu* self = new (ELeave) CFreestylePopupMenu( aResourceId );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CFreestylePopupMenu::CFreestylePopupMenu( TInt aResourceId )
+    {
+    iResourceId = aResourceId;
+    }
+
+void CFreestylePopupMenu::ConstructL()
+    {
+    TResourceReader reader;
+    CCoeEnv::Static()->CreateResourceReaderLC( reader, iResourceId );
+    
+    ConstructFromResourceL( reader );
+    
+    CleanupStack::PopAndDestroy();  // TResourceReader
+    }
+
+CFreestylePopupMenu::~CFreestylePopupMenu()
+    {
+    iItemList.Close();
+    }
+
+TInt CFreestylePopupMenu::LaunchPopupMenuL()
+    {
+    TInt selectedOption = KErrNotFound;
+    CDesCArrayFlat* arr = new (ELeave) CDesCArrayFlat( 5 );
+    CleanupStack::PushL( arr );
+
+    TInt count = iItemList.Count();
+    for ( TInt i=0; i<count; i++ )
+        {
+        TPopupMenuItem& item = iItemList[i];
+        item.iListIndex = KErrNotFound;
+        if ( !item.iDimmed )
+            {
+            arr->AppendL( item.iText );
+            item.iListIndex = arr->MdcaCount() - 1;
+            }
+        }
+
+    CAknListQueryDialog* dialog = new (ELeave) CAknListQueryDialog( &selectedOption );
+    dialog->PrepareLC( R_DRAFT_QUERY_DIALOG );
+    dialog->SetItemTextArray( arr );
+    dialog->SetOwnershipType( ELbmDoesNotOwnItemArray );
+
+    TInt ret = dialog->RunLD();
+
+    CleanupStack::PopAndDestroy( arr );
+        
+    TInt commandId = KErrCancel;
+    if ( ret )
+        {
+        commandId = CommandIdFromListIndex( selectedOption );
+        }
+    
+    return commandId;
+    }
+
+
+void CFreestylePopupMenu::SetDimmed( TInt aCommandId, TBool aDimmed )
+    {
+    TInt count = iItemList.Count();
+    
+    for ( TInt i=0; i<count; i++ )
+        {
+        TPopupMenuItem& item = iItemList[i];
+        if ( item.iCommandId == aCommandId )
+            {
+            item.iDimmed = aDimmed;
+            break;
+            }
+        }
+    }
+
+
+TInt CFreestylePopupMenu::CommandIdFromListIndex( TInt aListIndex )
+    {
+    TInt ret = KErrCancel;
+    
+    TInt count = iItemList.Count();
+    
+    for ( TInt i=0; i<count; i++ )
+        {
+        TPopupMenuItem& item = iItemList[i];
+        if ( item.iListIndex == aListIndex )
+            {
+            ret = item.iCommandId; 
+            break;
+            }
+        }
+    
+    return ret;
+    }
+
+void CFreestylePopupMenu::ConstructFromResourceL( TResourceReader& aReader )
+    {
+    TInt count = aReader.ReadInt16();
+
+    for ( TInt i=0; i<count; i++ )
+        {
+        TPopupMenuItem item;
+    
+        TPtrC ptr = aReader.ReadTPtrC();
+        StrCopy( item.iText, ptr );
+        item.iCommandId = aReader.ReadInt32();
+        item.iDimmed = EFalse;
+        item.iListIndex = KErrNotFound;
+        iItemList.AppendL( item );
+        
+        aReader.ReadInt32(); // extension link
+        }
+    }
+
+void CFreestylePopupMenu::StrCopy( TDes& aTarget, const TDesC& aSource )
+    {
+    TInt len = aTarget.MaxLength();
+    if( len < aSource.Length() ) 
+        {
+        aTarget.Copy( aSource.Left( len ) );
+        }
+    else
+        {
+        aTarget.Copy( aSource );
+        }
+    }
+