[Libreoffice-commits] .: Branch 'feature/unitymenus' - 3 commits - vcl/inc vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Sep 13 12:09:17 PDT 2012


 vcl/inc/unx/gtk/gloactiongroup.h      |    4 
 vcl/inc/unx/gtk/glomenu.h             |    6 +
 vcl/inc/unx/gtk/gtksalmenu.hxx        |   12 +-
 vcl/source/window/menu.cxx            |    5 
 vcl/unx/gtk/window/gloactiongroup.cxx |   59 +++++++++--
 vcl/unx/gtk/window/glomenu.cxx        |   28 +++++
 vcl/unx/gtk/window/gtksalmenu.cxx     |  177 +++++++++++++++++++++++++++++-----
 7 files changed, 249 insertions(+), 42 deletions(-)

New commits:
commit 1316b2293bb9cfae49e36db3645759b688cf63e9
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Thu Sep 13 20:08:07 2012 +0100

    Fixed a crash when opening an application from LO main screen.
    
    Change-Id: I942bcf761c7b9ba11c47bc618d55bdc85a472705

diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 1476e61..94e13a1 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -20,7 +20,7 @@
  * Author: Antonio Fernández <antonio.fernandez at aentos.es>
  */
 
-#include "unx/gtk/gtksalmenu.hxx"
+#include <unx/gtk/gtksalmenu.hxx>
 
 //#include <gtk/gtk.h>
 #include <unx/gtk/glomenu.h>
@@ -421,7 +421,7 @@ GtkSalMenu::GtkSalMenu( sal_Bool bMenuBar ) :
 GtkSalMenu::~GtkSalMenu()
 {
     if ( mbMenuBar == sal_True ) {
-        g_source_remove_by_user_data( this );
+//        g_source_remove_by_user_data( this );
 
         ((GtkSalFrame*) mpFrame)->SetMenu( NULL );
 
commit 872944ec078f6fd8e2de7d3001b8768b8c00b107
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Wed Sep 12 20:45:31 2012 +0100

    Menus are generated on demand now, but with some issues.
    
    Change-Id: Icec9b685e720a369cff4d2bbfc5bf4ba6614e390

diff --git a/vcl/inc/unx/gtk/gloactiongroup.h b/vcl/inc/unx/gtk/gloactiongroup.h
index e0d783f..61ec718 100644
--- a/vcl/inc/unx/gtk/gloactiongroup.h
+++ b/vcl/inc/unx/gtk/gloactiongroup.h
@@ -67,11 +67,13 @@ GLOActionGroup *    g_lo_action_group_new                   (gpointer
 
 void                g_lo_action_group_insert                (GLOActionGroup     *group,
                                                              const gchar        *action_name,
-                                                             gint                item_id);
+                                                             gint                item_id,
+                                                             gboolean            submenu);
 
 void                g_lo_action_group_insert_stateful       (GLOActionGroup     *group,
                                                              const gchar        *action_name,
                                                              gint                item_id,
+                                                             gboolean            submenu,
                                                              const GVariantType *parameter_type,
                                                              const GVariantType *state_type,
                                                              GVariant           *state_hint,
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index d7d5966..56aed28 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -55,7 +55,7 @@ private:
     GMenuModel*                     mpMenuModel;
     GActionGroup*                   mpActionGroup;
 
-    GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand );
+    GtkSalMenu*                 GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu );
 
 public:
     GtkSalMenu( sal_Bool bMenuBar );
@@ -101,6 +101,8 @@ public:
     void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName );
 
     void                        DispatchCommand( gint itemId, const gchar* aCommand );
+    void                        Activate( const gchar* aMenuCommand );
+    void                        Deactivate( const gchar* aMenuCommand );
 };
 
 class GtkSalMenuItem : public SalMenuItem
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index e921805..7fc74e4 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -1146,8 +1146,7 @@ void Menu::Select()
     }
 }
 
-// FIXME: Workaround to make GLOMenu without defining macros.
-//#if defined(QUARTZ)
+#if defined(QUARTZ)
 void Menu::ImplSelectWithStart( Menu* pSMenu )
 {
     Menu* pOldStartedFrom = pStartedFrom;
@@ -1158,7 +1157,7 @@ void Menu::ImplSelectWithStart( Menu* pSMenu )
         pOldStartedFrom->pStartedFrom = pOldStartedStarted;
     pStartedFrom = pOldStartedFrom;
 }
-//#endif
+#endif
 
 void Menu::RequestHelp( const HelpEvent& )
 {
diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx
index 171341d..1117388 100644
--- a/vcl/unx/gtk/window/gloactiongroup.cxx
+++ b/vcl/unx/gtk/window/gloactiongroup.cxx
@@ -43,7 +43,8 @@ struct _GLOAction
     GObject         parent_instance;
 
     gint            item_id;            // Menu item ID.
-    gboolean        enabled;            // TRUE if action is enabled, FALSE otherwise.
+    gboolean        submenu;            // TRUE if action is a submenu action.
+    gboolean        enabled;            // TRUE if action is enabled.
     GVariantType*   parameter_type;     // A GVariantType with the action parameter type.
     GVariantType*   state_type;         // A GVariantType with item state type
     GVariant*       state_hint;         // A GVariant with state hints.
@@ -65,6 +66,7 @@ static void
 g_lo_action_init (GLOAction *action)
 {
     action->item_id = -1;
+    action->submenu = FALSE;
     action->enabled = TRUE;
     action->parameter_type = NULL;
     action->state_type = NULL;
@@ -174,6 +176,30 @@ g_lo_action_group_query_action (GActionGroup        *group,
 }
 
 static void
+g_lo_action_group_perform_submenu_action (GLOActionGroup *group,
+                                          const gchar    *action_name,
+                                          GVariant       *state)
+{
+    GTK_YIELD_GRAB();
+
+    GtkSalFrame* pFrame = group->priv->frame;
+
+    if (pFrame == NULL)
+        return;
+
+    GtkSalMenu* pSalMenu = static_cast<GtkSalMenu*> (pFrame->GetMenu());
+
+    if (pSalMenu != NULL) {
+        gboolean bState = g_variant_get_boolean (state);
+
+        if (bState == TRUE)
+            pSalMenu->Activate (action_name);
+        else
+            pSalMenu->Deactivate (action_name);
+    }
+}
+
+static void
 g_lo_action_group_change_state (GActionGroup *group,
                                 const gchar  *action_name,
                                 GVariant     *value)
@@ -182,23 +208,29 @@ g_lo_action_group_change_state (GActionGroup *group,
         return;
 
     GLOActionGroup* lo_group = G_LO_ACTION_GROUP (group);
-
     GLOAction* action = G_LO_ACTION (g_hash_table_lookup (lo_group->priv->table, action_name));
 
     if (action == NULL)
         return;
 
-    if (action->state_type == NULL)
-        action->state_type = g_variant_type_copy(g_variant_get_type(value));
-
-    g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE);
+    if (action->submenu == TRUE)
+    {
+//        g_action_group_action_state_changed(group, action_name, value);
+        g_lo_action_group_perform_submenu_action (lo_group, action_name, value);
+    }
+    else
+    {
+        if (action->state_type == NULL)
+            action->state_type = g_variant_type_copy(g_variant_get_type(value));
 
-    if (action->state)
-        g_variant_unref(action->state);
+        g_return_if_fail (g_variant_is_of_type(value, action->state_type) == TRUE);
 
-    action->state = g_variant_take_ref(value);
+        if (action->state)
+            g_variant_unref(action->state);
 
-    g_action_group_action_state_changed(group, action_name, value);
+        action->state = g_variant_take_ref(value);
+        g_action_group_action_state_changed(group, action_name, value);
+    }
 }
 
 static void
@@ -226,15 +258,17 @@ g_lo_action_group_activate (GActionGroup *group,
 void
 g_lo_action_group_insert (GLOActionGroup *group,
                           const gchar    *action_name,
-                          gint            item_id)
+                          gint            item_id,
+                          gboolean        submenu)
 {
-    g_lo_action_group_insert_stateful (group, action_name, item_id, NULL, NULL, NULL, NULL);
+    g_lo_action_group_insert_stateful (group, action_name, item_id, submenu, NULL, NULL, NULL, NULL);
 }
 
 void
 g_lo_action_group_insert_stateful (GLOActionGroup     *group,
                                    const gchar        *action_name,
                                    gint                item_id,
+                                   gboolean            submenu,
                                    const GVariantType *parameter_type,
                                    const GVariantType *state_type,
                                    GVariant           *state_hint,
@@ -254,6 +288,7 @@ g_lo_action_group_insert_stateful (GLOActionGroup     *group,
         g_hash_table_insert (group->priv->table, g_strdup (action_name), action);
 
         action->item_id = item_id;
+        action->submenu = submenu;
 
         if (parameter_type)
             action->parameter_type = (GVariantType*) parameter_type;
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 98c52e5..1476e61 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -50,6 +50,106 @@ static gchar* GetCommandForSpecialItem( GtkSalMenuItem* pSalMenuItem )
     return aCommand;
 }
 
+static void UpdateNativeMenu2( GtkSalMenu *pMenu )
+{
+    if ( pMenu == NULL )
+        return;
+
+    Menu* pVCLMenu = pMenu->GetMenu();
+    GLOMenu* pLOMenu = G_LO_MENU( pMenu->GetMenuModel() );
+    GActionGroup* pActionGroup = pMenu->GetActionGroup();
+
+    sal_uInt16 nLOMenuSize = g_menu_model_get_n_items( G_MENU_MODEL( pLOMenu ) );
+
+    if ( nLOMenuSize == 0 )
+        g_lo_menu_new_section( pLOMenu, 0, NULL );
+
+    sal_uInt16 nSection = 0;
+    sal_uInt16 nItemPos = 0;
+    sal_uInt16 validItems = 0;
+    sal_uInt16 nItem;
+
+    for ( nItem = 0; nItem < pMenu->GetItemCount(); nItem++ ) {
+        GtkSalMenuItem *pSalMenuItem = pMenu->GetItemAtPos( nItem );
+        sal_uInt16 nId = pSalMenuItem->mnId;
+
+        if ( pSalMenuItem->mnType == MENUITEM_SEPARATOR )
+        {
+            nSection++;
+            nItemPos = 0;
+
+            if ( nLOMenuSize <= nSection )
+            {
+                g_lo_menu_new_section( pLOMenu, nSection, NULL );
+                nLOMenuSize++;
+            }
+
+            continue;
+        }
+
+        if ( nItemPos >= g_lo_menu_get_n_items_from_section( pLOMenu, nSection ) )
+            g_lo_menu_insert_in_section( pLOMenu, nSection, nItemPos, "EMPTY STRING" );
+
+        // Get internal menu item values.
+        String aText = pVCLMenu->GetItemText( nId );
+        rtl::OUString aCommand( pVCLMenu->GetItemCommand( nId ) );
+        sal_Bool itemEnabled = pVCLMenu->IsItemEnabled( nId );
+        KeyCode nAccelKey = pVCLMenu->GetAccelKey( nId );
+        sal_Bool itemChecked = pVCLMenu->IsItemChecked( nId );
+        MenuItemBits itemBits = pVCLMenu->GetItemBits( nId );
+
+        // Convert internal values to native values.
+        gboolean bChecked = ( itemChecked == sal_True ) ? TRUE : FALSE;
+        gboolean bEnabled = ( itemEnabled == sal_True ) ? TRUE : FALSE;
+        gchar* aNativeCommand = g_strdup( rtl::OUStringToOString( aCommand, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+        // Force updating of native menu labels.
+        pMenu->NativeSetItemText( nSection, nItemPos, aText );
+        pMenu->NativeSetAccelerator( nSection, nItemPos, nAccelKey, nAccelKey.GetName( pMenu->GetFrame()->GetWindow() ) );
+
+        // Some items are special, so they have different commands.
+        if ( g_strcmp0( aNativeCommand, "" ) == 0 )
+        {
+            gchar *aSpecialItemCmd = GetCommandForSpecialItem( pSalMenuItem );
+
+            if ( aSpecialItemCmd != NULL )
+            {
+                g_free( aNativeCommand );
+                aNativeCommand = aSpecialItemCmd;
+            }
+        }
+
+        if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL )
+        {
+            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE );
+            pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked );
+            pMenu->NativeSetEnableItem( aNativeCommand, bEnabled );
+        }
+
+        GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
+
+        if ( pSubmenu && pSubmenu->GetMenu() )
+        {
+            GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos );
+
+            if ( pSubMenuModel == NULL )
+            {
+                pSubMenuModel = g_lo_menu_new();
+                g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) );
+            }
+
+            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
+            pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
+            pSubmenu->SetActionGroup( pActionGroup );
+        }
+
+        g_free( aNativeCommand );
+
+        nItemPos++;
+        validItems++;
+    }
+}
+
 static void UpdateNativeMenu( GtkSalMenu* pMenu )
 {
     if ( pMenu == NULL )
@@ -406,10 +506,11 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
 
         // Generate the main menu structure.
         GenerateMenu( this );
+//        UpdateNativeMenu2( this );
 
         // Refresh the menu every second.
         // This code is a workaround until required modifications in Gtk+ are available.
-        g_timeout_add_seconds( 1, GenerateMenu, this );
+//        g_timeout_add_seconds( 1, GenerateMenu, this );
     }
 }
 
@@ -511,7 +612,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
             GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
             GVariant* pState = g_variant_new_boolean( bChecked );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, NULL, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, bIsSubmenu, NULL, pStateType, NULL, pState );
         }
         else if ( nBits & MIB_RADIOCHECK )
         {
@@ -521,12 +622,12 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
             GVariant* pState = g_variant_new_string( "" );
             pTarget = g_variant_new_string( aCommand );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, pParameterType, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, FALSE, pParameterType, pStateType, NULL, pState );
         }
         else
         {
             // Item is not special, so insert a stateless action.
-            g_lo_action_group_insert( pActionGroup, aCommand, nId );
+            g_lo_action_group_insert( pActionGroup, aCommand, nId, FALSE );
         }
     }
 
@@ -553,7 +654,7 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
         g_free( aCurrentCommand );
 }
 
-GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
+GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand, gboolean bGetSubmenu )
 {
     GtkSalMenu* pMenu = NULL;
 
@@ -566,13 +667,13 @@ GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
 
         if ( g_strcmp0( aItemCommandStr, aCommand ) == 0 )
         {
-            pMenu = this;
+            pMenu = ( bGetSubmenu == TRUE ) ? pSalItem->mpSubMenu : this;
             break;
         }
         else
         {
             if ( pSalItem->mpSubMenu != NULL )
-                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand );
+                pMenu = pSalItem->mpSubMenu->GetMenuForItemCommand( aCommand, bGetSubmenu );
 
             if ( pMenu != NULL )
                break;
@@ -588,7 +689,7 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
     if ( mbMenuBar != TRUE )
         return;
 
-    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aCommand );
+    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aCommand, FALSE );
     Menu* pSubMenu = ( pSalSubMenu != NULL ) ? pSalSubMenu->GetMenu() : NULL;
 
     MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu );
@@ -596,6 +697,31 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand )
     pMenuBar->HandleMenuCommandEvent( pSubMenu, itemId );
 }
 
+void GtkSalMenu::Activate( const gchar* aMenuCommand )
+{
+    if ( mbMenuBar != TRUE )
+        return;
+
+    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE );
+
+    if ( pSalSubMenu != NULL ) {
+        pSalSubMenu->mpVCLMenu->Activate();
+        UpdateNativeMenu2( pSalSubMenu );
+    }
+}
+
+void GtkSalMenu::Deactivate( const gchar* aMenuCommand )
+{
+    if ( mbMenuBar != TRUE )
+        return;
+
+    GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( (gchar*) aMenuCommand, TRUE );
+
+    if ( pSalSubMenu != NULL ) {
+        pSalSubMenu->mpVCLMenu->Deactivate();
+    }
+}
+
 void GtkSalMenu::CheckItem( unsigned nPos, sal_Bool bCheck )
 {
 }
commit 5fa0b942130d3380826e1e43bf707feb0875061e
Author: Antonio Fernandez <antonio.fernandez at aentos.es>
Date:   Wed Sep 12 16:33:13 2012 +0100

    Initial integration with Gtk+/Unity menus about-to-show feature.
    
    Change-Id: I064cf73e23b175140bdac2616ac922c349f0f051

diff --git a/vcl/inc/unx/gtk/glomenu.h b/vcl/inc/unx/gtk/glomenu.h
index c45be50..4c7c3e5 100644
--- a/vcl/inc/unx/gtk/glomenu.h
+++ b/vcl/inc/unx/gtk/glomenu.h
@@ -28,6 +28,7 @@
 
 #define G_LO_MENU_ATTRIBUTE_ACCELERATOR     "accel"
 #define G_LO_MENU_ATTRIBUTE_COMMAND         "command"
+#define G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION  "submenu-action"
 
 G_BEGIN_DECLS
 
@@ -128,6 +129,11 @@ GLOMenu *   g_lo_menu_get_submenu_from_item_in_section                  (GLOMenu
                                                                          gint         section,
                                                                          gint         position);
 
+void        g_lo_menu_set_submenu_action_to_item_in_section             (GLOMenu     *menu,
+                                                                         gint         section,
+                                                                         gint         position,
+                                                                         const gchar *action);
+
 GLOMenu *   g_lo_menu_get_menu_containing_item                          (GLOMenu     *menu,
                                                                          gint         item_id);
 
diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index d88c50d..d7d5966 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -89,7 +89,13 @@ public:
     virtual GActionGroup*       GetActionGroup() { return mpActionGroup; }
 
     void                        NativeSetItemText( unsigned nSection, unsigned nItemPos, const rtl::OUString& rText );
-    void                        NativeSetItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommandStr );
+    void                        NativeSetItemCommand( unsigned nSection,
+                                                      unsigned nItemPos,
+                                                      sal_uInt16 nId,
+                                                      const gchar* aCommand,
+                                                      MenuItemBits nBits,
+                                                      gboolean bChecked,
+                                                      gboolean bIsSubmenu );
     void                        NativeSetEnableItem( gchar* aCommand, gboolean bEnable );
     void                        NativeCheckItem( unsigned nSection, unsigned nItemPos, MenuItemBits bits, gboolean bCheck );
     void                        NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const KeyCode& rKeyCode, const rtl::OUString& rKeyName );
diff --git a/vcl/unx/gtk/window/glomenu.cxx b/vcl/unx/gtk/window/glomenu.cxx
index 9c0f835..36a70d1 100644
--- a/vcl/unx/gtk/window/glomenu.cxx
+++ b/vcl/unx/gtk/window/glomenu.cxx
@@ -189,7 +189,7 @@ g_lo_menu_set_attribute_value (GLOMenu     *menu,
     g_return_if_fail (attribute != NULL);
     g_return_if_fail (valid_attribute_name (attribute));
 
-    if (position >= menu->items->len)
+    if (position >= (gint) menu->items->len)
         return;
 
     struct item menu_item = g_array_index (menu->items, struct item, position);
@@ -512,6 +512,32 @@ g_lo_menu_get_submenu_from_item_in_section (GLOMenu     *menu,
     return G_LO_MENU (submenu);
 }
 
+void
+g_lo_menu_set_submenu_action_to_item_in_section (GLOMenu     *menu,
+                                                 gint         section,
+                                                 gint         position,
+                                                 const gchar *action)
+{
+    g_return_if_fail (G_IS_LO_MENU (menu));
+
+    GMenuModel *model = G_MENU_MODEL_CLASS (g_lo_menu_parent_class)
+                        ->get_item_link (G_MENU_MODEL (menu), section, G_MENU_LINK_SECTION);
+
+    g_return_if_fail (model != NULL);
+
+    GVariant *value;
+
+    if (action != NULL)
+        value = g_variant_new_string (action);
+    else
+        value = NULL;
+
+    g_lo_menu_set_attribute_value (G_LO_MENU (model), position, G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION, value);
+
+    // Notify the update.
+    g_menu_model_items_changed (model, position, 1, 1);
+}
+
 static void
 g_lo_menu_clear_item (struct item *menu_item)
 {
diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx
index 594d9ac..98c52e5 100644
--- a/vcl/unx/gtk/window/gtksalmenu.cxx
+++ b/vcl/unx/gtk/window/gtksalmenu.cxx
@@ -121,13 +121,11 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu )
 
         if ( g_strcmp0( aNativeCommand, "" ) != 0 && pSalMenuItem->mpSubMenu == NULL )
         {
-            pMenu->NativeSetItemCommand( nSection, nItemPos, pSalMenuItem, aNativeCommand );
+            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, bChecked, FALSE );
             pMenu->NativeCheckItem( nSection, nItemPos, itemBits, bChecked );
             pMenu->NativeSetEnableItem( aNativeCommand, bEnabled );
         }
 
-        g_free( aNativeCommand );
-
         GtkSalMenu* pSubmenu = pSalMenuItem->mpSubMenu;
 
         if ( pSubmenu && pSubmenu->GetMenu() )
@@ -140,6 +138,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu )
                 g_lo_menu_set_submenu_to_item_in_section( pLOMenu, nSection, nItemPos, G_MENU_MODEL( pSubMenuModel ) );
             }
 
+            pMenu->NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
+
             pSubmenu->GetMenu()->Activate();
             pSubmenu->GetMenu()->Deactivate();
 
@@ -148,6 +148,8 @@ static void UpdateNativeMenu( GtkSalMenu* pMenu )
             UpdateNativeMenu( pSubmenu );
         }
 
+        g_free( aNativeCommand );
+
         nItemPos++;
         validItems++;
     }
@@ -403,7 +405,7 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame )
         }
 
         // Generate the main menu structure.
-//        GenerateMenu( this );
+        GenerateMenu( this );
 
         // Refresh the menu every second.
         // This code is a workaround until required modifications in Gtk+ are available.
@@ -490,27 +492,28 @@ void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, con
         g_free( aCurrentAccel );
 }
 
-void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, GtkSalMenuItem* pItem, const gchar* aCommand )
+void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
+                                       unsigned nItemPos,
+                                       sal_uInt16 nId,
+                                       const gchar* aCommand,
+                                       MenuItemBits nBits,
+                                       gboolean bChecked,
+                                       gboolean bIsSubmenu )
 {
     GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
 
     GVariant *pTarget = NULL;
 
     if ( g_action_group_has_action( mpActionGroup, aCommand ) == FALSE ) {
-        gboolean bChecked = ( pItem->mpVCLMenu->IsItemChecked( pItem->mnId ) ) ? TRUE : FALSE;
-
-        // FIXME: Why pItem->mnBits differs from GetItemBits value?
-        MenuItemBits bits = pItem->mpVCLMenu->GetItemBits( pItem->mnId );
-
-        if ( bits & MIB_CHECKABLE )
+        if ( ( nBits & MIB_CHECKABLE ) || ( bIsSubmenu == TRUE ) )
         {
             // Item is a checkmark button.
             GVariantType* pStateType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_BOOLEAN );
             GVariant* pState = g_variant_new_boolean( bChecked );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, NULL, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, NULL, pStateType, NULL, pState );
         }
-        else if ( bits & MIB_RADIOCHECK )
+        else if ( nBits & MIB_RADIOCHECK )
         {
             // Item is a radio button.
             GVariantType* pParameterType = g_variant_type_new( (gchar*) G_VARIANT_TYPE_STRING );
@@ -518,12 +521,12 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
             GVariant* pState = g_variant_new_string( "" );
             pTarget = g_variant_new_string( aCommand );
 
-            g_lo_action_group_insert_stateful( pActionGroup, aCommand, pItem->mnId, pParameterType, pStateType, NULL, pState );
+            g_lo_action_group_insert_stateful( pActionGroup, aCommand, nId, pParameterType, pStateType, NULL, pState );
         }
         else
         {
             // Item is not special, so insert a stateless action.
-            g_lo_action_group_insert( pActionGroup, aCommand, pItem->mnId );
+            g_lo_action_group_insert( pActionGroup, aCommand, nId );
         }
     }
 
@@ -538,7 +541,10 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection, unsigned nItemPos, Gtk
 
         gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
 
-        g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
+        if ( bIsSubmenu == TRUE )
+            g_lo_menu_set_submenu_action_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand );
+        else
+            g_lo_menu_set_action_and_target_value_to_item_in_section( pMenu, nSection, nItemPos, aItemCommand, pTarget );
 
         g_free( aItemCommand );
     }
@@ -556,7 +562,6 @@ GtkSalMenu* GtkSalMenu::GetMenuForItemCommand( gchar* aCommand )
         GtkSalMenuItem *pSalItem = maItems[ nPos ];
 
         String aItemCommand = mpVCLMenu->GetItemCommand( pSalItem->mnId );
-
         gchar* aItemCommandStr = (gchar*) rtl::OUStringToOString( aItemCommand, RTL_TEXTENCODING_UTF8 ).getStr();
 
         if ( g_strcmp0( aItemCommandStr, aCommand ) == 0 )


More information about the Libreoffice-commits mailing list