diff --git a/app/core.cpp b/app/core.cpp index 25bc8a58f..d99af6539 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -425,6 +425,9 @@ void Core::SaveProjectInternal(Project *project) // Connect the save manager progress signal to the progress bar update on the dialog connect(psm, &ProjectSaveManager::ProgressChanged, lsd, &LoadSaveDialog::SetProgress, Qt::QueuedConnection); + // Connect cancel signal (must be a direct connection or it'll be queued after the save is already finished) + connect(lsd, &LoadSaveDialog::Cancelled, psm, &ProjectSaveManager::Cancel, Qt::DirectConnection); + // Connect cleanup functions (ensure everything new'd in this function is deleteLater'd) connect(psm, &ProjectSaveManager::Finished, lsd, &LoadSaveDialog::accept, Qt::QueuedConnection); connect(psm, &ProjectSaveManager::Finished, lsd, &LoadSaveDialog::deleteLater, Qt::QueuedConnection); diff --git a/app/dialog/loadsave/loadsave.cpp b/app/dialog/loadsave/loadsave.cpp index b207c87bb..05062f2ec 100644 --- a/app/dialog/loadsave/loadsave.cpp +++ b/app/dialog/loadsave/loadsave.cpp @@ -29,7 +29,6 @@ LoadSaveDialog::LoadSaveDialog(const QString& message, const QString& title, QWi QPushButton* cancel_btn = new QPushButton(tr("Cancel")); connect(cancel_btn, &QPushButton::clicked, this, &LoadSaveDialog::Cancelled); - connect(cancel_btn, &QPushButton::clicked, this, &LoadSaveDialog::reject); cancel_layout->addWidget(cancel_btn); cancel_layout->addStretch(); diff --git a/app/project/projectsavemanager.cpp b/app/project/projectsavemanager.cpp index 37c28ea42..7b9c498e4 100644 --- a/app/project/projectsavemanager.cpp +++ b/app/project/projectsavemanager.cpp @@ -1,7 +1,8 @@ #include "projectsavemanager.h" ProjectSaveManager::ProjectSaveManager(Project *project) : - project_(project) + project_(project), + cancelled_(false) { } @@ -11,6 +12,10 @@ void ProjectSaveManager::Start() int prog = 0; do { + if (cancelled_) { + break; + } + prog += 10; emit ProgressChanged(prog); @@ -20,3 +25,8 @@ void ProjectSaveManager::Start() emit Finished(); } + +void ProjectSaveManager::Cancel() +{ + cancelled_ = true; +} diff --git a/app/project/projectsavemanager.h b/app/project/projectsavemanager.h index e5767b9dd..7308fe0af 100644 --- a/app/project/projectsavemanager.h +++ b/app/project/projectsavemanager.h @@ -12,8 +12,22 @@ public: ProjectSaveManager(Project* project); public slots: + /** + * @brief Start the save process + * + * It's recommended to invoke this through Qt signals/slots/QueuedConnection after moving this object to a separate + * thread. + */ void Start(); + /** + * @brief Cancel the current save + * + * Always connect to this with a DirectConnection. Otherwise, it'll be queued AFTER the save function is already + * complete. + */ + void Cancel(); + signals: void ProgressChanged(int); @@ -22,6 +36,8 @@ signals: private: Project* project_; + QAtomicInt cancelled_; + }; #endif // PROJECTSAVEMANAGER_H