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;