include/vcl/builder.hxx                 |   14 ----
 include/vcl/weld.hxx                    |    2 
 include/vcl/widgetbuilder.hxx           |  112 +++++++++++++++++++++++++-------
 vcl/inc/qt5/QtBuilder.hxx               |    3 
 vcl/inc/qt5/QtInstanceMessageDialog.hxx |    2 
 vcl/inc/salvtables.hxx                  |    2 
 vcl/qt5/QtBuilder.cxx                   |    6 +
 vcl/qt5/QtInstanceMessageDialog.cxx     |    4 -
 vcl/source/app/salvtables.cxx           |    5 -
 vcl/source/window/builder.cxx           |   87 ------------------------
 vcl/unx/gtk3/gtkinst.cxx                |    6 -
 11 files changed, 116 insertions(+), 127 deletions(-)

New commits:
commit 46009c851764857e67202875cea7d4566bf6abeb
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Sun Nov 10 23:01:07 2024 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Nov 11 01:51:55 2024 +0100

    vcl: Return unique_ptr in weld::MessageDialog::weld_message_area
    
    The returned weld::Container* (but not the associated toolkit
    widget) is owned by the caller.
    Make that more obvious by returning a unique_ptr<weld::Container>
    instead of a raw pointer.
    
    This is also consistent with what other methods returning
    instances for which the caller takes over ownership
    (like weld::Widget::weld_parent) do, whereas
    e.g. weld::Notebook::get_page returns a weld::Container*
    that is owned by the weld::Notebook instance, not the caller.
    
    Change-Id: Ia839fac90ea93b9ac6be5819aa4bb3261a775f33
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176363
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index cc338544fe3f..ea918ec111fd 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -645,7 +645,7 @@ public:
     virtual OUString get_primary_text() const = 0;
     virtual void set_secondary_text(const OUString& rText) = 0;
     virtual OUString get_secondary_text() const = 0;
-    virtual Container* weld_message_area() = 0;
+    virtual std::unique_ptr<Container> weld_message_area() = 0;
 };
 
 class VCL_DLLPUBLIC Assistant : virtual public Dialog
diff --git a/vcl/inc/qt5/QtInstanceMessageDialog.hxx 
b/vcl/inc/qt5/QtInstanceMessageDialog.hxx
index 6f2cfac5606d..5e69a93732dc 100644
--- a/vcl/inc/qt5/QtInstanceMessageDialog.hxx
+++ b/vcl/inc/qt5/QtInstanceMessageDialog.hxx
@@ -29,7 +29,7 @@ public:
 
     virtual void set_secondary_text(const rtl::OUString& rText) override;
 
-    virtual Container* weld_message_area() override;
+    virtual std::unique_ptr<weld::Container> weld_message_area() override;
 
     virtual OUString get_primary_text() const override;
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index b42a3f71ebc2..e6341e4b87ed 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1215,7 +1215,7 @@ public:
 
     virtual OUString get_secondary_text() const override;
 
-    virtual weld::Container* weld_message_area() override;
+    virtual std::unique_ptr<weld::Container> weld_message_area() override;
 };
 
 class SalInstanceLinkButton : public SalInstanceWidget, public virtual 
weld::LinkButton
diff --git a/vcl/qt5/QtInstanceMessageDialog.cxx 
b/vcl/qt5/QtInstanceMessageDialog.cxx
index 9991539cc866..9716ee815531 100644
--- a/vcl/qt5/QtInstanceMessageDialog.cxx
+++ b/vcl/qt5/QtInstanceMessageDialog.cxx
@@ -52,9 +52,9 @@ void QtInstanceMessageDialog::set_secondary_text(const 
rtl::OUString& rText)
     m_pMessageDialog->setInformativeText(toQString(rText));
 }
 
-weld::Container* QtInstanceMessageDialog::weld_message_area()
+std::unique_ptr<weld::Container> QtInstanceMessageDialog::weld_message_area()
 {
-    return new QtInstanceContainer(m_pExtraControlsContainer);
+    return std::make_unique<QtInstanceContainer>(m_pExtraControlsContainer);
 }
 
 OUString QtInstanceMessageDialog::get_primary_text() const
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d394c462bc61..c7cf6877271c 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2016,9 +2016,10 @@ OUString SalInstanceMessageDialog::get_secondary_text() 
const
     return m_xMessageDialog->get_secondary_text();
 }
 
-weld::Container* SalInstanceMessageDialog::weld_message_area()
+std::unique_ptr<weld::Container> SalInstanceMessageDialog::weld_message_area()
 {
-    return new SalInstanceContainer(m_xMessageDialog->get_message_area(), 
m_pBuilder, false);
+    return 
std::make_unique<SalInstanceContainer>(m_xMessageDialog->get_message_area(), 
m_pBuilder,
+                                                  false);
 }
 
 int SalInstanceAssistant::find_page(std::u16string_view rIdent) const
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 221a580457ab..66a7995fcaf9 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -7371,12 +7371,12 @@ public:
         return ::get_secondary_text(m_pMessageDialog);
     }
 
-    virtual Container* weld_message_area() override
+    virtual std::unique_ptr<weld::Container> weld_message_area() override
     {
 #if !GTK_CHECK_VERSION(4, 0, 0)
-        return new 
GtkInstanceContainer(GTK_CONTAINER(gtk_message_dialog_get_message_area(m_pMessageDialog)),
 m_pBuilder, false);
+        return 
std::make_unique<GtkInstanceContainer>(GTK_CONTAINER(gtk_message_dialog_get_message_area(m_pMessageDialog)),
 m_pBuilder, false);
 #else
-        return new 
GtkInstanceContainer(gtk_message_dialog_get_message_area(m_pMessageDialog), 
m_pBuilder, false);
+        return 
std::make_unique<GtkInstanceContainer>(gtk_message_dialog_get_message_area(m_pMessageDialog),
 m_pBuilder, false);
 #endif
     }
 };
commit 774786a019090b357fffa4008f562988d10b2c8f
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Sun Nov 10 22:03:28 2024 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Nov 11 01:51:47 2024 +0100

    tdf#130857 VclBuilder: Complete moving XML parsing to base classes
    
    Move VclBuilder::handleMenuObject to the WidgetBuilder template
    base class, and add a new purely virtual WidgetBuilder::insertMenuObject
    that the existing VclBuilder equivalent now overrides.
    
    This moves the remaining XML parsing logic from VclBuilder
    to one of the base classes (WidgetBuilder, BuilderBase),
    following the approach outlined in
    
        commit f61ecf25636d401f862c4de226c04237e1fb2f69
        Author: OmkarAcharekar <omkarachareka...@gmail.com>
        Date:   Fri Sep 20 13:33:01 2024 +0200
    
            tdf#130857 refactor VclBuilder: Extract template base class
    
    Update the source code comments accordingly.
    
    For QtBuilder, initially add a dummy implementation
    that simply triggers an assert, but can be adjusted
    in the future to create native Qt menus.
    
    Change-Id: I3147cac28c7273cd4c4ea7344a083cd66af8337f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176362
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx
index 9006da0940e9..8a8995482c35 100644
--- a/include/vcl/builder.hxx
+++ b/include/vcl/builder.hxx
@@ -50,7 +50,6 @@ class ToolBox;
 class VclExpander;
 class VclMultiLineEdit;
 struct NotebookBarAddonsItem;
-namespace xmlreader { class XmlReader; }
 namespace com::sun::star::frame { class XFrame; }
 
 /// Creates a hierarchy of vcl::Windows (widgets) from a .ui file for dialogs, 
sidebar, etc.
@@ -267,16 +266,9 @@ private:
                                          
std::vector<vcl::EnumContext::Context>& rContext, stringmap& rProperties,
                                          stringmap& rAtkProperties) override;
 
-    void        insertMenuObject(
-                   Menu *pParent,
-                   PopupMenu *pSubMenu,
-                   const OUString &rClass,
-                   const OUString &rID,
-                   stringmap &rProps,
-                   stringmap &rAtkProps,
-                   accelmap &rAccels);
-
-    void handleMenuObject(PopupMenu* pParent, xmlreader::XmlReader& reader) 
override;
+    void insertMenuObject(PopupMenu* pParent, PopupMenu* pSubMenu, const 
OUString& rClass,
+                          const OUString& rID, stringmap& rProps, stringmap& 
rAtkProps,
+                          accelmap& rAccels) override;
 
     // if bToolbarItem=true, pParent is the ToolBox that the item belongs to, 
since there's no widget for the item itself
     void applyAtkProperties(vcl::Window* pWindow, const stringmap& rProperties,
diff --git a/include/vcl/widgetbuilder.hxx b/include/vcl/widgetbuilder.hxx
index a4a126d5c416..8e8a729fb57a 100644
--- a/include/vcl/widgetbuilder.hxx
+++ b/include/vcl/widgetbuilder.hxx
@@ -19,18 +19,11 @@
 /* Template class for a Builder to create a hierarchy of widgets from a .ui 
file
  * for dialogs, sidebar, etc.
  *
- * The idea is for this class to parse the .ui file and call overridable 
methods
+ * This class parses the .ui file and calls overridable methods
  * so subclasses can create the widgets of a specific toolkit.
  *
- * VclBuilder is the implementation using LibreOffice's own VCL toolkit
- * and there is a work-in-progress implementation using native Qt widgets
- * at https://gerrit.libreoffice.org/c/core/+/161831 .
- *
- * Currently, .ui file parsing isn't yet fully done by this class as described
- * above, but needs further refactoring to split the corresponding VclBuilder
- * methods into methods that do the parsing (which should reside in this class)
- * and overridable methods to actually create the widgets,... (which should 
reside in
- * VclBuilder and other subclasses).
+ * The VclBuilder subclass is the implementation using LibreOffice's own VCL 
toolkit
+ * and the QtBuilder subclass uses native Qt widgets.
  */
 template <typename Widget, typename WidgetPtr, typename MenuClass, typename 
MenuPtr>
 class WidgetBuilder : public BuilderBase
@@ -445,6 +438,89 @@ protected:
         }
     }
 
+    void handleMenuObject(MenuClass* pParent, xmlreader::XmlReader& reader)
+    {
+        OUString sClass;
+        OUString sID;
+        OUString sCustomProperty;
+        MenuClass* pSubMenu = nullptr;
+
+        xmlreader::Span name;
+        int nsId;
+
+        while (reader.nextAttribute(&nsId, &name))
+        {
+            if (name == "class")
+            {
+                name = reader.getAttributeValue(false);
+                sClass = OUString(name.begin, name.length, 
RTL_TEXTENCODING_UTF8);
+            }
+            else if (name == "id")
+            {
+                name = reader.getAttributeValue(false);
+                sID = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
+                if (isLegacy())
+                {
+                    sal_Int32 nDelim = sID.indexOf(':');
+                    if (nDelim != -1)
+                    {
+                        sCustomProperty = sID.subView(nDelim + 1);
+                        sID = sID.copy(0, nDelim);
+                    }
+                }
+            }
+        }
+
+        int nLevel = 1;
+
+        stringmap aProperties;
+        stringmap aAtkProperties;
+        accelmap aAccelerators;
+
+        if (!sCustomProperty.isEmpty())
+            aProperties[u"customproperty"_ustr] = sCustomProperty;
+
+        while (true)
+        {
+            xmlreader::XmlReader::Result res
+                = reader.nextItem(xmlreader::XmlReader::Text::NONE, &name, 
&nsId);
+
+            if (res == xmlreader::XmlReader::Result::Done)
+                break;
+
+            if (res == xmlreader::XmlReader::Result::Begin)
+            {
+                if (name == "child")
+                {
+                    size_t nChildMenuIdx = m_aMenus.size();
+                    handleChild(nullptr, &aAtkProperties, reader);
+                    bool bSubMenuInserted = m_aMenus.size() > nChildMenuIdx;
+                    if (bSubMenuInserted)
+                        pSubMenu = m_aMenus[nChildMenuIdx].m_pMenu;
+                }
+                else
+                {
+                    ++nLevel;
+                    if (name == "property")
+                        collectProperty(reader, aProperties);
+                    else if (name == "accelerator")
+                        collectAccelerator(reader, aAccelerators);
+                }
+            }
+
+            if (res == xmlreader::XmlReader::Result::End)
+            {
+                --nLevel;
+            }
+
+            if (!nLevel)
+                break;
+        }
+
+        insertMenuObject(pParent, pSubMenu, sClass, sID, aProperties, 
aAtkProperties,
+                         aAccelerators);
+    }
+
     virtual void applyAtkProperties(Widget* pWidget, const stringmap& 
rProperties,
                                     bool bToolbarItem)
         = 0;
@@ -476,18 +552,10 @@ protected:
     virtual bool isHorizontalTabControl(Widget* pWidget) = 0;
 
     virtual MenuPtr createMenu(const OUString& rID) = 0;
-
-    // These methods are currently only implemented by VclBuilder and should be
-    // refactored as described in the class documentation above (split into
-    // parsing done in this class + overridable methods that don't need 
XmlReader
-    // that get implemented in the subclasses)
-    //
-    // Until that's done, other subclasses can be used to handle only those 
.ui files
-    // not using the corresponding features (attributes/objects in the .ui 
file).
-    virtual void handleMenuObject(MenuClass* /*pParent*/, 
xmlreader::XmlReader& /*reader*/)
-    {
-        assert(false && "Functionality not implemented by this subclass yet.");
-    }
+    virtual void insertMenuObject(MenuClass* pParent, MenuClass* pSubMenu, 
const OUString& rClass,
+                                  const OUString& rID, stringmap& rProps, 
stringmap& rAtkProps,
+                                  accelmap& rAccels)
+        = 0;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtBuilder.hxx b/vcl/inc/qt5/QtBuilder.hxx
index 64b61827e3fd..4d6afc057969 100644
--- a/vcl/inc/qt5/QtBuilder.hxx
+++ b/vcl/inc/qt5/QtBuilder.hxx
@@ -77,6 +77,9 @@ public:
     virtual bool isHorizontalTabControl(QObject* pObject) override;
 
     virtual QMenu* createMenu(const OUString& rID) override;
+    virtual void insertMenuObject(QMenu* pParent, QMenu* pSubMenu, const 
OUString& rClass,
+                                  const OUString& rID, stringmap& rProps, 
stringmap& rAtkProps,
+                                  accelmap& rAccels) override;
 
     virtual void set_response(std::u16string_view sID, short nResponse) 
override;
 
diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx
index 1981a8a4c322..dc526a3fec77 100644
--- a/vcl/qt5/QtBuilder.cxx
+++ b/vcl/qt5/QtBuilder.cxx
@@ -433,6 +433,12 @@ QMenu* QtBuilder::createMenu(const OUString&)
     return nullptr;
 }
 
+void QtBuilder::insertMenuObject(QMenu*, QMenu*, const OUString&, const 
OUString&, stringmap&,
+                                 stringmap&, accelmap&)
+{
+    assert(false && "Not implemented yet");
+}
+
 void QtBuilder::applyAtkProperties(QObject* pObject, const stringmap& 
rProperties, bool)
 {
     if (!pObject || !pObject->isWidgetType())
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index c4feb7097ff5..0a06c388fb67 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -3018,88 +3018,6 @@ std::vector<ComboBoxTextItem> 
BuilderBase::handleItems(xmlreader::XmlReader& rea
     return aItems;
 }
 
-void VclBuilder::handleMenuObject(PopupMenu* pParent, xmlreader::XmlReader& 
reader)
-{
-    OUString sClass;
-    OUString sID;
-    OUString sCustomProperty;
-    PopupMenu *pSubMenu = nullptr;
-
-    xmlreader::Span name;
-    int nsId;
-
-    while (reader.nextAttribute(&nsId, &name))
-    {
-        if (name == "class")
-        {
-            name = reader.getAttributeValue(false);
-            sClass = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
-        }
-        else if (name == "id")
-        {
-            name = reader.getAttributeValue(false);
-            sID = OUString(name.begin, name.length, RTL_TEXTENCODING_UTF8);
-            if (isLegacy())
-            {
-                sal_Int32 nDelim = sID.indexOf(':');
-                if (nDelim != -1)
-                {
-                    sCustomProperty = sID.subView(nDelim+1);
-                    sID = sID.copy(0, nDelim);
-                }
-            }
-        }
-    }
-
-    int nLevel = 1;
-
-    stringmap aProperties;
-    stringmap aAtkProperties;
-    accelmap aAccelerators;
-
-    if (!sCustomProperty.isEmpty())
-        aProperties[u"customproperty"_ustr] = sCustomProperty;
-
-    while(true)
-    {
-        xmlreader::XmlReader::Result res = reader.nextItem(
-            xmlreader::XmlReader::Text::NONE, &name, &nsId);
-
-        if (res == xmlreader::XmlReader::Result::Done)
-            break;
-
-        if (res == xmlreader::XmlReader::Result::Begin)
-        {
-            if (name == "child")
-            {
-                size_t nChildMenuIdx = m_aMenus.size();
-                handleChild(nullptr, &aAtkProperties, reader);
-                bool bSubMenuInserted = m_aMenus.size() > nChildMenuIdx;
-                if (bSubMenuInserted)
-                    pSubMenu = m_aMenus[nChildMenuIdx].m_pMenu.get();
-            }
-            else
-            {
-                ++nLevel;
-                if (name == "property")
-                    collectProperty(reader, aProperties);
-                else if (name == "accelerator")
-                    collectAccelerator(reader, aAccelerators);
-            }
-        }
-
-        if (res == xmlreader::XmlReader::Result::End)
-        {
-            --nLevel;
-        }
-
-        if (!nLevel)
-            break;
-    }
-
-    insertMenuObject(pParent, pSubMenu, sClass, sID, aProperties, 
aAtkProperties, aAccelerators);
-}
-
 void BuilderBase::handleSizeGroup(xmlreader::XmlReader& reader)
 {
     m_pParserState->m_aSizeGroups.emplace_back();
@@ -3199,8 +3117,9 @@ namespace
     }
 }
 
-void VclBuilder::insertMenuObject(Menu *pParent, PopupMenu *pSubMenu, const 
OUString &rClass, const OUString &rID,
-    stringmap &rProps, stringmap &rAtkProps, accelmap &rAccels)
+void VclBuilder::insertMenuObject(PopupMenu* pParent, PopupMenu* pSubMenu, 
const OUString& rClass,
+                                  const OUString& rID, stringmap& rProps, 
stringmap& rAtkProps,
+                                  accelmap& rAccels)
 {
     sal_uInt16 nOldCount = pParent->GetItemCount();
     sal_uInt16 nNewId = ++m_pVclParserState->m_nLastMenuItemId;

Reply via email to