sc/source/ui/dbgui/tpsort.cxx | 2 +- vcl/inc/qt5/QtTools.hxx | 7 +++++++ vcl/qt5/QtInstanceBuilder.cxx | 4 ++++ vcl/qt5/QtTools.cxx | 9 +++++++++ vcl/qt5/QtWidget.cxx | 7 ++----- 5 files changed, 23 insertions(+), 6 deletions(-)
New commits: commit cb50a0e5bdb80fcf71abc02c5da3c716b15e4231 Author: Michael Weghorn <[email protected]> AuthorDate: Tue Oct 14 15:01:16 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Oct 15 16:39:16 2025 +0200 tdf#130857 qt: Extract helper to convert tooltip text to HTML Extract existing logic to a helper function, for reuse in other places handling tooltip texts in an upcoming commits. Explicitly handle an empty string arg to also return an empty string, as some QToolTip logic triggered with an upcoming commit in place skips showing a tooltip when an empty string is used, but converting to HTML would result in a non-empty tooltip string, even if there's no actual text to show. Change-Id: Ie863daff72be866731c3fc0d3618dd55bb0ad127 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192398 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx index e88759d220b6..e441f5a2e8ad 100644 --- a/vcl/inc/qt5/QtTools.hxx +++ b/vcl/inc/qt5/QtTools.hxx @@ -184,6 +184,13 @@ QString vclToQtStringWithAccelerator(const OUString& rText); */ OUString qtToVclStringWithAccelerator(const QString& rText); +/** + * Returns a rich text (HTML) representation of the given text, to be + * used for tooltips, in order to ensure they are wrapped (see tdf#162297 and tdf#166805). + * For empty strings, an empty string is returned. + */ +QString toRichTextTooltip(const OUString& rText); + template <typename charT, typename traits> inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, const QString& rString) diff --git a/vcl/qt5/QtTools.cxx b/vcl/qt5/QtTools.cxx index 6d700a2716bf..ecb360c3d452 100644 --- a/vcl/qt5/QtTools.cxx +++ b/vcl/qt5/QtTools.cxx @@ -402,4 +402,13 @@ OUString qtToVclStringWithAccelerator(const QString& rText) return toOUString(sModified.replace("&&", "&")); } +QString toRichTextTooltip(const OUString& rText) +{ + if (rText.isEmpty()) + return QString(); + + return QStringLiteral(u"<html>") + toQString(rText).toHtmlEscaped() + + QStringLiteral(u"</html>"); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 3bf463ef7a06..4d6deda111e7 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -485,11 +485,8 @@ bool QtWidget::handleEvent(QEvent* pEvent) const QtFrame* pPopupFrame = GetQtInstance().activePopup(); if (!m_rFrame.m_aTooltipText.isEmpty() && (!pPopupFrame || pPopupFrame == &m_rFrame)) { - // tdf#162297 and tdf#166805: Use an html tag to ensure the tooltip is wrapped - QString sTooltipText("<html>"); - sTooltipText += toQString(m_rFrame.m_aTooltipText).toHtmlEscaped(); - sTooltipText += "</html>"; - QToolTip::showText(QCursor::pos(), sTooltipText, this, m_rFrame.m_aTooltipArea); + QToolTip::showText(QCursor::pos(), toRichTextTooltip(m_rFrame.m_aTooltipText), this, + m_rFrame.m_aTooltipArea); } else { commit 24cde77aae0018ebc7cdf5f157811038fdbeb60e Author: Michael Weghorn <[email protected]> AuthorDate: Tue Oct 14 14:10:00 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Oct 15 16:39:11 2025 +0200 tdf#130857 qt weld: Support Calc "Sort" 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. The dialog can be triggered as follows: * start Calc * "Data" -> "Sort" Change-Id: Ica500005020169de0faf2dada052e5d8f5665ce9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192391 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index ed7ef1ff5899..fe6b77fe4395 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -139,6 +139,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile, const weld::W u"modules/scalc/ui/optdlg.ui"_ustr, u"modules/scalc/ui/selectsource.ui"_ustr, u"modules/scalc/ui/showsheetdialog.ui"_ustr, + u"modules/scalc/ui/sortdialog.ui"_ustr, u"modules/schart/ui/insertaxisdlg.ui"_ustr, u"modules/sdraw/ui/dlgsnap.ui"_ustr, u"modules/sdraw/ui/insertlayer.ui"_ustr, @@ -248,6 +249,9 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile, const weld::W u"filter/ui/pdfsignpage.ui"_ustr, u"filter/ui/pdfuserinterfacepage.ui"_ustr, u"filter/ui/pdfviewpage.ui"_ustr, + u"modules/scalc/ui/sortcriteriapage.ui"_ustr, + u"modules/scalc/ui/sortkey.ui"_ustr, + u"modules/scalc/ui/sortoptionspage.ui"_ustr, u"modules/scalc/ui/statisticsinfopage.ui"_ustr, u"modules/simpress/ui/annotationtagmenu.ui"_ustr, u"modules/swriter/ui/optcaptionpage.ui"_ustr, commit 5aaba693bf6018eae53711d2cfa5f2f35408117a Author: Michael Weghorn <[email protected]> AuthorDate: Tue Oct 14 14:14:01 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Oct 15 16:39:05 2025 +0200 tdf#130857 sc: Improve "Sort" dialog active item check In the handler that gets called when the active item for one of the sort key comboboxes changes, only consider an item to be active if one with a valid index is reported to be active in addition to checking it's not the placeholder item. This is relevant for the native Qt version of the dialog that upcoming commit Change-Id: Ica500005020169de0faf2dada052e5d8f5665ce9 Author: Michael Weghorn <[email protected]> Date: Tue Oct 14 14:10:00 2025 +0200 tdf#130857 qt weld: Support Calc "Sort" dialog will enable for the SAL_VCL_QT_USE_WELDED_WIDGETS=1 case. Without this adjusted check, the following scenario would result in the dialog not showing up, because new comboboxes are created without end: * start Calc * "Data" -> "Sort" * set column A for sort keys 1 to 3. * close dialog using "OK" button * start dialog using "Data" -> "Sort" again Sample backtrace: 1 __gnu_cxx::__ops::_Iter_less_iter::operator()<int *, int *> predefined_ops.h 45 0x7f171138e490 2 std::__lexicographical_compare_impl<int *, int *, __gnu_cxx::__ops::_Iter_less_iter> stl_algobase.h 1334 0x7f171138e34b 3 std::__lexicographical_compare<false>::__lc<int *, int *> stl_algobase.h 1351 0x7f171138e2c6 4 std::__lexicographical_compare_aux1<int *, int *> stl_algobase.h 1425 0x7f171138e265 5 std::__lexicographical_compare_aux<int *, int *> stl_algobase.h 1459 0x7f171138e221 6 std::lexicographical_compare<int *, int *> stl_algobase.h 1789 0x7f1711389ec0 7 QKeySequence::operator< qkeysequence.cpp 1455 0x7f17113886f9 8 QShortcutEntry::operator< qshortcutmap.cpp 46 0x7f1711398461 9 __gnu_debug::__check_partitioned_upper<QList<QShortcutEntry>::iterator, QShortcutEntry> functions.h 371 0x7f1711397e65 10 std::upper_bound<QList<QShortcutEntry>::iterator, QShortcutEntry> stl_algo.h 2027 0x7f1711394bc7 11 QShortcutMap::addShortcut qshortcutmap.cpp 130 0x7f17113912bf 12 QWidget::grabShortcut qwidget.cpp 12006 0x7f170fe73cc5 13 QAbstractButton::setShortcut qabstractbutton.cpp 543 0x7f170fffb45b 14 QAbstractButton::setText qabstractbutton.cpp 491 0x7f170fffb34a 15 QtBuilder::setButtonProperties QtBuilder.cxx 909 0x7f1712d9ae44 16 QtBuilder::setCheckButtonProperties QtBuilder.cxx 940 0x7f1712d9b39c 17 QtBuilder::makeObject QtBuilder.cxx 335 0x7f1712d988fb 18 QtBuilder::insertObject QtBuilder.cxx 112 0x7f1712d967c4 19 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleObject widgetbuilder.hxx 234 0x7f1712dae075 20 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleChild widgetbuilder.hxx 131 0x7f1712dac976 21 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleObject widgetbuilder.hxx 237 0x7f1712dae109 22 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleChild widgetbuilder.hxx 131 0x7f1712dac976 23 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleObject widgetbuilder.hxx 237 0x7f1712dae109 24 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::handleChild widgetbuilder.hxx 131 0x7f1712dac976 25 WidgetBuilder<QObject, QObject *, QMenu, QMenu *>::processUIFile widgetbuilder.hxx 70 0x7f1712dabbd8 26 QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0::operator()() const QtBuilder.cxx 68 0x7f1712d9f8e6 27 std::__invoke_impl<void, QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0&>(std::__invoke_other, QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0&) invoke.h 63 0x7f1712d9f8a5 28 std::__invoke_r<void, QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0&>(QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0&) invoke.h 113 0x7f1712d9f855 29 std::_Function_handler<void(), QtBuilder::QtBuilder(QWidget *, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&)::$_0>::_M_invoke std_function.h 292 0x7f1712d9f76d 30 std::function<void()>::operator() std_function.h 593 0x7f1712e2c55e 31 QtInstance::RunInMainThread QtInstance.cxx 205 0x7f1712e2378f 32 QtBuilder::QtBuilder QtBuilder.cxx 67 0x7f1712d96201 33 std::make_unique<QtBuilder, QWidget *&, std::basic_string_view<char16_t, std::char_traits<char16_t>>&, rtl::OUString const&> unique_ptr.h 1084 0x7f1712e587c7 34 QtInstanceBuilder::QtInstanceBuilder QtInstanceBuilder.cxx 53 0x7f1712e495c9 35 std::make_unique<QtInstanceBuilder, QWidget *&, rtl::OUString const&, rtl::OUString const&> unique_ptr.h 1084 0x7f1712e2eb58 36 QtInstance::CreateBuilder QtInstance.cxx 919 0x7f1712e28464 38 Application::CreateBuilder builder.cxx 209 0x7f171adf0346 39 ScSortKeyItem::ScSortKeyItem sortkeydlg.cxx 19 0x7f16b79b8a4d 40 ScSortKeyWindow::AddSortKey sortkeydlg.cxx 61 0x7f16b79b91de 41 ScTabPageSortFields::AddSortKey tpsort.cxx 486 0x7f16b79bdd3b 42 ScTabPageSortFields::SetLastSortKey tpsort.cxx 400 0x7f16b79bee5c 43 ScTabPageSortFields::SelectHdl tpsort.cxx 447 0x7f16b79bfa7f 44 ScTabPageSortFields::LinkStubSelectHdl tpsort.cxx 437 0x7f16b79bdd7d 45 Link<weld::ComboBox&, void>::Call link.hxx 105 0x7f1712e84c61 46 weld::ComboBox::signal_changed weld.hxx 773 0x7f1712e8486c 47 QtInstanceComboBox::signalChanged QtInstanceComboBox.cxx 381 0x7f1712e7accd 48 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceComboBox:: *)()>::call(void (QtInstanceComboBox:: *)(), QtInstanceComboBox *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 127 0x7f1712e85081 49 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceComboBox:: *)()>::call(void (QtInstanceComboBox:: *)(), QtInstanceComboBox *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceComboBox:: *)()>::call(void (QtInstanceComboBox:: *)(), QtInstanceComboBox *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7f1712e84fb9 50 QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (QtInstanceComboBox:: *)()>::call(void (QtInstanceComboBox:: *)(), QtInstanceComboBox *, void * *) qobjectdefs_impl.h 126 0x7f1712e84eeb 51 QtPrivate::FunctionPointer<void (QtInstanceComboBox:: *)()>::call<QtPrivate::List<>, void>(void (QtInstanceComboBox:: *)(), QtInstanceComboBox *, void * *) qobjectdefs_impl.h 174 0x7f1712e84e6d 52 QtPrivate::QCallableObject<void (QtInstanceComboBox:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobjectdefs_impl.h 545 0x7f1712e84d96 53 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7f1711ce95e2 54 doActivate<false> qobject.cpp 4342 0x7f1711f140af 55 QMetaObject::activate qobject.cpp 4402 0x7f1711f0a463 56 QMetaObject::activate<void, QString> qobjectdefs.h 319 0x7f170fe8111b 57 QComboBox::currentTextChanged moc_qcombobox.cpp 374 0x7f1710038e11 58 QComboBoxPrivate::updateCurrentText qcombobox.cpp 2980 0x7f171003627d 59 QComboBoxPrivate::emitCurrentIndexChanged qcombobox.cpp 1465 0x7f171003655e 60 QComboBoxPrivate::setCurrentIndex qcombobox.cpp 2250 0x7f171003156b 61 QComboBoxPrivate::rowsRemoved qcombobox.cpp 1196 0x7f171003674f 62 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>, QtPrivate::List<QModelIndex const&, int, int>, void, void (QComboBoxPrivate:: *)(QModelIndex const&, int, int)>::call(void (QComboBoxPrivate:: *)(QModelIndex const&, int, int), QComboBoxPrivate *, void * *)::{lambda()#1}::operator()() const qobjectdefs_impl.h 127 0x7f1710050592 63 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>, QtPrivate::List<QModelIndex const&, int, int>, void, void (QComboBoxPrivate:: *)(QModelIndex const&, int, int)>::call(void (QComboBoxPrivate:: *)(QModelIndex const&, int, int), QComboBoxPrivate *, void * *)::{lambda()#1}>(void * *, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>, QtPrivate::List<QModelIndex const&, int, int>, void, void (QComboBoxPrivate:: *)(QModelIndex const&, int, int)>::call(void (QComboBoxPrivate:: *)(QModelIndex const&, int, int), QComboBoxPrivate *, void * *)::{lambda()#1}&&) qobjectdefs_impl.h 65 0x7f17100504ed 64 QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>, QtPrivate::List<QModelIndex const&, int, int>, void, void (QComboBoxPrivate:: *)(QModelIndex const&, int, int)>::call qobjectdefs_impl.h 126 0x7f17100504a7 65 QtPrivate::FunctionPointer<void (QComboBoxPrivate:: *)(QModelIndex const&, int, int)>::call<QtPrivate::List<QModelIndex const&, int, int>, void> qobjectdefs_impl.h 174 0x7f1710050411 66 QtPrivate::QPrivateSlotObject<void (QComboBoxPrivate:: *)(QModelIndex const&, int, int), QtPrivate::List<QModelIndex const&, int, int>, void>::impl qobject_p.h 272 0x7f1710050340 67 QtPrivate::QSlotObjectBase::call qobjectdefs_impl.h 461 0x7f1711ce95e2 68 doActivate<false> qobject.cpp 4342 0x7f1711f140af 69 QMetaObject::activate qobject.cpp 4402 0x7f1711f0a463 70 QMetaObject::activate<void, QModelIndex, int, int, QAbstractItemModel::QPrivateSignal> qobjectdefs.h 319 0x7f171236b895 71 QAbstractItemModel::rowsRemoved moc_qabstractitemmodel.cpp 700 0x7f171235fb0a 72 QAbstractItemModel::endRemoveRows qabstractitemmodel.cpp 2977 0x7f171235fa86 73 QStandardItemModelPrivate::rowsRemoved qstandarditemmodel.cpp 656 0x7f17112422f3 74 QStandardItem::removeRows qstandarditemmodel.cpp 1774 0x7f171124375c 75 QStandardItemModel::removeRows qstandarditemmodel.cpp 3002 0x7f171124667b 76 QComboBox::clear qcombobox.cpp 2992 0x7f171003bfcc 77 QtInstanceComboBox::clear()::$_0::operator()() const QtInstanceComboBox.cxx 110 0x7f1712e7ff9c 78 std::__invoke_impl<void, QtInstanceComboBox::clear()::$_0&>(std::__invoke_other, QtInstanceComboBox::clear()::$_0&) invoke.h 63 0x7f1712e7ff75 79 std::__invoke_r<void, QtInstanceComboBox::clear()::$_0&>(QtInstanceComboBox::clear()::$_0&) invoke.h 113 0x7f1712e7ff25 80 std::_Function_handler<void(), QtInstanceComboBox::clear()::$_0>::_M_invoke std_function.h 292 0x7f1712e7fe4d 81 std::function<void()>::operator() std_function.h 593 0x7f1712e2c55e 82 QtInstance::RunInMainThread QtInstance.cxx 205 0x7f1712e2378f 83 QtInstanceComboBox::clear QtInstanceComboBox.cxx 110 0x7f1712e7bc6b 84 ScTabPageSortFields::FillFieldLists tpsort.cxx 316 0x7f16b79be6ab 85 ScTabPageSortFields::Reset tpsort.cxx 183 0x7f16b79be029 86 SfxTabDialogController::CreatePages tabdlg.cxx 962 0x7f17209a0b0a 87 SfxTabDialogController::Start_Impl tabdlg.cxx 1034 0x7f17209a1819 88 SfxTabDialogController::runAsync tabdlg.cxx 1091 0x7f17209a1c1e 89 (anonymous namespace)::ScAsyncTabController_Impl::StartExecuteAsync scdlgfact.cxx 942 0x7f16b792cad5 90 ScCellShell::ExecuteDB cellsh2.cxx 607 0x7f16e39d9ab6 91 SfxStubScCellShellExecuteDB scslots.hxx 7813 0x7f16e39b0845 92 SfxDispatcher::Call_Impl dispatch.cxx 256 0x7f17207a6d7e 93 SfxDispatcher::Execute_ dispatch.cxx 755 0x7f17207ab626 94 SfxBindings::Execute_Impl bindings.cxx 1045 0x7f17207931ae 95 SfxDispatchController_Impl::dispatch unoctitm.cxx 736 0x7f172087224d 96 SfxOfficeDispatch::dispatch unoctitm.cxx 255 0x7f1720870d04 97 framework::(anonymous namespace)::AsyncMenuExecute menubarmanager.cxx 792 0x7f1721af7264 98 Link<void *, void>::Call link.hxx 105 0x7f171b0629d1 99 ImplHandleUserEvent winproc.cxx 2312 0x7f171b05e2f1 100 ImplWindowFrameProc winproc.cxx 2869 0x7f171b05b21f 101 SalFrame::CallCallback salframe.hxx 310 0x7f1712e04d8c 102 QtInstance::ProcessEvent QtInstance.cxx 594 0x7f1712e2676f 103 SalUserEventList::DispatchUserEvents(bool)::$_0::operator()() const salusereventlist.cxx 119 0x7f171b6334fd 104 SalUserEventList::DispatchUserEvents salusereventlist.cxx 120 0x7f171b6333cb 105 QtInstance::ImplYield QtInstance.cxx 490 0x7f1712e22f51 106 QtInstance::DoYield QtInstance.cxx 512 0x7f1712e26331 107 ImplYield svapp.cxx 389 0x7f171b6ff456 108 Application::Yield svapp.cxx 492 0x7f171b6fed6f 109 Application::Execute svapp.cxx 364 0x7f171b6feb50 110 desktop::Desktop::Main app.cxx 1681 0x7f1724721d05 111 ImplSVMain svmain.cxx 230 0x7f171b72bc86 112 SVMain svmain.cxx 248 0x7f171b72d7a9 113 soffice_main sofficemain.cxx 122 0x7f172479ba3a 114 sal_main main.c 51 0x5625c28fb9fd 115 main main.c 49 0x5625c28fb9d7 Change-Id: I903f4321fe6d3bb6e995950bc83003f8d59aba1f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192390 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx index 0ac10173d1ff..be0cfdc00732 100644 --- a/sc/source/ui/dbgui/tpsort.cxx +++ b/sc/source/ui/dbgui/tpsort.cxx @@ -442,7 +442,7 @@ IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void ) // If last listbox is enabled add one item if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb) { - if ( aSelEntry != aStrUndefined ) + if (rLb.get_active() >= 0 && aSelEntry != aStrUndefined) { SetLastSortKey( nSortKeyCount ); return;
