include/vcl/weld/Entry.hxx | 42 +--------------------- include/vcl/weld/TextView.hxx | 40 +-------------------- include/vcl/weld/TextWidget.hxx | 66 +++++++++++++++++++++++++++++++++++ vcl/Library_vcl.mk | 1 vcl/inc/jsdialog/jsdialogbuilder.hxx | 2 - vcl/inc/qt5/QtInstanceEntry.hxx | 2 - vcl/inc/salvtables.hxx | 2 - vcl/jsdialog/jsdialogbuilder.cxx | 4 +- vcl/qt5/QtInstanceEntry.cxx | 2 - vcl/source/app/salvtables.cxx | 2 - vcl/source/weld/Entry.cxx | 14 ------- vcl/source/weld/TextView.cxx | 21 ----------- vcl/source/weld/TextWidget.cxx | 36 +++++++++++++++++++ vcl/unx/gtk3/gtkinst.cxx | 2 - 14 files changed, 115 insertions(+), 121 deletions(-)
New commits: commit 8f0638814d546acb3d8c9562d10445d43f40141f Author: Michael Weghorn <[email protected]> AuthorDate: Sat Jan 3 14:40:19 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sun Jan 4 15:04:00 2026 +0100 tdf#130857 weld: Block signals in Entry::replace_selection So far, weld::TextView::replace_selection was blocking signals, by not being virtual itself but calling a virtual helper method weld::TextView::do_replace_selection and blocking signals while doing so, while weld::Entry didn't do that. The weld::TextView behavior is consistent with how signals are handled elsewhere (only emitted on user-triggered changes, not programmatic ones). Therefore, align the weld::Entry behavior with the weld::TextView one, and move the logic to the common base class, weld::TextWidget. It seems unlikely that any existing code using weld::Entry would rely on signals being emitted, but if that turns out to be the case (i.e. behavior regresses with this commit), that code should probably be adjusted as necessary. This also prepares for implementing clipboard-related methods directly in the weld::TextWidget base class in an upcoming commit. Change-Id: I566c70bd98bbb92430107b1d40f9ee338fdbd749 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196451 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld/Entry.hxx b/include/vcl/weld/Entry.hxx index f6da7bb7e542..b11d3d612701 100644 --- a/include/vcl/weld/Entry.hxx +++ b/include/vcl/weld/Entry.hxx @@ -38,8 +38,6 @@ public: // The maximum length of the entry. Use 0 for no maximum virtual void set_max_length(int nChars) = 0; - virtual void replace_selection(const OUString& rText) = 0; - // nCursorPos can be -1 to set to the end void set_position(int nCursorPos); diff --git a/include/vcl/weld/TextView.hxx b/include/vcl/weld/TextView.hxx index a9ba66e37af8..319b929dfeff 100644 --- a/include/vcl/weld/TextView.hxx +++ b/include/vcl/weld/TextView.hxx @@ -34,11 +34,7 @@ protected: void signal_vadjustment_value_changed() { m_aVValueChangeHdl.Call(*this); } - virtual void do_replace_selection(const OUString& rText) = 0; - public: - void replace_selection(const OUString& rText); - virtual void set_monospace(bool bMonospace) = 0; // The maximum length of the entry. Use 0 for no maximum virtual void set_max_length(int nChars) = 0; diff --git a/include/vcl/weld/TextWidget.hxx b/include/vcl/weld/TextWidget.hxx index d7e61b77a8c5..8301868272d3 100644 --- a/include/vcl/weld/TextWidget.hxx +++ b/include/vcl/weld/TextWidget.hxx @@ -23,6 +23,7 @@ private: protected: virtual void do_set_text(const OUString& rText) = 0; virtual void do_select_region(int nStartPos, int nEndPos) = 0; + virtual void do_replace_selection(const OUString& rText) = 0; public: void set_text(const OUString& rText); @@ -31,6 +32,8 @@ public: // if nStartPos or nEndPos is -1 the max available text pos will be used void select_region(int nStartPos, int nEndPos); + void replace_selection(const OUString& rText); + // returns true if the selection has nonzero length virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0; diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 209fd4ede7ed..f2d978c57e1b 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -546,7 +546,7 @@ public: bool bTakeOwnership); virtual void do_set_text(const OUString& rText) override; void set_text_without_notify(const OUString& rText); - virtual void replace_selection(const OUString& rText) override; + virtual void do_replace_selection(const OUString& rText) override; }; class JSListBox final : public JSWidget<SalInstanceComboBoxWithoutEdit, ::ListBox> diff --git a/vcl/inc/qt5/QtInstanceEntry.hxx b/vcl/inc/qt5/QtInstanceEntry.hxx index fb7714312f59..b3e304953a41 100644 --- a/vcl/inc/qt5/QtInstanceEntry.hxx +++ b/vcl/inc/qt5/QtInstanceEntry.hxx @@ -31,7 +31,7 @@ public: virtual void set_max_length(int nChars) override; virtual void do_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 do_replace_selection(const OUString& rText) override; virtual void do_set_position(int nCursorPos) override; virtual int get_position() const override; virtual void set_editable(bool bEditable) override; diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 47db40b633c9..c3de55bcc50d 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -635,7 +635,7 @@ public: bool get_selection_bounds(int& rStartPos, int& rEndPos) override; - virtual void replace_selection(const OUString& rText) override; + virtual void do_replace_selection(const OUString& rText) override; virtual void do_set_position(int nCursorPos) override; diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 7dba2811a21f..c0c7daa1d9c0 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -1234,9 +1234,9 @@ void JSEntry::do_set_text(const OUString& rText) void JSEntry::set_text_without_notify(const OUString& rText) { SalInstanceEntry::set_text(rText); } -void JSEntry::replace_selection(const OUString& rText) +void JSEntry::do_replace_selection(const OUString& rText) { - SalInstanceEntry::replace_selection(rText); + SalInstanceEntry::do_replace_selection(rText); sendUpdate(); } diff --git a/vcl/qt5/QtInstanceEntry.cxx b/vcl/qt5/QtInstanceEntry.cxx index 5775bf86457c..daef32e454e8 100644 --- a/vcl/qt5/QtInstanceEntry.cxx +++ b/vcl/qt5/QtInstanceEntry.cxx @@ -84,7 +84,7 @@ bool QtInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos) return bHasSelection; } -void QtInstanceEntry::replace_selection(const OUString& rText) +void QtInstanceEntry::do_replace_selection(const OUString& rText) { SolarMutexGuard g; GetQtInstance().RunInMainThread([&] { m_pLineEdit->insert(toQString(rText)); }); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index e680bcc94347..b4ad6de38000 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -3321,7 +3321,7 @@ bool SalInstanceEntry::get_selection_bounds(int& rStartPos, int& rEndPos) return rSelection.Len(); } -void SalInstanceEntry::replace_selection(const OUString& rText) +void SalInstanceEntry::do_replace_selection(const OUString& rText) { m_xEntry->ReplaceSelected(rText); } diff --git a/vcl/source/weld/TextView.cxx b/vcl/source/weld/TextView.cxx index 6ecf726d7788..1bf968508314 100644 --- a/vcl/source/weld/TextView.cxx +++ b/vcl/source/weld/TextView.cxx @@ -11,13 +11,6 @@ namespace weld { -void weld::TextView::replace_selection(const OUString& rText) -{ - disable_notify_events(); - do_replace_selection(rText); - enable_notify_events(); -} - int weld::TextView::get_height_rows(int nRows) const { // can improve this if needed diff --git a/vcl/source/weld/TextWidget.cxx b/vcl/source/weld/TextWidget.cxx index 0e1f3e33280a..6d7c496ad334 100644 --- a/vcl/source/weld/TextWidget.cxx +++ b/vcl/source/weld/TextWidget.cxx @@ -24,6 +24,13 @@ void TextWidget::select_region(int nStartPos, int nEndPos) do_select_region(nStartPos, nEndPos); enable_notify_events(); } + +void TextWidget::replace_selection(const OUString& rText) +{ + disable_notify_events(); + do_replace_selection(rText); + enable_notify_events(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 2bb7be7c01bf..bdca8f4734b4 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -13168,7 +13168,7 @@ public: return gtk_editable_get_selection_bounds(m_pEditable, &rStartPos, &rEndPos); } - virtual void replace_selection(const OUString& rText) override + virtual void do_replace_selection(const OUString& rText) override { disable_notify_events(); gtk_editable_delete_selection(m_pEditable); commit b8461991d5ba4e005e298955dba80df194bc0208 Author: Michael Weghorn <[email protected]> AuthorDate: Sat Jan 3 14:13:22 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sun Jan 4 15:03:50 2026 +0100 tdf#130857 weld: Move some Entry and TextView logic to new TextWidget base weld::Entry and weld::TextView have quite some logic that is the same for both classes. Introduce weld::TextWidget as new abstract base class for both classes and move some logic there, in order to deduplicate that and ensure the API for both classes stays consistent (as now, both are changed at the same time when the signature for any common method is changed). weld::Entry::get_saved_value didn't have a weld::TextView equivalent before, so this is implicitly added with this commit. This refactoring also prepares for implementing clipboard-related methods directly in the weld::TextWidget base class in an upcoming commit. Change-Id: I68cbea4c9bb1438976f7473bd752e07175ee91dc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196450 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld/Entry.hxx b/include/vcl/weld/Entry.hxx index e670ed062500..f6da7bb7e542 100644 --- a/include/vcl/weld/Entry.hxx +++ b/include/vcl/weld/Entry.hxx @@ -10,15 +10,12 @@ #pragma once #include <vcl/dllapi.h> -#include <vcl/weld/weld.hxx> +#include <vcl/weld/TextWidget.hxx> namespace weld { -class VCL_DLLPUBLIC Entry : virtual public Widget +class VCL_DLLPUBLIC Entry : virtual public TextWidget { -private: - OUString m_sSavedValue; - protected: Link<Entry&, void> m_aChangeHdl; Link<OUString&, bool> m_aInsertTextHdl; @@ -33,32 +30,20 @@ protected: void signal_cursor_position(); - virtual void do_set_text(const OUString& rText) = 0; - virtual void do_select_region(int nStartPos, int nEndPos) = 0; virtual void do_set_position(int nCursorPos) = 0; public: - void set_text(const OUString& rText); - - virtual OUString get_text() const = 0; virtual void set_width_chars(int nChars) = 0; virtual int get_width_chars() const = 0; // The maximum length of the entry. Use 0 for no maximum virtual void set_max_length(int nChars) = 0; - // nEndPos can be -1 in order to select all text - void select_region(int nStartPos, int nEndPos); - - // returns true if the selection has nonzero length - virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0; virtual void replace_selection(const OUString& rText) = 0; // nCursorPos can be -1 to set to the end void set_position(int nCursorPos); virtual int get_position() const = 0; - virtual void set_editable(bool bEditable) = 0; - virtual bool get_editable() const = 0; virtual void set_visibility(bool bVisible) = 0; virtual void set_message_type(EntryMessageType eType) = 0; virtual void set_placeholder_text(const OUString& rText) = 0; @@ -66,19 +51,6 @@ public: virtual void set_overwrite_mode(bool bOn) = 0; virtual bool get_overwrite_mode() const = 0; - // font size is in points, not pixels, e.g. see Window::[G]etPointFont - virtual void set_font(const vcl::Font& rFont) = 0; - - /* - If you want to set a warning or error state, see set_message_type - instead where, if the toolkit supports it, a specific warning/error - indicator is shown. - - This explicit text color method exists to support rendering the - SvNumberformat color feature. - */ - virtual void set_font_color(const Color& rColor) = 0; - virtual void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; } void connect_insert_text(const Link<OUString&, bool>& rLink) { m_aInsertTextHdl = rLink; } // callback returns true to indicated no further processing of activate wanted @@ -88,15 +60,7 @@ public: m_aCursorPositionHdl = rLink; } - virtual void cut_clipboard() = 0; - virtual void copy_clipboard() = 0; - virtual void paste_clipboard() = 0; - virtual void set_alignment(TxtAlign eXAlign) = 0; - - void save_value() { m_sSavedValue = get_text(); } - OUString const& get_saved_value() const { return m_sSavedValue; } - bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); } }; } diff --git a/include/vcl/weld/TextView.hxx b/include/vcl/weld/TextView.hxx index b92edf238853..a9ba66e37af8 100644 --- a/include/vcl/weld/TextView.hxx +++ b/include/vcl/weld/TextView.hxx @@ -10,17 +10,14 @@ #pragma once #include <vcl/dllapi.h> -#include <vcl/weld/weld.hxx> +#include <vcl/weld/TextWidget.hxx> namespace weld { -class VCL_DLLPUBLIC TextView : virtual public Widget +class VCL_DLLPUBLIC TextView : virtual public TextWidget { friend class ::LOKTrigger; -private: - OUString m_sSavedValue; - protected: Link<TextView&, void> m_aChangeHdl; Link<TextView&, void> m_aVValueChangeHdl; @@ -37,41 +34,16 @@ protected: void signal_vadjustment_value_changed() { m_aVValueChangeHdl.Call(*this); } - virtual void do_set_text(const OUString& rText) = 0; - virtual void do_select_region(int nStartPos, int nEndPos) = 0; virtual void do_replace_selection(const OUString& rText) = 0; public: - void set_text(const OUString& rText); - virtual OUString get_text() const = 0; - - // if nStartPos or nEndPos is -1 the max available text pos will be used - void select_region(int nStartPos, int nEndPos); - - // returns true if the selection has nonzero length - virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0; - void replace_selection(const OUString& rText); - virtual void set_editable(bool bEditable) = 0; - virtual bool get_editable() const = 0; virtual void set_monospace(bool bMonospace) = 0; // The maximum length of the entry. Use 0 for no maximum virtual void set_max_length(int nChars) = 0; int get_height_rows(int nRows) const; - // font size is in points, not pixels, e.g. see Window::[G]etPointFont - virtual void set_font(const vcl::Font& rFont) = 0; - - /* - Typically you want to avoid the temptation of customizing - font colors - */ - virtual void set_font_color(const Color& rColor) = 0; - - void save_value() { m_sSavedValue = get_text(); } - bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); } - void connect_changed(const Link<TextView&, void>& rLink) { m_aChangeHdl = rLink; } virtual void connect_cursor_position(const Link<TextView&, void>& rLink) { @@ -88,10 +60,6 @@ public: // current line just so long as the cursor would move virtual bool can_move_cursor_with_down() const = 0; - virtual void cut_clipboard() = 0; - virtual void copy_clipboard() = 0; - virtual void paste_clipboard() = 0; - virtual void set_alignment(TxtAlign eXAlign) = 0; virtual int vadjustment_get_value() const = 0; diff --git a/include/vcl/weld/TextWidget.hxx b/include/vcl/weld/TextWidget.hxx new file mode 100644 index 000000000000..d7e61b77a8c5 --- /dev/null +++ b/include/vcl/weld/TextWidget.hxx @@ -0,0 +1,63 @@ +/* -*- 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 <vcl/dllapi.h> +#include <vcl/weld/weld.hxx> + +namespace weld +{ +/* Abstract base class for Entry and TextView. */ +class VCL_DLLPUBLIC TextWidget : virtual public Widget +{ +private: + OUString m_sSavedValue; + +protected: + virtual void do_set_text(const OUString& rText) = 0; + virtual void do_select_region(int nStartPos, int nEndPos) = 0; + +public: + void set_text(const OUString& rText); + virtual OUString get_text() const = 0; + + // if nStartPos or nEndPos is -1 the max available text pos will be used + void select_region(int nStartPos, int nEndPos); + + // returns true if the selection has nonzero length + virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0; + + virtual void set_editable(bool bEditable) = 0; + virtual bool get_editable() const = 0; + + // font size is in points, not pixels, e.g. see Window::[G]etPointFont + virtual void set_font(const vcl::Font& rFont) = 0; + + /* + Typically you want to avoid the temptation of customizing + font colors. + + For the Entry subclass, if you want to set a warning or error state, + see Entry::set_message_type instead where, if the toolkit supports it, + a specific warning/error indicator is shown. + */ + virtual void set_font_color(const Color& rColor) = 0; + + virtual void cut_clipboard() = 0; + virtual void copy_clipboard() = 0; + virtual void paste_clipboard() = 0; + + void save_value() { m_sSavedValue = get_text(); } + OUString const& get_saved_value() const { return m_sSavedValue; } + bool get_value_changed_from_saved() const { return m_sSavedValue != get_text(); } +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 1856a82ea221..3375b960715d 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -594,6 +594,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/weld/MetricSpinButton \ vcl/source/weld/SpinButton \ vcl/source/weld/TextView \ + vcl/source/weld/TextWidget \ vcl/source/weld/TreeView \ vcl/source/weld/weldutils \ vcl/backendtest/outputdevice/bitmap \ diff --git a/vcl/source/weld/Entry.cxx b/vcl/source/weld/Entry.cxx index 4b5497b67325..7fdfbdf1ac5c 100644 --- a/vcl/source/weld/Entry.cxx +++ b/vcl/source/weld/Entry.cxx @@ -32,20 +32,6 @@ void Entry::signal_cursor_position() m_aCursorPositionHdl.Call(*this); } -void Entry::set_text(const OUString& rText) -{ - disable_notify_events(); - do_set_text(rText); - enable_notify_events(); -} - -void Entry::select_region(int nStartPos, int nEndPos) -{ - disable_notify_events(); - do_select_region(nStartPos, nEndPos); - enable_notify_events(); -} - void Entry::set_position(int nCursorPos) { disable_notify_events(); diff --git a/vcl/source/weld/TextView.cxx b/vcl/source/weld/TextView.cxx index 55c390f78b08..6ecf726d7788 100644 --- a/vcl/source/weld/TextView.cxx +++ b/vcl/source/weld/TextView.cxx @@ -11,20 +11,6 @@ namespace weld { -void weld::TextView::set_text(const OUString& rText) -{ - disable_notify_events(); - do_set_text(rText); - enable_notify_events(); -} - -void weld::TextView::select_region(int nStartPos, int nEndPos) -{ - disable_notify_events(); - do_select_region(nStartPos, nEndPos); - enable_notify_events(); -} - void weld::TextView::replace_selection(const OUString& rText) { disable_notify_events(); diff --git a/vcl/source/weld/TextWidget.cxx b/vcl/source/weld/TextWidget.cxx new file mode 100644 index 000000000000..0e1f3e33280a --- /dev/null +++ b/vcl/source/weld/TextWidget.cxx @@ -0,0 +1,29 @@ +/* -*- 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 <vcl/weld/TextWidget.hxx> + +namespace weld +{ +void TextWidget::set_text(const OUString& rText) +{ + disable_notify_events(); + do_set_text(rText); + enable_notify_events(); +} + +void TextWidget::select_region(int nStartPos, int nEndPos) +{ + disable_notify_events(); + do_select_region(nStartPos, nEndPos); + enable_notify_events(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
