diff --git a/resources/report/js/script.js b/resources/report/js/script.js index 3ab20846..8aade6f1 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -359,6 +359,7 @@ function processCefError(err) { /* Error.stack seems to be Chromium-specific. It gives a lot more useful info than just the error message. */ console.log(err.stack); + closeProgressDialog(); showMessageBox('error', 'Error', err.message); } @@ -661,8 +662,11 @@ function openReadme(evt) { loot.query('openReadme').catch(processCefError); } function updateMasterlist(evt) { + updateProgressDialog('Updating masterlist...'); + openProgressDialog(); loot.query('updateMasterlist').then(JSON.parse).then(function(result){ if (result == null) { + closeProgressDialog(); return; } /* Update JS variables. */ @@ -683,6 +687,7 @@ function updateMasterlist(evt) { } } }); + closeProgressDialog(); }).catch(processCefError); } function sortUIElements(pluginNames) { @@ -746,11 +751,9 @@ function sortUIElements(pluginNames) { lastCard = card; }); } -function toggleProgressDialog() { +function openProgressDialog() { var progressDialog = document.getElementById('progressDialog'); - if (progressDialog.open) { - progressDialog.close(); - } else { + if (!progressDialog.open) { progressDialog.showModal(); } } @@ -758,12 +761,18 @@ function updateProgressDialog(message) { var progressDialog = document.getElementById('progressDialog'); progressDialog.getElementsByTagName('h1')[0].textContent = message; } +function closeProgressDialog() { + var progressDialog = document.getElementById('progressDialog'); + if (progressDialog.open) { + progressDialog.close(); + } +} function sortPlugins(evt) { - updateProgressDialog('Sorting plugins...'); - toggleProgressDialog(); if (loot.settings.updateMasterlist) { updateMasterlist(evt); } + updateProgressDialog('Sorting plugins...'); + openProgressDialog(); loot.query('sortPlugins').then(JSON.parse).then(function(result){ if (result) { var loadOrder = []; @@ -800,7 +809,7 @@ function sortPlugins(evt) { hideElement(document.getElementById('sortButton')); showElement(document.getElementById('applySortButton')); showElement(document.getElementById('cancelSortButton')); - toggleProgressDialog(); + closeProgressDialog(); } }).catch(processCefError); } diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index eb3fa58d..9d75d7cc 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -166,18 +166,7 @@ namespace loot { return true; } else if (request == "updateMasterlist") { - try { - callback->Success(UpdateMasterlist()); - } - catch (error &e) { - BOOST_LOG_TRIVIAL(error) << "Failed to update the masterlist. " << e.what(); - callback->Failure(e.code(), e.what()); - } - catch (exception &e) { - BOOST_LOG_TRIVIAL(error) << "Failed to update the masterlist. " << e.what(); - callback->Failure(-1, e.what()); - } - return true; + return CefPostTask(TID_FILE, base::Bind(&Handler::UpdateMasterlist, base::Unretained(this), callback)); } else if (request == "sortPlugins") { return CefPostTask(TID_FILE, base::Bind(&Handler::SortPlugins, base::Unretained(this), callback)); @@ -728,93 +717,103 @@ namespace loot { return JSON::stringify(gameNode); } - std::string Handler::UpdateMasterlist() { - BOOST_LOG_TRIVIAL(debug) << "Updating and parsing masterlist."; - - //Set language. - unsigned int language; - if (g_app_state.GetSettings()["language"]) - language = Language(g_app_state.GetSettings()["language"].as()).Code(); - else - language = Language::any; - BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); - - // Update / parse masterlist. - bool wasChanged = true; + void Handler::UpdateMasterlist(CefRefPtr callback) { try { - wasChanged = g_app_state.CurrentGame().masterlist.Load(g_app_state.CurrentGame(), language); - } - catch (loot::error &e) { - if (e.code() == loot::error::ok) { - // There was a parsing error, but roll-back was successful, so the process - // should still complete. - g_app_state.CurrentGame().masterlist.messages.push_back(Message(Message::error, e.what())); - wasChanged = true; + BOOST_LOG_TRIVIAL(debug) << "Updating and parsing masterlist."; + + //Set language. + unsigned int language; + if (g_app_state.GetSettings()["language"]) + language = Language(g_app_state.GetSettings()["language"].as()).Code(); + else + language = Language::any; + BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name(); + + // Update / parse masterlist. + bool wasChanged = true; + try { + wasChanged = g_app_state.CurrentGame().masterlist.Load(g_app_state.CurrentGame(), language); + } + catch (loot::error &e) { + if (e.code() == loot::error::ok) { + // There was a parsing error, but roll-back was successful, so the process + // should still complete. + g_app_state.CurrentGame().masterlist.messages.push_back(Message(Message::error, e.what())); + wasChanged = true; + } + else + throw e; + } + + // Now regenerate the JS-side masterlist data if the masterlist was changed. + if (wasChanged) { + // The data structure is to be set as 'loot.game'. + YAML::Node gameNode; + + // Store the masterlist revision and date. + gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath()); + gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); + + for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { + Plugin mlistPlugin(pluginPair.second); + mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(pluginPair.second)); + + YAML::Node pluginNode; + if (!mlistPlugin.HasNameOnly()) { + // Now add the masterlist metadata to the pluginNode. + pluginNode["masterlist"]["after"] = mlistPlugin.LoadAfter(); + pluginNode["masterlist"]["req"] = mlistPlugin.Reqs(); + pluginNode["masterlist"]["inc"] = mlistPlugin.Incs(); + pluginNode["masterlist"]["msg"] = mlistPlugin.Messages(); + pluginNode["masterlist"]["tag"] = mlistPlugin.Tags(); + pluginNode["masterlist"]["dirty"] = mlistPlugin.DirtyInfo(); + } + + // Now merge masterlist and userlist metadata and evaluate, + // putting any resulting metadata into the base of the pluginNode. + YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name()); + + for (auto it = derivedNode.begin(); it != derivedNode.end(); ++it) { + const string key = it->first.as(); + pluginNode[key] = it->second; + } + + gameNode["plugins"].push_back(pluginNode); + } + + //Evaluate any conditions in the global messages. + BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions."; + list messages = g_app_state.CurrentGame().masterlist.messages; + try { + list::iterator it = messages.begin(); + while (it != messages.end()) { + if (!it->EvalCondition(g_app_state.CurrentGame(), language)) + it = messages.erase(it); + else + ++it; + } + } + catch (std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "A global message contains a condition that could not be evaluated. Details: " << e.what(); + messages.push_back(Message(Message::error, (format(loc::translate("A global message contains a condition that could not be evaluated. Details: %1%")) % e.what()).str())); + } + + // Now store global messages from masterlist. + gameNode["globalMessages"] = messages; + + callback->Success(JSON::stringify(gameNode)); } else - throw e; + callback->Success("null"); } - - // Now regenerate the JS-side masterlist data if the masterlist was changed. - if (wasChanged) { - // The data structure is to be set as 'loot.game'. - YAML::Node gameNode; - - // Store the masterlist revision and date. - gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath()); - gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath()); - - for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { - Plugin mlistPlugin(pluginPair.second); - mlistPlugin.MergeMetadata(g_app_state.CurrentGame().masterlist.FindPlugin(pluginPair.second)); - - YAML::Node pluginNode; - if (!mlistPlugin.HasNameOnly()) { - // Now add the masterlist metadata to the pluginNode. - pluginNode["masterlist"]["after"] = mlistPlugin.LoadAfter(); - pluginNode["masterlist"]["req"] = mlistPlugin.Reqs(); - pluginNode["masterlist"]["inc"] = mlistPlugin.Incs(); - pluginNode["masterlist"]["msg"] = mlistPlugin.Messages(); - pluginNode["masterlist"]["tag"] = mlistPlugin.Tags(); - pluginNode["masterlist"]["dirty"] = mlistPlugin.DirtyInfo(); - } - - // Now merge masterlist and userlist metadata and evaluate, - // putting any resulting metadata into the base of the pluginNode. - YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name()); - - for (auto it = derivedNode.begin(); it != derivedNode.end(); ++it) { - const string key = it->first.as(); - pluginNode[key] = it->second; - } - - gameNode["plugins"].push_back(pluginNode); - } - - //Evaluate any conditions in the global messages. - BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions."; - list messages = g_app_state.CurrentGame().masterlist.messages; - try { - list::iterator it = messages.begin(); - while (it != messages.end()) { - if (!it->EvalCondition(g_app_state.CurrentGame(), language)) - it = messages.erase(it); - else - ++it; - } - } - catch (std::exception& e) { - BOOST_LOG_TRIVIAL(error) << "A global message contains a condition that could not be evaluated. Details: " << e.what(); - messages.push_back(Message(Message::error, (format(loc::translate("A global message contains a condition that could not be evaluated. Details: %1%")) % e.what()).str())); - } - - // Now store global messages from masterlist. - gameNode["globalMessages"] = messages; - - return JSON::stringify(gameNode); + catch (error &e) { + BOOST_LOG_TRIVIAL(error) << "Failed to update the masterlist. " << e.what(); + callback->Failure(e.code(), e.what()); + } + catch (exception &e) { + BOOST_LOG_TRIVIAL(error) << "Failed to update the masterlist. " << e.what(); + callback->Failure(-1, e.what()); } - else - return "null"; } std::string Handler::ClearAllMetadata() { @@ -843,7 +842,7 @@ namespace loot { return "[]"; } - void Handler::SortPlugins(CefRefPtr callback) { + void Handler::SortPlugins(CefRefPtr callback) { //Set language. unsigned int language; if (g_app_state.GetSettings()["language"]) diff --git a/src/gui/handler.h b/src/gui/handler.h index 8b556b5e..bfa8499d 100644 --- a/src/gui/handler.h +++ b/src/gui/handler.h @@ -57,7 +57,7 @@ namespace loot { std::string GetGameTypes(); std::string GetInstalledGames(); std::string GetGameData(); - std::string UpdateMasterlist(); + void UpdateMasterlist(CefRefPtr callback); std::string ClearAllMetadata(); void SortPlugins(CefRefPtr callback);