include/vcl/builderbase.hxx | 1 vcl/inc/qt5/QtBuilder.hxx | 1 vcl/qt5/QtBuilder.cxx | 53 ++++++++++++++++++++++++++++++++++++------ vcl/qt5/QtInstanceBuilder.cxx | 1 vcl/source/window/builder.cxx | 25 +++++++++++-------- 5 files changed, 64 insertions(+), 17 deletions(-)
New commits: commit be0d872afc8a1b7dd9d740893f9bc1b5ed94f45f Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 11 10:31:09 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri Apr 11 19:43:49 2025 +0200 tdf#130857 qt weld: Support Math's "Spacing" dialog Declare support for Math's "Format" -> "Spacing" dialog. This means that native Qt widgets are used for that dialog now when using the qt5 or qt6 VCL plugin and starting LO with environment variable SAL_VCL_QT_USE_WELDED_WIDGETS=1 set. This dialog makes use of the GtkRadioMenuItem support added in previous commit Change-Id: I2c9e8d2ecbef4b09a95bfb2f8057e714b984a329 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Fri Apr 11 10:24:33 2025 +0200 tdf#130857 qt weld: Support "GtkRadioMenuItem" Currently, the image isn't always updated when choosing a different category via "Category" menu button. This will be addressed in a separate commit. Change-Id: I3018c5a76cd863332ac8560a926105ae76327a38 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184025 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 682b98b4e6ef..187f1070dea9 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -102,6 +102,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile) u"modules/smath/ui/fontsizedialog.ui"_ustr, u"modules/smath/ui/savedefaultsdialog.ui"_ustr, u"modules/smath/ui/smathsettings.ui"_ustr, + u"modules/smath/ui/spacingdialog.ui"_ustr, u"modules/spropctrlr/ui/taborder.ui"_ustr, u"modules/swriter/ui/authenticationsettingsdialog.ui"_ustr, u"modules/swriter/ui/columnwidth.ui"_ustr, commit 5492c9bfa51ab45b936c6191066640608384c0e1 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 11 10:24:33 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri Apr 11 19:43:42 2025 +0200 tdf#130857 qt weld: Support "GtkRadioMenuItem" Implement support for GtkRadioMenuItem [1] menu items in .ui files. Reuse the logic implemented for "GtkMenuItem". In addition, support the "group" property which specifies what radio button group the item belongs to. For GTK, this is the ID of another GtkRadioMenuItem object. For Qt, use a QActionGroup. Let it be owned by the QMenu that the menu items belong to, so it is deleted together with the menu. (The Qt concept of QActionGroup is basically the same as QButtonGroup for radio buttons, see also QtBuilder::setRadioButtonGroup.) From a quick test, VclBuilder doesn't seem to evaluate the "group" property, but seems to use some logic that simply considers adjacent radio menu items as part of the same group. This will be used by Math's "Format" -> "Spacing" dialog, for which support will be declared in an upcoming commit. [1] https://docs.gtk.org/gtk3/class.RadioMenuItem.html [2] https://docs.gtk.org/gtk3/property.RadioMenuItem.group.html Change-Id: Id0eece0eef65b8c52f77996c67662584f5665726 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184024 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtBuilder.hxx b/vcl/inc/qt5/QtBuilder.hxx index 371c2af22d17..ca469e31a622 100644 --- a/vcl/inc/qt5/QtBuilder.hxx +++ b/vcl/inc/qt5/QtBuilder.hxx @@ -92,6 +92,7 @@ private: static void setEntryProperties(QLineEdit& rLineEdit, stringmap& rProps); static void setLabelProperties(QLabel& rLabel, stringmap& rProps); static void setMessageDialogProperties(QMessageBox& rMessageBox, stringmap& rProps); + static void setMenuActionGroup(QMenu* pMenu, QAction* pAction, const OUString& rRadioGroupId); void setMenuButtonProperties(QToolButton& rButton, stringmap& rProps, QWidget* pParentWidget); void setScaleProperties(QSlider& rSlider, stringmap& rProps); void setSpinButtonProperties(QDoubleSpinBox& rSpinBox, stringmap& rProps); diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx index 20e5c86cfd3b..7d5214f133af 100644 --- a/vcl/qt5/QtBuilder.cxx +++ b/vcl/qt5/QtBuilder.cxx @@ -20,7 +20,13 @@ #include <rtl/ustrbuf.hxx> #include <vcl/qt/QtUtils.hxx> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include <QtGui/QActionGroup> +#endif #include <QtGui/QStandardItemModel> +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include <QtWidgets/QActionGroup> +#endif #include <QtWidgets/QButtonGroup> #include <QtWidgets/QCheckBox> #include <QtWidgets/QComboBox> @@ -598,20 +604,53 @@ QMenu* QtBuilder::createMenu(const OUString& rId) return pMenu; } +void QtBuilder::setMenuActionGroup(QMenu* pMenu, QAction* pAction, const OUString& rRadioGroupId) +{ + // use QActionGroup owned by and set as property for the QMenu + QActionGroup* pActionGroup = nullptr; + const OString sPropertyKey = OUString(u"ACTIONGROUP::"_ustr + rRadioGroupId).toUtf8(); + QVariant aVariant = pMenu->property(sPropertyKey.getStr()); + if (aVariant.isValid()) + { + assert(aVariant.canConvert<QActionGroup*>()); + pActionGroup = aVariant.value<QActionGroup*>(); + } + else + { + pActionGroup = new QActionGroup(pMenu); + pMenu->setProperty(sPropertyKey.getStr(), QVariant::fromValue(pActionGroup)); + // insert the menu item which defines the group (whose ID matches the group's ID) + QAction* pIdAction = pMenu->findChild<QAction*>(toQString(rRadioGroupId)); + assert(pIdAction && "No action with the ID that the group refers to"); + pActionGroup->addAction(pIdAction); + } + + pActionGroup->addAction(pAction); +} + void QtBuilder::insertMenuObject(QMenu* pParent, QMenu* pSubMenu, const OUString& rClass, const OUString& rID, stringmap& rProps, stringmap&, accelmap&) { assert(!pSubMenu && "Handling not implemented yet"); (void)pSubMenu; - if (rClass == "GtkMenuItem") - { - const OUString sLabel = extractLabel(rProps); - QAction* pAction = pParent->addAction(toQString(sLabel)); - pAction->setObjectName(toQString(rID)); + const OUString sLabel = extractLabel(rProps); + QAction* pAction = pParent->addAction(toQString(sLabel)); + pAction->setObjectName(toQString(rID)); - const OUString sActionName(extractActionName(rProps)); - QtInstanceMenu::setActionName(*pAction, sActionName); + const OUString sActionName(extractActionName(rProps)); + QtInstanceMenu::setActionName(*pAction, sActionName); + + if (rClass == u"GtkMenuItem") + { + // nothing else to do + } + else if (rClass == u"GtkRadioMenuItem") + { + pAction->setCheckable(true); + const OUString sGroup = extractGroup(rProps); + if (!sGroup.isEmpty()) + setMenuActionGroup(pParent, pAction, sGroup); } else { commit e61975fac8148c667374d815fb376a273f304d24 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 11 09:59:47 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri Apr 11 19:43:36 2025 +0200 tdf#130857 vcl: Extract BuilderBase::extractGroup helper This will allow to reuse the existing logic to also process the "group" property for GtkRadioMenuItem objects [1] in an upcoming commit for QtBuilder. [1] https://docs.gtk.org/gtk3/property.RadioMenuItem.group.html Change-Id: Ib0b545132dffedc5c33b34ff37d39473c6797343 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184023 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/include/vcl/builderbase.hxx b/include/vcl/builderbase.hxx index 181f9461a68f..950d0922140d 100644 --- a/include/vcl/builderbase.hxx +++ b/include/vcl/builderbase.hxx @@ -87,6 +87,7 @@ protected: static void collectAccelerator(xmlreader::XmlReader& reader, accelmap& rMap); stringmap collectPackingProperties(xmlreader::XmlReader& reader); void collectProperty(xmlreader::XmlReader& rReader, stringmap& rMap) const; + static OUString extractGroup(stringmap& rMap); static bool extractHeadersVisible(stringmap& rMap); static bool extractEntry(stringmap& rMap); static OUString extractIconName(stringmap& rMap); diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 0817f527d739..9103933538b7 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -1079,16 +1079,11 @@ namespace void BuilderBase::extractRadioButtonGroup(const OUString &id, stringmap &rMap) { - VclBuilder::stringmap::iterator aFind = rMap.find(u"group"_ustr); - if (aFind != rMap.end()) - { - OUString sID = aFind->second; - sal_Int32 nDelim = sID.indexOf(':'); - if (nDelim != -1) - sID = sID.copy(0, nDelim); - m_pParserState->m_aRadioButtonGroupMaps.emplace_back(id, sID); - rMap.erase(aFind); - } + const OUString sGroupId = extractGroup(rMap); + if (sGroupId.isEmpty()) + return; + + m_pParserState->m_aRadioButtonGroupMaps.emplace_back(id, sGroupId); } void VclBuilder::connectNumericFormatterAdjustment(const OUString &id, const OUString &rAdjustment) @@ -3370,6 +3365,16 @@ bool BuilderBase::extractEntry(VclBuilder::stringmap &rMap) return extractBoolEntry(rMap, u"has-entry"_ustr, false); } +OUString BuilderBase::extractGroup(stringmap& rMap) +{ + OUString sGroup = extractStringEntry(rMap, u"group"_ustr); + sal_Int32 nDelim = sGroup.indexOf(':'); + if (nDelim != -1) + sGroup = sGroup.copy(0, nDelim); + + return sGroup; +} + bool BuilderBase::extractHeadersVisible(VclBuilder::stringmap& rMap) { return extractBoolEntry(rMap, u"headers-visible"_ustr, true);