vcl/inc/qt5/QtDoubleSpinBox.hxx | 9 +------ vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx | 5 +++ vcl/inc/qt5/QtInstanceSpinButton.hxx | 1 vcl/qt5/QtDoubleSpinBox.cxx | 9 +------ vcl/qt5/QtInstanceBuilder.cxx | 1 vcl/qt5/QtInstanceFormattedSpinButton.cxx | 33 ++++++++++++++++++++++---- vcl/qt5/QtInstanceSpinButton.cxx | 12 +++++++-- 7 files changed, 50 insertions(+), 20 deletions(-)
New commits: commit d1f97a537b576454b2d93406d372cc4ed36d0b32 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Feb 20 20:36:23 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Feb 20 23:23:16 2025 +0100 tdf#130857 qt weld: Support Impress slide show settings 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 uses a weld::FormattedSpinButton with a TimeFormatter for which support has been implemented in previous commits up to Change-Id: Idde78409b6e4564521e96c8ef9947492b6a33e63 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Thu Feb 20 20:02:50 2025 +0100 tdf#130857 qt weld: Allow typing spinbox value when TimeFormatter is used Sample steps to trigger the dialog and interact with the spinbox: * start Impress * "Slide Show" -> "Slide Show Settings" * check the "Loop and repeat after" checkbox in the "Presentation Mode" frame * select all text in the spinbutton * type "1:2:3" for a time of "01:02:03" to be set Change-Id: I2d1552d4bc5a97da38ddb3678f20aa2a1faeb014 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181966 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 727f34e1d645..a9ddf3955f1b 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -86,6 +86,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile) u"modules/scalc/ui/selectsource.ui"_ustr, u"modules/scalc/ui/showsheetdialog.ui"_ustr, 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/fontsizedialog.ui"_ustr, u"modules/smath/ui/savedefaultsdialog.ui"_ustr, commit 3e3fae39dc7f9f88b88dce8fc3fe06652be51228 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Feb 20 20:31:57 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Feb 20 23:23:10 2025 +0100 tdf#130857 qt weld: Consistently use QString in QtDoubleSpinBox Switch uses of OUString in QtDoubleSpinBox to QString and drop includes for LO-specific types. Instead, let QtInstance{Formatted}SpinButton take care of the QString <-> OUString conversion. Change-Id: I2b3cc2e2fd855c890b7a808f955bff33c855a4cd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181965 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtDoubleSpinBox.hxx b/vcl/inc/qt5/QtDoubleSpinBox.hxx index 4e8938f86980..190587446b92 100644 --- a/vcl/inc/qt5/QtDoubleSpinBox.hxx +++ b/vcl/inc/qt5/QtDoubleSpinBox.hxx @@ -9,11 +9,6 @@ #pragma once -class QtInstanceSpinButton; - -#include <rtl/ustring.hxx> -#include <tools/gen.hxx> - #include <QtWidgets/QDoubleSpinBox> #include <QtWidgets/QLineEdit> #include <QtWidgets/QWidget> @@ -24,7 +19,7 @@ class QtDoubleSpinBox : public QDoubleSpinBox { Q_OBJECT - std::function<std::optional<OUString>(double)> m_aFormatValueFunction; + std::function<std::optional<QString>(double)> m_aFormatValueFunction; std::function<std::optional<double>(const QString&)> m_aParseTextFunction; public: @@ -37,7 +32,7 @@ public: virtual double valueFromText(const QString& rText) const override; virtual QValidator::State validate(QString& rInput, int& rPos) const override; - void setFormatValueFunction(std::function<std::optional<OUString>(double)> aFunction) + void setFormatValueFunction(std::function<std::optional<QString>(double)> aFunction) { m_aFormatValueFunction = aFunction; } diff --git a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx index 68a36bf451cf..31bf37f58909 100644 --- a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx +++ b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx @@ -39,7 +39,7 @@ public: virtual void sync_increments_from_formatter() override; private: - OUString formatValue(double fValue); + QString formatValue(double fValue); private Q_SLOTS: void handleValueChanged(); diff --git a/vcl/inc/qt5/QtInstanceSpinButton.hxx b/vcl/inc/qt5/QtInstanceSpinButton.hxx index 4664a3fcf5c7..d1f6c76751df 100644 --- a/vcl/inc/qt5/QtInstanceSpinButton.hxx +++ b/vcl/inc/qt5/QtInstanceSpinButton.hxx @@ -39,6 +39,7 @@ public: private: std::optional<double> convertTextToDouble(const QString& rText); + std::optional<QString> formatValue(double fValue); private Q_SLOTS: void handleValueChanged(); diff --git a/vcl/qt5/QtDoubleSpinBox.cxx b/vcl/qt5/QtDoubleSpinBox.cxx index adf8193a89f7..88dc97319653 100644 --- a/vcl/qt5/QtDoubleSpinBox.cxx +++ b/vcl/qt5/QtDoubleSpinBox.cxx @@ -9,11 +9,6 @@ #include <QtDoubleSpinBox.hxx> #include <QtDoubleSpinBox.moc> -#include <QtInstanceSpinButton.hxx> - -#include <QtTools.hxx> - -#include <vcl/qt/QtUtils.hxx> QtDoubleSpinBox::QtDoubleSpinBox(QWidget* pParent) : QDoubleSpinBox(pParent) @@ -28,9 +23,9 @@ QString QtDoubleSpinBox::textFromValue(double fValue) const { if (m_aFormatValueFunction) { - std::optional<OUString> aText = m_aFormatValueFunction(fValue); + std::optional<QString> aText = m_aFormatValueFunction(fValue); if (aText.has_value()) - return toQString(aText.value()); + return aText.value(); } return QDoubleSpinBox::textFromValue(fValue); diff --git a/vcl/qt5/QtInstanceFormattedSpinButton.cxx b/vcl/qt5/QtInstanceFormattedSpinButton.cxx index 612b276cae8b..c1132ccc1ea2 100644 --- a/vcl/qt5/QtInstanceFormattedSpinButton.cxx +++ b/vcl/qt5/QtInstanceFormattedSpinButton.cxx @@ -10,6 +10,8 @@ #include <QtInstanceFormattedSpinButton.hxx> #include <QtInstanceFormattedSpinButton.moc> +#include <vcl/qt/QtUtils.hxx> + QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox* pSpinBox) : QtInstanceEntry(pSpinBox->lineEdit()) , m_pSpinBox(pSpinBox) @@ -124,7 +126,7 @@ void QtInstanceFormattedSpinButton::sync_increments_from_formatter() }); } -OUString QtInstanceFormattedSpinButton::formatValue(double fValue) +QString QtInstanceFormattedSpinButton::formatValue(double fValue) { SolarMutexGuard g; @@ -141,7 +143,7 @@ OUString QtInstanceFormattedSpinButton::formatValue(double fValue) sText = GetFormatter().FormatValue(fValue); }); - return sText; + return toQString(sText); } void QtInstanceFormattedSpinButton::handleValueChanged() diff --git a/vcl/qt5/QtInstanceSpinButton.cxx b/vcl/qt5/QtInstanceSpinButton.cxx index 98cc11262c30..3305c5f5e5de 100644 --- a/vcl/qt5/QtInstanceSpinButton.cxx +++ b/vcl/qt5/QtInstanceSpinButton.cxx @@ -35,8 +35,7 @@ QtInstanceSpinButton::QtInstanceSpinButton(QtDoubleSpinBox* pSpinBox) &QtInstanceSpinButton::handleTextChanged); // set functions to convert between value and formatted text - m_pSpinBox->setFormatValueFunction( - [this](double fValue) { return format_floating_point_value(fValue); }); + m_pSpinBox->setFormatValueFunction([this](double fValue) { return formatValue(fValue); }); m_pSpinBox->setParseTextFunction( [this](const QString& rText) { return convertTextToDouble(rText); }); } @@ -117,6 +116,15 @@ std::optional<double> QtInstanceSpinButton::convertTextToDouble(const QString& r return {}; } +std::optional<QString> QtInstanceSpinButton::formatValue(double fValue) +{ + std::optional<OUString> aText = format_floating_point_value(fValue); + if (!aText.has_value()) + return {}; + + return std::optional<QString>(toQString(aText.value())); +} + void QtInstanceSpinButton::handleValueChanged() { SolarMutexGuard aGuard; commit e1a864dafa0753c6ccab2559f1ae7d0742f3ee7f Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Feb 20 20:02:50 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Feb 20 23:23:04 2025 +0100 tdf#130857 qt weld: Allow typing spinbox value when TimeFormatter is used So far, when trying to manually insert/edit text in a QtInstanceFormattedSpinButton (its QtDoubleSpinBox widget), that didn't work as expected when TimeFormatter is used for it formatter, e.g. for the following scenario with upcoming Change-Id: I2d1552d4bc5a97da38ddb3678f20aa2a1faeb014 Author: Michael Weghorn <m.wegh...@posteo.de> tdf#130857 qt weld: Support Impress slide show settings dialog in place: * start Impress * "Slide Show" -> "Slide Show Settings" * check the "Loop and repeat after" checkbox in the "Presentation Mode" frame * select all text in the spinbutton * type "1:2:3" The text typed didn't appear as expected because it was already replaced by other text before finishing typing. This is because weld::TimeFormatter reacts to cursor position changes in the spinbutton edit/entry (s. weld::TimeFormatter::CursorChangedHdl in frame 18 in the below backtrace) and calls QtInstanceFormattedSpinButton::sync_increments_from_formatter (frame 16) which calls QDoubleSpinBox::setSingleStep (frame 9) which is Qt-internal and calls QAbstractSpinBoxPrivate::updateEdit (8) which updates the text in the spinbox with the one returned by QtDoubleSpinBox::textFromValue (s. frame 6). Changing the text just because the cursor moves while typing is not desirable. Prevent that by introducing a QtInstanceFormattedSpinButton::m_bInSetSingleStep member to detect that case and simply returning the current spinbox text (instead of formatting the passed value) in the function that is responsible for converting a value into display text. With this commit (and the upcoming change to support the dialog), the scenario above now results in a time value of "01:02:03" being set in the spinbox, as is the case with the GTK or VCL implementations as well. 1 QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0::operator()(double) const QtInstanceFormattedSpinButton.cxx 38 0x7fffe43ddbc7 2 std::__invoke_impl<rtl::OUString, QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0&, double>(std::__invoke_other, QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0&, double&&) invoke.h 61 0x7fffe43ddb8c 3 std::__invoke_r<std::optional<rtl::OUString>, QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0&, double>(QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0&, double&&) invoke.h 114 0x7fffe43ddaf1 4 std::_Function_handler<std::optional<rtl::OUString>(double), QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox *)::$_0>::_M_invoke std_function.h 290 0x7fffe43dd9e8 5 std::function<std::optional<rtl::OUString>(double)>::operator() std_function.h 591 0x7fffe432f159 6 QtDoubleSpinBox::textFromValue QtDoubleSpinBox.cxx 31 0x7fffe432eddd 7 QDoubleSpinBoxPrivate::textFromValue qspinbox.cpp 1400 0x7fffe17d2616 8 QAbstractSpinBoxPrivate::updateEdit qabstractspinbox.cpp 1784 0x7fffe17c95ba 9 QDoubleSpinBox::setSingleStep qspinbox.cpp 780 0x7fffe17d0635 10 QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0::operator()() const QtInstanceFormattedSpinButton.cxx 120 0x7fffe43df11c 11 std::__invoke_impl<void, QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0&>(std::__invoke_other, QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0&) invoke.h 61 0x7fffe43df0d5 12 std::__invoke_r<void, QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0&>(QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0&) invoke.h 111 0x7fffe43df085 13 std::_Function_handler<void(), QtInstanceFormattedSpinButton::sync_increments_from_formatter()::$_0>::_M_invoke std_function.h 290 0x7fffe43defad 14 std::function<void()>::operator() std_function.h 591 0x7fffe439195e 15 QtInstance::RunInMainThread QtInstance.cxx 206 0x7fffe438946f 16 QtInstanceFormattedSpinButton::sync_increments_from_formatter QtInstanceFormattedSpinButton.cxx 118 0x7fffe43dd78b 17 weld::EntryFormatter::SetSpinSize weldutils.cxx 230 0x7fffeecbcba2 18 weld::TimeFormatter::CursorChangedHdl field2.cxx 3183 0x7fffee51ef57 19 weld::TimeFormatter::LinkStubCursorChangedHdl field2.cxx 3166 0x7fffee51ee2d 20 Link<weld::Entry&, void>::Call link.hxx 105 0x7fffe43d8e61 21 weld::Entry::signal_cursor_position weld.hxx 1795 0x7fffe43d8ecc 22 QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0::operator()() const QtInstanceEntry.cxx 24 0x7fffe43d566f 23 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0>::call(QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0&, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 116 0x7fffe43d5648 24 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0>::call(QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0&, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0>::call(QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0&, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7fffe43d5629 25 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0>::call(QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0&, void * *) qobjectdefs_impl.h 115 0x7fffe43d55f2 26 QtPrivate::FunctorCallable<QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0>::call<QtPrivate::List<>, void>(QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0&, void *, void * *) qobjectdefs_impl.h 337 0x7fffe43d55a1 27 QtPrivate::QCallableObject<QtInstanceEntry::QtInstanceEntry(QLineEdit *)::$_0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 547 0x7fffe43d5548 28 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7fffe3303c22 29 doActivate<false> qobject.cpp 4223 0x7fffe3521c84 30 QMetaObject::activate qobject.cpp 4283 0x7fffe3517e93 31 QMetaObject::activate<void, int, int> qobjectdefs.h 319 0x7fffe163a675 32 QLineEdit::cursorPositionChanged moc_qlineedit.cpp 345 0x7fffe16fbbe4 33 QLineEditPrivate::cursorPositionChanged qlineedit_p.cpp 139 0x7fffe1702cdb 34 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul>, QtPrivate::List<int, int>, void, void (QLineEditPrivate:: *)(int, int)>::call(void (QLineEditPrivate:: *)(int, int), QLineEditPrivate *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 127 0x7fffe170aac7 35 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul>, QtPrivate::List<int, int>, void, void (QLineEditPrivate:: *)(int, int)>::call(void (QLineEditPrivate:: *)(int, int), QLineEditPrivate *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul>, QtPrivate::List<int, int>, void, void (QLineEditPrivate:: *)(int, int)>::call(void (QLineEditPrivate:: *)(int, int), QLineEditPrivate *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7fffe170aa2d 36 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul>, QtPrivate::List<int, int>, void, void (QLineEditPrivate:: *)(int, int)>::call qobjectdefs_impl.h 126 0x7fffe170a9e7 37 QtPrivate::FunctionPointer<void (QLineEditPrivate:: *)(int, int)>::call<QtPrivate::List<int, int>, void> qobjectdefs_impl.h 174 0x7fffe170a951 38 QtPrivate::QPrivateSlotObject<void (QLineEditPrivate:: *)(int, int), QtPrivate::List<int, int>, void>::impl qobject_p.h 272 0x7fffe170a880 39 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7fffe3303c22 40 doActivate<false> qobject.cpp 4223 0x7fffe3521c84 41 QMetaObject::activate qobject.cpp 4283 0x7fffe3517e93 42 QMetaObject::activate<void, int, int> qobjectdefs.h 319 0x7fffe163a675 43 QWidgetLineControl::cursorPositionChanged moc_qwidgetlinecontrol_p.cpp 192 0x7fffe171494f 44 QWidgetLineControl::emitCursorPositionChanged qwidgetlinecontrol.cpp 1400 0x7fffe1710bdc 45 QWidgetLineControl::moveCursor qwidgetlinecontrol.cpp 471 0x7fffe17118b1 46 QLineEdit::mousePressEvent qlineedit.cpp 1536 0x7fffe16f685d 47 QWidget::event qwidget.cpp 8960 0x7fffe14a09d1 48 QLineEdit::event qlineedit.cpp 1493 0x7fffe16f64c8 49 QApplicationPrivate::notify_helper qapplication.cpp 3309 0x7fffe13e2e80 50 QApplication::notify qapplication.cpp 2786 0x7fffe13e4b52 51 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1100 0x7fffe344c429 52 QCoreApplication::sendSpontaneousEvent qcoreapplication.cpp 1554 0x7fffe344d129 53 QApplicationPrivate::sendMouseEvent qapplication.cpp 2367 0x7fffe13e37a7 54 QWidgetWindow::handleMouseEvent qwidgetwindow.cpp 669 0x7fffe14dffc8 [...] Change-Id: Idde78409b6e4564521e96c8ef9947492b6a33e63 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181964 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx index 1ae5add3b3ac..68a36bf451cf 100644 --- a/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx +++ b/vcl/inc/qt5/QtInstanceFormattedSpinButton.hxx @@ -23,6 +23,8 @@ class QtInstanceFormattedSpinButton : public QtInstanceEntry, std::unique_ptr<weld::EntryFormatter> m_xOwnFormatter; weld::EntryFormatter* m_pFormatter; + bool m_bInSetSingleStep = false; + public: QtInstanceFormattedSpinButton(QtDoubleSpinBox* pSpinBox); virtual ~QtInstanceFormattedSpinButton(); @@ -36,6 +38,9 @@ public: virtual void sync_value_from_formatter() override; virtual void sync_increments_from_formatter() override; +private: + OUString formatValue(double fValue); + private Q_SLOTS: void handleValueChanged(); }; diff --git a/vcl/qt5/QtInstanceFormattedSpinButton.cxx b/vcl/qt5/QtInstanceFormattedSpinButton.cxx index b56a973c3383..612b276cae8b 100644 --- a/vcl/qt5/QtInstanceFormattedSpinButton.cxx +++ b/vcl/qt5/QtInstanceFormattedSpinButton.cxx @@ -34,8 +34,7 @@ QtInstanceFormattedSpinButton::QtInstanceFormattedSpinButton(QtDoubleSpinBox* pS &QtInstanceFormattedSpinButton::handleTextChanged); // set functions to convert between value and formatted text - m_pSpinBox->setFormatValueFunction( - [this](double fValue) { return GetFormatter().FormatValue(fValue); }); + m_pSpinBox->setFormatValueFunction([this](double fValue) { return formatValue(fValue); }); m_pSpinBox->setParseTextFunction( [this](const QString& rText) { return GetFormatter().ParseText(toOUString(rText)); }); } @@ -116,9 +115,33 @@ void QtInstanceFormattedSpinButton::sync_increments_from_formatter() SolarMutexGuard g; GetQtInstance().RunInMainThread([&] { - if (m_pFormatter) - m_pSpinBox->setSingleStep(m_pFormatter->GetSpinSize()); + if (!m_pFormatter) + return; + + m_bInSetSingleStep = true; + m_pSpinBox->setSingleStep(m_pFormatter->GetSpinSize()); + m_bInSetSingleStep = false; + }); +} + +OUString QtInstanceFormattedSpinButton::formatValue(double fValue) +{ + SolarMutexGuard g; + + OUString sText; + GetQtInstance().RunInMainThread([&] { + // If the formatter is a TimeFormatter, its CursorChangedHdl would trigger + // an update of the text via QDoubleSpinBox::setSingleStep that calls + // QAbstractSpinBoxPrivate::updateEdit, which would replace text that is currently + // being typed. + // Detect that case and simply return the current text. + if (m_bInSetSingleStep) + sText = toOUString(m_pSpinBox->text()); + else + sText = GetFormatter().FormatValue(fValue); }); + + return sText; } void QtInstanceFormattedSpinButton::handleValueChanged()