From 19f5099c93ad34dad6357241b916e0865f77b2d0 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 11 Jul 2024 13:22:36 +0200 Subject: [PATCH] StudioWelcome: fix crashes when setupWizard fails Task-number: QDS-13209 Change-Id: I5751de9d5a5c8065a7cbad91c048d7d4d60de238 Reviewed-by: Tim Jenssen --- src/plugins/studiowelcome/qdsnewdialog.cpp | 22 ++++++++++----------- src/plugins/studiowelcome/qdsnewdialog.h | 5 +++-- src/plugins/studiowelcome/wizardhandler.cpp | 5 ++++- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/plugins/studiowelcome/qdsnewdialog.cpp b/src/plugins/studiowelcome/qdsnewdialog.cpp index 671670f609f..54dec46f74f 100644 --- a/src/plugins/studiowelcome/qdsnewdialog.cpp +++ b/src/plugins/studiowelcome/qdsnewdialog.cpp @@ -49,7 +49,7 @@ QString uniqueProjectName(const QString &path) /***********************/ QdsNewDialog::QdsNewDialog(QWidget *parent) - : m_dialog{new QQuickWidget(parent)} + : m_dialog{Utils::makeUniqueObjectPtr(parent)} , m_categoryModel{new PresetCategoryModel(&m_presetData, this)} , m_presetModel{new PresetModel(&m_presetData, this)} , m_screenSizeModel{new ScreenSizeModel(this)} @@ -57,7 +57,7 @@ QdsNewDialog::QdsNewDialog(QWidget *parent) , m_recentsStore{"RecentPresets.json", StorePolicy::UniqueValues} , m_userPresetsStore{"UserPresets.json", StorePolicy::UniqueNames} { - setParent(m_dialog); + connect(m_dialog.get(), &QObject::destroyed, this, &QObject::deleteLater); m_recentsStore.setReverseOrder(); m_recentsStore.setMaximum(10); @@ -89,9 +89,10 @@ QdsNewDialog::QdsNewDialog(QWidget *parent) m_dialog->installEventFilter(this); QObject::connect(&m_wizard, &WizardHandler::wizardCreationFailed, this, [this] { - QMessageBox::critical(m_dialog, tr("New Project"), tr("Failed to initialize data.")); + // TODO: if the dialog itself could react on the error + // the would not be necessary + QMessageBox::critical(m_dialog.get(), tr("New Project"), tr("Failed to initialize data.")); reject(); - deleteLater(); }); QObject::connect(m_styleModel.data(), &StyleModel::modelAboutToBeReset, this, [this] { @@ -101,7 +102,7 @@ QdsNewDialog::QdsNewDialog(QWidget *parent) bool QdsNewDialog::eventFilter(QObject *obj, QEvent *event) { - if (obj == m_dialog && event->type() == QEvent::KeyPress + if (obj == m_dialog.get() && event->type() == QEvent::KeyPress && static_cast(event)->key() == Qt::Key_Escape) { reject(); return true; @@ -314,7 +315,7 @@ void QdsNewDialog::setWizardFactories(QList factories_, { Utils::Id platform = Utils::Id::fromSetting("Desktop"); - WizardFactories factories{factories_, m_dialog, platform}; + WizardFactories factories{factories_, m_dialog.get(), platform}; std::vector recents = m_recentsStore.fetchAll(); std::vector userPresets = m_userPresetsStore.fetchAll(); @@ -404,8 +405,6 @@ void QdsNewDialog::accept() m_recentsStore.save(preset); m_dialog->close(); - m_dialog->deleteLater(); - m_dialog = nullptr; } void QdsNewDialog::reject() @@ -415,12 +414,13 @@ void QdsNewDialog::reject() m_wizard.destroyWizard(); m_dialog->close(); - m_dialog = nullptr; + m_dialog.reset(); } QString QdsNewDialog::chooseProjectLocation() { - Utils::FilePath newPath = Utils::FileUtils::getExistingDirectory(m_dialog, tr("Choose Directory"), + Utils::FilePath newPath = Utils::FileUtils::getExistingDirectory(m_dialog.get(), + tr("Choose Directory"), m_qmlProjectLocation); return QDir::toNativeSeparators(newPath.toString()); @@ -473,7 +473,7 @@ void QdsNewDialog::savePresetDialogAccept() UserPresetData preset = currentUserPresetData(m_qmlPresetName); if (!m_userPresetsStore.save(preset)) { - QMessageBox::warning(m_dialog, + QMessageBox::warning(m_dialog.get(), tr("Save Preset"), tr("A preset with this name already exists.")); return; diff --git a/src/plugins/studiowelcome/qdsnewdialog.h b/src/plugins/studiowelcome/qdsnewdialog.h index f4f24d1810a..95bfa52fe9b 100644 --- a/src/plugins/studiowelcome/qdsnewdialog.h +++ b/src/plugins/studiowelcome/qdsnewdialog.h @@ -7,6 +7,7 @@ #include #include +#include #include "wizardhandler.h" #include "presetmodel.h" @@ -64,7 +65,7 @@ public: explicit QdsNewDialog(QWidget *parent); - QWidget *widget() override { return m_dialog; } + QWidget *widget() override { return m_dialog.get(); } void setWizardFactories(QList factories, const Utils::FilePath &defaultLocation, const QVariantMap &extraVariables) override; @@ -139,7 +140,7 @@ private slots: void onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel); private: - QQuickWidget *m_dialog = nullptr; + Utils::UniqueObjectPtr m_dialog; PresetData m_presetData; QPointer m_categoryModel; diff --git a/src/plugins/studiowelcome/wizardhandler.cpp b/src/plugins/studiowelcome/wizardhandler.cpp index 961fb701eeb..b86d33a1dfb 100644 --- a/src/plugins/studiowelcome/wizardhandler.cpp +++ b/src/plugins/studiowelcome/wizardhandler.cpp @@ -53,7 +53,10 @@ void WizardHandler::setupWizard() initializeProjectPage(m_wizard->page(0)); initializeFieldsPage(m_wizard->page(1)); - + if (!m_detailsPage) { + emit wizardCreationFailed(); + return; + } auto *screenFactorModel = getScreenFactorModel(m_detailsPage); auto *styleModel = getStyleModel(m_detailsPage);