include/vcl/builder.hxx | 38 ++--- include/vcl/builderbase.hxx | 1 include/vcl/widgetbuilder.hxx | 290 ++++++++++++++++++++++++++++++++++++++++++ vcl/source/window/builder.cxx | 204 ----------------------------- 4 files changed, 308 insertions(+), 225 deletions(-)
New commits: commit 385bbbd6e1f602d066b00c0913aefa36e75ce5a6 Author: Michael Weghorn <[email protected]> AuthorDate: Fri Sep 20 14:03:00 2024 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Sep 25 21:08:59 2024 +0200 tdf#130857 Move VclBuilder::handleObject to WidgetBuilder base Move `VclBuilder::handleObject` to the template base class `WidgetBuilder` introduced in previous commit Change-Id: I2d81cc6dd54d796b549357a4444b95627661c623 Author: OmkarAcharekar <[email protected]> Date: Fri Sep 20 13:33:01 2024 +0200 tdf#130857 refactor VclBuilder: Extract template base class Add new virtual methods to that base class to override in the subclasses. These are currently the ones that `VclBuilder` already implements for `vcl::Window`. More refactoring - in particular for those methods that currently still do XML parsing themselves is planned for the future once the relevant functionality will be implemented in other subclasses. For now, those methods that do XML parsing themseslves trigger an assert in the base class implementation and remain unchanged in the `VclBuilder` implementation. One aspect to be aware of is that `WidgetPtr` should explicitly be initialized to `nullptr` if not assigned a different value: While `VclPtr` that gets used for `VclBuilder` has a default ctor that takes care of proper initialization, that's not the case for the upcoming `QtBuilder` [1] that just uses `QObject*` for `WidgetPtr`. [1] https://gerrit.libreoffice.org/c/core/+/161831 Change-Id: I5c1b7201c82ca2c0c2d7389642aee407ebea16ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173737 Reviewed-by: Michael Weghorn <[email protected]> Tested-by: Jenkins diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx index 353d300015b3..3ad480eece64 100644 --- a/include/vcl/builder.hxx +++ b/include/vcl/builder.hxx @@ -189,8 +189,8 @@ private: void mungeModel(ComboBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); void mungeModel(SvTabListBox &rTarget, const ListStore &rStore, sal_uInt16 nActiveId); - void insertComboBoxOrListBoxItems(vcl::Window *pWindow, VclBuilder::stringmap &rMap, - const std::vector<ComboBoxTextItem>& rItems); + void insertComboBoxOrListBoxItems(vcl::Window* pWindow, stringmap& rMap, + const std::vector<ComboBoxTextItem>& rItems) override; static void mungeTextBuffer(VclMultiLineEdit &rTarget, const TextBuffer &rTextBuffer); @@ -269,10 +269,9 @@ private: void tweakInsertedChild(vcl::Window *pParent, vcl::Window* pCurrentChild, std::string_view sType, std::string_view sInternalChild) override; - VclPtr<vcl::Window> insertObject(vcl::Window *pParent, - const OUString &rClass, const OUString &rID, - stringmap &rProps, stringmap &rPangoAttributes, - stringmap &rAtkProps); + VclPtr<vcl::Window> insertObject(vcl::Window* pParent, const OUString& rClass, + const OUString& rID, stringmap& rProps, + stringmap& rPangoAttributes, stringmap& rAtkProps) override; VclPtr<vcl::Window> makeObject(vcl::Window *pParent, const OUString &rClass, const OUString &rID, @@ -290,8 +289,6 @@ private: void extractButtonImage(const OUString &id, stringmap &rMap, bool bRadio); void extractMnemonicWidget(const OUString &id, stringmap &rMap); - VclPtr<vcl::Window> handleObject(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem) override; - void applyPackingProperties(vcl::Window* pCurrent, vcl::Window* pParent, const stringmap& rPackingProperties) override; @@ -309,13 +306,15 @@ private: void handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader) override; void handleMenu(xmlreader::XmlReader& reader, vcl::Window* pParent, const OUString& rID, - bool bMenuBar); + bool bMenuBar) 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, bool bToolbarItem); + void applyAtkProperties(vcl::Window* pWindow, const stringmap& rProperties, + bool bToolbarItem) override; - static void setPriority(vcl::Window* pWindow, int nPriority); - static void setContext(vcl::Window* pWindow, std::vector<vcl::EnumContext::Context>&& aContext); + void setPriority(vcl::Window* pWindow, int nPriority) override; + void setContext(vcl::Window* pWindow, + std::vector<vcl::EnumContext::Context>&& aContext) override; PackingData get_window_packing_data(const vcl::Window *pWindow) const; void set_window_packing_position(const vcl::Window *pWindow, sal_Int32 nPosition); diff --git a/include/vcl/widgetbuilder.hxx b/include/vcl/widgetbuilder.hxx index a12bff918c0a..da2370ad5845 100644 --- a/include/vcl/widgetbuilder.hxx +++ b/include/vcl/widgetbuilder.hxx @@ -9,8 +9,8 @@ #pragma once +#include <sal/log.hxx> #include <vcl/builderbase.hxx> - #include <xmlreader/span.hxx> #include <xmlreader/xmlreader.hxx> @@ -114,13 +114,159 @@ protected: } } + WidgetPtr handleObject(Widget* pParent, stringmap* pAtkProps, xmlreader::XmlReader& reader, + bool bToolbarItem) + { + OUString sClass; + OUString sID; + OUString sCustomProperty; + extractClassAndIdAndCustomProperty(reader, sClass, sID, sCustomProperty); + + if (sClass == "GtkListStore" || sClass == "GtkTreeStore") + { + handleListStore(reader, sID, sClass); + return nullptr; + } + else if (sClass == "GtkMenu") + { + handleMenu(reader, pParent, sID, false); + return nullptr; + } + else if (sClass == "GtkMenuBar") + { + handleMenu(reader, pParent, sID, true); + return nullptr; + } + else if (sClass == "GtkSizeGroup") + { + handleSizeGroup(reader); + return nullptr; + } + else if (sClass == "AtkObject") + { + assert((pParent || pAtkProps) && "must have one set"); + assert(!(pParent && pAtkProps) && "must not have both"); + auto aAtkProperties = handleAtkObject(reader); + if (pParent) + applyAtkProperties(pParent, aAtkProperties, bToolbarItem); + if (pAtkProps) + *pAtkProps = std::move(aAtkProperties); + return nullptr; + } + + int nLevel = 1; + + stringmap aProperties, aPangoAttributes; + stringmap aAtkAttributes; + std::vector<ComboBoxTextItem> aItems; + + if (!sCustomProperty.isEmpty()) + aProperties[u"customproperty"_ustr] = sCustomProperty; + + WidgetPtr pCurrentChild = nullptr; + while (true) + { + xmlreader::Span name; + int nsId; + 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") + { + if (!pCurrentChild) + { + pCurrentChild = insertObject(pParent, sClass, sID, aProperties, + aPangoAttributes, aAtkAttributes); + } + handleChild(pCurrentChild, nullptr, reader, isToolbarItemClass(sClass)); + } + else if (name == "items") + aItems = handleItems(reader); + else if (name == "style") + { + int nPriority = 0; + std::vector<vcl::EnumContext::Context> aContext + = handleStyle(reader, nPriority); + if (nPriority != 0) + setPriority(pCurrentChild, nPriority); + if (!aContext.empty()) + setContext(pCurrentChild, std::move(aContext)); + } + else + { + ++nLevel; + if (name == "property") + collectProperty(reader, aProperties); + else if (name == "attribute") + collectPangoAttribute(reader, aPangoAttributes); + else if (name == "relation") + collectAtkRelationAttribute(reader, aAtkAttributes); + else if (name == "role") + collectAtkRoleAttribute(reader, aAtkAttributes); + else if (name == "action-widget") + handleActionWidget(reader); + } + } + + if (res == xmlreader::XmlReader::Result::End) + { + --nLevel; + } + + if (!nLevel) + break; + } + + if (sClass == "GtkAdjustment") + { + addAdjustment(sID, aProperties); + return nullptr; + } + else if (sClass == "GtkTextBuffer") + { + addTextBuffer(sID, aProperties); + return nullptr; + } + + if (!pCurrentChild) + { + pCurrentChild + = insertObject(pParent, sClass, sID, aProperties, aPangoAttributes, aAtkAttributes); + } + + if (!aItems.empty()) + insertComboBoxOrListBoxItems(pCurrentChild, aProperties, aItems); + + return pCurrentChild; + } + + virtual void applyAtkProperties(Widget* pWidget, const stringmap& rProperties, + bool bToolbarItem) + = 0; virtual void applyPackingProperties(Widget* pCurrentChild, Widget* pParent, const stringmap& rPackingProperties) = 0; + virtual void insertComboBoxOrListBoxItems(Widget* pWidget, stringmap& rMap, + const std::vector<ComboBoxTextItem>& rItems) + = 0; + + virtual WidgetPtr insertObject(Widget* pParent, const OUString& rClass, const OUString& rID, + stringmap& rProps, stringmap& rPangoAttributes, + stringmap& rAtkProps) + = 0; + virtual void tweakInsertedChild(Widget* pParent, Widget* pCurrentChild, std::string_view sType, std::string_view sInternalChild) = 0; + virtual void setPriority(Widget* pWidget, int nPriority) = 0; + virtual void setContext(Widget* pWidget, std::vector<vcl::EnumContext::Context>&& aContext) = 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 @@ -128,13 +274,14 @@ protected: // // 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 WidgetPtr handleObject(Widget* /*pParent*/, stringmap* /*pAtkProps*/, - xmlreader::XmlReader& /*reader*/, bool /*bToolbarItem*/) + virtual void handleMenu(xmlreader::XmlReader& /*reader*/, Widget* /*pParent*/, + const OUString& /*rID*/, bool /*bMenuBar*/) { assert(false && "Functionality not implemented by this subclass yet."); - return nullptr; } + virtual void handleTabChild(Widget* /*pParent*/, xmlreader::XmlReader& /*reader*/) + { assert(false && "Functionality not implemented by this subclass yet."); } diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 3e1fad42fbe5..25bab94a1265 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -67,7 +67,6 @@ #include <messagedialog.hxx> #include <ContextVBox.hxx> #include <DropdownBox.hxx> -#include <IPrioritable.hxx> #include <OptionalBox.hxx> #include <PriorityMergedHBox.hxx> #include <PriorityHBox.hxx> @@ -3571,135 +3570,6 @@ void BuilderBase::extractClassAndIdAndCustomProperty(xmlreader::XmlReader& reade } } -VclPtr<vcl::Window> VclBuilder::handleObject(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem) -{ - OUString sClass; - OUString sID; - OUString sCustomProperty; - extractClassAndIdAndCustomProperty(reader, sClass, sID, sCustomProperty); - - if (sClass == "GtkListStore" || sClass == "GtkTreeStore") - { - handleListStore(reader, sID, sClass); - return nullptr; - } - else if (sClass == "GtkMenu") - { - handleMenu(reader, pParent, sID, false); - return nullptr; - } - else if (sClass == "GtkMenuBar") - { - handleMenu(reader, pParent, sID, true); - return nullptr; - } - else if (sClass == "GtkSizeGroup") - { - handleSizeGroup(reader); - return nullptr; - } - else if (sClass == "AtkObject") - { - assert((pParent || pAtkProps) && "must have one set"); - assert(!(pParent && pAtkProps) && "must not have both"); - auto aAtkProperties = handleAtkObject(reader); - if (pParent) - applyAtkProperties(pParent, aAtkProperties, bToolbarItem); - if (pAtkProps) - *pAtkProps = std::move(aAtkProperties); - return nullptr; - } - - int nLevel = 1; - - stringmap aProperties, aPangoAttributes; - stringmap aAtkAttributes; - std::vector<ComboBoxTextItem> aItems; - - if (!sCustomProperty.isEmpty()) - aProperties[u"customproperty"_ustr] = sCustomProperty; - - VclPtr<vcl::Window> pCurrentChild; - while(true) - { - xmlreader::Span name; - int nsId; - 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") - { - if (!pCurrentChild) - { - pCurrentChild = insertObject(pParent, sClass, sID, - aProperties, aPangoAttributes, aAtkAttributes); - } - handleChild(pCurrentChild, nullptr, reader, isToolbarItemClass(sClass)); - } - else if (name == "items") - aItems = handleItems(reader); - else if (name == "style") - { - int nPriority = 0; - std::vector<vcl::EnumContext::Context> aContext = handleStyle(reader, nPriority); - if (nPriority != 0) - setPriority(pCurrentChild, nPriority); - if (!aContext.empty()) - setContext(pCurrentChild, std::move(aContext)); - } - else - { - ++nLevel; - if (name == "property") - collectProperty(reader, aProperties); - else if (name == "attribute") - collectPangoAttribute(reader, aPangoAttributes); - else if (name == "relation") - collectAtkRelationAttribute(reader, aAtkAttributes); - else if (name == "role") - collectAtkRoleAttribute(reader, aAtkAttributes); - else if (name == "action-widget") - handleActionWidget(reader); - } - } - - if (res == xmlreader::XmlReader::Result::End) - { - --nLevel; - } - - if (!nLevel) - break; - } - - if (sClass == "GtkAdjustment") - { - addAdjustment(sID, aProperties); - return nullptr; - } - else if (sClass == "GtkTextBuffer") - { - addTextBuffer(sID, aProperties); - return nullptr; - } - - if (!pCurrentChild) - { - pCurrentChild = insertObject(pParent, sClass, sID, aProperties, - aPangoAttributes, aAtkAttributes); - } - - if (!aItems.empty()) - insertComboBoxOrListBoxItems(pCurrentChild, aProperties, aItems); - - return pCurrentChild; -} - void BuilderBase::handleInterfaceDomain(xmlreader::XmlReader& rReader) { xmlreader::Span name = rReader.getAttributeValue(false); commit f61ecf25636d401f862c4de226c04237e1fb2f69 Author: OmkarAcharekar <[email protected]> AuthorDate: Fri Sep 20 13:33:01 2024 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Sep 25 21:08:50 2024 +0200 tdf#130857 refactor VclBuilder: Extract template base class Refactor `VclBuilder` by extracting the `handleChild` method and moving it into a new template base class `WidgetBuilder`, so both `VclBuilder` and an upcoming `QtBuilder` (see [1]) can share the common logic to parse the .ui file and override the virtual methods like `applyPackingProperties`, `tweakInsertedChild` etc. to handle toolkit specific cases, as mentioned as one potential approach in Caolán's email [2]. The new class has 2 template parameters `Widget` and `WidgetPtr` to account for the fact that `VclBuilder` doesn't just use `vcl::Window*`, but there's a specific class, `VclPtr`. As the inline comments say, more refactoring will be needed to abstract the current `VclBuilder` implementations of various methods from the `vcl::Window` specifics and make them reusable for other subclasses as well, but this commit is a start. The idea is to allow for incrementally refactoring aspects relevant for specific .ui files/features rather than having to refactor everything and implement support for all widget types at once, see also commit 9b3a2996e710fee11145dcbbe38a6f1e6f646ec8 Author: OmkarAcharekar <[email protected]> Date: Wed Sep 18 09:35:09 2024 +0200 tdf#130857 qt weld: Add QtInstanceBuilder skeleton which adds an initially empty list of .ui files that should be handled by the upcoming Qt-based implementation. [1] https://gerrit.libreoffice.org/c/core/+/161831 [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html Co-authored-by: Michael Weghorn <[email protected]> Change-Id: I2d81cc6dd54d796b549357a4444b95627661c623 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163103 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx index 8adf844c55e4..353d300015b3 100644 --- a/include/vcl/builder.hxx +++ b/include/vcl/builder.hxx @@ -15,7 +15,7 @@ #include <tools/fldunit.hxx> #include <vcl/dllapi.h> #include <utility> -#include <vcl/builderbase.hxx> +#include <vcl/widgetbuilder.hxx> #include <vcl/window.hxx> #include <vcl/vclptr.hxx> #include <vcl/toolboxid.hxx> @@ -54,7 +54,7 @@ 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. -class VCL_DLLPUBLIC VclBuilder : public BuilderBase +class VCL_DLLPUBLIC VclBuilder : public WidgetBuilder<vcl::Window, VclPtr<vcl::Window>> { public: /// These functions create a new widget with parent pParent and return it in rRet @@ -267,7 +267,7 @@ private: private: // tweak newly inserted child depending on window type void tweakInsertedChild(vcl::Window *pParent, vcl::Window* pCurrentChild, - std::string_view sType, std::string_view sInternalChild); + std::string_view sType, std::string_view sInternalChild) override; VclPtr<vcl::Window> insertObject(vcl::Window *pParent, const OUString &rClass, const OUString &rID, @@ -290,15 +290,10 @@ private: void extractButtonImage(const OUString &id, stringmap &rMap, bool bRadio); void extractMnemonicWidget(const OUString &id, stringmap &rMap); - // either pParent or pAtkProps must be set, pParent for a child of a widget, pAtkProps for - // collecting the atk info for a GtkMenuItem, - // if bToolbarItem=true, pParent is the ToolBox that the item belongs to, since there's no widget for the item itself - void handleChild(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem = false); - // if bToolbarItem=true, pParent is the ToolBox that the item belongs to, since there's no widget for the item itself - VclPtr<vcl::Window> handleObject(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem); + VclPtr<vcl::Window> handleObject(vcl::Window *pParent, stringmap *pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem) override; void applyPackingProperties(vcl::Window* pCurrent, vcl::Window* pParent, - const stringmap& rPackingProperties); + const stringmap& rPackingProperties) override; void insertMenuObject( Menu *pParent, @@ -312,7 +307,7 @@ private: void handleMenuChild(Menu *pParent, xmlreader::XmlReader &reader); void handleMenuObject(Menu *pParent, xmlreader::XmlReader &reader); - void handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader); + void handleTabChild(vcl::Window *pParent, xmlreader::XmlReader &reader) override; void handleMenu(xmlreader::XmlReader& reader, vcl::Window* pParent, const OUString& rID, bool bMenuBar); diff --git a/include/vcl/builderbase.hxx b/include/vcl/builderbase.hxx index 9c6e744ba8b9..3c833c054434 100644 --- a/include/vcl/builderbase.hxx +++ b/include/vcl/builderbase.hxx @@ -44,6 +44,7 @@ public: protected: BuilderBase(const OUString& rUIFile, bool bLegacy); + virtual ~BuilderBase() = default; struct ListStore { diff --git a/include/vcl/widgetbuilder.hxx b/include/vcl/widgetbuilder.hxx new file mode 100644 index 000000000000..a12bff918c0a --- /dev/null +++ b/include/vcl/widgetbuilder.hxx @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <vcl/builderbase.hxx> + +#include <xmlreader/span.hxx> +#include <xmlreader/xmlreader.hxx> + +/* 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 + * 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). + */ +template <typename Widget, typename WidgetPtr> class WidgetBuilder : public BuilderBase +{ +protected: + WidgetBuilder(const OUString& rUIFile, bool bLegacy) + : BuilderBase(rUIFile, bLegacy) + { + } + virtual ~WidgetBuilder() = default; + + // either pParent or pAtkProps must be set, pParent for a child of a widget, pAtkProps for + // collecting the atk info for a GtkMenuItem or tab child + void handleChild(Widget* pParent, stringmap* pAtkProps, xmlreader::XmlReader& reader, + bool bToolbarItem = false) + { + xmlreader::Span name; + int nsId; + OString sType, sInternalChild; + + while (reader.nextAttribute(&nsId, &name)) + { + if (name == "type") + { + name = reader.getAttributeValue(false); + sType = OString(name.begin, name.length); + } + else if (name == "internal-child") + { + name = reader.getAttributeValue(false); + sInternalChild = OString(name.begin, name.length); + } + } + + if (sType == "tab") + { + handleTabChild(pParent, reader); + return; + } + + WidgetPtr pCurrentChild = nullptr; + int nLevel = 1; + while (true) + { + xmlreader::XmlReader::Result res + = reader.nextItem(xmlreader::XmlReader::Text::NONE, &name, &nsId); + + if (res == xmlreader::XmlReader::Result::Begin) + { + if (name == "object" || name == "placeholder") + { + pCurrentChild = handleObject(pParent, pAtkProps, reader, bToolbarItem); + + bool bObjectInserted = pCurrentChild && pParent != pCurrentChild; + if (bObjectInserted) + tweakInsertedChild(pParent, pCurrentChild, sType, sInternalChild); + } + else if (name == "packing") + { + const stringmap aPackingProperties = collectPackingProperties(reader); + applyPackingProperties(pCurrentChild, pParent, aPackingProperties); + } + else if (name == "interface") + { + while (reader.nextAttribute(&nsId, &name)) + { + if (name == "domain") + handleInterfaceDomain(reader); + } + ++nLevel; + } + else + ++nLevel; + } + + if (res == xmlreader::XmlReader::Result::End) + --nLevel; + + if (!nLevel) + break; + + if (res == xmlreader::XmlReader::Result::Done) + break; + } + } + + virtual void applyPackingProperties(Widget* pCurrentChild, Widget* pParent, + const stringmap& rPackingProperties) + = 0; + virtual void tweakInsertedChild(Widget* pParent, Widget* pCurrentChild, std::string_view sType, + std::string_view sInternalChild) + = 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 sublasses) + // + // 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 WidgetPtr handleObject(Widget* /*pParent*/, stringmap* /*pAtkProps*/, + xmlreader::XmlReader& /*reader*/, bool /*bToolbarItem*/) + { + assert(false && "Functionality not implemented by this subclass yet."); + return nullptr; + } + virtual void handleTabChild(Widget* /*pParent*/, xmlreader::XmlReader& /*reader*/) + { + assert(false && "Functionality not implemented by this subclass yet."); + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 9a95b64294e3..3e1fad42fbe5 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -491,7 +491,7 @@ void BuilderBase::resetParserState() { m_pParserState.reset(); } VclBuilder::VclBuilder(vcl::Window* pParent, const OUString& sUIDir, const OUString& sUIFile, OUString sID, css::uno::Reference<css::frame::XFrame> xFrame, bool bLegacy, const NotebookBarAddonsItem* pNotebookBarAddonsItem) - : BuilderBase(sUIFile, bLegacy) + : WidgetBuilder(sUIFile, bLegacy) , m_pNotebookBarAddonsItem(pNotebookBarAddonsItem ? new NotebookBarAddonsItem(*pNotebookBarAddonsItem) : new NotebookBarAddonsItem{}) @@ -2837,78 +2837,6 @@ void VclBuilder::tweakInsertedChild(vcl::Window *pParent, vcl::Window* pCurrentC } } -void VclBuilder::handleChild(vcl::Window *pParent, stringmap* pAtkProps, xmlreader::XmlReader &reader, bool bToolbarItem) -{ - xmlreader::Span name; - int nsId; - OString sType, sInternalChild; - - while (reader.nextAttribute(&nsId, &name)) - { - if (name == "type") - { - name = reader.getAttributeValue(false); - sType = OString(name.begin, name.length); - } - else if (name == "internal-child") - { - name = reader.getAttributeValue(false); - sInternalChild = OString(name.begin, name.length); - } - } - - if (sType == "tab") - { - handleTabChild(pParent, reader); - return; - } - - VclPtr<vcl::Window> pCurrentChild; - int nLevel = 1; - while(true) - { - xmlreader::XmlReader::Result res = reader.nextItem( - xmlreader::XmlReader::Text::NONE, &name, &nsId); - - if (res == xmlreader::XmlReader::Result::Begin) - { - if (name == "object" || name == "placeholder") - { - pCurrentChild = handleObject(pParent, pAtkProps, reader, bToolbarItem); - - bool bObjectInserted = pCurrentChild && pParent != pCurrentChild; - if (bObjectInserted) - tweakInsertedChild(pParent, pCurrentChild, sType, sInternalChild); - } - else if (name == "packing") - { - const stringmap aPackingProperties = collectPackingProperties(reader); - applyPackingProperties(pCurrentChild, pParent, aPackingProperties); - } - else if (name == "interface") - { - while (reader.nextAttribute(&nsId, &name)) - { - if (name == "domain") - handleInterfaceDomain(reader); - } - ++nLevel; - } - else - ++nLevel; - } - - if (res == xmlreader::XmlReader::Result::End) - --nLevel; - - if (!nLevel) - break; - - if (res == xmlreader::XmlReader::Result::Done) - break; - } -} - void BuilderBase::collectPangoAttribute(xmlreader::XmlReader& reader, stringmap& rMap) { xmlreader::Span span;
