include/vcl/weld.hxx | 7 ++++++- sc/source/ui/StatisticsDialogs/FTestDialog.cxx | 4 ++-- sc/source/ui/StatisticsDialogs/RegressionDialog.cxx | 8 ++++---- sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx | 6 +++--- sc/source/ui/StatisticsDialogs/TTestDialog.cxx | 4 ++-- sc/source/ui/StatisticsDialogs/ZTestDialog.cxx | 4 ++-- sc/source/ui/inc/StatisticsTwoVariableDialog.hxx | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-)
New commits: commit c0e7bf13239fadcb2db434ee80cd7d212646748f Author: Michael Weghorn <[email protected]> AuthorDate: Tue Oct 21 21:24:25 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Oct 22 07:23:01 2025 +0200 tdf#130857 qt weld: Don't call Entry::signal_changed while blocked As is the case for most of the signal handlers, don't call the actual handler in weld::Entry::signal_changed when signals are currently blocked. This means that e.g. when setting new text using weld::Entry::set_text, this will not result in the handler getting called. For the SalInstanceEntry case, weld::signal_changed wasn't called anyway, but for QtInstanceEntry that was the case, so this aligns the behavior by making sure that the handlers set in dialog implementations don't get called for the case of native Qt dialogs with SAL_VCL_QT_USE_WELDED_WIDGETS=1 either. The GTK implementation has its own logic that was preventing the method from getting called, as GtkInstanceEditable::do_set_text results in GtkInstanceEditable::disable_notify_events getting called, which blocks the signal handler with id GtkInstanceEditable::m_nChangedSignalId, which is the one that the GtkInstanceEditable ctor connects to the "changed" signal of the GtkEditable [1]. Prior to this commit, the dialog newly supported since commit d24e74b16b728ebca060bd5349cba945a55a018b Author: Michael Weghorn <[email protected]> Date: Fri Oct 17 17:57:17 2025 +0200 tdf#130857 qt weld: Support Calc "F-Test" dialog would behave differently for the qt6 VCL plugin with SAL_VCL_QT_USE_WELDED_WIDGETS=1: When starting the dialog using "Data" -> "Statistics" -> "F-Test" in Calc, then clicking the button to select a "Variable 1 range", then clicking into one cell and dragging the mouse to select more cells, only a single cell would ever be selected, instead of selecting all cells from the first to the last one the mouse was moved over while the left mouse button was still pressed. This was due to the weld::Entry::signal_changed getting called and calling the handler set in RefEdit. Relevant backtrace: 1 formula::RefEdit::LinkStubModify funcutl.cxx 348 0x7f2f9c458f30 2 Link<weld::Entry&, void>::Call link.hxx 105 0x7f2fd529c6f1 3 weld::Entry::signal_changed weld.hxx 2069 0x7f2fd529c3ac 4 QtInstanceEntry::handleTextChanged QtInstanceEntry.cxx 194 0x7f2fd52969cd 5 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceEntry:: *)()>::call(void (QtInstanceEntry:: *)(), QtInstanceEntry *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 127 0x7f2fd529cb61 6 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceEntry:: *)()>::call(void (QtInstanceEntry:: *)(), QtInstanceEntry *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceEntry:: *)()>::call(void (QtInstanceEntry:: *)(), QtInstanceEntry *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7f2fd529ca99 7 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceEntry:: *)()>::call(void (QtInstanceEntry:: *)(), QtInstanceEntry *, void * *) qobjectdefs_impl.h 126 0x7f2fd529c9cb 8 QtPrivate::FunctionPointer<void (QtInstanceEntry:: *)()>::call<QtPrivate::List<>, void>(void (QtInstanceEntry:: *)(), QtInstanceEntry *, void * *) qobjectdefs_impl.h 174 0x7f2fd529c94d 9 QtPrivate::QCallableObject<void (QtInstanceEntry:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 545 0x7f2fd529c876 10 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7f2fd40e9722 11 doActivate<false> qobject.cpp 4342 0x7f2fd4315812 12 QMetaObject::activate qobject.cpp 4402 0x7f2fd430bb23 13 QMetaObject::activate<void, QString> qobjectdefs.h 319 0x7f2fd22819bb 14 QLineEdit::textChanged moc_qlineedit.cpp 333 0x7f2fd24d299e 15 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<QString const&>, void, void (QLineEdit:: *)(QString const&)>::call(void (QLineEdit:: *)(QString const&), QLineEdit *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 127 0x7f2fd24e0f18 16 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<QString const&>, void, void (QLineEdit:: *)(QString const&)>::call(void (QLineEdit:: *)(QString const&), QLineEdit *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<QString const&>, void, void (QLineEdit:: *)(QString const&)>::call(void (QLineEdit:: *)(QString const&), QLineEdit *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7f2fd24e0e8d 17 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<QString const&>, void, void (QLineEdit:: *)(QString const&)>::call qobjectdefs_impl.h 126 0x7f2fd24e0e47 18 QtPrivate::FunctionPointer<void (QLineEdit:: *)(QString const&)>::call<QtPrivate::List<QString const&>, void> qobjectdefs_impl.h 174 0x7f2fd24e0db1 19 QtPrivate::QCallableObject<void (QLineEdit:: *)(QString const&), QtPrivate::List<QString const&>, void>::impl qobjectdefs_impl.h 545 0x7f2fd24e0cdb 20 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7f2fd40e9722 21 doActivate<false> qobject.cpp 4342 0x7f2fd4315812 22 QMetaObject::activate qobject.cpp 4402 0x7f2fd430bb23 23 QMetaObject::activate<void, QString> qobjectdefs.h 319 0x7f2fd22819bb 24 QWidgetLineControl::textChanged moc_qwidgetlinecontrol_p.cpp 211 0x7f2fd24e9911 25 QWidgetLineControl::finishChange qwidgetlinecontrol.cpp 716 0x7f2fd24e7006 26 QWidgetLineControl::internalSetText qwidgetlinecontrol.cpp 752 0x7f2fd24e876b 27 QWidgetLineControl::setText qwidgetlinecontrol_p.h 221 0x7f2fd24d5798 28 QLineEditPrivate::setText qlineedit_p.cpp 277 0x7f2fd24dad4a 29 QLineEdit::setText qlineedit.cpp 296 0x7f2fd24cb03e 30 QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0::operator()() const QtInstanceEntry.cxx 32 0x7f2fd5299156 31 std::__invoke_impl<void, QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0&>(std::__invoke_other, QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0&) invoke.h 63 0x7f2fd5299105 32 std::__invoke_r<void, QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0&>(QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0&) invoke.h 113 0x7f2fd52990b5 33 std::_Function_handler<void(), QtInstanceEntry::do_set_text(rtl::OUString const&)::$_0>::_M_invoke std_function.h 292 0x7f2fd5298fcd 34 std::function<void()>::operator() std_function.h 593 0x7f2fd522eb9e 35 QtInstance::RunInMainThread QtInstance.cxx 205 0x7f2fd5225dcf 36 QtInstanceEntry::do_set_text QtInstanceEntry.cxx 32 0x7f2fd529717a 37 weld::Entry::set_text weld.hxx 2086 0x7f2f9c439961 38 formula::RefEdit::SetRefString funcutl.cxx 293 0x7f2f9c45872f 39 ScStatisticsTwoVariableDialog::SetReference StatisticsTwoVariableDialog.cxx 161 0x7f2f7368d440 40 ScModule::SetReference scmod.cxx 1819 0x7f2f7324bdef 41 ScTabView::InitRefMode tabview4.cxx 385 0x7f2f73bb6cce 42 ScViewFunctionSet::SetCursorAtCell select.cxx 494 0x7f2f73b5f45a 43 ScViewFunctionSet::SetCursorAtPoint select.cxx 425 0x7f2f73b5f029 44 SelectionEngine::SelMouseButtonDown seleng.cxx 172 0x7f2fdd575f04 45 ScTabView::SelMouseButtonDown tabview3.cxx 1227 0x7f2f73ba1281 46 ScGridWindow::HandleMouseButtonDown gridwin.cxx 2219 0x7f2f73a495df 47 ScGridWindow::MouseButtonDown gridwin.cxx 1840 0x7f2f73a47e92 48 ImplHandleMouseEvent winproc.cxx 733 0x7f2fdd622d31 49 ImplHandleSalMouseButtonDown winproc.cxx 2365 0x7f2fdd6272e1 50 ImplWindowFrameProc winproc.cxx 2703 0x7f2fdd625f51 51 SalFrame::CallCallback salframe.hxx 310 0x7f2fd520721c 52 QtFrame::CallCallback QtFrame.hxx 234 0x7f2fd52040f5 53 QtWidget::handleMouseButtonEvent QtWidget.cxx 112 0x7f2fd537070a 54 QtWidget::mousePressEvent QtWidget.cxx 117 0x7f2fd537075e 55 QWidget::event qwidget.cpp 9021 0x7f2fd226f1d1 56 QtWidget::event QtWidget.cxx 501 0x7f2fd53723aa [...] With this commit in place, this works as expected now and a range of multiple cells can be selected this way. [1] https://docs.gtk.org/gtk3/signal.Editable.changed.html Change-Id: I9040eeac6979479b663756968693965cabf5c286 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192807 Reviewed-by: Michael Weghorn <[email protected]> Tested-by: Jenkins diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 893890d1268c..672307aca740 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -2066,7 +2066,12 @@ protected: friend class ::LOKTrigger; - void signal_changed() { m_aChangeHdl.Call(*this); } + void signal_changed() + { + if (notify_events_disabled()) + return; + m_aChangeHdl.Call(*this); + } void signal_cursor_position() { commit faea3b508ee90859f3702d01d93d7d96cce0526c Author: Michael Weghorn <[email protected]> AuthorDate: Tue Oct 21 21:17:07 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Oct 22 07:22:52 2025 +0200 sc: Make ScStatisticsTwoVariableDialog::GroupedBy an enum class Change-Id: Ic4af87637bd3a499a90319aea533a9e659481009 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192806 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/sc/source/ui/StatisticsDialogs/FTestDialog.cxx b/sc/source/ui/StatisticsDialogs/FTestDialog.cxx index a4e527dab9b3..cc6382400c06 100644 --- a/sc/source/ui/StatisticsDialogs/FTestDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/FTestDialog.cxx @@ -46,13 +46,13 @@ ScRange ScFTestDialog::ApplyOutput(ScDocShell& rDocShell) FormulaTemplate aTemplate(&mDocument); std::unique_ptr<DataRangeIterator> pVariable1Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable1Iterator.reset(new DataRangeByColumnIterator(mVariable1Range)); else pVariable1Iterator.reset(new DataRangeByRowIterator(mVariable1Range)); std::unique_ptr<DataRangeIterator> pVariable2Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable2Iterator.reset(new DataRangeByColumnIterator(mVariable2Range)); else pVariable2Iterator.reset(new DataRangeByRowIterator(mVariable2Range)); diff --git a/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx b/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx index b32e53a046f6..03d0fbdbc3a4 100644 --- a/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/RegressionDialog.cxx @@ -240,7 +240,7 @@ bool ScRegressionDialog::InputRangesValid() mVariable1Range.PutInOrder(); mVariable2Range.PutInOrder(); - bool bGroupedByColumn = mGroupedBy == BY_COLUMN; + bool bGroupedByColumn = mGroupedBy == GroupedBy::BY_COLUMN; bool bYHasSingleDim = ( (bGroupedByColumn && @@ -298,7 +298,7 @@ ScRange ScRegressionDialog::GetDataRange(const ScRange& rRange) return rRange; ScRange aDataRange(rRange); - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) aDataRange.aStart.IncRow(1); else aDataRange.aStart.IncCol(1); @@ -314,7 +314,7 @@ OUString ScRegressionDialog::GetVariableNameFormula(bool bXVar, size_t nIndex, b if (mxWithLabelsCheckBox->get_active()) { ScAddress aAddr(bXVar ? mVariable1Range.aStart : mVariable2Range.aStart); - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) aAddr.IncCol(nIndex - 1); else aAddr.IncRow(nIndex - 1); @@ -617,7 +617,7 @@ void ScRegressionDialog::WriteRegressionEstimatesWithCI(AddressWalkerWriter& rOu void ScRegressionDialog::WritePredictionsWithResiduals(AddressWalkerWriter& rOutput, FormulaTemplate& rTemplate, size_t nRegressionIndex) { - bool bGroupedByColumn = mGroupedBy == BY_COLUMN; + bool bGroupedByColumn = mGroupedBy == GroupedBy::BY_COLUMN; rOutput.newLine(); rOutput.push(); diff --git a/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx b/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx index 5e00ac1968d1..950506022429 100644 --- a/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/StatisticsTwoVariableDialog.cxx @@ -37,7 +37,7 @@ ScStatisticsTwoVariableDialog::ScStatisticsTwoVariableDialog( , mVariable2Range(ScAddress::INITIALIZE_INVALID) , mAddressDetails(mDocument.GetAddressConvention(), 0, 0 ) , mOutputAddress(ScAddress::INITIALIZE_INVALID) - , mGroupedBy(BY_COLUMN) + , mGroupedBy(GroupedBy::BY_COLUMN) , mxButtonOk(m_xBuilder->weld_button(u"ok"_ustr)) , mxButtonCancel(m_xBuilder->weld_button(u"cancel"_ustr)) , mxGroupByColumnsRadio(m_xBuilder->weld_radio_button(u"groupedby-columns-radio"_ustr)) @@ -245,9 +245,9 @@ IMPL_LINK_NOARG( ScStatisticsTwoVariableDialog, LoseButtonFocusHandler, formula: IMPL_LINK_NOARG(ScStatisticsTwoVariableDialog, GroupByChanged, weld::Toggleable&, void) { if (mxGroupByColumnsRadio->get_active()) - mGroupedBy = BY_COLUMN; + mGroupedBy = GroupedBy::BY_COLUMN; else if (mxGroupByRowsRadio->get_active()) - mGroupedBy = BY_ROW; + mGroupedBy = GroupedBy::BY_ROW; ValidateDialogInput(); } diff --git a/sc/source/ui/StatisticsDialogs/TTestDialog.cxx b/sc/source/ui/StatisticsDialogs/TTestDialog.cxx index b354f4ee02a8..c3207eb0043c 100644 --- a/sc/source/ui/StatisticsDialogs/TTestDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/TTestDialog.cxx @@ -46,13 +46,13 @@ ScRange ScTTestDialog::ApplyOutput(ScDocShell& rDocShell) FormulaTemplate aTemplate(&mDocument); std::unique_ptr<DataRangeIterator> pVariable1Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable1Iterator.reset(new DataRangeByColumnIterator(mVariable1Range)); else pVariable1Iterator.reset(new DataRangeByRowIterator(mVariable1Range)); std::unique_ptr<DataRangeIterator> pVariable2Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable2Iterator.reset(new DataRangeByColumnIterator(mVariable2Range)); else pVariable2Iterator.reset(new DataRangeByRowIterator(mVariable2Range)); diff --git a/sc/source/ui/StatisticsDialogs/ZTestDialog.cxx b/sc/source/ui/StatisticsDialogs/ZTestDialog.cxx index 0966af0aaf1b..a849453073c4 100644 --- a/sc/source/ui/StatisticsDialogs/ZTestDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/ZTestDialog.cxx @@ -46,13 +46,13 @@ ScRange ScZTestDialog::ApplyOutput(ScDocShell& rDocShell) FormulaTemplate aTemplate(&mDocument); std::unique_ptr<DataRangeIterator> pVariable1Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable1Iterator.reset(new DataRangeByColumnIterator(mVariable1Range)); else pVariable1Iterator.reset(new DataRangeByRowIterator(mVariable1Range)); std::unique_ptr<DataRangeIterator> pVariable2Iterator; - if (mGroupedBy == BY_COLUMN) + if (mGroupedBy == GroupedBy::BY_COLUMN) pVariable2Iterator.reset(new DataRangeByColumnIterator(mVariable2Range)); else pVariable2Iterator.reset(new DataRangeByRowIterator(mVariable2Range)); diff --git a/sc/source/ui/inc/StatisticsTwoVariableDialog.hxx b/sc/source/ui/inc/StatisticsTwoVariableDialog.hxx index dde63e9c8ced..0ed7d6b242e9 100644 --- a/sc/source/ui/inc/StatisticsTwoVariableDialog.hxx +++ b/sc/source/ui/inc/StatisticsTwoVariableDialog.hxx @@ -17,7 +17,7 @@ class ScStatisticsTwoVariableDialog : public ScAnyRefDlgController { public: - enum GroupedBy { + enum class GroupedBy { BY_COLUMN, BY_ROW };
