Blob Blame History Raw
From 66db55aa84e8401a9eccedb02c67150833a344ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Tue, 15 Mar 2016 11:15:40 +0000
Subject: [PATCH] Resolves: tdf#98636

On changing a menu item from a non-submenu to a submenu then update
the newly created menu as if it was the first full update of
the entire menu hierarchy.

On changing a menu item from a submenu to a non-submenu its evidentially
not sufficient to unset the G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION attribute
so remove the submenu-item and add a new non-submenu item to force
its new type

Change-Id: I2030d9198d6849643a5991ddfffc1cc3425ba72e
---
 vcl/inc/unx/gtk/gtksalmenu.hxx |  2 +-
 vcl/unx/gtk/glomenu.cxx        |  1 +
 vcl/unx/gtk/gtksalmenu.cxx     | 24 ++++++++++++++++++++----
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx
index 8dadcfe..0e1cfd1 100644
--- a/vcl/inc/unx/gtk/gtksalmenu.hxx
+++ b/vcl/inc/unx/gtk/gtksalmenu.hxx
@@ -87,7 +87,7 @@ public:
     bool                        IsItemVisible( unsigned nPos );
 
     void                        NativeSetItemText( unsigned nSection, unsigned nItemPos, const OUString& rText );
-    void                        NativeSetItemCommand( unsigned nSection,
+    bool                        NativeSetItemCommand( unsigned nSection,
                                                       unsigned nItemPos,
                                                       sal_uInt16 nId,
                                                       const gchar* aCommand,
diff --git a/vcl/unx/gtk/glomenu.cxx b/vcl/unx/gtk/glomenu.cxx
index 835e832..e8529e0 100644
--- a/vcl/unx/gtk/glomenu.cxx
+++ b/vcl/unx/gtk/glomenu.cxx
@@ -294,6 +294,7 @@ g_lo_menu_set_action_and_target_value (GLOMenu     *menu,
 
     g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_ACTION, action_value);
     g_lo_menu_set_attribute_value (menu, position, G_MENU_ATTRIBUTE_TARGET, target_value);
+    g_lo_menu_set_attribute_value (menu, position, G_LO_MENU_ATTRIBUTE_SUBMENU_ACTION, nullptr);
 
     g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 1);
 }
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
index 91b7f35..48520c2 100644
--- a/vcl/unx/gtk/gtksalmenu.cxx
+++ b/vcl/unx/gtk/gtksalmenu.cxx
@@ -297,7 +297,7 @@ void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries)
 
         if ( pSubmenu && pSubmenu->GetMenu() )
         {
-            NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
+            bool bNonMenuChangedToMenu = NativeSetItemCommand( nSection, nItemPos, nId, aNativeCommand, itemBits, FALSE, TRUE );
             pNewCommandList = g_list_append( pNewCommandList, g_strdup( aNativeCommand ) );
 
             GLOMenu* pSubMenuModel = g_lo_menu_get_submenu_from_item_in_section( pLOMenu, nSection, nItemPos );
@@ -310,12 +310,12 @@ void GtkSalMenu::ImplUpdate(bool bRecurse, bool bRemoveDisabledEntries)
 
             g_object_unref( pSubMenuModel );
 
-            if ( bRecurse )
+            if (bRecurse || bNonMenuChangedToMenu)
             {
                 SAL_INFO("vcl.unity", "preparing submenu  " << pSubMenuModel << " to menu model " << G_MENU_MODEL(pSubMenuModel) << " and action group " << G_ACTION_GROUP(pActionGroup));
                 pSubmenu->SetMenuModel( G_MENU_MODEL( pSubMenuModel ) );
                 pSubmenu->SetActionGroup( G_ACTION_GROUP( pActionGroup ) );
-                pSubmenu->ImplUpdate(bRecurse, bRemoveDisabledEntries);
+                pSubmenu->ImplUpdate(true, bRemoveDisabledEntries);
             }
         }
 
@@ -798,7 +798,7 @@ void GtkSalMenu::NativeSetAccelerator( unsigned nSection, unsigned nItemPos, con
     g_free( aCurrentAccel );
 }
 
-void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
+bool GtkSalMenu::NativeSetItemCommand( unsigned nSection,
                                        unsigned nItemPos,
                                        sal_uInt16 nId,
                                        const gchar* aCommand,
@@ -806,6 +806,8 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
                                        gboolean bChecked,
                                        gboolean bIsSubmenu )
 {
+    bool bSubMenuAddedOrRemoved = false;
+
     SolarMutexGuard aGuard;
     GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP( mpActionGroup );
 
@@ -845,6 +847,18 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
 
     if ( aCurrentCommand == nullptr || g_strcmp0( aCurrentCommand, aCommand ) != 0 )
     {
+        bool bOldHasSubmenu = g_lo_menu_get_submenu_from_item_in_section(pMenu, nSection, nItemPos) != nullptr;
+        bSubMenuAddedOrRemoved = bOldHasSubmenu != bIsSubmenu;
+        if (bSubMenuAddedOrRemoved)
+        {
+            //tdf#98636 its not good enough to unset the "submenu-action" attribute to change something
+            //from a submenu to a non-submenu item, so remove the old one entirely and re-add it to
+            //support achieving that
+            gchar* pLabel = g_lo_menu_get_label_from_item_in_section(pMenu, nSection, nItemPos);
+            g_lo_menu_remove_from_section(pMenu, nSection, nItemPos);
+            g_lo_menu_insert_in_section(pMenu, nSection, nItemPos, pLabel);
+        }
+
         g_lo_menu_set_command_to_item_in_section( pMenu, nSection, nItemPos, aCommand );
 
         gchar* aItemCommand = g_strconcat("win.", aCommand, NULL );
@@ -865,6 +879,8 @@ void GtkSalMenu::NativeSetItemCommand( unsigned nSection,
 
     if (pTarget)
         g_variant_unref(pTarget);
+
+    return bSubMenuAddedOrRemoved;
 }
 
 GtkSalMenu* GtkSalMenu::GetMenuForItemCommand(gchar* aCommand, int& rDupsToSkip, gboolean bGetSubmenu)
-- 
2.7.1