cui/uiconfig/ui/objecttitledescdialog.ui | 3 solenv/sanitizers/ui/cui.suppr | 1 vcl/Library_vclplug_qt5.mk | 1 vcl/Library_vclplug_qt6.mk | 1 vcl/inc/qt5/QtInstanceBuilder.hxx | 2 vcl/inc/qt5/QtInstanceTextView.hxx | 52 +++++++++++ vcl/inc/qt6/QtInstanceTextView.hxx | 12 ++ vcl/qt5/QtBuilder.cxx | 5 + vcl/qt5/QtInstanceBuilder.cxx | 9 + vcl/qt5/QtInstanceTextView.cxx | 140 +++++++++++++++++++++++++++++++ vcl/qt6/QtInstanceTextView.cxx | 12 ++ 11 files changed, 232 insertions(+), 6 deletions(-)
New commits: commit fbd0030b97c9878c098498eb9213e73d4ae31e94 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Oct 4 21:39:44 2024 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Oct 5 09:39:39 2024 +0200 tdf#119931: cui a11y: Specify mnenomic-widget in "Alt Text" dialog Specify that the mnemonic widget for the "Alt Text" label is the text view where the description can be entered. This e.g. ensures that the a11y labelled-by label-for relations get reported. Drop the corresponding suppression for gla11y. When using the Orca screen reader with the gtk3 VCL plugin, Orca now announces "Alt Text" when the text view gets focus, while that was not the case before. Dialog can be triggered by e.g. selecting a QR code in Writer, then opening the context menu and choosing the "Alt Text" menu entry. Change-Id: I5c8b06198a45cfbe5e1fc4a85ac568094b596819 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174506 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/cui/uiconfig/ui/objecttitledescdialog.ui b/cui/uiconfig/ui/objecttitledescdialog.ui index 3085ac6124d2..c27ce4ebd30d 100644 --- a/cui/uiconfig/ui/objecttitledescdialog.ui +++ b/cui/uiconfig/ui/objecttitledescdialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> +<!-- Generated with glade 3.40.0 --> <interface domain="cui"> <requires lib="gtk+" version="3.20"/> <object class="GtkTextBuffer" id="textbuffer1"> @@ -127,6 +127,7 @@ <property name="tooltip-text" translatable="yes" context="objecttitledescdialog|desc_label|tooltip_text">Give longer explanation of non-text content that is too complex to be described briefly in “Text”</property> <property name="label" translatable="yes" context="objecttitledescdialog|desc_label">_Alt Text:</property> <property name="use-underline">True</property> + <property name="mnemonic-widget">desc_entry</property> <property name="xalign">0</property> </object> <packing> diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr index 1bbedb8ee184..a7e12f93e5bc 100644 --- a/solenv/sanitizers/ui/cui.suppr +++ b/solenv/sanitizers/ui/cui.suppr @@ -92,7 +92,6 @@ cui/uiconfig/ui/newlibdialog.ui://GtkLabel[@id='altmacrotitle'] orphan-label cui/uiconfig/ui/newlibdialog.ui://GtkLabel[@id='altrenametitle'] orphan-label cui/uiconfig/ui/numberingformatpage.ui://GtkLabel[@id='commentft'] orphan-label cui/uiconfig/ui/numberingoptionspage.ui://GtkLabel[@id='separator'] orphan-label -cui/uiconfig/ui/objecttitledescdialog.ui://GtkLabel[@id='desc_label'] orphan-label cui/uiconfig/ui/optadvancedpage.ui://GtkLabel[@id='selectruntime'] orphan-label cui/uiconfig/ui/optadvancedpage.ui://GtkLabel[@id='javapath'] orphan-label cui/uiconfig/ui/optappearancepage.ui://GtkLabel[@id='uielements'] orphan-label commit 71e819a2d774aa12ae9093762f5ab6fdaaa74eac Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Oct 4 16:54:31 2024 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Oct 5 09:39:31 2024 +0200 tdf#130857 qt weld: Add a QtInstanceTextView Add a native Qt implementation for weld::TextView QtInstanceTextView, that uses a QPlainTextEdit, and let QtInstanceBuilder use it when it encounters a "GtkTextView" object in a .ui file. Implement methods which are probably the most relevant ones. For now, trigger an assert in case any of the not yet implemented methods gets called. None of the .ui files currently marked as supported by QtInstanceBuilder uses this new class yet, but it will be needed to support more in the future, e.g. for cui/uiconfig/ui/objecttitledescdialog.ui. With this commit in place, adding that file to the set of supported ones in QtInstanceBuilder::IsUIFileSupported makes the dialog somehow show up as a native Qt dialog with the qt6 VCL plugin when e.g. selecting a QR code in an existing document, then opening the context menu and choosing "Alt Text", but there are various issues that still need to be fixed before it can actually be claimed as working/supported. Change-Id: Id7217d4a8a86f953d8b289c8a09cb8d1e2040bf1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174495 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk index d3046eba60a4..767eab5e4024 100644 --- a/vcl/Library_vclplug_qt5.mk +++ b/vcl/Library_vclplug_qt5.mk @@ -103,6 +103,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\ vcl/qt5/QtInstanceEntry \ vcl/qt5/QtInstanceMessageDialog \ vcl/qt5/QtInstanceLabel \ + vcl/qt5/QtInstanceTextView \ vcl/qt5/QtInstanceWidget \ vcl/qt5/QtInstanceWindow \ vcl/qt5/QtMainWindow \ diff --git a/vcl/Library_vclplug_qt6.mk b/vcl/Library_vclplug_qt6.mk index 832adf500931..01e0ae5a2a9d 100644 --- a/vcl/Library_vclplug_qt6.mk +++ b/vcl/Library_vclplug_qt6.mk @@ -102,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt6,\ vcl/qt6/QtInstanceEntry \ vcl/qt6/QtInstanceLabel \ vcl/qt6/QtInstanceMessageDialog \ + vcl/qt6/QtInstanceTextView \ vcl/qt6/QtInstanceWidget \ vcl/qt6/QtInstanceWindow \ vcl/qt6/QtMainWindow \ diff --git a/vcl/inc/qt5/QtInstanceBuilder.hxx b/vcl/inc/qt5/QtInstanceBuilder.hxx index 713f7c5fed6a..3b2bde087507 100644 --- a/vcl/inc/qt5/QtInstanceBuilder.hxx +++ b/vcl/inc/qt5/QtInstanceBuilder.hxx @@ -67,7 +67,7 @@ public: virtual std::unique_ptr<weld::TreeView> weld_tree_view(const OUString&) override; virtual std::unique_ptr<weld::IconView> weld_icon_view(const OUString&) override; virtual std::unique_ptr<weld::Label> weld_label(const OUString&) override; - virtual std::unique_ptr<weld::TextView> weld_text_view(const OUString&) override; + virtual std::unique_ptr<weld::TextView> weld_text_view(const OUString& rId) override; virtual std::unique_ptr<weld::Expander> weld_expander(const OUString&) override; virtual std::unique_ptr<weld::DrawingArea> weld_drawing_area(const OUString&, const a11yref& rA11yImpl = nullptr, diff --git a/vcl/inc/qt5/QtInstanceTextView.hxx b/vcl/inc/qt5/QtInstanceTextView.hxx new file mode 100644 index 000000000000..392527db955c --- /dev/null +++ b/vcl/inc/qt5/QtInstanceTextView.hxx @@ -0,0 +1,52 @@ +/* -*- 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 "QtInstanceWidget.hxx" + +#include <QtWidgets/QPlainTextEdit> + +class QtInstanceTextView : public QtInstanceWidget, public virtual weld::TextView +{ + QPlainTextEdit* m_pTextEdit; + +public: + QtInstanceTextView(QPlainTextEdit* pTextEdit); + + virtual void set_text(const OUString& rText) override; + virtual OUString get_text() const override; + virtual void select_region(int nStartPos, int nEndPos) override; + virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) override; + virtual void replace_selection(const OUString& rText) override; + virtual void set_editable(bool bEditable) override; + virtual bool get_editable() const override; + virtual void set_monospace(bool bMonospace) override; + virtual void set_max_length(int nChars) override; + + virtual void set_font(const vcl::Font& rFont) override; + virtual void set_font_color(const Color& rColor) override; + + virtual bool can_move_cursor_with_up() const override; + virtual bool can_move_cursor_with_down() const override; + + virtual void cut_clipboard() override; + virtual void copy_clipboard() override; + virtual void paste_clipboard() override; + + virtual void set_alignment(TxtAlign eXAlign) override; + + virtual int vadjustment_get_value() const override; + virtual int vadjustment_get_upper() const override; + virtual int vadjustment_get_lower() const override; + virtual int vadjustment_get_page_size() const override; + virtual void vadjustment_set_value(int nValue) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/qt6/QtInstanceTextView.hxx b/vcl/inc/qt6/QtInstanceTextView.hxx new file mode 100644 index 000000000000..c576999abb7c --- /dev/null +++ b/vcl/inc/qt6/QtInstanceTextView.hxx @@ -0,0 +1,12 @@ +/* -*- 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/. + */ + +#include "../qt5/QtInstanceTextView.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx index f1aedbce9a90..36affcc04718 100644 --- a/vcl/qt5/QtBuilder.cxx +++ b/vcl/qt5/QtBuilder.cxx @@ -21,6 +21,7 @@ #include <QtWidgets/QLabel> #include <QtWidgets/QLineEdit> #include <QtWidgets/QLayout> +#include <QtWidgets/QPlainTextEdit> #include <QtWidgets/QPushButton> #include <QtWidgets/QScrollArea> @@ -162,6 +163,10 @@ QObject* QtBuilder::makeObject(QObject* pParent, std::u16string_view sName, cons { pObject = new QScrollArea(pParentWidget); } + else if (sName == u"GtkTextView") + { + pObject = new QPlainTextEdit(pParentWidget); + } else { SAL_WARN("vcl.qt", "Widget type not supported yet: " diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 8bab727f6800..0f9f1872ed07 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -16,6 +16,7 @@ #include <QtInstanceEntry.hxx> #include <QtInstanceLabel.hxx> #include <QtInstanceMessageDialog.hxx> +#include <QtInstanceTextView.hxx> QtInstanceBuilder::QtInstanceBuilder(QWidget* pParent, std::u16string_view sUIRoot, const OUString& rUIFile) @@ -254,10 +255,12 @@ std::unique_ptr<weld::Label> QtInstanceBuilder::weld_label(const OUString& rId) return xRet; } -std::unique_ptr<weld::TextView> QtInstanceBuilder::weld_text_view(const OUString&) +std::unique_ptr<weld::TextView> QtInstanceBuilder::weld_text_view(const OUString& rId) { - assert(false && "Not implemented yet"); - return nullptr; + QPlainTextEdit* pTextEdit = m_xBuilder->get<QPlainTextEdit>(rId); + std::unique_ptr<weld::TextView> xRet(pTextEdit ? std::make_unique<QtInstanceTextView>(pTextEdit) + : nullptr); + return xRet; } std::unique_ptr<weld::Expander> QtInstanceBuilder::weld_expander(const OUString&) diff --git a/vcl/qt5/QtInstanceTextView.cxx b/vcl/qt5/QtInstanceTextView.cxx new file mode 100644 index 000000000000..60b50de721bf --- /dev/null +++ b/vcl/qt5/QtInstanceTextView.cxx @@ -0,0 +1,140 @@ +/* -*- 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/. + */ + +#include <QtInstanceTextView.hxx> + +#include <QtGui/QTextCursor> + +QtInstanceTextView::QtInstanceTextView(QPlainTextEdit* pTextEdit) + : QtInstanceWidget(pTextEdit) + , m_pTextEdit(pTextEdit) +{ + assert(m_pTextEdit); +} + +void QtInstanceTextView::set_text(const OUString& rText) +{ + SolarMutexGuard g; + GetQtInstance().RunInMainThread([&] { m_pTextEdit->setPlainText(toQString(rText)); }); +} + +OUString QtInstanceTextView::get_text() const +{ + SolarMutexGuard g; + OUString sText; + GetQtInstance().RunInMainThread([&] { sText = toOUString(m_pTextEdit->toPlainText()); }); + return sText; +} + +void QtInstanceTextView::select_region(int nStartPos, int nEndPos) +{ + SolarMutexGuard g; + + GetQtInstance().RunInMainThread([&] { + if (nEndPos == -1) + nEndPos = m_pTextEdit->toPlainText().length(); + + QTextCursor aCursor = m_pTextEdit->textCursor(); + aCursor.setPosition(nStartPos); + aCursor.setPosition(nEndPos, QTextCursor::KeepAnchor); + m_pTextEdit->setTextCursor(aCursor); + }); +} + +bool QtInstanceTextView::get_selection_bounds(int& rStartPos, int& rEndPos) +{ + SolarMutexGuard g; + + bool bHasSelection = false; + GetQtInstance().RunInMainThread([&] { + QTextCursor aCursor = m_pTextEdit->textCursor(); + bHasSelection = aCursor.hasSelection(); + rStartPos = aCursor.selectionStart(); + rEndPos = aCursor.selectionEnd(); + }); + + return bHasSelection; +} + +void QtInstanceTextView::replace_selection(const OUString& rText) +{ + SolarMutexGuard g; + GetQtInstance().RunInMainThread([&] { m_pTextEdit->insertPlainText(toQString(rText)); }); +} + +void QtInstanceTextView::set_editable(bool bEditable) +{ + SolarMutexGuard g; + GetQtInstance().RunInMainThread([&] { m_pTextEdit->setReadOnly(!bEditable); }); +} + +bool QtInstanceTextView::get_editable() const +{ + SolarMutexGuard g; + bool bEditable = false; + GetQtInstance().RunInMainThread([&] { bEditable = !m_pTextEdit->isReadOnly(); }); + + return bEditable; +} + +void QtInstanceTextView::set_monospace(bool) { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::set_max_length(int) { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::set_font(const vcl::Font&) { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::set_font_color(const Color&) { assert(false && "Not implemented yet"); } + +bool QtInstanceTextView::can_move_cursor_with_up() const +{ + assert(false && "Not implemented yet"); + return false; +} + +bool QtInstanceTextView::can_move_cursor_with_down() const +{ + assert(false && "Not implemented yet"); + return false; +} + +void QtInstanceTextView::cut_clipboard() { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::copy_clipboard() { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::paste_clipboard() { assert(false && "Not implemented yet"); } + +void QtInstanceTextView::set_alignment(TxtAlign) { assert(false && "Not implemented yet"); } + +int QtInstanceTextView::vadjustment_get_value() const +{ + assert(false && "Not implemented yet"); + return -1; +} + +int QtInstanceTextView::vadjustment_get_upper() const +{ + assert(false && "Not implemented yet"); + return -1; +} + +int QtInstanceTextView::vadjustment_get_lower() const +{ + assert(false && "Not implemented yet"); + return -1; +} + +int QtInstanceTextView::vadjustment_get_page_size() const +{ + assert(false && "Not implemented yet"); + return -1; +} + +void QtInstanceTextView::vadjustment_set_value(int) { assert(false && "Not implemented yet"); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt6/QtInstanceTextView.cxx b/vcl/qt6/QtInstanceTextView.cxx new file mode 100644 index 000000000000..43ffd58bbb0e --- /dev/null +++ b/vcl/qt6/QtInstanceTextView.cxx @@ -0,0 +1,12 @@ +/* -*- 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/. + */ + +#include "../qt5/QtInstanceTextView.cxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */