From fbd77791cd6b6130fe319e1291b24d7844adec69 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 21 Mar 2019 00:18:47 +1100 Subject: [PATCH] implemented #574 --- dialogs/preferencesdialog.cpp | 4 ++-- dialogs/proxydialog.cpp | 3 ++- effects/internal/vsthost.cpp | 3 ++- global/global.cpp | 22 +++++++++++++++++++--- global/global.h | 35 +++++++++++++++++++++++++++++++++++ panels/project.cpp | 4 ++-- project/loadthread.cpp | 2 +- project/sourcescommon.cpp | 3 ++- undo/undo.cpp | 6 +++--- 9 files changed, 68 insertions(+), 14 deletions(-) diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index 4717dc7ae..9e366344f 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -319,8 +319,8 @@ void PreferencesDialog::save() { accept(); if (restart_after_saving) { - // since we already ran can_close_project(), bypass checking again by running setWindowModified(false) - olive::MainWindow->setWindowModified(false); + // since we already ran can_close_project(), bypass checking again by running set_modified(false) + olive::Global->set_modified(false); olive::MainWindow->close(); diff --git a/dialogs/proxydialog.cpp b/dialogs/proxydialog.cpp index bcc0a0745..d86044860 100644 --- a/dialogs/proxydialog.cpp +++ b/dialogs/proxydialog.cpp @@ -31,6 +31,7 @@ #include "project/proxygenerator.h" #include "project/footage.h" #include "ui/mainwindow.h" +#include "global/global.h" ProxyDialog::ProxyDialog(QWidget *parent, const QVector &media) : QDialog(parent), @@ -155,7 +156,7 @@ void ProxyDialog::accept() { olive::proxy_generator.queue(info_list.at(i)); } - olive::MainWindow->setWindowModified(true); + olive::Global->set_modified(true); QDialog::accept(); } diff --git a/effects/internal/vsthost.cpp b/effects/internal/vsthost.cpp index ade778f06..8a07f69dc 100644 --- a/effects/internal/vsthost.cpp +++ b/effects/internal/vsthost.cpp @@ -33,6 +33,7 @@ #include "rendering/audio.h" #include "ui/mainwindow.h" +#include "global/global.h" #include "global/debug.h" #ifdef __linux__ @@ -85,7 +86,7 @@ intptr_t hostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t v // but we are aware of it break; case audioMasterEndEdit: // change made - olive::MainWindow->setWindowModified(true); + olive::Global->set_modified(true); break; default: qInfo() << "Plugin requested unhandled opcode" << opcode; diff --git a/global/global.cpp b/global/global.cpp index 16a59c9c6..668586dc9 100644 --- a/global/global.cpp +++ b/global/global.cpp @@ -48,7 +48,9 @@ std::unique_ptr olive::Global; QString olive::ActiveProjectFilename; QString olive::AppName; -OliveGlobal::OliveGlobal() { +OliveGlobal::OliveGlobal() : + changed_since_last_autorecovery(false) +{ // sets current app name QString version_id; @@ -107,6 +109,17 @@ void OliveGlobal::set_rendering_state(bool rendering) { } } +void OliveGlobal::set_modified(bool modified) +{ + olive::MainWindow->setWindowModified(modified); + changed_since_last_autorecovery = modified; +} + +bool OliveGlobal::is_modified() +{ + return olive::MainWindow->isWindowModified(); +} + void OliveGlobal::load_project_on_launch(const QString& s) { olive::ActiveProjectFilename = s; enable_load_project_on_init = true; @@ -219,7 +232,7 @@ bool OliveGlobal::save_project() { } bool OliveGlobal::can_close_project() { - if (olive::MainWindow->isWindowModified()) { + if (is_modified()) { QMessageBox* m = new QMessageBox( QMessageBox::Question, tr("Unsaved Project"), @@ -281,8 +294,11 @@ void OliveGlobal::finished_initialize() { } void OliveGlobal::save_autorecovery_file() { - if (olive::MainWindow->isWindowModified()) { + if (changed_since_last_autorecovery) { panel_project->save_project(true); + + changed_since_last_autorecovery = false; + qInfo() << "Auto-recovery project saved"; } } diff --git a/global/global.h b/global/global.h index 6a9d57617..4c4cc0872 100644 --- a/global/global.h +++ b/global/global.h @@ -92,6 +92,31 @@ public: */ void set_rendering_state(bool rendering); + /** + * @brief Set the application's "modified" state + * + * Primarily controls whether the application prompts the user to save the project upon closing or not. Also + * technically controls whether to create autorecovery files as they'll only be generated if there are unsaved + * changes. + * + * @param modified + * + * TRUE if the project has been modified, FALSE if it has not. + */ + void set_modified(bool modified); + + /** + * @brief Get application's current "modified" state + * + * Currently just a wrapper around MainWindow::isWindowModified(), but use this instead in case it changes. + * This value is used to determine whether the currently open project has unsaved changes. + * + * @return + * + * TRUE if the project has been modified since the last save. + */ + bool is_modified(); + /** * @brief Set a project to load just after launching * @@ -324,6 +349,16 @@ private: */ std::unique_ptr translator; + /** + * @brief Internal variable for whether the project has changed since the last autorecovery + * + * Set by set_modified(), which should be called alongside any change made to the project file and is "unset" when + * an autorecovery file is made. Provides an extra layer of abstraction from the application "modified" state to + * prevents an autorecovery file saving multiple times if the project hasn't actually changed since the last + * autorecovery, but still hasn't been saved into the original file yet. + */ + bool changed_since_last_autorecovery; + private slots: }; diff --git a/panels/project.cpp b/panels/project.cpp index dfacd8488..2ef1ec72e 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1046,7 +1046,7 @@ void Project::new_project() { olive::Global->set_sequence(nullptr); panel_footage_viewer->set_media(nullptr); clear(); - olive::MainWindow->setWindowModified(false); + olive::Global->set_modified(false); } void Project::load_project(const QString& filename, bool autorecovery, bool clear) { @@ -1314,7 +1314,7 @@ void Project::save_project(bool autorecovery) { if (!autorecovery) { add_recent_project(olive::ActiveProjectFilename); - olive::MainWindow->setWindowModified(false); + olive::Global->set_modified(false); } } diff --git a/project/loadthread.cpp b/project/loadthread.cpp index eca71eb90..052a28406 100644 --- a/project/loadthread.cpp +++ b/project/loadthread.cpp @@ -774,7 +774,7 @@ void LoadThread::success_func() { panel_project->add_recent_project(filename_); } - olive::MainWindow->setWindowModified(autorecovery_ || !clear_); + olive::Global->set_modified(autorecovery_ || !clear_); if (open_seq != nullptr) { olive::Global->set_sequence(open_seq); } diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index 2d6bd9b5f..e516774e0 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -39,6 +39,7 @@ #include "project/projectfilter.h" #include "timeline/sequence.h" #include "global/config.h" +#include "global/global.h" #include "dialogs/proxydialog.h" #include "ui/viewerwidget.h" #include "project/proxygenerator.h" @@ -446,5 +447,5 @@ void SourcesCommon::clear_proxies_from_selected() { panel_sequence_viewer->viewer_widget->frame_update(); } - olive::MainWindow->setWindowModified(true); + olive::Global->set_modified(true); } diff --git a/undo/undo.cpp b/undo/undo.cpp index 172755afb..5b34ffa14 100644 --- a/undo/undo.cpp +++ b/undo/undo.cpp @@ -1136,7 +1136,7 @@ void OliveAction::undo() { doUndo(); if (set_window_modified) { - olive::MainWindow->setWindowModified(old_window_modified); + olive::Global->set_modified(old_window_modified); } } @@ -1146,10 +1146,10 @@ void OliveAction::redo() { if (set_window_modified) { // store current modified state - old_window_modified = olive::MainWindow->isWindowModified(); + old_window_modified = olive::Global->is_modified(); // set modified to true - olive::MainWindow->setWindowModified(true); + olive::Global->set_modified(true); } }