emailuis/emailui/src/FreestyleMessageHeaderURLEventHandler.cpp
branchRCL_3
changeset 61 dcf0eedfc1a3
parent 52 efd4f1afd43e
--- a/emailuis/emailui/src/FreestyleMessageHeaderURLEventHandler.cpp	Thu Jul 15 18:19:25 2010 +0300
+++ b/emailuis/emailui/src/FreestyleMessageHeaderURLEventHandler.cpp	Thu Aug 19 09:38:05 2010 +0300
@@ -31,11 +31,11 @@
 #include <brctldefs.h>
 #include <e32std.h>
 #include <eikmobs.h>
-#include <coemain.h>  
+#include <coemain.h>
 #include <schemehandler.h>
 
-EXPORT_C CFreestyleMessageHeaderURLEventHandler* CFreestyleMessageHeaderURLEventHandler::NewL( 
-        CFreestyleEmailUiAppUi& aAppUi, 
+EXPORT_C CFreestyleMessageHeaderURLEventHandler* CFreestyleMessageHeaderURLEventHandler::NewL(
+        CFreestyleEmailUiAppUi& aAppUi,
         CFsEmailUiHtmlViewerView& aView )
     {
     CFreestyleMessageHeaderURLEventHandler* obj = new (ELeave) CFreestyleMessageHeaderURLEventHandler( aAppUi, aView );
@@ -45,54 +45,54 @@
     return obj;
     }
 
-CFreestyleMessageHeaderURLEventHandler::CFreestyleMessageHeaderURLEventHandler( 
-        CFreestyleEmailUiAppUi& aAppUi, 
+CFreestyleMessageHeaderURLEventHandler::CFreestyleMessageHeaderURLEventHandler(
+        CFreestyleEmailUiAppUi& aAppUi,
         CFsEmailUiHtmlViewerView& aView )
-    : iAppUi( aAppUi ), 
-    iView( aView ), 
-    iMailMessage( NULL ), 
+    : iAppUi( aAppUi ),
+    iView( aView ),
+    iMailMessage( NULL ),
     iAttachmentsListModel( NULL )
     {
     }
 
 void CFreestyleMessageHeaderURLEventHandler::ConstructL()
     {
-    iMessageHeaderURL = CFreestyleMessageHeaderURL::NewL();   
+    iMessageHeaderURL = CFreestyleMessageHeaderURL::NewL();
     iHTMLReloadAO = CFSHtmlReloadAO::NewL(iView);
-    
+
     }
 
 CFreestyleMessageHeaderURLEventHandler::~CFreestyleMessageHeaderURLEventHandler ()
     {
     delete iMessageHeaderURL;
-    delete iHTMLReloadAO; 
+    delete iHTMLReloadAO;
     if( iEmailAddressStylusPopup )
         {
-        delete iEmailAddressStylusPopup; 
+        delete iEmailAddressStylusPopup;
         }
-    
+
     if( iAttachmentStylusPopup )
         {
-        delete iAttachmentStylusPopup; 
+        delete iAttachmentStylusPopup;
         }
-    
+
     if( iWebAddressStylusPopup )
         {
-        delete iWebAddressStylusPopup; 
-        }   
-    
+        delete iWebAddressStylusPopup;
+        }
+
     delete iUrl;
     }
 
 EXPORT_C TBool CFreestyleMessageHeaderURLEventHandler::HandleEventL( const TDesC& aUri )
     {
-    iMailMessage = iView.CurrentMessage(); 
+    iMailMessage = iView.CurrentMessage();
     iAttachmentsListModel = iView.CurrentAttachmentsListModel();
-    
+
     if ( ! CFreestyleMessageHeaderURL::IsMessageHeaderURL( aUri ) )
         {
         //Handle http and https links
-        if( ( aUri.FindF( KURLHttpPrefix ) ) == 0 
+        if( ( aUri.FindF( KURLHttpPrefix ) ) == 0
                 ||( aUri.FindF( KURLHttpsPrefix ) ) == 0 )
             {
             if ( iUrl )
@@ -103,7 +103,7 @@
             iUrl = aUri.AllocL();
             LaunchWebAddressMenuL( );
             return ETrue;
-            }         
+            }
         //Link wasn't handled
         return EFalse;
         }
@@ -148,8 +148,12 @@
  */
 void CFreestyleMessageHeaderURLEventHandler::LaunchEmailAddressMenuL()
     {
+    if ( LaunchEmailAddressMenuHWKeyL() )
+        {
+        return;
+        }
     
-    //Change the creation of the stylus menu here to avoid crash when calling SetItemDimmed(ETrue) multiple times 
+    //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)
@@ -157,25 +161,53 @@
        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.ClientRect().Center(), 
+
+    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:
@@ -187,37 +219,37 @@
             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;      
+            break;
             }
-            
+
         case EFsEmailUiCmdActionsOpenWeb:
         case EFsEmailUiCmdActionsAddBookmark:
         case EFsEmailUiCmdActionsCopyWWWAddressToClipboard:
@@ -225,18 +257,18 @@
             iView.HandleWebAddressCommandL( aCommand, *iUrl );
             break;
             }
-            
+
         }
     }
 
-const TAttachmentData& CFreestyleMessageHeaderURLEventHandler::FindAttachmentL( 
+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++)
         {
@@ -246,10 +278,10 @@
             break;
             }
         }
-    
+
     if ( found == KErrNotFound )
         {
-        // Probably, only the headers were downloaded. Check if attachments 
+        // Probably, only the headers were downloaded. Check if attachments
         // were downloaded later.
         if( iMailMessage )
             {
@@ -269,15 +301,21 @@
             User::Leave( KErrNotFound );
             }
         }
-    
+
     return iAttachmentsListModel->GetModel()[found];
     }
 
-void CFreestyleMessageHeaderURLEventHandler::LaunchAttachmentMenuL( 
+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.
@@ -292,36 +330,116 @@
     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( 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 ) )
         {        
-        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelDownload, EFalse );  
+        popup->SetDimmed( EFsEmailUiCmdCancelDownload, EFalse );  
         }
     else if ( aAttachment.downloadProgress == KComplete )
         {
-        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+        popup->SetDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
         
         // block saving of embedded messages if needed.
         if ( iView.IsEmbeddedMsgView() )
             {
             if ( iView.IsEmbeddedMsgSavingAllowed() || !isMessage )
                 {
-                iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, EFalse );    
+                popup->SetDimmed( EFsEmailUiCmdSave, EFalse );    
                 }              
             }
         else
             {
-            iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, isMessage && !iView.IsEmbeddedMsgSavingAllowed() );
+            popup->SetDimmed( EFsEmailUiCmdSave, isMessage && !iView.IsEmbeddedMsgSavingAllowed() );
             }
         
         if ( iAttachmentsListModel->GetModel().Count() > 1 )
@@ -333,37 +451,48 @@
                 // are any message type attachments. This is due to limitations of Activesync plugin.
                 if( !(iView.IsEmbeddedMsgView() && iAttachmentsListModel->IsThereAnyMessageAttachments()) )
                     {
-                    iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSaveAll, EFalse );    
+                    popup->SetDimmed( EFsEmailUiCmdSaveAll, EFalse );    
                     }
                 }
             }         
         }
     else
         {
-        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
-        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSave, isMessage ); 
+        popup->SetDimmed( EFsEmailUiCmdOpenAttachment, EFalse );
+        popup->SetDimmed( EFsEmailUiCmdSave, isMessage ); 
         if ( iAttachmentsListModel->GetModel().Count() > 1 )
             {
-            iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdSaveAll,
+            popup->SetDimmed( EFsEmailUiCmdSaveAll,
                     iAttachmentsListModel->IsThereAnyMessageAttachments() && !iView.IsEmbeddedMsgSavingAllowed() );
             }         
         }
 
     if ( iAttachmentsListModel->IsMultiplyDownloadsOngoing() )
         {
-        iAttachmentStylusPopup->SetItemDimmed( EFsEmailUiCmdCancelAllDownloads, EFalse );
+        popup->SetDimmed( EFsEmailUiCmdCancelAllDownloads, EFalse );
         }
     
-    iAttachmentStylusPopup->SetPosition( iAppUi.LastSeenPointerPosition(), 
-                                         CAknStylusPopUpMenu::EPositionTypeLeftTop );
-    iAttachmentStylusPopup->ShowMenu();
+    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()
     {
-    
-    //Change the creation of the stylus menu here to avoid crash when calling SetItemDimmed(ETrue) multiple times 
+    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 )
@@ -371,19 +500,44 @@
         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.ClientRect().Center(), 
+
+    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*/)
     {
@@ -398,3 +552,141 @@
     {
     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 );
+        }
+    }
+