From eb44124b4b2a2308160cc37938590dc93360ddd4 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 23 Dec 2014 14:35:40 +0000 Subject: [PATCH] Confirm quit when an editor panel is open. Closes #280. Also changed the confirmation dialog so that the quit can be cancelled, rather than forcing load order changes to be applied or cancelled before quitting. --- resources/report/js/script.js | 31 +++++++++++++++++++++---------- src/gui/app.cpp | 2 +- src/gui/app.h | 4 ++-- src/gui/handler.cpp | 16 +++++++++++----- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/resources/report/js/script.js b/resources/report/js/script.js index edda599c..34c77743 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -796,14 +796,21 @@ function focusSearch(evt) { document.getElementById('searchBox').focus(); } } -function handleUnappliedChangesClose() { - showMessageDialog('Unapplied Sorting Changes', 'You have not yet applied or cancelled your sorted load order. Apply your load order before quitting?', true, function(result){ +function handleUnappliedChangesClose(change) { + showMessageDialog('Unapplied Sorting Changes', 'You have not yet applied or cancelled your ' + change + '. Are you sure you want to quit?', true, function(result){ if (result) { - applySort().then(function(){ - window.close(); - }).catch(processCefError); - } else { - cancelSort().then(function(){ + /* Cancel any sorting and close any editors. Cheat by sending a + cancelSort query for as many times as necessary. */ + var queries = []; + var numQueries = 0; + if (!document.getElementById('applySortButton').classList.contains('hidden')) { + numQueries += 1; + } + numQueries += document.body.getAttribute('data-editors'); + for (var i = 0; i < numQueries; ++i) { + queries.push(loot.query('cancelSort')); + } + Promise.all(queries).then(function(){ window.close(); }).catch(processCefError); } @@ -839,6 +846,8 @@ function handleEditorOpen(evt) { document.getElementById('sortButton').setAttribute('disabled', ''); } document.body.setAttribute('data-editors', numEditors); + + return loot.query('editorOpened').catch(processCefError); } function handleEditorClose(evt) { /* evt.detail is true if the apply button was pressed. */ @@ -972,10 +981,12 @@ function handleSidebarClick(evt) { } } function handleQuit(evt) { - if (document.getElementById('applySortButton').classList.contains('hidden')) { - window.close(); + if (!document.getElementById('applySortButton').classList.contains('hidden')) { + handleUnappliedChangesClose('sorted load order'); + } else if (document.body.hasAttribute('data-editors')) { + handleUnappliedChangesClose('metadata edits'); } else { - handleUnappliedChangesClose(); + window.close(); } } function setupEventHandlers() { diff --git a/src/gui/app.cpp b/src/gui/app.cpp index 62ea8422..07822592 100644 --- a/src/gui/app.cpp +++ b/src/gui/app.cpp @@ -136,7 +136,7 @@ namespace loot { // LootState member functions //--------------------------- - LootState::LootState() : isMidSort(false), _currentGame(0) {} + LootState::LootState() : numUnappliedChanges(0), _currentGame(0) {} void LootState::Init(const std::string& cmdLineGame) { // Do some preliminary locale / UTF-8 support setup here, in case the settings file reading requires it. diff --git a/src/gui/app.h b/src/gui/app.h index 59c8e173..d63ba2f7 100644 --- a/src/gui/app.h +++ b/src/gui/app.h @@ -82,8 +82,8 @@ namespace loot { void UpdateSettings(const YAML::Node& settings); void SaveSettings(); - // Used to check if LOOT has unaccepted sorting changes on quit. - bool isMidSort; + // Used to check if LOOT has unaccepted sorting or metadata changes on quit. + int numUnappliedChanges; private: YAML::Node _settings; std::vector _games; diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 9e7c8d76..72d0d92d 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -167,7 +167,12 @@ namespace loot { return true; } else if (request == "cancelSort") { - g_app_state.isMidSort = false; + --g_app_state.numUnappliedChanges; + callback->Success(""); + return true; + } + else if (request == "editorOpened") { + ++g_app_state.numUnappliedChanges; callback->Success(""); return true; } @@ -248,6 +253,7 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "Editor for plugin closed."; // One argument, which is the plugin metadata that has changed (+ its name). callback->Success(ApplyUserEdits(request["args"][0])); + --g_app_state.numUnappliedChanges; return true; } else if (requestName == "closeSettings") { @@ -279,7 +285,7 @@ namespace loot { return true; } else if (requestName == "applySort") { - g_app_state.isMidSort = false; + --g_app_state.numUnappliedChanges; BOOST_LOG_TRIVIAL(trace) << "User has accepted sorted load order, applying it."; try { g_app_state.CurrentGame().SetLoadOrder(request["args"][0].as>()); @@ -909,7 +915,7 @@ namespace loot { node.push_back(pluginNode); } - g_app_state.isMidSort = true; + ++g_app_state.numUnappliedChanges; if (node.size() > 0) callback->Success(JSON::stringify(node)); @@ -1131,8 +1137,8 @@ namespace loot { assert(CefCurrentlyOn(TID_UI)); // Check if unapplied sorting changes exist. - if (g_app_state.isMidSort) { - browser->GetMainFrame()->ExecuteJavaScript("handleUnappliedChangesClose();", browser->GetMainFrame()->GetURL(), 0); + if (g_app_state.numUnappliedChanges > 0) { + browser->GetMainFrame()->ExecuteJavaScript("handleQuit();", browser->GetMainFrame()->GetURL(), 0); return true; }