starmath/uiconfig/smath/ui/fontdialog.ui | 36 ++++----- vcl/CustomTarget_qt5_moc.mk | 1 vcl/CustomTarget_qt6_moc.mk | 1 vcl/Library_vclplug_qt5.mk | 1 vcl/Library_vclplug_qt6.mk | 1 vcl/inc/qt5/QtInstanceBuilder.hxx | 3 vcl/inc/qt5/QtInstanceEntryTreeView.hxx | 46 +++++++++++ vcl/inc/qt6/QtInstanceEntryTreeView.hxx | 12 +++ vcl/qt5/QtInstanceBuilder.cxx | 16 +++- vcl/qt5/QtInstanceEntryTreeView.cxx | 119 +++++++++++++++++++++++++++++++ vcl/qt6/QtInstanceEntryTreeView.cxx | 12 +++ 11 files changed, 226 insertions(+), 22 deletions(-)
New commits: commit e35a70707094d444ae7146b0e4be397499c4f0d9 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 18 23:09:11 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Apr 19 09:51:10 2025 +0200 tdf#130857 Define widgets in Math's font dialog in order Switch the order in which the widgets in the .ui file are defined so that the order matches the visual appearance (and "left-attach"/"top-attach" properties order), which makes sure that tab focus order with the Qt-based VCL plugins is correct as well when using native Qt widgets (SAL_VCL_QT_USE_WELDED_WIDGETS=1), where focus order is (by default) based on widget creation order. See commit 02692566ad9fc7c3484f8581ffa0004cd4e43987 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Thu Oct 24 17:43:35 2024 +0200 tdf#130857 optnewdictionarydialog.ui: Define focusable widgets in order for more background. This dialog can be triggered in Math as follows: * "Format" -> "Fonts" * click the "Modify" menu buttton and select any entry Change-Id: Ia2339e3d7b0a8fdc31a7b4fb498eddee63772cf4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184364 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/starmath/uiconfig/smath/ui/fontdialog.ui b/starmath/uiconfig/smath/ui/fontdialog.ui index d6543c22696b..66431a50d1c0 100644 --- a/starmath/uiconfig/smath/ui/fontdialog.ui +++ b/starmath/uiconfig/smath/ui/fontdialog.ui @@ -104,6 +104,24 @@ <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="row-spacing">3</property> + <child> + <object class="GtkEntry" id="font"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="activates-default">True</property> + <property name="truncate-multiline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="font-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="fontdialog|extended_tip|font">Select a font from the list.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> <child> <object class="GtkScrolledWindow"> <property name="visible">True</property> @@ -143,24 +161,6 @@ <property name="top-attach">1</property> </packing> </child> - <child> - <object class="GtkEntry" id="font"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="hexpand">True</property> - <property name="activates-default">True</property> - <property name="truncate-multiline">True</property> - <child internal-child="accessible"> - <object class="AtkObject" id="font-atkobject"> - <property name="AtkObject::accessible-description" translatable="yes" context="fontdialog|extended_tip|font">Select a font from the list.</property> - </object> - </child> - </object> - <packing> - <property name="left-attach">0</property> - <property name="top-attach">0</property> - </packing> - </child> </object> </child> <child type="label"> commit 2071333e226d0ca3d5cdce36a6afbe3947c71f9b Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 18 23:04:05 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Apr 19 09:51:03 2025 +0200 tdf#130857 qt weld: Support Math's font 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 can be triggered in Math as follows: * "Format" -> "Fonts" * click the "Modify" menu buttton and select any entry This dialog makes use of weld::EntryTreeView for which a Qt implementation was added in previous commit Change-Id: Ide3063e27dd36e87539b9eaf7165dc073669323f Author: Michael Weghorn <m.wegh...@posteo.de> Date: Fri Apr 18 23:00:09 2025 +0200 tdf#130857 qt weld: Introduce QtInstanceEntryTreeView Change-Id: I88ac6a76b9f70872d965b435c02f35a5bdbbf2d1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184363 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 4ba04c9ba185..b31a735ad664 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -103,6 +103,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile) u"modules/schart/ui/insertaxisdlg.ui"_ustr, u"modules/simpress/ui/presentationdialog.ui"_ustr, u"modules/smath/ui/alignmentdialog.ui"_ustr, + u"modules/smath/ui/fontdialog.ui"_ustr, u"modules/smath/ui/fontsizedialog.ui"_ustr, u"modules/smath/ui/savedefaultsdialog.ui"_ustr, u"modules/smath/ui/smathsettings.ui"_ustr, commit e61a6f9598867db80de1d34837569d48afb7e522 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Apr 18 23:00:09 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Apr 19 09:50:56 2025 +0200 tdf#130857 qt weld: Introduce QtInstanceEntryTreeView This is the weld::EntryTreeView implementation using native Qt widgets. A weld::EntryTreeView is a combobox-like widget, but consisting of two widgets: a weld::Entry and a weld::TreeView. In QtInstanceEntryTreeView, implement logic similar to the GTK (GtkInstanceEntryTreeView) and VCL (SalInstanceEntryTreeView) implementations: * Auto-completion based on the tree view entries when typing in the entry/edit * automatically selecting the corresponding tree view entry when the entry/edit text matches one * forward (page) up/down key events on the entry/edit to the tree view, so this can be used to navigate through the entries This worked as expected in a quick test of Math's font dialog that can be triggered as follows: * "Format" -> "Fonts" * click the "Modify" menu buttton and select any entry Support for that dialog will be declared in QtInstanceBuilder in a separate commit. Change-Id: Ide3063e27dd36e87539b9eaf7165dc073669323f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184362 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/CustomTarget_qt5_moc.mk b/vcl/CustomTarget_qt5_moc.mk index c7a3e691535f..7e04d5756fbc 100644 --- a/vcl/CustomTarget_qt5_moc.mk +++ b/vcl/CustomTarget_qt5_moc.mk @@ -25,6 +25,7 @@ $(call gb_CustomTarget_get_target,vcl/qt5) : \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceDrawingArea.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceEntry.moc \ + $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceEntryTreeView.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceExpander.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceFormattedSpinButton.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceGrid.moc \ diff --git a/vcl/CustomTarget_qt6_moc.mk b/vcl/CustomTarget_qt6_moc.mk index 0ed358e0d8d3..79b203ea70a1 100644 --- a/vcl/CustomTarget_qt6_moc.mk +++ b/vcl/CustomTarget_qt6_moc.mk @@ -25,6 +25,7 @@ $(call gb_CustomTarget_get_target,vcl/qt6) : \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceDrawingArea.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceEntry.moc \ + $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceEntryTreeView.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceExpander.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceFormattedSpinButton.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceGrid.moc \ diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk index f254fed9ae14..5f1a31a8f617 100644 --- a/vcl/Library_vclplug_qt5.mk +++ b/vcl/Library_vclplug_qt5.mk @@ -109,6 +109,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\ vcl/qt5/QtInstanceDialog \ vcl/qt5/QtInstanceDrawingArea \ vcl/qt5/QtInstanceEntry \ + vcl/qt5/QtInstanceEntryTreeView \ vcl/qt5/QtInstanceExpander \ vcl/qt5/QtInstanceFormattedSpinButton \ vcl/qt5/QtInstanceFrame \ diff --git a/vcl/Library_vclplug_qt6.mk b/vcl/Library_vclplug_qt6.mk index 74fe907cd458..5e40085748a9 100644 --- a/vcl/Library_vclplug_qt6.mk +++ b/vcl/Library_vclplug_qt6.mk @@ -108,6 +108,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt6,\ vcl/qt6/QtInstanceDialog \ vcl/qt6/QtInstanceDrawingArea \ vcl/qt6/QtInstanceEntry \ + vcl/qt6/QtInstanceEntryTreeView \ vcl/qt6/QtInstanceExpander \ vcl/qt6/QtInstanceFormattedSpinButton \ vcl/qt6/QtInstanceFrame \ diff --git a/vcl/inc/qt5/QtInstanceBuilder.hxx b/vcl/inc/qt5/QtInstanceBuilder.hxx index c01e705a22fd..788484dcbbb3 100644 --- a/vcl/inc/qt5/QtInstanceBuilder.hxx +++ b/vcl/inc/qt5/QtInstanceBuilder.hxx @@ -64,7 +64,8 @@ public: weld_formatted_spin_button(const OUString& rId) override; virtual std::unique_ptr<weld::ComboBox> weld_combo_box(const OUString& rId) override; virtual std::unique_ptr<weld::EntryTreeView> - weld_entry_tree_view(const OUString&, const OUString&, const OUString&) override; + weld_entry_tree_view(const OUString& rContainerId, const OUString& rEntryId, + const OUString& rTreeViewId) override; virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OUString& rId) override; virtual std::unique_ptr<weld::IconView> weld_icon_view(const OUString& rId) override; virtual std::unique_ptr<weld::Label> weld_label(const OUString& rId) override; diff --git a/vcl/inc/qt5/QtInstanceEntryTreeView.hxx b/vcl/inc/qt5/QtInstanceEntryTreeView.hxx new file mode 100644 index 000000000000..7ce03edc2512 --- /dev/null +++ b/vcl/inc/qt5/QtInstanceEntryTreeView.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "QtInstanceContainer.hxx" + +#include <QtWidgets/QLineEdit> +#include <QtWidgets/QTreeView> + +class QtInstanceBuilder; + +class QtInstanceEntryTreeView final : public QtInstanceContainer, public virtual weld::EntryTreeView +{ + Q_OBJECT + + QLineEdit* m_pLineEdit; + QTreeView* m_pTreeView; + +public: + QtInstanceEntryTreeView(QWidget* pContainer, QLineEdit* pLineEdit, QTreeView* pTreeView, + std::unique_ptr<weld::Entry> xEntry, + std::unique_ptr<weld::TreeView> xTreeView); + + virtual void grab_focus() override; + virtual void connect_focus_in(const Link<Widget&, void>& rLink) override; + virtual void connect_focus_out(const Link<Widget&, void>& rLink) override; + + virtual void make_sorted() override; + virtual bool changed_by_direct_pick() const override; + virtual void set_entry_completion(bool bEnable, bool bCaseSensitive = false) override; + virtual VclPtr<VirtualDevice> create_render_virtual_device() const override; + + virtual bool eventFilter(QObject* pObject, QEvent* pEvent) override; + +private Q_SLOTS: + void editTextChanged(const QString& rText); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/qt6/QtInstanceEntryTreeView.hxx b/vcl/inc/qt6/QtInstanceEntryTreeView.hxx new file mode 100644 index 000000000000..4f7b42b878e5 --- /dev/null +++ b/vcl/inc/qt6/QtInstanceEntryTreeView.hxx @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include "../qt5/QtInstanceEntryTreeView.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 6a4f817a72c6..4ba04c9ba185 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -18,6 +18,7 @@ #include <QtInstanceComboBox.hxx> #include <QtInstanceDrawingArea.hxx> #include <QtInstanceEntry.hxx> +#include <QtInstanceEntryTreeView.hxx> #include <QtInstanceExpander.hxx> #include <QtInstanceFormattedSpinButton.hxx> #include <QtInstanceFrame.hxx> @@ -388,10 +389,18 @@ std::unique_ptr<weld::ComboBox> QtInstanceBuilder::weld_combo_box(const OUString } std::unique_ptr<weld::EntryTreeView> -QtInstanceBuilder::weld_entry_tree_view(const OUString&, const OUString&, const OUString&) +QtInstanceBuilder::weld_entry_tree_view(const OUString& rContainerId, const OUString& rEntryId, + const OUString& rTreeViewId) { - assert(false && "Not implemented yet"); - return nullptr; + QWidget* pWidget = m_xBuilder->get<QWidget>(rContainerId); + QLineEdit* pLineEdit = m_xBuilder->get<QLineEdit>(rEntryId); + QTreeView* pTreeView = m_xBuilder->get<QTreeView>(rTreeViewId); + assert(pWidget && pLineEdit && pTreeView); + + std::unique_ptr<weld::EntryTreeView> xRet(std::make_unique<QtInstanceEntryTreeView>( + pWidget, pLineEdit, pTreeView, weld_entry(rEntryId), weld_tree_view(rTreeViewId))); + + return xRet; } std::unique_ptr<weld::TreeView> QtInstanceBuilder::weld_tree_view(const OUString& rId) diff --git a/vcl/qt5/QtInstanceEntryTreeView.cxx b/vcl/qt5/QtInstanceEntryTreeView.cxx new file mode 100644 index 000000000000..b7883becbfa0 --- /dev/null +++ b/vcl/qt5/QtInstanceEntryTreeView.cxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <QtInstanceEntryTreeView.hxx> +#include <QtInstanceEntryTreeView.moc> + +#include <QtInstanceBuilder.hxx> + +#include <QtWidgets/QCompleter> + +QtInstanceEntryTreeView::QtInstanceEntryTreeView(QWidget* pContainer, QLineEdit* pLineEdit, + QTreeView* pTreeView, + std::unique_ptr<weld::Entry> xEntry, + std::unique_ptr<weld::TreeView> xTreeView) + : weld::EntryTreeView(std::move(xEntry), std::move(xTreeView)) + , QtInstanceContainer(pContainer) + , m_pLineEdit(pLineEdit) + , m_pTreeView(pTreeView) +{ + set_entry_completion(true, true); + + connect(m_pLineEdit, &QLineEdit::textChanged, this, &QtInstanceEntryTreeView::editTextChanged); + m_pLineEdit->installEventFilter(this); +} + +void QtInstanceEntryTreeView::grab_focus() { m_xEntry->grab_focus(); } + +void QtInstanceEntryTreeView::connect_focus_in(const Link<Widget&, void>& rLink) +{ + m_xEntry->connect_focus_in(rLink); +} + +void QtInstanceEntryTreeView::connect_focus_out(const Link<Widget&, void>& rLink) +{ + m_xEntry->connect_focus_out(rLink); +} + +void QtInstanceEntryTreeView::make_sorted() { m_xTreeView->make_sorted(); } + +bool QtInstanceEntryTreeView::changed_by_direct_pick() const +{ + assert(false && "Not implemented yet"); + return false; +} + +void QtInstanceEntryTreeView::set_entry_completion(bool bEnable, bool bCaseSensitive) +{ + SolarMutexGuard g; + GetQtInstance().RunInMainThread([&] { + QCompleter* pCompleter = nullptr; + if (bEnable) + { + pCompleter = new QCompleter(m_pTreeView->model(), m_pTreeView); + pCompleter->setCompletionMode(QCompleter::InlineCompletion); + pCompleter->setFilterMode(Qt::MatchStartsWith); + Qt::CaseSensitivity eCaseSensitivity + = bCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + pCompleter->setCaseSensitivity(eCaseSensitivity); + } + + m_pLineEdit->setCompleter(pCompleter); + }); +} + +VclPtr<VirtualDevice> QtInstanceEntryTreeView::create_render_virtual_device() const +{ + return create_virtual_device(); +} + +bool QtInstanceEntryTreeView::eventFilter(QObject* pObject, QEvent* pEvent) +{ + if (pObject != m_pLineEdit) + return false; + + switch (pEvent->type()) + { + case QEvent::KeyPress: + { + QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(pEvent); + + // don't intercept key event handling if modifiers (other than key pad) are used + if (pKeyEvent->modifiers() & ~Qt::KeypadModifier) + return false; + + switch (pKeyEvent->key()) + { + case Qt::Key_Down: + case Qt::Key_PageDown: + case Qt::Key_PageUp: + case Qt::Key_Up: + // forward key events for navigation through entries to the tree view + return QCoreApplication::sendEvent(m_pTreeView, pEvent); + default: + return false; + } + } + default: + return false; + } +} + +void QtInstanceEntryTreeView::editTextChanged(const QString& rText) +{ + const int nIndex = m_xTreeView->find_text(toOUString(rText)); + if (nIndex < 0) + return; + + const QModelIndex aModelIndex = m_pTreeView->model()->index(nIndex, 0); + m_pTreeView->selectionModel()->setCurrentIndex(aModelIndex, + QItemSelectionModel::ClearAndSelect); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/qt6/QtInstanceEntryTreeView.cxx b/vcl/qt6/QtInstanceEntryTreeView.cxx new file mode 100644 index 000000000000..e7158a5b2d60 --- /dev/null +++ b/vcl/qt6/QtInstanceEntryTreeView.cxx @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include "../qt5/QtInstanceEntryTreeView.cxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */