[Libreoffice-commits] core.git: 2 commits - sc/source solenv/sanitizers vcl/uiconfig vcl/UIConfig_vcl.mk vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Wed Aug 11 14:56:35 UTC 2021


 sc/source/core/data/documen2.cxx     |    3 
 sc/source/ui/docshell/docfunc.cxx    |    5 
 solenv/sanitizers/ui/vcl.suppr       |    6 -
 vcl/UIConfig_vcl.mk                  |    3 
 vcl/uiconfig/ui/menutogglebutton4.ui |   29 +++++
 vcl/unx/gtk3/gtkinst.cxx             |  153 ++++++++++++++++++----------
 vcl/unx/gtk4/convert3to4.cxx         |  186 ++++++++++++++++++-----------------
 7 files changed, 237 insertions(+), 148 deletions(-)

New commits:
commit 3ad8347f25935d60e55ff12fd1844001a50bedc4
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Aug 11 14:45:02 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Aug 11 16:56:15 2021 +0200

    add some --disable-scripting fixes
    
    Change-Id: I28c4d38a035201acc2b0e5acc5908c4e74ae80e7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120327
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 1db11be0c777..28f19df43539 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -87,6 +87,7 @@
 #include <listenercontext.hxx>
 #include <datamapper.hxx>
 #include <drwlayer.hxx>
+#include <config_features.h>
 
 using namespace com::sun::star;
 
@@ -1026,11 +1027,13 @@ sal_uLong ScDocument::TransferTab( ScDocument& rSrcDoc, SCTAB nSrcPos,
         if ( pSrcShell )
         {
             OUString aLibName("Standard");
+#if HAVE_FEATURE_SCRIPTING
             const BasicManager *pBasicManager = pSrcShell->GetBasicManager();
             if (pBasicManager && !pBasicManager->GetName().isEmpty())
             {
                 aLibName = pSrcShell->GetBasicManager()->GetName();
             }
+#endif
             OUString sSource;
             uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer();
             uno::Reference< container::XNameContainer > xLib;
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index ac011281dd36..d0ad63f1ff95 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -94,6 +94,7 @@
 #include <conditio.hxx>
 #include <columnspanset.hxx>
 #include <validat.hxx>
+#include <config_features.h>
 
 #include <memory>
 #include <utility>
@@ -3198,10 +3199,12 @@ void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, const OUString& sSource )
     if( xLibContainer.is() )
     {
         OUString aLibName( "Standard" );
+#if HAVE_FEATURE_SCRIPTING
         if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
         {
             aLibName = rDocSh.GetBasicManager()->GetName();
         }
+#endif
         uno::Any aLibAny = xLibContainer->getByName( aLibName );
         aLibAny >>= xLib;
     }
@@ -3238,10 +3241,12 @@ void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName )
     if( xLibContainer.is() )
     {
         OUString aLibName( "Standard" );
+#if HAVE_FEATURE_SCRIPTING
         if ( rDocSh.GetBasicManager() && !rDocSh.GetBasicManager()->GetName().isEmpty() )
         {
             aLibName = rDocSh.GetBasicManager()->GetName();
         }
+#endif
         uno::Any aLibAny = xLibContainer->getByName( aLibName );
         aLibAny >>= xLib;
     }
commit 54c2de7e77dad1a1151c074f2ec5bfe1527d4d12
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Aug 11 10:53:44 2021 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Aug 11 16:56:02 2021 +0200

    gtk4: get startcenter MenuToggleButton working
    
    the button parts, not the menu part yet
    
    Change-Id: I016d2c2160a4e8c0c4d1e096f49d0e518b89a55b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120326
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/solenv/sanitizers/ui/vcl.suppr b/solenv/sanitizers/ui/vcl.suppr
index c053a035fd32..a07c25780a76 100644
--- a/solenv/sanitizers/ui/vcl.suppr
+++ b/solenv/sanitizers/ui/vcl.suppr
@@ -7,8 +7,10 @@ vcl/uiconfig/ui/combobox.ui://GtkEntry[@id='entry'] no-labelled-by
 vcl/uiconfig/ui/combobox.ui://GtkToggleButton[@id='button'] button-no-label
 vcl/uiconfig/ui/combobox.ui://GtkMenuButton[@id='overlaybutton'] button-no-label
 vcl/uiconfig/ui/cupspassworddialog.ui://GtkLabel[@id='text'] orphan-label
-vcl/uiconfig/ui/menutogglebutton.ui://GtkToggleButton[@id='togglebutton'] button-no-label
-vcl/uiconfig/ui/menutogglebutton.ui://GtkButton[@id='menubutton'] button-no-label
+vcl/uiconfig/ui/menutogglebutton3.ui://GtkToggleButton[@id='togglebutton'] button-no-label
+vcl/uiconfig/ui/menutogglebutton3.ui://GtkButton[@id='menubutton'] button-no-label
+vcl/uiconfig/ui/menutogglebutton4.ui://GtkToggleButton[@id='togglebutton'] button-no-label
+vcl/uiconfig/ui/menutogglebutton4.ui://GtkButton[@id='menubutton'] button-no-label
 vcl/uiconfig/ui/printdialog.ui://GtkLabel[@id='totalnumpages'] orphan-label
 vcl/uiconfig/ui/printdialog.ui://GtkImage[@id='collateimage'] no-labelled-by
 vcl/uiconfig/ui/printdialog.ui://GtkLabel[@id='pagemargintxt2'] orphan-label
diff --git a/vcl/UIConfig_vcl.mk b/vcl/UIConfig_vcl.mk
index 72b7e08d2700..703cef1e6e1c 100644
--- a/vcl/UIConfig_vcl.mk
+++ b/vcl/UIConfig_vcl.mk
@@ -19,7 +19,8 @@ $(eval $(call gb_UIConfig_add_uifiles,vcl,\
 	vcl/uiconfig/ui/errornoprinterdialog \
 	vcl/uiconfig/ui/interimdockparent \
 	vcl/uiconfig/ui/interimtearableparent \
-	vcl/uiconfig/ui/menutogglebutton \
+	vcl/uiconfig/ui/menutogglebutton3 \
+	vcl/uiconfig/ui/menutogglebutton4 \
 	vcl/uiconfig/ui/printdialog \
 	vcl/uiconfig/ui/printerdevicepage \
 	vcl/uiconfig/ui/printerpaperpage \
diff --git a/vcl/uiconfig/ui/menutogglebutton.ui b/vcl/uiconfig/ui/menutogglebutton3.ui
similarity index 100%
rename from vcl/uiconfig/ui/menutogglebutton.ui
rename to vcl/uiconfig/ui/menutogglebutton3.ui
diff --git a/vcl/uiconfig/ui/menutogglebutton4.ui b/vcl/uiconfig/ui/menutogglebutton4.ui
new file mode 100644
index 000000000000..74c1e2fe3353
--- /dev/null
+++ b/vcl/uiconfig/ui/menutogglebutton4.ui
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="vcl">
+  <object class="GtkBox" id="box">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="hexpand">False</property>
+    <child>
+      <object class="GtkToggleButton" id="togglebutton">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="receives-default">True</property>
+        <property name="hexpand">True</property>
+        <property name="use-underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkButton" id="menubutton">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="icon-name">pan-down-symbolic</property>
+        <property name="receives-default">True</property>
+      </object>
+    </child>
+    <style>
+      <class name="linked"/>
+    </style>
+  </object>
+</interface>
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 9ad49d81d9e8..2147a1e49956 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -2222,7 +2222,32 @@ namespace
         return pWidget;
     }
 
+    void container_remove(GtkWidget* pContainer, GtkWidget* pChild)
+    {
 #if !GTK_CHECK_VERSION(4, 0, 0)
+        gtk_container_remove(GTK_CONTAINER(pContainer), pChild);
+#else
+        assert(GTK_IS_BOX(pContainer) || GTK_IS_GRID(pContainer));
+        if (GTK_IS_BOX(pContainer))
+            gtk_box_remove(GTK_BOX(pContainer), pChild);
+        else if (GTK_IS_GRID(pContainer))
+            gtk_grid_remove(GTK_GRID(pContainer), pChild);
+#endif
+    }
+
+    void container_add(GtkWidget* pContainer, GtkWidget* pChild)
+    {
+#if !GTK_CHECK_VERSION(4, 0, 0)
+        gtk_container_add(GTK_CONTAINER(pContainer), pChild);
+#else
+        assert(GTK_IS_BOX(pContainer) || GTK_IS_GRID(pContainer));
+        if (GTK_IS_BOX(pContainer))
+            gtk_box_append(GTK_BOX(pContainer), pChild);
+        else if (GTK_IS_GRID(pContainer))
+            gtk_grid_attach(GTK_GRID(pContainer), pChild, 0, 0, 1, 1);
+#endif
+    }
+
     void replaceWidget(GtkWidget* pWidget, GtkWidget* pReplacement)
     {
         // remove the widget and replace it with pReplacement
@@ -2235,17 +2260,21 @@ namespace
         g_object_ref(pWidget);
 
         gint nTopAttach(0), nLeftAttach(0), nHeight(1), nWidth(1);
-#if !GTK_CHECK_VERSION(4, 0, 0)
         if (GTK_IS_GRID(pParent))
         {
+#if !GTK_CHECK_VERSION(4, 0, 0)
             gtk_container_child_get(GTK_CONTAINER(pParent), pWidget,
                     "left-attach", &nLeftAttach,
                     "top-attach", &nTopAttach,
                     "width", &nWidth,
                     "height", &nHeight,
                     nullptr);
-        }
+#else
+            gtk_grid_query_child(GTK_GRID(pParent), pWidget,
+                                 &nLeftAttach, &nTopAttach,
+                                 &nWidth, &nHeight);
 #endif
+        }
 
 #if !GTK_CHECK_VERSION(4, 0, 0)
         gboolean bExpand(false), bFill(false);
@@ -2262,8 +2291,6 @@ namespace
                     "position", &nPosition,
                     nullptr);
         }
-
-        gtk_container_remove(GTK_CONTAINER(pParent), pWidget);
 #endif
 
         gtk_widget_set_visible(pReplacement, gtk_widget_get_visible(pWidget));
@@ -2310,7 +2337,7 @@ namespace
                     "position", nPosition,
                     nullptr);
 #else
-            gtk_box_prepend(GTK_BOX(pParent), pReplacement);
+            gtk_box_insert_child_after(GTK_BOX(pParent), pReplacement, pWidget);
 #endif
         }
 #if !GTK_CHECK_VERSION(4, 0, 0)
@@ -2327,27 +2354,24 @@ namespace
         gtk_widget_set_halign(pReplacement, gtk_widget_get_halign(pWidget));
         gtk_widget_set_valign(pReplacement, gtk_widget_get_valign(pWidget));
 
+        container_remove(pParent, pWidget);
+
         // coverity[freed_arg : FALSE] - this does not free pWidget, it is reffed by pReplacement
         g_object_unref(pWidget);
     }
-#endif
 
-#if !GTK_CHECK_VERSION(4, 0, 0)
     void insertAsParent(GtkWidget* pWidget, GtkWidget* pReplacement)
     {
         g_object_ref(pWidget);
 
         replaceWidget(pWidget, pReplacement);
 
-#if !GTK_CHECK_VERSION(4, 0, 0)
         // coverity[pass_freed_arg : FALSE] - pWidget is not freed here due to initial g_object_ref
-        gtk_container_add(GTK_CONTAINER(pReplacement), pWidget);
-#endif
+        container_add(pReplacement, pWidget);
 
         // coverity[freed_arg : FALSE] - this does not free pWidget, it is reffed by pReplacement
         g_object_unref(pWidget);
     }
-#endif
 
     GtkWidget* ensureEventWidget(GtkWidget* pWidget)
     {
@@ -5441,32 +5465,6 @@ IMPL_LINK_NOARG(ChildFrame, ImplHandleLayoutTimerHdl, Timer*, void)
     Layout();
 }
 
-void container_remove(GtkWidget* pContainer, GtkWidget* pChild)
-{
-#if !GTK_CHECK_VERSION(4, 0, 0)
-    gtk_container_remove(GTK_CONTAINER(pContainer), pChild);
-#else
-    assert(GTK_IS_BOX(pContainer) || GTK_IS_GRID(pContainer));
-    if (GTK_IS_BOX(pContainer))
-        gtk_box_remove(GTK_BOX(pContainer), pChild);
-    else if (GTK_IS_GRID(pContainer))
-        gtk_grid_remove(GTK_GRID(pContainer), pChild);
-#endif
-}
-
-void container_add(GtkWidget* pContainer, GtkWidget* pChild)
-{
-#if !GTK_CHECK_VERSION(4, 0, 0)
-    gtk_container_add(GTK_CONTAINER(pContainer), pChild);
-#else
-    assert(GTK_IS_BOX(pContainer) || GTK_IS_GRID(pContainer));
-    if (GTK_IS_BOX(pContainer))
-        gtk_box_append(GTK_BOX(pContainer), pChild);
-    else if (GTK_IS_GRID(pContainer))
-        gtk_grid_attach(GTK_GRID(pContainer), pChild, 0, 0, 1, 1);
-#endif
-}
-
 class GtkInstanceContainer : public GtkInstanceWidget, public virtual weld::Container
 {
 private:
@@ -10034,15 +10032,16 @@ public:
     }
 };
 
-#if !GTK_CHECK_VERSION(4, 0, 0)
-
 class GtkInstanceMenuToggleButton : public GtkInstanceToggleButton, public MenuHelper
                                   , public virtual weld::MenuToggleButton
 {
 private:
     GtkBox* m_pContainer;
     GtkButton* m_pToggleMenuButton;
+    GtkMenuButton* m_pMenuButton;
+#if !GTK_CHECK_VERSION(4, 0, 0)
     gulong m_nMenuBtnClickedId;
+#endif
     gulong m_nToggleStateFlagsChangedId;
     gulong m_nMenuBtnStateFlagsChangedId;
 
@@ -10064,6 +10063,7 @@ private:
         gtk_widget_set_state_flags(GTK_WIDGET(pThis->m_pToggleButton), eFinalFlags, true);
     }
 
+#if !GTK_CHECK_VERSION(4, 0, 0)
     static void signalMenuBtnClicked(GtkButton*, gpointer widget)
     {
         GtkInstanceMenuToggleButton* pThis = static_cast<GtkInstanceMenuToggleButton*>(widget);
@@ -10130,6 +10130,7 @@ private:
         g_main_loop_unref(pLoop);
         g_signal_handler_disconnect(m_pMenu, nSignalId);
     }
+#endif
 
     static gboolean signalMenuToggleButton(GtkWidget*, gboolean bGroupCycling, gpointer widget)
     {
@@ -10142,21 +10143,31 @@ public:
         GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
         : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(gtk_builder_get_object(pMenuToggleButtonBuilder, "togglebutton")),
                                   pBuilder, bTakeOwnership)
+#if !GTK_CHECK_VERSION(4, 0, 0)
         , MenuHelper(gtk_menu_button_get_popup(pMenuButton), false)
+#else
+        , MenuHelper(GTK_POPOVER_MENU(gtk_menu_button_get_popover(pMenuButton)), false)
+#endif
         , m_pContainer(GTK_BOX(gtk_builder_get_object(pMenuToggleButtonBuilder, "box")))
         , m_pToggleMenuButton(GTK_BUTTON(gtk_builder_get_object(pMenuToggleButtonBuilder, "menubutton")))
+        , m_pMenuButton(pMenuButton)
+#if !GTK_CHECK_VERSION(4, 0, 0)
         , m_nMenuBtnClickedId(g_signal_connect(m_pToggleMenuButton, "clicked", G_CALLBACK(signalMenuBtnClicked), this))
+#endif
         , m_nToggleStateFlagsChangedId(g_signal_connect(m_pToggleButton, "state-flags-changed", G_CALLBACK(signalToggleStateFlagsChanged), this))
         , m_nMenuBtnStateFlagsChangedId(g_signal_connect(m_pToggleMenuButton, "state-flags-changed", G_CALLBACK(signalMenuBtnStateFlagsChanged), this))
     {
-        GtkInstanceMenuButton::formatMenuButton(gtk_bin_get_child(GTK_BIN(pMenuButton)));
+#if !GTK_CHECK_VERSION(4, 0, 0)
+        GtkInstanceMenuButton::formatMenuButton(gtk_bin_get_child(GTK_BIN(m_pMenuButton)));
+#endif
 
-        insertAsParent(GTK_WIDGET(pMenuButton), GTK_WIDGET(m_pContainer));
-        gtk_widget_hide(GTK_WIDGET(pMenuButton));
+        insertAsParent(GTK_WIDGET(m_pMenuButton), GTK_WIDGET(m_pContainer));
+        gtk_widget_hide(GTK_WIDGET(m_pMenuButton));
 
         // move the first GtkMenuButton child, as created by GtkInstanceMenuButton ctor, into the GtkToggleButton
         // instead, leaving just the indicator behind in the GtkMenuButton
-        GtkWidget* pButtonBox = gtk_bin_get_child(GTK_BIN(pMenuButton));
+#if !GTK_CHECK_VERSION(4, 0, 0)
+        GtkWidget* pButtonBox = gtk_bin_get_child(GTK_BIN(m_pMenuButton));
         GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pButtonBox));
         int nGroup = 0;
         for (GList* pChild = g_list_first(pChildren); pChild && nGroup < 2; pChild = g_list_next(pChild), ++nGroup)
@@ -10172,45 +10183,75 @@ public:
             g_object_unref(pWidget);
         }
         g_list_free(pChildren);
+#else
+        GtkWidget* pChild = gtk_widget_get_last_child(GTK_WIDGET(m_pMenuButton));
+        g_object_ref(pChild);
+        gtk_widget_unparent(pChild);
+        gtk_button_set_child(GTK_BUTTON(m_pToggleButton), pChild);
+        g_object_unref(pChild);
+#endif
 
         // match the GtkToggleButton relief to the GtkMenuButton
-        GtkReliefStyle eStyle = gtk_button_get_relief(GTK_BUTTON(pMenuButton));
+#if !GTK_CHECK_VERSION(4, 0, 0)
+        const GtkReliefStyle eStyle = gtk_button_get_relief(GTK_BUTTON(m_pMenuButton));
         gtk_button_set_relief(GTK_BUTTON(m_pToggleButton), eStyle);
         gtk_button_set_relief(GTK_BUTTON(m_pToggleMenuButton), eStyle);
+#else
+        const bool bStyle = gtk_menu_button_get_has_frame(GTK_MENU_BUTTON(m_pMenuButton));
+        gtk_button_set_has_frame(GTK_BUTTON(m_pToggleButton), bStyle);
+        gtk_button_set_has_frame(GTK_BUTTON(m_pToggleMenuButton), bStyle);
+#endif
 
         // move the GtkMenuButton margins up to the new parent
         gtk_widget_set_margin_top(GTK_WIDGET(m_pContainer),
-            gtk_widget_get_margin_top(GTK_WIDGET(pMenuButton)));
+            gtk_widget_get_margin_top(GTK_WIDGET(m_pMenuButton)));
         gtk_widget_set_margin_bottom(GTK_WIDGET(m_pContainer),
-            gtk_widget_get_margin_bottom(GTK_WIDGET(pMenuButton)));
+            gtk_widget_get_margin_bottom(GTK_WIDGET(m_pMenuButton)));
         gtk_widget_set_margin_start(GTK_WIDGET(m_pContainer),
-            gtk_widget_get_margin_start(GTK_WIDGET(pMenuButton)));
+            gtk_widget_get_margin_start(GTK_WIDGET(m_pMenuButton)));
         gtk_widget_set_margin_end(GTK_WIDGET(m_pContainer),
-            gtk_widget_get_margin_end(GTK_WIDGET(pMenuButton)));
+            gtk_widget_get_margin_end(GTK_WIDGET(m_pMenuButton)));
 
+#if !GTK_CHECK_VERSION(4, 0, 0)
         gtk_menu_detach(m_pMenu);
         gtk_menu_attach_to_widget(m_pMenu, GTK_WIDGET(m_pToggleButton), nullptr);
+#endif
 
         g_signal_connect(m_pContainer, "mnemonic-activate", G_CALLBACK(signalMenuToggleButton), this);
     }
 
     virtual void disable_notify_events() override
     {
+#if !GTK_CHECK_VERSION(4, 0, 0)
         g_signal_handler_block(m_pToggleMenuButton, m_nMenuBtnClickedId);
+#endif
         GtkInstanceToggleButton::disable_notify_events();
     }
 
     virtual void enable_notify_events() override
     {
         GtkInstanceToggleButton::enable_notify_events();
+#if !GTK_CHECK_VERSION(4, 0, 0)
         g_signal_handler_unblock(m_pToggleMenuButton, m_nMenuBtnClickedId);
+#endif
     }
 
     virtual ~GtkInstanceMenuToggleButton()
     {
         g_signal_handler_disconnect(m_pToggleButton, m_nToggleStateFlagsChangedId);
         g_signal_handler_disconnect(m_pToggleMenuButton, m_nMenuBtnStateFlagsChangedId);
+#if !GTK_CHECK_VERSION(4, 0, 0)
         g_signal_handler_disconnect(m_pToggleMenuButton, m_nMenuBtnClickedId);
+#endif
+
+#if GTK_CHECK_VERSION(4, 0, 0)
+        GtkWidget* pChild = gtk_button_get_child(GTK_BUTTON(m_pToggleButton));
+        g_object_ref(pChild);
+        gtk_button_set_child(GTK_BUTTON(m_pToggleButton), nullptr);
+        gtk_widget_unparent(pChild);
+        gtk_widget_set_parent(pChild, GTK_WIDGET(m_pMenuButton));
+        g_object_unref(pChild);
+#endif
     }
 
     virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
@@ -10269,7 +10310,6 @@ public:
         assert(false && "not implemented");
     }
 };
-#endif
 
 class GtkInstanceMenu : public MenuHelper, public virtual weld::Menu
 {
@@ -17298,16 +17338,20 @@ void GtkInstanceDrawingArea::im_context_set_cursor_location(const tools::Rectang
 
 namespace {
 
-#if !GTK_CHECK_VERSION(4, 0, 0)
-
 GtkBuilder* makeMenuToggleButtonBuilder()
 {
-    OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/menutogglebutton.ui");
+#if !GTK_CHECK_VERSION(4, 0, 0)
+    OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/menutogglebutton3.ui");
+#else
+    OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/menutogglebutton4.ui");
+#endif
     OUString aPath;
     osl::FileBase::getSystemPathFromFileURL(aUri, aPath);
     return gtk_builder_new_from_file(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr());
 }
 
+#if !GTK_CHECK_VERSION(4, 0, 0)
+
 GtkBuilder* makeComboBoxBuilder()
 {
     OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/combobox.ui");
@@ -22103,7 +22147,6 @@ public:
 
     virtual std::unique_ptr<weld::MenuToggleButton> weld_menu_toggle_button(const OString &id) override
     {
-#if !GTK_CHECK_VERSION(4, 0, 0)
         GtkMenuButton* pButton = GTK_MENU_BUTTON(gtk_builder_get_object(m_pBuilder, id.getStr()));
         if (!pButton)
             return nullptr;
@@ -22111,10 +22154,6 @@ public:
         // gtk doesn't come with exactly the same concept
         GtkBuilder* pMenuToggleButton = makeMenuToggleButtonBuilder();
         return std::make_unique<GtkInstanceMenuToggleButton>(pMenuToggleButton, pButton, this, false);
-#else
-        (void)id;
-        return nullptr;
-#endif
     }
 
     virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OString &id) override
diff --git a/vcl/unx/gtk4/convert3to4.cxx b/vcl/unx/gtk4/convert3to4.cxx
index dc896a28cf4e..837a96035e2b 100644
--- a/vcl/unx/gtk4/convert3to4.cxx
+++ b/vcl/unx/gtk4/convert3to4.cxx
@@ -715,41 +715,11 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
 
                         auto xDoc = xChild->getOwnerDocument();
 
-                        if (GetParentObjectType(xChild) == "GtkButton"
-                            || GetParentObjectType(xChild) == "GtkToggleButton")
-                        {
-                            // relocate it to be a child of this GtkButton
-                            xGeneratedImageChild = xDoc->createElement("child");
-                            xGeneratedImageChild->appendChild(
-                                xImageNode->getParentNode()->removeChild(xImageNode));
-                            xObjectCandidate->appendChild(xGeneratedImageChild);
-                        }
-                        else if (GetParentObjectType(xChild) == "GtkMenuButton")
-                        {
-                            auto xProp = xImageNode->getFirstChild();
-                            while (xProp.is())
-                            {
-                                if (xProp->getNodeName() == "property")
-                                {
-                                    css::uno::Reference<css::xml::dom::XNamedNodeMap> xPropMap
-                                        = xProp->getAttributes();
-                                    css::uno::Reference<css::xml::dom::XNode> xPropName
-                                        = xPropMap->getNamedItem("name");
-                                    OUString sPropName(xPropName->getNodeValue().replace('_', '-'));
-                                    if (sPropName == "icon-name")
-                                    {
-                                        OUString sIconName(xProp->getFirstChild()->getNodeValue());
-                                        auto xIconName
-                                            = CreateProperty(xDoc, "icon-name", sIconName);
-                                        xObjectCandidate->insertBefore(xIconName, xChild);
-                                        break;
-                                    }
-                                }
-
-                                xProp = xProp->getNextSibling();
-                            }
-                            xImageNode->getParentNode()->removeChild(xImageNode);
-                        }
+                        // relocate it to be a child of this GtkButton
+                        xGeneratedImageChild = xDoc->createElement("child");
+                        xGeneratedImageChild->appendChild(
+                            xImageNode->getParentNode()->removeChild(xImageNode));
+                        xObjectCandidate->appendChild(xGeneratedImageChild);
                     }
 
                     xRemoveList.push_back(xChild);
@@ -1316,7 +1286,7 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
             }
 
             // only create the child box for GtkButton/GtkToggleButton
-            if (bChildAlwaysShowImage && sClass != "GtkMenuButton")
+            if (bChildAlwaysShowImage)
             {
                 auto xImageCandidateNode = xChild->getLastChild();
                 if (xImageCandidateNode && xImageCandidateNode->getNodeName() != "child")
@@ -1324,65 +1294,105 @@ ConvertResult Convert3To4(const css::uno::Reference<css::xml::dom::XNode>& xNode
                 if (xImageCandidateNode)
                     xChild->removeChild(xImageCandidateNode);
 
-                css::uno::Reference<css::xml::dom::XElement> xNewChildNode
-                    = xDoc->createElement("child");
-                css::uno::Reference<css::xml::dom::XElement> xNewObjectNode
-                    = xDoc->createElement("object");
-                css::uno::Reference<css::xml::dom::XAttr> xBoxClassName
-                    = xDoc->createAttribute("class");
-                xBoxClassName->setValue("GtkBox");
-                xNewObjectNode->setAttributeNode(xBoxClassName);
-
-                if (eChildImagePos == GTK_POS_TOP || eChildImagePos == GTK_POS_BOTTOM)
+                // for GtkMenuButton if this is a gearmenu with just an icon
+                // then "icon-name" is used for the indicator and there is
+                // expected to be no text. If there is a GtkPicture then treat
+                // this like a GtkButton and presumably its a ToggleMenuButton
+                // and the relocation of contents happens in the builder
+                if (sClass == "GtkMenuButton")
                 {
-                    auto xOrientation = CreateProperty(xDoc, "orientation", "vertical");
-                    xNewObjectNode->appendChild(xOrientation);
+                    bChildAlwaysShowImage = false;
+                    if (xImageCandidateNode)
+                    {
+                        bChildAlwaysShowImage = true;
+                        auto xImageObject = GetChildObject(xImageCandidateNode);
+                        auto xProp = xImageObject->getFirstChild();
+                        while (xProp.is())
+                        {
+                            if (xProp->getNodeName() == "property")
+                            {
+                                css::uno::Reference<css::xml::dom::XNamedNodeMap> xPropMap
+                                    = xProp->getAttributes();
+                                css::uno::Reference<css::xml::dom::XNode> xPropName
+                                    = xPropMap->getNamedItem("name");
+                                OUString sPropName(xPropName->getNodeValue().replace('_', '-'));
+                                if (sPropName == "icon-name")
+                                {
+                                    OUString sIconName(xProp->getFirstChild()->getNodeValue());
+                                    auto xIconName = CreateProperty(xDoc, "icon-name", sIconName);
+                                    insertAsFirstChild(xChild, xIconName);
+                                    bChildAlwaysShowImage = false;
+                                    break;
+                                }
+                            }
+
+                            xProp = xProp->getNextSibling();
+                        }
+                    }
                 }
 
-                xNewObjectNode->appendChild(CreateProperty(xDoc, "spacing", "6"));
-                if (!bChildXAlign)
-                    xNewObjectNode->appendChild(CreateProperty(xDoc, "halign", "center"));
+                if (bChildAlwaysShowImage)
+                {
+                    css::uno::Reference<css::xml::dom::XElement> xNewChildNode
+                        = xDoc->createElement("child");
+                    css::uno::Reference<css::xml::dom::XElement> xNewObjectNode
+                        = xDoc->createElement("object");
+                    css::uno::Reference<css::xml::dom::XAttr> xBoxClassName
+                        = xDoc->createAttribute("class");
+                    xBoxClassName->setValue("GtkBox");
+                    xNewObjectNode->setAttributeNode(xBoxClassName);
+
+                    if (eChildImagePos == GTK_POS_TOP || eChildImagePos == GTK_POS_BOTTOM)
+                    {
+                        auto xOrientation = CreateProperty(xDoc, "orientation", "vertical");
+                        xNewObjectNode->appendChild(xOrientation);
+                    }
 
-                xNewChildNode->appendChild(xNewObjectNode);
+                    xNewObjectNode->appendChild(CreateProperty(xDoc, "spacing", "6"));
+                    if (!bChildXAlign)
+                        xNewObjectNode->appendChild(CreateProperty(xDoc, "halign", "center"));
 
-                xChild->appendChild(xNewChildNode);
+                    xNewChildNode->appendChild(xNewObjectNode);
 
-                css::uno::Reference<css::xml::dom::XElement> xNewLabelChildNode
-                    = xDoc->createElement("child");
-                css::uno::Reference<css::xml::dom::XElement> xNewChildObjectNode
-                    = xDoc->createElement("object");
-                css::uno::Reference<css::xml::dom::XAttr> xLabelClassName
-                    = xDoc->createAttribute("class");
-                xLabelClassName->setValue("GtkLabel");
-                xNewChildObjectNode->setAttributeNode(xLabelClassName);
-                if (xChildPropertyLabel)
-                {
-                    xNewChildObjectNode->appendChild(
-                        xChildPropertyLabel->getParentNode()->removeChild(xChildPropertyLabel));
-                }
-                else
-                {
-                    auto xNotVisible = CreateProperty(xDoc, "visible", "False");
-                    xNewChildObjectNode->appendChild(xNotVisible);
-                }
-                if (bChildUseUnderline)
-                {
-                    auto xUseUnderline = CreateProperty(xDoc, "use-underline", "True");
-                    xNewChildObjectNode->appendChild(xUseUnderline);
-                }
-                xNewLabelChildNode->appendChild(xNewChildObjectNode);
+                    xChild->appendChild(xNewChildNode);
 
-                if (eChildImagePos == GTK_POS_LEFT || eChildImagePos == GTK_POS_TOP)
-                {
-                    if (xImageCandidateNode)
-                        xNewObjectNode->appendChild(xImageCandidateNode);
-                    xNewObjectNode->appendChild(xNewLabelChildNode);
-                }
-                else
-                {
-                    xNewObjectNode->appendChild(xNewLabelChildNode);
-                    if (xImageCandidateNode)
-                        xNewObjectNode->appendChild(xImageCandidateNode);
+                    css::uno::Reference<css::xml::dom::XElement> xNewLabelChildNode
+                        = xDoc->createElement("child");
+                    css::uno::Reference<css::xml::dom::XElement> xNewChildObjectNode
+                        = xDoc->createElement("object");
+                    css::uno::Reference<css::xml::dom::XAttr> xLabelClassName
+                        = xDoc->createAttribute("class");
+                    xLabelClassName->setValue("GtkLabel");
+                    xNewChildObjectNode->setAttributeNode(xLabelClassName);
+                    if (xChildPropertyLabel)
+                    {
+                        xNewChildObjectNode->appendChild(
+                            xChildPropertyLabel->getParentNode()->removeChild(xChildPropertyLabel));
+                    }
+                    else
+                    {
+                        auto xNotVisible = CreateProperty(xDoc, "visible", "False");
+                        xNewChildObjectNode->appendChild(xNotVisible);
+                    }
+                    if (bChildUseUnderline)
+                    {
+                        auto xUseUnderline = CreateProperty(xDoc, "use-underline", "True");
+                        xNewChildObjectNode->appendChild(xUseUnderline);
+                    }
+                    xNewLabelChildNode->appendChild(xNewChildObjectNode);
+
+                    if (eChildImagePos == GTK_POS_LEFT || eChildImagePos == GTK_POS_TOP)
+                    {
+                        if (xImageCandidateNode)
+                            xNewObjectNode->appendChild(xImageCandidateNode);
+                        xNewObjectNode->appendChild(xNewLabelChildNode);
+                    }
+                    else
+                    {
+                        xNewObjectNode->appendChild(xNewLabelChildNode);
+                        if (xImageCandidateNode)
+                            xNewObjectNode->appendChild(xImageCandidateNode);
+                    }
                 }
             }
         }


More information about the Libreoffice-commits mailing list