[Libreoffice-commits] core.git: Branch 'libreoffice-6-2' - include/vcl sfx2/source vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Feb 19 17:29:02 UTC 2019


 include/vcl/weld.hxx          |    5 
 sfx2/source/appl/sfxhelp.cxx  |   34 ++----
 vcl/source/app/salvtables.cxx |  224 ++++++++++++++++++++++++------------------
 vcl/unx/gtk3/gtk3gtkinst.cxx  |  213 ++++++++++++++++++++++++---------------
 4 files changed, 280 insertions(+), 196 deletions(-)

New commits:
commit 3432a0c5bb94e5c6f4dfa62e6f26939e69b8c6b8
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Feb 18 13:50:15 2019 +0000
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Feb 19 18:28:39 2019 +0100

    Resolves: tdf#122355 search help for active notebook page
    
    before checking for the dialog, to get more specific
    help results.
    
    Change-Id: I2d6128fa39d3f7ebf15e194354307dd924590009
    Reviewed-on: https://gerrit.libreoffice.org/67981
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 15b705474505..557f206abeca 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -142,6 +142,11 @@ public:
 
     virtual Container* weld_parent() const = 0;
 
+    //iterate upwards through the hierarchy sarting at this widgets parent,
+    //calling func with their helpid until func returns true or we run out of
+    //parents
+    virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) = 0;
+
     virtual ~Widget() {}
 };
 
diff --git a/sfx2/source/appl/sfxhelp.cxx b/sfx2/source/appl/sfxhelp.cxx
index 169d6a641425..03de650df70e 100644
--- a/sfx2/source/appl/sfxhelp.cxx
+++ b/sfx2/source/appl/sfxhelp.cxx
@@ -1243,26 +1243,22 @@ bool SfxHelp::Start_Impl(const OUString& rURL, weld::Widget* pWidget, const OUSt
 
             if ( impl_hasHelpInstalled() && pWidget && SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
             {
-                // no help found -> try with parent help id.
-                std::unique_ptr<weld::Widget> xParent(pWidget->weld_parent());
-                while (xParent)
+                bool bUseFinalFallback = true;
+                // no help found -> try ids of parents.
+                pWidget->help_hierarchy_foreach([&aHelpModuleName, &aHelpURL, &bUseFinalFallback](const OString& rHelpId){
+                    if (rHelpId.isEmpty())
+                        return false;
+                    aHelpURL = CreateHelpURL( OStringToOUString(rHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName);
+                    bool bFinished = !SfxContentHelper::IsHelpErrorDocument(aHelpURL);
+                    if (bFinished)
+                        bUseFinalFallback = false;
+                    return bFinished;
+                });
+
+                if (bUseFinalFallback)
                 {
-                    OString aHelpId = xParent->get_help_id();
-                    aHelpURL = CreateHelpURL( OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName );
-
-                    if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
-                    {
-                        break;
-                    }
-                    else
-                    {
-                        xParent.reset(xParent->weld_parent());
-                        if (!xParent)
-                        {
-                            // create help url of start page ( helpid == 0 -> start page)
-                            aHelpURL = CreateHelpURL( OUString(), aHelpModuleName );
-                        }
-                    }
+                    // create help url of start page ( helpid == 0 -> start page)
+                    aHelpURL = CreateHelpURL( OUString(), aHelpModuleName );
                 }
             }
             break;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 9dacfafaf9cf..297926d03012 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -224,11 +224,15 @@ SalMenuItem::~SalMenuItem()
 {
 }
 
+class SalInstanceBuilder;
+
 class SalInstanceWidget : public virtual weld::Widget
 {
-private:
+protected:
     VclPtr<vcl::Window> m_xWidget;
+    SalInstanceBuilder* m_pBuilder;
 
+private:
     DECL_LINK(EventListener, VclWindowEvent&, void);
 
     const bool m_bTakeOwnership;
@@ -248,8 +252,9 @@ protected:
     virtual void HandleEventListener(VclWindowEvent& rEvent);
 
 public:
-    SalInstanceWidget(vcl::Window* pWidget, bool bTakeOwnership)
+    SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
         : m_xWidget(pWidget)
+        , m_pBuilder(pBuilder)
         , m_bTakeOwnership(bTakeOwnership)
         , m_bEventListener(false)
         , m_nBlockNotify(0)
@@ -549,6 +554,8 @@ public:
         --m_nBlockNotify;
     }
 
+    virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) override;
+
     SystemWindow* getSystemWindow()
     {
         return m_xWidget->GetSystemWindow();
@@ -693,8 +700,8 @@ class SalInstanceContainer : public SalInstanceWidget, public virtual weld::Cont
 private:
     VclPtr<vcl::Window> m_xContainer;
 public:
-    SalInstanceContainer(vcl::Window* pContainer, bool bTakeOwnership)
-        : SalInstanceWidget(pContainer, bTakeOwnership)
+    SalInstanceContainer(vcl::Window* pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pContainer, pBuilder, bTakeOwnership)
         , m_xContainer(pContainer)
     {
     }
@@ -711,7 +718,7 @@ public:
 weld::Container* SalInstanceWidget::weld_parent() const
 {
     vcl::Window* pParent = m_xWidget->GetParent();
-    return pParent ? new SalInstanceContainer(pParent, false) : nullptr;
+    return pParent ? new SalInstanceContainer(pParent, m_pBuilder, false) : nullptr;
 }
 
 class SalInstanceWindow : public SalInstanceContainer, public virtual weld::Window
@@ -736,8 +743,8 @@ private:
     }
 
 public:
-    SalInstanceWindow(vcl::Window* pWindow, bool bTakeOwnership)
-        : SalInstanceContainer(pWindow, bTakeOwnership)
+    SalInstanceWindow(vcl::Window* pWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pWindow, pBuilder, bTakeOwnership)
         , m_xWindow(pWindow)
     {
         override_child_help(m_xWindow);
@@ -767,7 +774,7 @@ public:
                 break;
             sHelpId = pWidget->GetHelpId();
         }
-        std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, false) : nullptr);
+        std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, m_pBuilder, false) : nullptr);
         weld::Widget* pSource = xTemp ? xTemp.get() : this;
         bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
         Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
@@ -880,8 +887,8 @@ private:
     VclPtr<::Dialog> m_xDialog;
 
 public:
-    SalInstanceDialog(::Dialog* pDialog, bool bTakeOwnership)
-        : SalInstanceWindow(pDialog, bTakeOwnership)
+    SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWindow(pDialog, pBuilder, bTakeOwnership)
         , m_xDialog(pDialog)
     {
     }
@@ -931,7 +938,7 @@ public:
 
     virtual Container* weld_content_area() override
     {
-        return new SalInstanceContainer(m_xDialog->get_content_area(), false);
+        return new SalInstanceContainer(m_xDialog->get_content_area(), m_pBuilder, false);
     }
 };
 
@@ -940,8 +947,8 @@ class SalInstanceMessageDialog : public SalInstanceDialog, public virtual weld::
 private:
     VclPtr<::MessageDialog> m_xMessageDialog;
 public:
-    SalInstanceMessageDialog(::MessageDialog* pDialog, bool bTakeOwnership)
-        : SalInstanceDialog(pDialog, bTakeOwnership)
+    SalInstanceMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
         , m_xMessageDialog(pDialog)
     {
     }
@@ -968,7 +975,7 @@ public:
 
     virtual Container* weld_message_area() override
     {
-        return new SalInstanceContainer(m_xMessageDialog->get_message_area(), false);
+        return new SalInstanceContainer(m_xMessageDialog->get_message_area(), m_pBuilder, false);
     }
 };
 
@@ -977,8 +984,8 @@ class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
 private:
     VclPtr<VclFrame> m_xFrame;
 public:
-    SalInstanceFrame(VclFrame* pFrame, bool bTakeOwnership)
-        : SalInstanceContainer(pFrame, bTakeOwnership)
+    SalInstanceFrame(VclFrame* pFrame, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pFrame, pBuilder, bTakeOwnership)
         , m_xFrame(pFrame)
     {
     }
@@ -1004,8 +1011,8 @@ private:
     DECL_LINK(VscrollHdl, ScrollBar*, void);
 
 public:
-    SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, bool bTakeOwnership)
-        : SalInstanceContainer(pScrolledWindow, bTakeOwnership)
+    SalInstanceScrolledWindow(VclScrolledWindow* pScrolledWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pScrolledWindow, pBuilder, bTakeOwnership)
         , m_xScrolledWindow(pScrolledWindow)
         , m_bUserManagedScrolling(false)
     {
@@ -1132,8 +1139,8 @@ private:
     DECL_LINK(ActivatePageHdl, TabControl*, void);
 
 public:
-    SalInstanceNotebook(TabControl* pNotebook, bool bTakeOwnership)
-        : SalInstanceContainer(pNotebook, bTakeOwnership)
+    SalInstanceNotebook(TabControl* pNotebook, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pNotebook, pBuilder, bTakeOwnership)
         , m_xNotebook(pNotebook)
     {
         m_xNotebook->SetActivatePageHdl(LINK(this, SalInstanceNotebook, ActivatePageHdl));
@@ -1161,7 +1168,7 @@ public:
         if (m_aPages.size() < nPageIndex + 1U)
             m_aPages.resize(nPageIndex + 1U);
         if (!m_aPages[nPageIndex])
-            m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, false));
+            m_aPages[nPageIndex].reset(new SalInstanceContainer(pChild, m_pBuilder, false));
         return m_aPages[nPageIndex].get();
     }
 
@@ -1236,8 +1243,8 @@ private:
 
     DECL_LINK(ClickHdl, ::Button*, void);
 public:
-    SalInstanceButton(::Button* pButton, bool bTakeOwnership)
-        : SalInstanceContainer(pButton, bTakeOwnership)
+    SalInstanceButton(::Button* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pButton, pBuilder, bTakeOwnership)
         , m_xButton(pButton)
         , m_aOldClickHdl(pButton->GetClickHdl())
     {
@@ -1305,7 +1312,7 @@ IMPL_LINK(SalInstanceButton, ClickHdl, ::Button*, pButton, void)
 weld::Button* SalInstanceDialog::get_widget_for_response(int nResponse)
 {
     PushButton* pButton = dynamic_cast<PushButton*>(m_xDialog->get_widget_for_response(nResponse));
-    return pButton ? new SalInstanceButton(pButton, false) : nullptr;
+    return pButton ? new SalInstanceButton(pButton, nullptr, false) : nullptr;
 }
 
 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
@@ -1317,8 +1324,8 @@ private:
     DECL_LINK(ActivateHdl, ::MenuButton*, void);
 
 public:
-    SalInstanceMenuButton(::MenuButton* pButton, bool bTakeOwnership)
-        : SalInstanceButton(pButton, bTakeOwnership)
+    SalInstanceMenuButton(::MenuButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
         , m_xMenuButton(pButton)
     {
         m_xMenuButton->SetActivateHdl(LINK(this, SalInstanceMenuButton, ActivateHdl));
@@ -1419,8 +1426,8 @@ private:
     DECL_LINK(ToggleHdl, ::RadioButton&, void);
 
 public:
-    SalInstanceRadioButton(::RadioButton* pButton, bool bTakeOwnership)
-        : SalInstanceButton(pButton, bTakeOwnership)
+    SalInstanceRadioButton(::RadioButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
         , m_xRadioButton(pButton)
     {
         m_xRadioButton->SetToggleHdl(LINK(this, SalInstanceRadioButton, ToggleHdl));
@@ -1474,8 +1481,8 @@ private:
     DECL_LINK(ToggleListener, VclWindowEvent&, void);
 
 public:
-    SalInstanceToggleButton(PushButton* pButton, bool bTakeOwnership)
-        : SalInstanceButton(pButton, bTakeOwnership)
+    SalInstanceToggleButton(PushButton* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
         , m_xToggleButton(pButton)
     {
     }
@@ -1533,8 +1540,8 @@ private:
 
     DECL_LINK(ToggleHdl, CheckBox&, void);
 public:
-    SalInstanceCheckButton(CheckBox* pButton, bool bTakeOwnership)
-        : SalInstanceButton(pButton, bTakeOwnership)
+    SalInstanceCheckButton(CheckBox* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceButton(pButton, pBuilder, bTakeOwnership)
         , m_xCheckButton(pButton)
     {
         m_xCheckButton->SetToggleHdl(LINK(this, SalInstanceCheckButton, ToggleHdl));
@@ -1587,8 +1594,8 @@ private:
 
     DECL_LINK(SlideHdl, Slider*, void);
 public:
-    SalInstanceScale(Slider* pScale, bool bTakeOwnership)
-        : SalInstanceWidget(pScale, bTakeOwnership)
+    SalInstanceScale(Slider* pScale, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pScale, pBuilder, bTakeOwnership)
         , m_xScale(pScale)
     {
         m_xScale->SetSlideHdl(LINK(this, SalInstanceScale, SlideHdl));
@@ -1627,8 +1634,8 @@ private:
     VclPtr<::ProgressBar> m_xProgressBar;
 
 public:
-    SalInstanceProgressBar(::ProgressBar* pProgressBar, bool bTakeOwnership)
-        : SalInstanceWidget(pProgressBar, bTakeOwnership)
+    SalInstanceProgressBar(::ProgressBar* pProgressBar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pProgressBar, pBuilder, bTakeOwnership)
         , m_xProgressBar(pProgressBar)
     {
     }
@@ -1645,8 +1652,8 @@ private:
     VclPtr<FixedImage> m_xImage;
 
 public:
-    SalInstanceImage(FixedImage* pImage, bool bTakeOwnership)
-        : SalInstanceWidget(pImage, bTakeOwnership)
+    SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pImage, pBuilder, bTakeOwnership)
         , m_xImage(pImage)
     {
     }
@@ -1694,8 +1701,8 @@ private:
 
     WeldTextFilter m_aTextFilter;
 public:
-    SalInstanceEntry(Edit* pEntry, bool bTakeOwnership)
-        : SalInstanceWidget(pEntry, bTakeOwnership)
+    SalInstanceEntry(Edit* pEntry, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pEntry, pBuilder, bTakeOwnership)
         , m_xEntry(pEntry)
         , m_aTextFilter(m_aInsertTextHdl)
     {
@@ -1868,8 +1875,8 @@ private:
     DECL_LINK(EndDragHdl, HeaderBar*, void);
     DECL_LINK(ToggleHdl, SvLBoxButtonData*, void);
 public:
-    SalInstanceTreeView(SvTabListBox* pTreeView, bool bTakeOwnership)
-        : SalInstanceContainer(pTreeView, bTakeOwnership)
+    SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
         , m_xTreeView(pTreeView)
         , m_aCheckButtonData(pTreeView, false)
         , m_aRadioButtonData(pTreeView, true)
@@ -2542,8 +2549,8 @@ private:
     }
 
 public:
-    SalInstanceSpinButton(FormattedField* pButton, bool bTakeOwnership)
-        : SalInstanceEntry(pButton, bTakeOwnership)
+    SalInstanceSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
         , m_xButton(pButton)
     {
         m_xButton->SetThousandsSep(false);  //off by default, MetricSpinButton enables it
@@ -2659,8 +2666,8 @@ private:
     VclPtr<FormattedField> m_xButton;
 
 public:
-    SalInstanceFormattedSpinButton(FormattedField* pButton, bool bTakeOwnership)
-        : SalInstanceEntry(pButton, bTakeOwnership)
+    SalInstanceFormattedSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceEntry(pButton, pBuilder, bTakeOwnership)
         , m_xButton(pButton)
     {
         // #i6278# allow more decimal places than the output format.  As
@@ -2713,8 +2720,8 @@ class SalInstanceLabel : public SalInstanceWidget, public virtual weld::Label
 private:
     VclPtr<FixedText> m_xLabel;
 public:
-    SalInstanceLabel(FixedText* pLabel, bool bTakeOwnership)
-        : SalInstanceWidget(pLabel, bTakeOwnership)
+    SalInstanceLabel(FixedText* pLabel, SalInstanceBuilder *pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pLabel, pBuilder, bTakeOwnership)
         , m_xLabel(pLabel)
     {
     }
@@ -2742,8 +2749,8 @@ private:
     VclPtr<VclMultiLineEdit> m_xTextView;
 
 public:
-    SalInstanceTextView(VclMultiLineEdit* pTextView, bool bTakeOwnership)
-        : SalInstanceContainer(pTextView, bTakeOwnership)
+    SalInstanceTextView(VclMultiLineEdit* pTextView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pTextView, pBuilder, bTakeOwnership)
         , m_xTextView(pTextView)
     {
     }
@@ -2792,8 +2799,8 @@ private:
     DECL_LINK(ExpandedHdl, VclExpander&, void);
 
 public:
-    SalInstanceExpander(VclExpander* pExpander, bool bTakeOwnership)
-        : SalInstanceContainer(pExpander, bTakeOwnership)
+    SalInstanceExpander(VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pExpander, pBuilder, bTakeOwnership)
         , m_xExpander(pExpander)
     {
         m_xExpander->SetExpandedHdl(LINK(this, SalInstanceExpander, ExpandedHdl));
@@ -2852,9 +2859,9 @@ private:
     }
 
 public:
-    SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, const a11yref& rAlly,
+    SalInstanceDrawingArea(VclDrawingArea* pDrawingArea, SalInstanceBuilder* pBuilder, const a11yref& rAlly,
             FactoryFunction pUITestFactoryFunction, void* pUserData, bool bTakeOwnership)
-        : SalInstanceWidget(pDrawingArea, bTakeOwnership)
+        : SalInstanceWidget(pDrawingArea, pBuilder, bTakeOwnership)
         , m_xDrawingArea(pDrawingArea)
     {
         m_xDrawingArea->SetAccessible(rAlly);
@@ -3021,8 +3028,8 @@ protected:
     VclPtr<vcl_type> m_xComboBox;
 
 public:
-    SalInstanceComboBox(vcl_type* pComboBox, bool bTakeOwnership)
-        : SalInstanceContainer(pComboBox, bTakeOwnership)
+    SalInstanceComboBox(vcl_type* pComboBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceContainer(pComboBox, pBuilder, bTakeOwnership)
         , m_xComboBox(pComboBox)
     {
     }
@@ -3151,8 +3158,8 @@ private:
     DECL_LINK(SelectHdl, ListBox&, void);
 
 public:
-    SalInstanceComboBoxWithoutEdit(ListBox* pListBox, bool bTakeOwnership)
-        : SalInstanceComboBox<ListBox>(pListBox, bTakeOwnership)
+    SalInstanceComboBoxWithoutEdit(ListBox* pListBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceComboBox<ListBox>(pListBox, pBuilder, bTakeOwnership)
     {
         m_xComboBox->SetSelectHdl(LINK(this, SalInstanceComboBoxWithoutEdit, SelectHdl));
     }
@@ -3244,8 +3251,8 @@ private:
     DECL_LINK(EntryActivateHdl, Edit&, bool);
     WeldTextFilter m_aTextFilter;
 public:
-    SalInstanceComboBoxWithEdit(::ComboBox* pComboBox, bool bTakeOwnership)
-        : SalInstanceComboBox<::ComboBox>(pComboBox, bTakeOwnership)
+    SalInstanceComboBoxWithEdit(::ComboBox* pComboBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : SalInstanceComboBox<::ComboBox>(pComboBox, pBuilder, bTakeOwnership)
         , m_aTextFilter(m_aEntryInsertTextHdl)
     {
         m_xComboBox->SetModifyHdl(LINK(this, SalInstanceComboBoxWithEdit, ChangeHdl));
@@ -3353,9 +3360,10 @@ private:
     SalInstanceEntry* m_pEntry;
     SalInstanceTreeView* m_pTreeView;
 public:
-    SalInstanceEntryTreeView(vcl::Window *pContainer, bool bTakeOwnership, std::unique_ptr<weld::Entry> xEntry, std::unique_ptr<weld::TreeView> xTreeView)
+    SalInstanceEntryTreeView(vcl::Window *pContainer, SalInstanceBuilder* pBuilder, bool bTakeOwnership,
+                             std::unique_ptr<weld::Entry> xEntry, std::unique_ptr<weld::TreeView> xTreeView)
         : EntryTreeView(std::move(xEntry), std::move(xTreeView))
-        , SalInstanceContainer(pContainer, bTakeOwnership)
+        , SalInstanceContainer(pContainer, pBuilder, bTakeOwnership)
         , m_pEntry(dynamic_cast<SalInstanceEntry*>(m_xEntry.get()))
         , m_pTreeView(dynamic_cast<SalInstanceTreeView*>(m_xTreeView.get()))
     {
@@ -3465,10 +3473,15 @@ public:
     {
     }
 
+    VclBuilder& get_builder() const
+    {
+        return *m_xBuilder;
+    }
+
     virtual std::unique_ptr<weld::MessageDialog> weld_message_dialog(const OString &id, bool bTakeOwnership) override
     {
         MessageDialog* pMessageDialog = m_xBuilder->get<MessageDialog>(id);
-        std::unique_ptr<weld::MessageDialog> pRet(pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, false) : nullptr);
+        std::unique_ptr<weld::MessageDialog> pRet(pMessageDialog ? new SalInstanceMessageDialog(pMessageDialog, this, false) : nullptr);
         if (bTakeOwnership && pMessageDialog)
         {
             assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
@@ -3481,7 +3494,7 @@ public:
     virtual std::unique_ptr<weld::Dialog> weld_dialog(const OString &id, bool bTakeOwnership) override
     {
         Dialog* pDialog = m_xBuilder->get<Dialog>(id);
-        std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, false) : nullptr);
+        std::unique_ptr<weld::Dialog> pRet(pDialog ? new SalInstanceDialog(pDialog, this, false) : nullptr);
         if (bTakeOwnership && pDialog)
         {
             assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
@@ -3494,25 +3507,25 @@ public:
     virtual std::unique_ptr<weld::Window> weld_window(const OString &id, bool bTakeOwnership) override
     {
         SystemWindow* pWindow = m_xBuilder->get<SystemWindow>(id);
-        return pWindow ? o3tl::make_unique<SalInstanceWindow>(pWindow, bTakeOwnership) : nullptr;
+        return pWindow ? o3tl::make_unique<SalInstanceWindow>(pWindow, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Widget> weld_widget(const OString &id, bool bTakeOwnership) override
     {
         vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
-        return pWidget ? o3tl::make_unique<SalInstanceWidget>(pWidget, bTakeOwnership) : nullptr;
+        return pWidget ? o3tl::make_unique<SalInstanceWidget>(pWidget, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Container> weld_container(const OString &id, bool bTakeOwnership) override
     {
         vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
-        return pContainer ? o3tl::make_unique<SalInstanceContainer>(pContainer, bTakeOwnership) : nullptr;
+        return pContainer ? o3tl::make_unique<SalInstanceContainer>(pContainer, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Frame> weld_frame(const OString &id, bool bTakeOwnership) override
     {
         VclFrame* pFrame = m_xBuilder->get<VclFrame>(id);
-        std::unique_ptr<weld::Frame> pRet(pFrame ? new SalInstanceFrame(pFrame, false) : nullptr);
+        std::unique_ptr<weld::Frame> pRet(pFrame ? new SalInstanceFrame(pFrame, this, false) : nullptr);
         if (bTakeOwnership && pFrame)
         {
             assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
@@ -3525,73 +3538,73 @@ public:
     virtual std::unique_ptr<weld::ScrolledWindow> weld_scrolled_window(const OString &id, bool bTakeOwnership) override
     {
         VclScrolledWindow* pScrolledWindow = m_xBuilder->get<VclScrolledWindow>(id);
-        return pScrolledWindow ? o3tl::make_unique<SalInstanceScrolledWindow>(pScrolledWindow, bTakeOwnership) : nullptr;
+        return pScrolledWindow ? o3tl::make_unique<SalInstanceScrolledWindow>(pScrolledWindow, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Notebook> weld_notebook(const OString &id, bool bTakeOwnership) override
     {
         TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
-        return pNotebook ? o3tl::make_unique<SalInstanceNotebook>(pNotebook, bTakeOwnership) : nullptr;
+        return pNotebook ? o3tl::make_unique<SalInstanceNotebook>(pNotebook, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Button> weld_button(const OString &id, bool bTakeOwnership) override
     {
         Button* pButton = m_xBuilder->get<Button>(id);
-        return pButton ? o3tl::make_unique<SalInstanceButton>(pButton, bTakeOwnership) : nullptr;
+        return pButton ? o3tl::make_unique<SalInstanceButton>(pButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OString &id, bool bTakeOwnership) override
     {
         MenuButton* pButton = m_xBuilder->get<MenuButton>(id);
-        return pButton ? o3tl::make_unique<SalInstanceMenuButton>(pButton, bTakeOwnership) : nullptr;
+        return pButton ? o3tl::make_unique<SalInstanceMenuButton>(pButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OString &id, bool bTakeOwnership) override
     {
         PushButton* pToggleButton = m_xBuilder->get<PushButton>(id);
-        return pToggleButton ? o3tl::make_unique<SalInstanceToggleButton>(pToggleButton, bTakeOwnership) : nullptr;
+        return pToggleButton ? o3tl::make_unique<SalInstanceToggleButton>(pToggleButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::RadioButton> weld_radio_button(const OString &id, bool bTakeOwnership) override
     {
         RadioButton* pRadioButton = m_xBuilder->get<RadioButton>(id);
-        return pRadioButton ? o3tl::make_unique<SalInstanceRadioButton>(pRadioButton, bTakeOwnership) : nullptr;
+        return pRadioButton ? o3tl::make_unique<SalInstanceRadioButton>(pRadioButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::CheckButton> weld_check_button(const OString &id, bool bTakeOwnership) override
     {
         CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
-        return pCheckButton ? o3tl::make_unique<SalInstanceCheckButton>(pCheckButton, bTakeOwnership) : nullptr;
+        return pCheckButton ? o3tl::make_unique<SalInstanceCheckButton>(pCheckButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Scale> weld_scale(const OString &id, bool bTakeOwnership) override
     {
         Slider* pSlider = m_xBuilder->get<Slider>(id);
-        return pSlider ? o3tl::make_unique<SalInstanceScale>(pSlider, bTakeOwnership) : nullptr;
+        return pSlider ? o3tl::make_unique<SalInstanceScale>(pSlider, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::ProgressBar> weld_progress_bar(const OString &id, bool bTakeOwnership) override
     {
         ::ProgressBar* pProgress = m_xBuilder->get<::ProgressBar>(id);
-        return pProgress ? o3tl::make_unique<SalInstanceProgressBar>(pProgress, bTakeOwnership) : nullptr;
+        return pProgress ? o3tl::make_unique<SalInstanceProgressBar>(pProgress, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Image> weld_image(const OString &id, bool bTakeOwnership) override
     {
         FixedImage* pImage = m_xBuilder->get<FixedImage>(id);
-        return pImage ? o3tl::make_unique<SalInstanceImage>(pImage, bTakeOwnership) : nullptr;
+        return pImage ? o3tl::make_unique<SalInstanceImage>(pImage, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Entry> weld_entry(const OString &id, bool bTakeOwnership) override
     {
         Edit* pEntry = m_xBuilder->get<Edit>(id);
-        return pEntry ? o3tl::make_unique<SalInstanceEntry>(pEntry, bTakeOwnership) : nullptr;
+        return pEntry ? o3tl::make_unique<SalInstanceEntry>(pEntry, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OString &id, bool bTakeOwnership) override
     {
         FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
-        return pSpinButton ? o3tl::make_unique<SalInstanceSpinButton>(pSpinButton, bTakeOwnership) : nullptr;
+        return pSpinButton ? o3tl::make_unique<SalInstanceSpinButton>(pSpinButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::MetricSpinButton> weld_metric_spin_button(const OString& id, FieldUnit eUnit,
@@ -3610,7 +3623,7 @@ public:
                                                                                   bool bTakeOwnership) override
     {
         FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
-        return pSpinButton ? o3tl::make_unique<SalInstanceFormattedSpinButton>(pSpinButton, bTakeOwnership) : nullptr;
+        return pSpinButton ? o3tl::make_unique<SalInstanceFormattedSpinButton>(pSpinButton, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::TimeSpinButton> weld_time_spin_button(const OString& id, TimeFieldFormat eFormat,
@@ -3627,47 +3640,48 @@ public:
         vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
         ::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
         if (pComboBox)
-            return o3tl::make_unique<SalInstanceComboBoxWithEdit>(pComboBox, bTakeOwnership);
+            return o3tl::make_unique<SalInstanceComboBoxWithEdit>(pComboBox, this, bTakeOwnership);
         ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
-        return pListBox ? o3tl::make_unique<SalInstanceComboBoxWithoutEdit>(pListBox, bTakeOwnership) : nullptr;
+        return pListBox ? o3tl::make_unique<SalInstanceComboBoxWithoutEdit>(pListBox, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::EntryTreeView> weld_entry_tree_view(const OString& containerid, const OString& entryid, const OString& treeviewid, bool bTakeOwnership) override
     {
         vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(containerid);
-        return pContainer ? o3tl::make_unique<SalInstanceEntryTreeView>(pContainer, bTakeOwnership, weld_entry(entryid, bTakeOwnership),
-                                                                        weld_tree_view(treeviewid, bTakeOwnership)) : nullptr;
+        return pContainer ? o3tl::make_unique<SalInstanceEntryTreeView>(pContainer, this, bTakeOwnership,
+                                                                       weld_entry(entryid, bTakeOwnership),
+                                                                       weld_tree_view(treeviewid, bTakeOwnership)) : nullptr;
     }
 
     virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString &id, bool bTakeOwnership) override
     {
         SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
-        return pTreeView ? o3tl::make_unique<SalInstanceTreeView>(pTreeView, bTakeOwnership) : nullptr;
+        return pTreeView ? o3tl::make_unique<SalInstanceTreeView>(pTreeView, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Label> weld_label(const OString &id, bool bTakeOwnership) override
     {
         FixedText* pLabel = m_xBuilder->get<FixedText>(id);
-        return pLabel ? o3tl::make_unique<SalInstanceLabel>(pLabel, bTakeOwnership) : nullptr;
+        return pLabel ? o3tl::make_unique<SalInstanceLabel>(pLabel, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::TextView> weld_text_view(const OString &id, bool bTakeOwnership) override
     {
         VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
-        return pTextView ? o3tl::make_unique<SalInstanceTextView>(pTextView, bTakeOwnership) : nullptr;
+        return pTextView ? o3tl::make_unique<SalInstanceTextView>(pTextView, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Expander> weld_expander(const OString &id, bool bTakeOwnership) override
     {
         VclExpander* pExpander = m_xBuilder->get<VclExpander>(id);
-        return pExpander ? o3tl::make_unique<SalInstanceExpander>(pExpander, bTakeOwnership) : nullptr;
+        return pExpander ? o3tl::make_unique<SalInstanceExpander>(pExpander, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::DrawingArea> weld_drawing_area(const OString &id, const a11yref& rA11yImpl,
             FactoryFunction pUITestFactoryFunction, void* pUserData, bool bTakeOwnership) override
     {
         VclDrawingArea* pDrawingArea = m_xBuilder->get<VclDrawingArea>(id);
-        return pDrawingArea ? o3tl::make_unique<SalInstanceDrawingArea>(pDrawingArea, rA11yImpl,
+        return pDrawingArea ? o3tl::make_unique<SalInstanceDrawingArea>(pDrawingArea, this, rA11yImpl,
                 pUITestFactoryFunction, pUserData, bTakeOwnership) : nullptr;
     }
 
@@ -3711,12 +3725,38 @@ weld::Builder* Application::CreateInterimBuilder(weld::Widget* pParent, const OU
     return Application::CreateInterimBuilder(pParentWidget, rUIFile);
 }
 
+//iterate upwards through the hierarchy from this widgets through its parents
+//calling func with their helpid until func returns true or we run out of parents
+void SalInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OString&)>& func)
+{
+    vcl::Window* pParent = m_xWidget;
+    while ((pParent = pParent->GetParent()))
+    {
+        if (m_pBuilder && pParent->IsDialog())
+        {
+            // tdf#122355 During help fallback, before we ask a dialog for its help
+            // see if it has a TabControl and ask the active tab of that for help
+            TabControl *pCtrl = m_pBuilder->get_builder().get<TabControl>("tabcontrol");
+            TabPage* pTabPage = pCtrl ? pCtrl->GetTabPage(pCtrl->GetCurPageId()) : nullptr;
+            vcl::Window *pTabChild = pTabPage ? pTabPage->GetWindow(GetWindowType::FirstChild) : nullptr;
+            pTabChild = pTabChild ? pTabChild->GetWindow(GetWindowType::FirstChild) : nullptr;
+            if (pTabChild)
+            {
+                if (func(pTabChild->GetHelpId()))
+                    return;
+            }
+        }
+        if (func(pParent->GetHelpId()))
+            return;
+    }
+}
+
 weld::MessageDialog* SalInstance::CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType, VclButtonsType eButtonsType, const OUString& rPrimaryMessage)
 {
     SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
     SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
     VclPtrInstance<MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType, eButtonsType);
-    return new SalInstanceMessageDialog(xMessageDialog, true);
+    return new SalInstanceMessageDialog(xMessageDialog, nullptr, true);
 }
 
 weld::Window* SalInstance::GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow)
@@ -3738,7 +3778,7 @@ weld::Window* SalFrame::GetFrameWeld() const
         pWindow = pWindow ? pWindow->ImplGetWindow() : nullptr;
         assert(!pWindow || (pWindow->IsSystemWindow() || pWindow->IsDockingWindow()));
         if (pWindow)
-            m_xFrameWeld.reset(new SalInstanceWindow(pWindow, false));
+            m_xFrameWeld.reset(new SalInstanceWindow(pWindow, nullptr, false));
     }
     return m_xFrameWeld.get();
 }
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 16b32937dfa3..a9fdfd3615eb 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1220,6 +1220,7 @@ class GtkInstanceWidget : public virtual weld::Widget
 {
 protected:
     GtkWidget* m_pWidget;
+    GtkInstanceBuilder* m_pBuilder;
 
     static void signalFocusIn(GtkWidget*, GdkEvent*, gpointer widget)
     {
@@ -1275,8 +1276,9 @@ private:
     }
 
 public:
-    GtkInstanceWidget(GtkWidget* pWidget, bool bTakeOwnership)
+    GtkInstanceWidget(GtkWidget* pWidget, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
         : m_pWidget(pWidget)
+        , m_pBuilder(pBuilder)
         , m_bTakeOwnership(bTakeOwnership)
         , m_bFrozen(false)
         , m_nFocusInSignalId(0)
@@ -1662,6 +1664,8 @@ public:
         if (m_nFocusInSignalId)
             g_signal_handler_unblock(m_pWidget, m_nFocusInSignalId);
     }
+
+    virtual void help_hierarchy_foreach(const std::function<bool(const OString&)>& func) override;
 };
 
 namespace
@@ -1999,8 +2003,8 @@ class GtkInstanceContainer : public GtkInstanceWidget, public virtual weld::Cont
 private:
     GtkContainer* m_pContainer;
 public:
-    GtkInstanceContainer(GtkContainer* pContainer, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pContainer), bTakeOwnership)
+    GtkInstanceContainer(GtkContainer* pContainer, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pContainer), pBuilder, bTakeOwnership)
         , m_pContainer(pContainer)
     {
     }
@@ -2026,7 +2030,7 @@ public:
 weld::Container* GtkInstanceWidget::weld_parent() const
 {
     GtkWidget* pParent = gtk_widget_get_parent(m_pWidget);
-    return pParent ? new GtkInstanceContainer(GTK_CONTAINER(pParent), false) : nullptr;
+    return pParent ? new GtkInstanceContainer(GTK_CONTAINER(pParent), m_pBuilder, false) : nullptr;
 }
 
 class GtkInstanceWindow : public GtkInstanceContainer, public virtual weld::Window
@@ -2043,8 +2047,8 @@ private:
 protected:
     void help();
 public:
-    GtkInstanceWindow(GtkWindow* pWindow, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pWindow), bTakeOwnership)
+    GtkInstanceWindow(GtkWindow* pWindow, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pWindow), pBuilder, bTakeOwnership)
         , m_pWindow(pWindow)
     {
         //hook up F1 to show help
@@ -2437,8 +2441,8 @@ private:
     }
 
 public:
-    GtkInstanceDialog(GtkDialog* pDialog, bool bTakeOwnership)
-        : GtkInstanceWindow(GTK_WINDOW(pDialog), bTakeOwnership)
+    GtkInstanceDialog(GtkDialog* pDialog, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWindow(GTK_WINDOW(pDialog), pBuilder, bTakeOwnership)
         , m_pDialog(pDialog)
         , m_aDialogRun(pDialog)
         , m_nCloseSignalId(g_signal_connect(m_pDialog, "close", G_CALLBACK(signalClose), this))
@@ -2546,7 +2550,7 @@ public:
 
     virtual Container* weld_content_area() override
     {
-        return new GtkInstanceContainer(GTK_CONTAINER(gtk_dialog_get_content_area(m_pDialog)), false);
+        return new GtkInstanceContainer(GTK_CONTAINER(gtk_dialog_get_content_area(m_pDialog)), m_pBuilder, false);
     }
 
     virtual void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>&) override
@@ -2567,8 +2571,8 @@ class GtkInstanceMessageDialog : public GtkInstanceDialog, public virtual weld::
 private:
     GtkMessageDialog* m_pMessageDialog;
 public:
-    GtkInstanceMessageDialog(GtkMessageDialog* pMessageDialog, bool bTakeOwnership)
-        : GtkInstanceDialog(GTK_DIALOG(pMessageDialog), bTakeOwnership)
+    GtkInstanceMessageDialog(GtkMessageDialog* pMessageDialog, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceDialog(GTK_DIALOG(pMessageDialog), pBuilder, bTakeOwnership)
         , m_pMessageDialog(pMessageDialog)
     {
     }
@@ -2595,7 +2599,7 @@ public:
 
     virtual Container* weld_message_area() override
     {
-        return new GtkInstanceContainer(GTK_CONTAINER(gtk_message_dialog_get_message_area(m_pMessageDialog)), false);
+        return new GtkInstanceContainer(GTK_CONTAINER(gtk_message_dialog_get_message_area(m_pMessageDialog)), m_pBuilder, false);
     }
 };
 
@@ -2604,8 +2608,8 @@ class GtkInstanceFrame : public GtkInstanceContainer, public virtual weld::Frame
 private:
     GtkFrame* m_pFrame;
 public:
-    GtkInstanceFrame(GtkFrame* pFrame, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pFrame), bTakeOwnership)
+    GtkInstanceFrame(GtkFrame* pFrame, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pFrame), pBuilder, bTakeOwnership)
         , m_pFrame(pFrame)
     {
     }
@@ -2888,8 +2892,8 @@ private:
     }
 
 public:
-    GtkInstanceScrolledWindow(GtkScrolledWindow* pScrolledWindow, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pScrolledWindow), bTakeOwnership)
+    GtkInstanceScrolledWindow(GtkScrolledWindow* pScrolledWindow, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pScrolledWindow), pBuilder, bTakeOwnership)
         , m_pScrolledWindow(pScrolledWindow)
         , m_pOrigViewport(nullptr)
         , m_pVAdjustment(gtk_scrolled_window_get_vadjustment(m_pScrolledWindow))
@@ -3449,8 +3453,8 @@ private:
     }
 
 public:
-    GtkInstanceNotebook(GtkNotebook* pNotebook, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pNotebook), bTakeOwnership)
+    GtkInstanceNotebook(GtkNotebook* pNotebook, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pNotebook), pBuilder, bTakeOwnership)
         , m_pNotebook(pNotebook)
         , m_pOverFlowBox(nullptr)
         , m_pOverFlowNotebook(GTK_NOTEBOOK(gtk_notebook_new()))
@@ -3535,7 +3539,7 @@ public:
         if (m_aPages.size() < nPageIndex + 1)
             m_aPages.resize(nPageIndex + 1);
         if (!m_aPages[nPageIndex])
-            m_aPages[nPageIndex].reset(new GtkInstanceContainer(pChild, false));
+            m_aPages[nPageIndex].reset(new GtkInstanceContainer(pChild, m_pBuilder, false));
         return m_aPages[nPageIndex].get();
     }
 
@@ -3672,8 +3676,8 @@ private:
     }
 
 public:
-    GtkInstanceButton(GtkButton* pButton, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pButton), bTakeOwnership)
+    GtkInstanceButton(GtkButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pButton), pBuilder, bTakeOwnership)
         , m_pButton(pButton)
         , m_nSignalId(g_signal_connect(pButton, "clicked", G_CALLBACK(signalClicked), this))
     {
@@ -3750,7 +3754,7 @@ weld::Button* GtkInstanceDialog::get_widget_for_response(int nResponse)
     GtkButton* pButton = GTK_BUTTON(gtk_dialog_get_widget_for_response(m_pDialog, VclToGtk(nResponse)));
     if (!pButton)
         return nullptr;
-    return new GtkInstanceButton(pButton, false);
+    return new GtkInstanceButton(pButton, m_pBuilder, false);
 }
 
 void GtkInstanceDialog::response(int nResponse)
@@ -3790,8 +3794,8 @@ private:
         pThis->signal_toggled();
     }
 public:
-    GtkInstanceToggleButton(GtkToggleButton* pButton, bool bTakeOwnership)
-        : GtkInstanceButton(GTK_BUTTON(pButton), bTakeOwnership)
+    GtkInstanceToggleButton(GtkToggleButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceButton(GTK_BUTTON(pButton), pBuilder, bTakeOwnership)
         , m_pToggleButton(pButton)
         , m_nSignalId(g_signal_connect(m_pToggleButton, "toggled", G_CALLBACK(signalToggled), this))
     {
@@ -4013,8 +4017,8 @@ private:
     }
 
 public:
-    GtkInstanceMenuButton(GtkMenuButton* pMenuButton, bool bTakeOwnership)
-        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pMenuButton), bTakeOwnership)
+    GtkInstanceMenuButton(GtkMenuButton* pMenuButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pMenuButton), pBuilder, bTakeOwnership)
         , MenuHelper(gtk_menu_button_get_popup(pMenuButton), false)
         , m_pMenuButton(pMenuButton)
         , m_pImage(nullptr)
@@ -4345,8 +4349,8 @@ public:
 class GtkInstanceRadioButton : public GtkInstanceToggleButton, public virtual weld::RadioButton
 {
 public:
-    GtkInstanceRadioButton(GtkRadioButton* pButton, bool bTakeOwnership)
-        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), bTakeOwnership)
+    GtkInstanceRadioButton(GtkRadioButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), pBuilder, bTakeOwnership)
     {
     }
 };
@@ -4354,8 +4358,8 @@ public:
 class GtkInstanceCheckButton : public GtkInstanceToggleButton, public virtual weld::CheckButton
 {
 public:
-    GtkInstanceCheckButton(GtkCheckButton* pButton, bool bTakeOwnership)
-        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), bTakeOwnership)
+    GtkInstanceCheckButton(GtkCheckButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(pButton), pBuilder, bTakeOwnership)
     {
     }
 };
@@ -4374,8 +4378,8 @@ private:
     }
 
 public:
-    GtkInstanceScale(GtkScale* pScale, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pScale), bTakeOwnership)
+    GtkInstanceScale(GtkScale* pScale, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pScale), pBuilder, bTakeOwnership)
         , m_pScale(pScale)
         , m_nValueChangedSignalId(g_signal_connect(m_pScale, "value-changed", G_CALLBACK(signalValueChanged), this))
     {
@@ -4424,8 +4428,8 @@ private:
     GtkProgressBar* m_pProgressBar;
 
 public:
-    GtkInstanceProgressBar(GtkProgressBar* pProgressBar, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pProgressBar), bTakeOwnership)
+    GtkInstanceProgressBar(GtkProgressBar* pProgressBar, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pProgressBar), pBuilder, bTakeOwnership)
         , m_pProgressBar(pProgressBar)
     {
     }
@@ -4442,8 +4446,8 @@ private:
     GtkImage* m_pImage;
 
 public:
-    GtkInstanceImage(GtkImage* pImage, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pImage), bTakeOwnership)
+    GtkInstanceImage(GtkImage* pImage, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pImage), pBuilder, bTakeOwnership)
         , m_pImage(pImage)
     {
     }
@@ -4505,8 +4509,8 @@ private:
     }
 
 public:
-    GtkInstanceEntry(GtkEntry* pEntry, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pEntry), bTakeOwnership)
+    GtkInstanceEntry(GtkEntry* pEntry, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pEntry), pBuilder, bTakeOwnership)
         , m_pEntry(pEntry)
         , m_nChangedSignalId(g_signal_connect(pEntry, "changed", G_CALLBACK(signalChanged), this))
         , m_nInsertTextSignalId(g_signal_connect(pEntry, "insert-text", G_CALLBACK(signalInsertText), this))
@@ -5074,8 +5078,8 @@ private:
     }
 
 public:
-    GtkInstanceTreeView(GtkTreeView* pTreeView, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pTreeView), bTakeOwnership)
+    GtkInstanceTreeView(GtkTreeView* pTreeView, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pTreeView), pBuilder, bTakeOwnership)
         , m_pTreeView(pTreeView)
         , m_pTreeStore(GTK_TREE_STORE(gtk_tree_view_get_model(m_pTreeView)))
         , m_nTextCol(-1)
@@ -5807,8 +5811,8 @@ private:
     }
 
 public:
-    GtkInstanceSpinButton(GtkSpinButton* pButton, bool bTakeOwnership)
-        : GtkInstanceEntry(GTK_ENTRY(pButton), bTakeOwnership)
+    GtkInstanceSpinButton(GtkSpinButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceEntry(GTK_ENTRY(pButton), pBuilder, bTakeOwnership)
         , m_pButton(pButton)
         , m_nValueChangedSignalId(g_signal_connect(pButton, "value-changed", G_CALLBACK(signalValueChanged), this))
         , m_nOutputSignalId(g_signal_connect(pButton, "output", G_CALLBACK(signalOutput), this))
@@ -6000,8 +6004,8 @@ private:
     }
 
 public:
-    GtkInstanceFormattedSpinButton(GtkSpinButton* pButton, bool bTakeOwnership)
-        : GtkInstanceEntry(GTK_ENTRY(pButton), bTakeOwnership)
+    GtkInstanceFormattedSpinButton(GtkSpinButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceEntry(GTK_ENTRY(pButton), pBuilder, bTakeOwnership)
         , m_pButton(pButton)
         , m_pFormatter(nullptr)
         , m_pLastOutputColor(nullptr)
@@ -6076,8 +6080,8 @@ class GtkInstanceLabel : public GtkInstanceWidget, public virtual weld::Label
 private:
     GtkLabel* m_pLabel;
 public:
-    GtkInstanceLabel(GtkLabel* pLabel, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pLabel), bTakeOwnership)
+    GtkInstanceLabel(GtkLabel* pLabel, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pLabel), pBuilder, bTakeOwnership)
         , m_pLabel(pLabel)
     {
     }
@@ -6104,8 +6108,8 @@ class GtkInstanceTextView : public GtkInstanceContainer, public virtual weld::Te
 private:
     GtkTextView* m_pTextView;
 public:
-    GtkInstanceTextView(GtkTextView* pTextView, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pTextView), bTakeOwnership)
+    GtkInstanceTextView(GtkTextView* pTextView, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pTextView), pBuilder, bTakeOwnership)
         , m_pTextView(pTextView)
     {
     }
@@ -6398,8 +6402,8 @@ private:
         return true;
     }
 public:
-    GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, const a11yref& rA11y, bool bTakeOwnership)
-        : GtkInstanceWidget(GTK_WIDGET(pDrawingArea), bTakeOwnership)
+    GtkInstanceDrawingArea(GtkDrawingArea* pDrawingArea, GtkInstanceBuilder* pBuilder, const a11yref& rA11y, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pDrawingArea), pBuilder, bTakeOwnership)
         , m_pDrawingArea(pDrawingArea)
         , m_xAccessible(rA11y)
         , m_pAccessible(nullptr)
@@ -6893,8 +6897,8 @@ private:
     }
 
 public:
-    GtkInstanceComboBox(GtkComboBox* pComboBox, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pComboBox), bTakeOwnership)
+    GtkInstanceComboBox(GtkComboBox* pComboBox, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pComboBox), pBuilder, bTakeOwnership)
         , m_pComboBox(pComboBox)
         , m_pTreeModel(gtk_combo_box_get_model(m_pComboBox))
         , m_pMenu(nullptr)
@@ -7408,9 +7412,10 @@ private:
 
 
 public:
-    GtkInstanceEntryTreeView(GtkContainer* pContainer, bool bTakeOwnership, std::unique_ptr<weld::Entry> xEntry, std::unique_ptr<weld::TreeView> xTreeView)
+    GtkInstanceEntryTreeView(GtkContainer* pContainer, GtkInstanceBuilder* pBuilder, bool bTakeOwnership,
+                             std::unique_ptr<weld::Entry> xEntry, std::unique_ptr<weld::TreeView> xTreeView)
         : EntryTreeView(std::move(xEntry), std::move(xTreeView))
-        , GtkInstanceContainer(pContainer, bTakeOwnership)
+        , GtkInstanceContainer(pContainer, pBuilder, bTakeOwnership)
         , m_pEntry(dynamic_cast<GtkInstanceEntry*>(m_xEntry.get()))
         , m_pTreeView(dynamic_cast<GtkInstanceTreeView*>(m_xTreeView.get()))
         , m_nAutoCompleteIdleId(0)
@@ -7513,8 +7518,8 @@ private:
     }
 
 public:
-    GtkInstanceExpander(GtkExpander* pExpander, bool bTakeOwnership)
-        : GtkInstanceContainer(GTK_CONTAINER(pExpander), bTakeOwnership)
+    GtkInstanceExpander(GtkExpander* pExpander, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+        : GtkInstanceContainer(GTK_CONTAINER(pExpander), pBuilder, bTakeOwnership)
         , m_pExpander(pExpander)
         , m_nSignalId(g_signal_connect(m_pExpander, "notify::expanded", G_CALLBACK(signalExpanded), this))
     {
@@ -7826,7 +7831,7 @@ public:
         if (!pMessageDialog)
             return nullptr;
         gtk_window_set_transient_for(GTK_WINDOW(pMessageDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
-        return o3tl::make_unique<GtkInstanceMessageDialog>(pMessageDialog, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceMessageDialog>(pMessageDialog, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Dialog> weld_dialog(const OString &id, bool bTakeOwnership) override
@@ -7836,13 +7841,13 @@ public:
             return nullptr;
         if (m_pParentWidget)
             gtk_window_set_transient_for(GTK_WINDOW(pDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
-        return o3tl::make_unique<GtkInstanceDialog>(pDialog, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceDialog>(pDialog, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Window> weld_window(const OString &id, bool bTakeOwnership) override
     {
         GtkWindow* pWindow = GTK_WINDOW(gtk_builder_get_object(m_pBuilder, id.getStr()));
-        return pWindow ? o3tl::make_unique<GtkInstanceWindow>(pWindow, bTakeOwnership) : nullptr;
+        return pWindow ? o3tl::make_unique<GtkInstanceWindow>(pWindow, this, bTakeOwnership) : nullptr;
     }
 
     virtual std::unique_ptr<weld::Widget> weld_widget(const OString &id, bool bTakeOwnership) override
@@ -7851,7 +7856,7 @@ public:
         if (!pWidget)
             return nullptr;
         auto_add_parentless_widgets_to_container(pWidget);
-        return o3tl::make_unique<GtkInstanceWidget>(pWidget, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceWidget>(pWidget, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Container> weld_container(const OString &id, bool bTakeOwnership) override
@@ -7860,7 +7865,7 @@ public:
         if (!pContainer)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pContainer));
-        return o3tl::make_unique<GtkInstanceContainer>(pContainer, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceContainer>(pContainer, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Frame> weld_frame(const OString &id, bool bTakeOwnership) override
@@ -7869,7 +7874,7 @@ public:
         if (!pFrame)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pFrame));
-        return o3tl::make_unique<GtkInstanceFrame>(pFrame, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceFrame>(pFrame, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::ScrolledWindow> weld_scrolled_window(const OString &id, bool bTakeOwnership) override
@@ -7878,7 +7883,7 @@ public:
         if (!pScrolledWindow)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pScrolledWindow));
-        return o3tl::make_unique<GtkInstanceScrolledWindow>(pScrolledWindow, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceScrolledWindow>(pScrolledWindow, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Notebook> weld_notebook(const OString &id, bool bTakeOwnership) override
@@ -7887,7 +7892,7 @@ public:
         if (!pNotebook)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pNotebook));
-        return o3tl::make_unique<GtkInstanceNotebook>(pNotebook, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceNotebook>(pNotebook, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Button> weld_button(const OString &id, bool bTakeOwnership) override
@@ -7896,7 +7901,7 @@ public:
         if (!pButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pButton));
-        return o3tl::make_unique<GtkInstanceButton>(pButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceButton>(pButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OString &id, bool bTakeOwnership) override
@@ -7905,7 +7910,7 @@ public:
         if (!pButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pButton));
-        return o3tl::make_unique<GtkInstanceMenuButton>(pButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceMenuButton>(pButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OString &id, bool bTakeOwnership) override
@@ -7914,7 +7919,7 @@ public:
         if (!pToggleButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pToggleButton));
-        return o3tl::make_unique<GtkInstanceToggleButton>(pToggleButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceToggleButton>(pToggleButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::RadioButton> weld_radio_button(const OString &id, bool bTakeOwnership) override
@@ -7923,7 +7928,7 @@ public:
         if (!pRadioButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pRadioButton));
-        return o3tl::make_unique<GtkInstanceRadioButton>(pRadioButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceRadioButton>(pRadioButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::CheckButton> weld_check_button(const OString &id, bool bTakeOwnership) override
@@ -7932,7 +7937,7 @@ public:
         if (!pCheckButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pCheckButton));
-        return o3tl::make_unique<GtkInstanceCheckButton>(pCheckButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceCheckButton>(pCheckButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Scale> weld_scale(const OString &id, bool bTakeOwnership) override
@@ -7941,7 +7946,7 @@ public:
         if (!pScale)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pScale));
-        return o3tl::make_unique<GtkInstanceScale>(pScale, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceScale>(pScale, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::ProgressBar> weld_progress_bar(const OString &id, bool bTakeOwnership) override
@@ -7950,7 +7955,7 @@ public:
         if (!pProgressBar)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pProgressBar));
-        return o3tl::make_unique<GtkInstanceProgressBar>(pProgressBar, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceProgressBar>(pProgressBar, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Image> weld_image(const OString &id, bool bTakeOwnership) override
@@ -7959,7 +7964,7 @@ public:
         if (!pImage)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pImage));
-        return o3tl::make_unique<GtkInstanceImage>(pImage, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceImage>(pImage, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Entry> weld_entry(const OString &id, bool bTakeOwnership) override
@@ -7968,7 +7973,7 @@ public:
         if (!pEntry)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pEntry));
-        return o3tl::make_unique<GtkInstanceEntry>(pEntry, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceEntry>(pEntry, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::SpinButton> weld_spin_button(const OString &id, bool bTakeOwnership) override
@@ -7977,7 +7982,7 @@ public:
         if (!pSpinButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pSpinButton));
-        return o3tl::make_unique<GtkInstanceSpinButton>(pSpinButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceSpinButton>(pSpinButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::MetricSpinButton> weld_metric_spin_button(const OString& id, FieldUnit eUnit,
@@ -7992,7 +7997,7 @@ public:
         if (!pSpinButton)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pSpinButton));
-        return o3tl::make_unique<GtkInstanceFormattedSpinButton>(pSpinButton, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceFormattedSpinButton>(pSpinButton, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::TimeSpinButton> weld_time_spin_button(const OString& id, TimeFieldFormat eFormat,
@@ -8007,7 +8012,7 @@ public:
         if (!pComboBox)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pComboBox));
-        return o3tl::make_unique<GtkInstanceComboBox>(pComboBox, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceComboBox>(pComboBox, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OString &id, bool bTakeOwnership) override
@@ -8016,7 +8021,7 @@ public:
         if (!pTreeView)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pTreeView));
-        return o3tl::make_unique<GtkInstanceTreeView>(pTreeView, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceTreeView>(pTreeView, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::EntryTreeView> weld_entry_tree_view(const OString& containerid, const OString& entryid, const OString& treeviewid, bool bTakeOwnership) override
@@ -8025,7 +8030,9 @@ public:
         if (!pContainer)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pContainer));
-        return o3tl::make_unique<GtkInstanceEntryTreeView>(pContainer, bTakeOwnership, weld_entry(entryid, bTakeOwnership), weld_tree_view(treeviewid, bTakeOwnership));
+        return o3tl::make_unique<GtkInstanceEntryTreeView>(pContainer, this, bTakeOwnership,
+                                                          weld_entry(entryid, bTakeOwnership),
+                                                          weld_tree_view(treeviewid, bTakeOwnership));
     }
 
     virtual std::unique_ptr<weld::Label> weld_label(const OString &id, bool bTakeOwnership) override
@@ -8034,7 +8041,7 @@ public:
         if (!pLabel)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pLabel));
-        return o3tl::make_unique<GtkInstanceLabel>(pLabel, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceLabel>(pLabel, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::TextView> weld_text_view(const OString &id, bool bTakeOwnership) override
@@ -8043,7 +8050,7 @@ public:
         if (!pTextView)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pTextView));
-        return o3tl::make_unique<GtkInstanceTextView>(pTextView, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceTextView>(pTextView, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Expander> weld_expander(const OString &id, bool bTakeOwnership) override
@@ -8052,7 +8059,7 @@ public:
         if (!pExpander)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pExpander));
-        return o3tl::make_unique<GtkInstanceExpander>(pExpander, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceExpander>(pExpander, this, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::DrawingArea> weld_drawing_area(const OString &id, const a11yref& rA11y,
@@ -8062,7 +8069,7 @@ public:
         if (!pDrawingArea)
             return nullptr;
         auto_add_parentless_widgets_to_container(GTK_WIDGET(pDrawingArea));
-        return o3tl::make_unique<GtkInstanceDrawingArea>(pDrawingArea, rA11y, bTakeOwnership);
+        return o3tl::make_unique<GtkInstanceDrawingArea>(pDrawingArea, this, rA11y, bTakeOwnership);
     }
 
     virtual std::unique_ptr<weld::Menu> weld_menu(const OString &id, bool bTakeOwnership) override
@@ -8093,7 +8100,7 @@ void GtkInstanceWindow::help()
             break;
         sHelpId = ::get_help_id(pWidget);
     }
-    std::unique_ptr<weld::Widget> xTemp(pWidget != m_pWidget ? new GtkInstanceWidget(pWidget, false) : nullptr);
+    std::unique_ptr<weld::Widget> xTemp(pWidget != m_pWidget ? new GtkInstanceWidget(pWidget, m_pBuilder, false) : nullptr);
     weld::Widget* pSource = xTemp ? xTemp.get() : this;
     bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource);
     Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr;
@@ -8101,6 +8108,42 @@ void GtkInstanceWindow::help()
         pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource);
 }
 
+//iterate upwards through the hierarchy from this widgets through its parents
+//calling func with their helpid until func returns true or we run out of parents
+void GtkInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OString&)>& func)
+{
+    GtkWidget* pParent = m_pWidget;
+    while ((pParent = gtk_widget_get_parent(pParent)))
+    {
+        // tdf#122355 before trying dialog help, check to see if there is a notebook
+        // called tabcontrol, and try the help for the current page of that first
+        if (m_pBuilder && GTK_IS_DIALOG(pParent))
+        {
+            std::unique_ptr<weld::Notebook> xNotebook(m_pBuilder->weld_notebook("tabcontrol", false));
+            if (xNotebook)
+            {
+                if (GtkInstanceContainer* pPage = dynamic_cast<GtkInstanceContainer*>(xNotebook->get_page(xNotebook->get_current_page_ident())))
+                {
+                    bool bFinished = false;
+                    GtkWidget* pContainer = pPage->getWidget();
+                    GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pContainer));
+                    GList* pChild = g_list_first(pChildren);
+                    if (pChild)
+                    {
+                        GtkWidget* pPageWidget = static_cast<GtkWidget*>(pChild->data);
+                        bFinished = func(::get_help_id(pPageWidget));
+                    }
+                    g_list_free(pChildren);
+                    if (bFinished)
+                        return;
+                }
+            }
+        }
+        if (func(::get_help_id(pParent)))
+            return;
+    }
+}
+
 weld::Builder* GtkInstance::CreateBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile)
 {
     GtkInstanceWidget* pParentWidget = dynamic_cast<GtkInstanceWidget*>(pParent);
@@ -8117,7 +8160,7 @@ weld::MessageDialog* GtkInstance::CreateMessageDialog(weld::Widget* pParent, Vcl
     GtkMessageDialog* pMessageDialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(pParentWindow, GTK_DIALOG_MODAL,
                                                           VclToGtk(eMessageType), VclToGtk(eButtonsType), "%s",
                                                           OUStringToOString(rPrimaryMessage, RTL_TEXTENCODING_UTF8).getStr()));
-    return new GtkInstanceMessageDialog(pMessageDialog, true);
+    return new GtkInstanceMessageDialog(pMessageDialog, nullptr, true);
 }
 
 weld::Window* GtkInstance::GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow)
@@ -8130,7 +8173,7 @@ weld::Window* GtkInstance::GetFrameWeld(const css::uno::Reference<css::awt::XWin
 weld::Window* GtkSalFrame::GetFrameWeld() const
 {
     if (!m_xFrameWeld)
-        m_xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(getWindow()), false));
+        m_xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(getWindow()), nullptr, false));
     return m_xFrameWeld.get();
 }
 


More information about the Libreoffice-commits mailing list