vcl/qt5/QtBuilder.cxx | 12 ++- vcl/qt5/QtInstanceBuilder.cxx | 168 +++++++++++++++++++++++++----------------- 2 files changed, 110 insertions(+), 70 deletions(-)
New commits: commit fbca764f46b39a21a3a1d68276fba08d0a0e54a6 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri May 2 11:40:43 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 2 18:30:25 2025 +0200 tdf#130857 qt weld: Make sure .ui file is processed in main thread QWidgets may only be created in the GUI/main thread, and that is what happens when processing the .ui file. Therefore, ensure this is always run in the main thread. One case observed where this was not the case was the crash recovery dialog getting created after Impress had crashed due to an assert being hit somewhere in the QtMultimedia library in a non-main thread. Backtrace: (gdb) bt #0 __GI_abort () at ./stdlib/abort.c:91 #1 0x00007fe93850641d in qAbort () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:46 #2 0x00007fe93854dd9a in qt_maybe_message_fatal<QString&> (msgType=QtFatalMsg, context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2140 #3 0x00007fe938547004 in qt_message (msgType=QtFatalMsg, context=..., msg=0x7fe938ca8ed3 "ASSERT failure in %s: \"%s\", file %s, line %d", ap=0x7fe8e27d6f30) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:412 #4 0x00007fe93854934d in QMessageLogger::fatal (this=0x7fe8e27d70d0, msg=0x7fe938ca8ed3 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:901 #5 0x00007fe9385064d3 in qt_assert_x (where=0x7fe936e5576a "QWidget", what=0x7fe936e5580b "Widgets must be created in the GUI thread.", file=0x7fe936e556b4 "/home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp", line=945) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:115 #6 0x00007fe93668477d in QWidgetPrivate::init (this=0x7fe88c19c3f0, parentWidget=0x0, f=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:944 #7 0x00007fe9366845e6 in QWidget::QWidget (this=0x7fe88c003370, dd=..., parent=0x0, f=...) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qwidget.cpp:862 #8 0x00007fe936a92cb5 in QDialog::QDialog (this=0x7fe88c003370, parent=0x0, f=...) at /home/michi/development/git/qt5/qtbase/src/widgets/dialogs/qdialog.cpp:375 #9 0x00007fe93955ed73 in QtBuilder::makeObject (this=0x7fe88c0049f0, pParent=0x0, sName=u"GtkDialog", sType="", sID="DocRecoverySaveDialog", rMap=std::__debug::map with 7 elements = {...}) at vcl/qt6/../qt5/QtBuilder.cxx:213 #10 0x00007fe93955e1a4 in QtBuilder::insertObject (this=0x7fe88c0049f0, pParent=0x0, rClass="GtkDialog", sType="", rID="DocRecoverySaveDialog", rProps=std::__debug::map with 7 elements = {...}) at vcl/qt6/../qt5/QtBuilder.cxx:109 #11 0x00007fe9395742e5 in WidgetBuilder<QObject, QObject*, QMenu, QMenu*>::handleObject (this=0x7fe88c0049f0, pParent=0x0, pAtkProps=0x0, reader=..., sType="", sInternalChild="", bToolbarItem=false) at include/vcl/widgetbuilder.hxx:234 #12 0x00007fe939572c16 in WidgetBuilder<QObject, QObject*, QMenu, QMenu*>::handleChild (this=0x7fe88c0049f0, pParent=0x0, pAtkProps=0x0, reader=..., bToolbarItem=false) at include/vcl/widgetbuilder.hxx:131 #13 0x00007fe939566468 in WidgetBuilder<QObject, QObject*, QMenu, QMenu*>::processUIFile (this=0x7fe88c0049f0, pParent=0x0) at include/vcl/widgetbuilder.hxx:70 #14 0x00007fe93955da70 in QtBuilder::QtBuilder (this=0x7fe88c0049f0, pParent=0x0, sUIRoot=u"file:///home/michi/development/git/libreoffice/instdir/program/../share/config/soffice.cfg/", rUIFile="svx/ui/docrecoverysavedialog.ui") at vcl/qt6/../qt5/QtBuilder.cxx:66 #15 0x00007fe9396117a7 in std::make_unique<QtBuilder, QWidget*&, std::basic_string_view<char16_t, std::char_traits<char16_t> >&, rtl::OUString const&> (__args=@0x7fe8e27d91a0: 0x0, __args=u"file:///home/michi/development/git/libreoffice/instdir/program/../share/config/soffice.cfg/", __args="svx/ui/docrecoverysavedialog.ui") at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/unique_ptr.h:1077 #16 0x00007fe93960ed69 in QtInstanceBuilder::QtInstanceBuilder (this=0x7fe88c0db2d0, pParent=0x0, sUIRoot=u"file:///home/michi/development/git/libreoffice/instdir/program/../share/config/soffice.cfg/", rUIFile="svx/ui/docrecoverysavedialog.ui") at vcl/qt6/../qt5/QtInstanceBuilder.cxx:52 #17 0x00007fe9395f55a8 in std::make_unique<QtInstanceBuilder, QWidget*&, rtl::OUString const&, rtl::OUString const&> (__args=@0x7fe8e27d92a0: 0x0, __args="file:///home/michi/development/git/libreoffice/instdir/program/../share/config/soffice.cfg/", __args="svx/ui/docrecoverysavedialog.ui") at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/unique_ptr.h:1077 #18 0x00007fe9395ef490 in QtInstance::CreateBuilder (this=0x56149a5271a0, pParent=0x0, rUIRoot="file:///home/michi/development/git/libreoffice/instdir/program/../share/config/soffice.cfg/", rUIFile="svx/ui/docrecoverysavedialog.ui") at vcl/qt6/../qt5/QtInstance.cxx:916 #19 0x00007fe9395ef52c in non-virtual thunk to QtInstance::CreateBuilder(weld::Widget*, rtl::OUString const&, rtl::OUString const&) () at /home/michi/development/git/libreoffice/instdir/program/libvclplug_qt6lo.so #20 0x00007fe94160079f in Application::CreateBuilder (pParent=0x0, rUIFile="svx/ui/docrecoverysavedialog.ui", bMobile=false, nLOKWindowId=0) at /home/michi/development/git/libreoffice/vcl/source/window/builder.cxx:204 #21 0x00007fe94208901d in weld::GenericDialogController::GenericDialogController (this=0x7fe88c0095a0, pParent=0x0, rUIFile="svx/ui/docrecoverysavedialog.ui", rDialogId="DocRecoverySaveDialog", bMobile=false) at /home/michi/development/git/libreoffice/vcl/source/app/weldutils.cxx:53 #22 0x00007fe945a1f83d in svx::DocRecovery::SaveDialog::SaveDialog (this=0x7fe88c0095a0, pParent=0x0, pCore=0x7fe88c0dafe0) at /home/michi/development/git/libreoffice/svx/source/dialog/docrecovery.cxx:574 #23 0x00007fe945a35e25 in (anonymous namespace)::RecoveryUI::impl_doEmergencySave (this=0x7fe88c0d4010) at /home/michi/development/git/libreoffice/svx/source/unodraw/recoveryui.cxx:254 #24 0x00007fe945a35b03 in (anonymous namespace)::RecoveryUI::dispatchWithReturnValue (this=0x7fe88c0d4010, aURL=...) at /home/michi/development/git/libreoffice/svx/source/unodraw/recoveryui.cxx:148 #25 0x00007fe945a35ca4 in non-virtual thunk to (anonymous namespace)::RecoveryUI::dispatchWithReturnValue(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) () at /home/michi/development/git/libreoffice/instdir/program/libsvxlo.so #26 0x00007fe94af24c4f in desktop::(anonymous namespace)::impl_callRecoveryUI (bEmergencySave=true, bExistsRecoveryData=false) at /home/michi/development/git/libreoffice/desktop/source/app/app.cxx:1057 #27 0x00007fe94af248a1 in desktop::Desktop::Exception (this=0x7ffc5c0f5540, nCategory=ExceptionCategory::System) at /home/michi/development/git/libreoffice/desktop/source/app/app.cxx:1212 #28 0x00007fe9420667fa in VCLExceptionSignal_impl (pInfo=0x7fe8e27d9d88) at /home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:178 #29 0x00007fe94b2484aa in callSignalHandler (pInfo=0x7fe8e27d9d88) at /home/michi/development/git/libreoffice/sal/osl/all/signalshared.cxx:47 #30 0x00007fe94b2dc3d3 in (anonymous namespace)::signalHandlerFunction (signal=6, info=0x7fe8e27d9fb0, context=0x7fe8e27d9e80) at /home/michi/development/git/libreoffice/sal/osl/unx/signal.cxx:423 #31 0x00007fe94ac49df0 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6 #32 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #33 0x00007fe94ac9e9ff in __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89 #34 0x00007fe94ac49cc2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #35 0x00007fe94ac324ac in __GI_abort () at ./stdlib/abort.c:73 #36 0x00007fe93850641d in qAbort () at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:46 #37 0x00007fe93854dd9a in qt_maybe_message_fatal<QString&> (msgType=QtFatalMsg, context=..., message=...) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:2140 #38 0x00007fe938547004 in qt_message (msgType=QtFatalMsg, context=..., msg=0x7fe938ca8eb2 "ASSERT: \"%s\" in file %s, line %d", ap=0x7fe8e27dae30) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:412 #39 0x00007fe93854934d in QMessageLogger::fatal (this=0x7fe8e27dafd8, msg=0x7fe938ca8eb2 "ASSERT: \"%s\" in file %s, line %d") at /home/michi/development/git/qt5/qtbase/src/corelib/global/qlogging.cpp:901 #40 0x00007fe93850646b in qt_assert (assertion=0x7fe935abd3d7 "subject == PW_ID_CORE", file=0x7fe935abcca8 "/home/michi/development/git/qt5/qtmultimedia/src/multimedia/pipewire/qpipewire_audiocontextmanager.cpp", line=267) at /home/michi/development/git/qt5/qtbase/src/corelib/global/qassert.cpp:106 #41 0x00007fe9359e3b3c in QtPipeWire::QAudioContextManager::startListenDefaultMetadata(QtPipeWire::StrongIdType<unsigned int, QtPipeWire::ObjectIdTag>, unsigned int)::$_0::operator()(void*, unsigned int, char const*, char const*, char const*) const (this=0x7fe8e27db0c7, data=0x7fe935c05d10 <QGlobalStatic<QtGlobalStatic::Holder<QtPipeWire::(anonymous namespace)::Q_QGS_s_audioContextInstance> >::instance()::holder>, subject=113, key=0x5614a39ce960 "target.node", type=0x5614a39ce978 "Spa:Id", value=0x5614a39ce988 "-1") at /home/michi/development/git/qt5/qtmultimedia/src/multimedia/pipewire/qpipewire_audiocontextmanager.cpp:267 #42 0x00007fe9359e2ce8 in QtPipeWire::QAudioContextManager::startListenDefaultMetadata(QtPipeWire::StrongIdType<unsigned int, QtPipeWire::ObjectIdTag>, unsigned int)::$_0::__invoke(void*, unsigned int, char const*, char const*, char const*) (data=0x7fe935c05d10 <QGlobalStatic<QtGlobalStatic::Holder<QtPipeWire::(anonymous namespace)::Q_QGS_s_audioContextInstance> >::instance()::holder>, subject=113, key=0x5614a39ce960 "target.node", type=0x5614a39ce978 "Spa:Id", value=0x5614a39ce988 "-1") at /home/michi/development/git/qt5/qtmultimedia/src/multimedia/pipewire/qpipewire_audiocontextmanager.cpp:265 #43 0x00007fe8f1574054 in ??? () at /usr/lib/x86_64-linux-gnu/pipewire-0.3/libpipewire-module-metadata.so #44 0x00007fe8f0d61671 in ??? () at /usr/lib/x86_64-linux-gnu/pipewire-0.3/libpipewire-module-protocol-native.so #45 0x00007fe8f0d61e08 in ??? () at /usr/lib/x86_64-linux-gnu/pipewire-0.3/libpipewire-module-protocol-native.so #46 0x00007fe8f2dd5c46 in ??? () at /usr/lib/x86_64-linux-gnu/spa-0.2/support/libspa-support.so #47 0x00007fe935347b55 in ??? () at /lib/x86_64-linux-gnu/libpipewire-0.3.so.0 #48 0x00007fe94ac9cb7b in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:448 #49 0x00007fe94ad1a7b8 in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78 Change-Id: I5f9f1f82d8ca76a50872d0b81b67059f78d413fc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184896 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx index e06f9ab81dc2..bdf9848485a0 100644 --- a/vcl/qt5/QtBuilder.cxx +++ b/vcl/qt5/QtBuilder.cxx @@ -63,11 +63,15 @@ QString convertAccelerator(const OUString& rText) QtBuilder::QtBuilder(QWidget* pParent, std::u16string_view sUIRoot, const OUString& rUIFile) : WidgetBuilder(sUIRoot, rUIFile, false) { - processUIFile(pParent); + SolarMutexGuard g; - // tweak widget hierarchy (remove unnecessary parent widgets) - for (const std::pair<QWidget*, QWidget*>& rPair : m_aWidgetReplacements) - replaceWidget(rPair.first, rPair.second); + GetQtInstance().RunInMainThread([&] { + processUIFile(pParent); + + // tweak widget hierarchy (remove unnecessary parent widgets) + for (const std::pair<QWidget*, QWidget*>& rPair : m_aWidgetReplacements) + replaceWidget(rPair.first, rPair.second); + }); } QtBuilder::~QtBuilder() {} commit 63467889b0ddea39ca305a2ab2396e99359b35d0 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri May 2 11:37:15 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri May 2 18:30:18 2025 +0200 Revert "tdf#130857 qt weld: Assert widgets exist, drop fallback" It turns out that there are use cases where IDs are used for which no widget exists in the .ui file. At leasts the SmCategoryDesc ctor doesn't use hard-coded widget IDs but generates them dynamically and includes `nCategoryIdx`, so the resulting ID may or may not have an associated widget, and the null case is handled there. This reverts commit 960703ce7fe55af062bd33e6bc9f6f33bfd193e8. Change-Id: I760f1ac82c5e4e22409fe0ab99309e6b23c37aa7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184895 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index a92182740ff0..2ed807576b0c 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -161,22 +161,25 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile) std::unique_ptr<weld::MessageDialog> QtInstanceBuilder::weld_message_dialog(const OUString& id) { QMessageBox* pMessageBox = m_xBuilder->get<QMessageBox>(id); - assert(pMessageBox); - return std::make_unique<QtInstanceMessageDialog>(pMessageBox); + std::unique_ptr<weld::MessageDialog> xRet( + pMessageBox ? std::make_unique<QtInstanceMessageDialog>(pMessageBox) : nullptr); + return xRet; } std::unique_ptr<weld::Dialog> QtInstanceBuilder::weld_dialog(const OUString& rId) { QDialog* pDialog = m_xBuilder->get<QDialog>(rId); - assert(pDialog); - return std::make_unique<QtInstanceDialog>(pDialog); + std::unique_ptr<weld::Dialog> xRet(pDialog ? std::make_unique<QtInstanceDialog>(pDialog) + : nullptr); + return xRet; } std::unique_ptr<weld::Assistant> QtInstanceBuilder::weld_assistant(const OUString& rId) { QWizard* pWizard = m_xBuilder->get<QWizard>(rId); - assert(pWizard); - return std::make_unique<QtInstanceAssistant>(pWizard); + std::unique_ptr<weld::Assistant> xRet(pWizard ? std::make_unique<QtInstanceAssistant>(pWizard) + : nullptr); + return xRet; } std::unique_ptr<weld::Window> QtInstanceBuilder::create_screenshot_window() @@ -188,14 +191,17 @@ std::unique_ptr<weld::Window> QtInstanceBuilder::create_screenshot_window() std::unique_ptr<weld::Widget> QtInstanceBuilder::weld_widget(const OUString& rId) { QWidget* pWidget = m_xBuilder->get<QWidget>(rId); - assert(pWidget); - return std::make_unique<QtInstanceWidget>(pWidget); + std::unique_ptr<weld::Widget> xRet(pWidget ? std::make_unique<QtInstanceWidget>(pWidget) + : nullptr); + return xRet; } std::unique_ptr<weld::Container> QtInstanceBuilder::weld_container(const OUString& rId) { QWidget* pWidget = m_xBuilder->get<QWidget>(rId); - assert(pWidget); + if (!pWidget) + return nullptr; + assert(pWidget->layout() && "no layout"); return std::make_unique<QtInstanceContainer>(pWidget); } @@ -203,7 +209,9 @@ std::unique_ptr<weld::Container> QtInstanceBuilder::weld_container(const OUStrin std::unique_ptr<weld::Box> QtInstanceBuilder::weld_box(const OUString& rId) { QWidget* pWidget = m_xBuilder->get<QWidget>(rId); - assert(pWidget); + if (!pWidget) + return nullptr; + assert(qobject_cast<QBoxLayout*>(pWidget->layout()) && "widget doesn't have a box layout"); return std::make_unique<QtInstanceBox>(pWidget); } @@ -211,7 +219,9 @@ std::unique_ptr<weld::Box> QtInstanceBuilder::weld_box(const OUString& rId) std::unique_ptr<weld::Grid> QtInstanceBuilder::weld_grid(const OUString& rId) { QWidget* pWidget = m_xBuilder->get<QWidget>(rId); - assert(pWidget); + if (!pWidget) + return nullptr; + assert(qobject_cast<QGridLayout*>(pWidget->layout()) && "no grid layout"); return std::make_unique<QtInstanceGrid>(pWidget); } @@ -225,37 +235,42 @@ std::unique_ptr<weld::Paned> QtInstanceBuilder::weld_paned(const OUString&) std::unique_ptr<weld::Frame> QtInstanceBuilder::weld_frame(const OUString& rId) { QGroupBox* pGroupBox = m_xBuilder->get<QGroupBox>(rId); - assert(pGroupBox); - return std::make_unique<QtInstanceFrame>(pGroupBox); + std::unique_ptr<weld::Frame> xRet(pGroupBox ? std::make_unique<QtInstanceFrame>(pGroupBox) + : nullptr); + return xRet; } std::unique_ptr<weld::ScrolledWindow> QtInstanceBuilder::weld_scrolled_window(const OUString& rId, bool) { QScrollArea* pScrollArea = m_xBuilder->get<QScrollArea>(rId); - assert(pScrollArea); - return std::make_unique<QtInstanceScrolledWindow>(pScrollArea); + std::unique_ptr<weld::ScrolledWindow> xRet( + pScrollArea ? std::make_unique<QtInstanceScrolledWindow>(pScrollArea) : nullptr); + return xRet; } std::unique_ptr<weld::Notebook> QtInstanceBuilder::weld_notebook(const OUString& rId) { QTabWidget* pTabWidget = m_xBuilder->get<QTabWidget>(rId); - assert(pTabWidget); - return std::make_unique<QtInstanceNotebook>(pTabWidget); + std::unique_ptr<weld::Notebook> xRet( + pTabWidget ? std::make_unique<QtInstanceNotebook>(pTabWidget) : nullptr); + return xRet; } std::unique_ptr<weld::Button> QtInstanceBuilder::weld_button(const OUString& rId) { QPushButton* pButton = m_xBuilder->get<QPushButton>(rId); - assert(pButton); - return std::make_unique<QtInstanceButton>(pButton); + std::unique_ptr<weld::Button> xRet(pButton ? std::make_unique<QtInstanceButton>(pButton) + : nullptr); + return xRet; } std::unique_ptr<weld::MenuButton> QtInstanceBuilder::weld_menu_button(const OUString& rId) { QToolButton* pButton = m_xBuilder->get<QToolButton>(rId); - assert(pButton); - return std::make_unique<QtInstanceMenuButton>(pButton); + std::unique_ptr<weld::MenuButton> xRet(pButton ? std::make_unique<QtInstanceMenuButton>(pButton) + : nullptr); + return xRet; } std::unique_ptr<weld::MenuToggleButton> QtInstanceBuilder::weld_menu_toggle_button(const OUString&) @@ -267,50 +282,57 @@ std::unique_ptr<weld::MenuToggleButton> QtInstanceBuilder::weld_menu_toggle_butt std::unique_ptr<weld::LinkButton> QtInstanceBuilder::weld_link_button(const OUString& rId) { QtHyperlinkLabel* pLabel = m_xBuilder->get<QtHyperlinkLabel>(rId); - assert(pLabel); - return std::make_unique<QtInstanceLinkButton>(pLabel); + std::unique_ptr<weld::LinkButton> xRet(pLabel ? std::make_unique<QtInstanceLinkButton>(pLabel) + : nullptr); + return xRet; } std::unique_ptr<weld::ToggleButton> QtInstanceBuilder::weld_toggle_button(const OUString& rId) { QAbstractButton* pButton = m_xBuilder->get<QAbstractButton>(rId); - assert(pButton); - return std::make_unique<QtInstanceToggleButton>(pButton); + std::unique_ptr<weld::ToggleButton> xRet( + pButton ? std::make_unique<QtInstanceToggleButton>(pButton) : nullptr); + return xRet; } std::unique_ptr<weld::RadioButton> QtInstanceBuilder::weld_radio_button(const OUString& rId) { QRadioButton* pRadioButton = m_xBuilder->get<QRadioButton>(rId); - assert(pRadioButton); - return std::make_unique<QtInstanceRadioButton>(pRadioButton); + std::unique_ptr<weld::RadioButton> xRet( + pRadioButton ? std::make_unique<QtInstanceRadioButton>(pRadioButton) : nullptr); + return xRet; } std::unique_ptr<weld::CheckButton> QtInstanceBuilder::weld_check_button(const OUString& rId) { QCheckBox* pCheckBox = m_xBuilder->get<QCheckBox>(rId); - assert(pCheckBox); - return std::make_unique<QtInstanceCheckButton>(pCheckBox); + std::unique_ptr<weld::CheckButton> xRet( + pCheckBox ? std::make_unique<QtInstanceCheckButton>(pCheckBox) : nullptr); + return xRet; } std::unique_ptr<weld::Scale> QtInstanceBuilder::weld_scale(const OUString& rId) { QSlider* pSlider = m_xBuilder->get<QSlider>(rId); - assert(pSlider); - return std::make_unique<QtInstanceScale>(pSlider); + std::unique_ptr<weld::Scale> xRet(pSlider ? std::make_unique<QtInstanceScale>(pSlider) + : nullptr); + return xRet; } std::unique_ptr<weld::ProgressBar> QtInstanceBuilder::weld_progress_bar(const OUString& rId) { QProgressBar* pProgressBar = m_xBuilder->get<QProgressBar>(rId); - assert(pProgressBar); - return std::make_unique<QtInstanceProgressBar>(pProgressBar); + std::unique_ptr<weld::ProgressBar> xRet( + pProgressBar ? std::make_unique<QtInstanceProgressBar>(pProgressBar) : nullptr); + return xRet; } std::unique_ptr<weld::LevelBar> QtInstanceBuilder::weld_level_bar(const OUString& rId) { QProgressBar* pProgressBar = m_xBuilder->get<QProgressBar>(rId); - assert(pProgressBar); - return std::make_unique<QtInstanceLevelBar>(pProgressBar); + std::unique_ptr<weld::LevelBar> xRet( + pProgressBar ? std::make_unique<QtInstanceLevelBar>(pProgressBar) : nullptr); + return xRet; } std::unique_ptr<weld::Spinner> QtInstanceBuilder::weld_spinner(const OUString&) @@ -322,8 +344,8 @@ std::unique_ptr<weld::Spinner> QtInstanceBuilder::weld_spinner(const OUString&) std::unique_ptr<weld::Image> QtInstanceBuilder::weld_image(const OUString& rId) { QLabel* pLabel = m_xBuilder->get<QLabel>(rId); - assert(pLabel); - return std::make_unique<QtInstanceImage>(pLabel); + std::unique_ptr<weld::Image> xRet(pLabel ? std::make_unique<QtInstanceImage>(pLabel) : nullptr); + return xRet; } std::unique_ptr<weld::Calendar> QtInstanceBuilder::weld_calendar(const OUString&) @@ -335,15 +357,17 @@ std::unique_ptr<weld::Calendar> QtInstanceBuilder::weld_calendar(const OUString& std::unique_ptr<weld::Entry> QtInstanceBuilder::weld_entry(const OUString& rId) { QLineEdit* pLineEdit = m_xBuilder->get<QLineEdit>(rId); - assert(pLineEdit); - return std::make_unique<QtInstanceEntry>(pLineEdit); + std::unique_ptr<weld::Entry> xRet(pLineEdit ? std::make_unique<QtInstanceEntry>(pLineEdit) + : nullptr); + return xRet; } std::unique_ptr<weld::SpinButton> QtInstanceBuilder::weld_spin_button(const OUString& rId) { QtDoubleSpinBox* pSpinBox = m_xBuilder->get<QtDoubleSpinBox>(rId); - assert(pSpinBox); - return std::make_unique<QtInstanceSpinButton>(pSpinBox); + std::unique_ptr<weld::SpinButton> xRet( + pSpinBox ? std::make_unique<QtInstanceSpinButton>(pSpinBox) : nullptr); + return xRet; } std::unique_ptr<weld::MetricSpinButton> @@ -356,15 +380,17 @@ std::unique_ptr<weld::FormattedSpinButton> QtInstanceBuilder::weld_formatted_spin_button(const OUString& rId) { QtDoubleSpinBox* pSpinBox = m_xBuilder->get<QtDoubleSpinBox>(rId); - assert(pSpinBox); - return std::make_unique<QtInstanceFormattedSpinButton>(pSpinBox); + std::unique_ptr<weld::FormattedSpinButton> xRet( + pSpinBox ? std::make_unique<QtInstanceFormattedSpinButton>(pSpinBox) : nullptr); + return xRet; } std::unique_ptr<weld::ComboBox> QtInstanceBuilder::weld_combo_box(const OUString& rId) { QComboBox* pComboBox = m_xBuilder->get<QComboBox>(rId); - assert(pComboBox); - return std::make_unique<QtInstanceComboBox>(pComboBox); + std::unique_ptr<weld::ComboBox> xRet(pComboBox ? std::make_unique<QtInstanceComboBox>(pComboBox) + : nullptr); + return xRet; } std::unique_ptr<weld::EntryTreeView> @@ -376,43 +402,49 @@ QtInstanceBuilder::weld_entry_tree_view(const OUString& rContainerId, const OUSt QTreeView* pTreeView = m_xBuilder->get<QTreeView>(rTreeViewId); assert(pWidget && pLineEdit && pTreeView); - return std::make_unique<QtInstanceEntryTreeView>( - pWidget, pLineEdit, pTreeView, weld_entry(rEntryId), weld_tree_view(rTreeViewId)); + std::unique_ptr<weld::EntryTreeView> xRet(std::make_unique<QtInstanceEntryTreeView>( + pWidget, pLineEdit, pTreeView, weld_entry(rEntryId), weld_tree_view(rTreeViewId))); + + return xRet; } std::unique_ptr<weld::TreeView> QtInstanceBuilder::weld_tree_view(const OUString& rId) { QTreeView* pTreeView = m_xBuilder->get<QTreeView>(rId); - assert(pTreeView); - return std::make_unique<QtInstanceTreeView>(pTreeView); + std::unique_ptr<weld::TreeView> xRet(pTreeView ? std::make_unique<QtInstanceTreeView>(pTreeView) + : nullptr); + return xRet; } std::unique_ptr<weld::IconView> QtInstanceBuilder::weld_icon_view(const OUString& rId) { QListView* pListView = m_xBuilder->get<QListView>(rId); - assert(pListView); - return std::make_unique<QtInstanceIconView>(pListView); + std::unique_ptr<weld::IconView> xRet(pListView ? std::make_unique<QtInstanceIconView>(pListView) + : nullptr); + return xRet; } std::unique_ptr<weld::Label> QtInstanceBuilder::weld_label(const OUString& rId) { QLabel* pLabel = m_xBuilder->get<QLabel>(rId); - assert(pLabel); - return std::make_unique<QtInstanceLabel>(pLabel); + std::unique_ptr<weld::Label> xRet(pLabel ? std::make_unique<QtInstanceLabel>(pLabel) : nullptr); + return xRet; } std::unique_ptr<weld::TextView> QtInstanceBuilder::weld_text_view(const OUString& rId) { QPlainTextEdit* pTextEdit = m_xBuilder->get<QPlainTextEdit>(rId); - assert(pTextEdit); - return std::make_unique<QtInstanceTextView>(pTextEdit); + 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& rId) { QtExpander* pExpander = m_xBuilder->get<QtExpander>(rId); - assert(pExpander); - return std::make_unique<QtInstanceExpander>(pExpander); + std::unique_ptr<weld::Expander> xRet(pExpander ? std::make_unique<QtInstanceExpander>(pExpander) + : nullptr); + return xRet; } std::unique_ptr<weld::DrawingArea> QtInstanceBuilder::weld_drawing_area(const OUString& rId, @@ -420,7 +452,8 @@ std::unique_ptr<weld::DrawingArea> QtInstanceBuilder::weld_drawing_area(const OU FactoryFunction, void*) { QLabel* pLabel = m_xBuilder->get<QLabel>(rId); - assert(pLabel); + if (!pLabel) + return nullptr; if (rA11yImpl.is()) QtAccessibleWidget::setCustomAccessible(*pLabel, rA11yImpl); @@ -431,29 +464,32 @@ std::unique_ptr<weld::DrawingArea> QtInstanceBuilder::weld_drawing_area(const OU std::unique_ptr<weld::Menu> QtInstanceBuilder::weld_menu(const OUString& rId) { QMenu* pMenu = m_xBuilder->get_menu(rId); - assert(pMenu); - return std::make_unique<QtInstanceMenu>(pMenu); + std::unique_ptr<weld::Menu> xRet(pMenu ? std::make_unique<QtInstanceMenu>(pMenu) : nullptr); + return xRet; } std::unique_ptr<weld::Popover> QtInstanceBuilder::weld_popover(const OUString& rId) { QWidget* pWidget = m_xBuilder->get<QWidget>(rId); - assert(pWidget); - return std::make_unique<QtInstancePopover>(pWidget); + std::unique_ptr<weld::Popover> xRet(pWidget ? std::make_unique<QtInstancePopover>(pWidget) + : nullptr); + return xRet; } std::unique_ptr<weld::Toolbar> QtInstanceBuilder::weld_toolbar(const OUString& rId) { QToolBar* pToolBar = m_xBuilder->get<QToolBar>(rId); - assert(pToolBar); - return std::make_unique<QtInstanceToolbar>(pToolBar); + std::unique_ptr<weld::Toolbar> xRet(pToolBar ? std::make_unique<QtInstanceToolbar>(pToolBar) + : nullptr); + return xRet; } std::unique_ptr<weld::Scrollbar> QtInstanceBuilder::weld_scrollbar(const OUString& rId) { QScrollBar* pScrollBar = m_xBuilder->get<QScrollBar>(rId); - assert(pScrollBar); - return std::make_unique<QtInstanceScrollbar>(pScrollBar); + std::unique_ptr<weld::Scrollbar> xRet( + pScrollBar ? std::make_unique<QtInstanceScrollbar>(pScrollBar) : nullptr); + return xRet; } std::unique_ptr<weld::SizeGroup> QtInstanceBuilder::create_size_group()