diff --git a/resources/report/js/events.js b/resources/report/js/events.js
index 6f01e76b..0f85748b 100644
--- a/resources/report/js/events.js
+++ b/resources/report/js/events.js
@@ -333,6 +333,28 @@ function onCopyContent(evt) {
toast(l10n.jed.translate("LOOT's content has been copied to the clipboard.").fetch());
}).catch(processCefError);
}
+function onCopyLoadOrder(evt) {
+ var plugins = [];
+
+ if (loot.game) {
+ if (loot.game.plugins) {
+ loot.game.plugins.forEach(function(plugin){
+ plugins.push(plugin.name);
+ });
+ }
+ }
+
+ var request = JSON.stringify({
+ name: 'copyLoadOrder',
+ args: [
+ plugins
+ ]
+ });
+
+ loot.query(request).then(function(){
+ toast(l10n.jed.translate("The load order has been copied to the clipboard.").fetch());
+ }).catch(processCefError);
+}
function onSwitchSidebarTab(evt) {
if (evt.detail.isSelected) {
document.getElementById(evt.target.selected).parentElement.selected = evt.target.selected;
@@ -696,6 +718,7 @@ function setupEventHandlers() {
document.getElementById('redatePluginsButton').addEventListener('click', onRedatePlugins, false);
document.getElementById('openLogButton').addEventListener('click', onOpenLogLocation, false);
document.getElementById('wipeUserlistButton').addEventListener('click', onClearAllMetadata, false);
+ document.getElementById('copyLoadOrderButton').addEventListener('click', onCopyLoadOrder, false);
document.getElementById('copyContentButton').addEventListener('click', onCopyContent, false);
document.getElementById('refreshContentButton').addEventListener('click', onContentRefresh, false);
document.getElementById('settingsButton').addEventListener('click', onShowSettingsDialog, false);
diff --git a/resources/report/report.html b/resources/report/report.html
index a0c3b0bd..c8565aac 100644
--- a/resources/report/report.html
+++ b/resources/report/report.html
@@ -119,6 +119,10 @@
Clear All User Metadata
+
+
+ Copy Load Order
+
Copy Content
diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp
index bd44dcc1..1d98263e 100644
--- a/src/gui/handler.cpp
+++ b/src/gui/handler.cpp
@@ -43,6 +43,7 @@
#include
#include
+#include
using namespace std;
@@ -323,6 +324,34 @@ namespace loot {
}
return true;
}
+ else if (requestName == "copyLoadOrder") {
+ // Has one arg, an array of plugins in load order. Output them with indices in dec and hex.
+ try {
+ stringstream ss;
+ vector plugins = request["args"][0].as>();
+ int decLength = 1;
+ if (plugins.size() > 99) {
+ decLength = 3;
+ }
+ else if (plugins.size() > 9) {
+ decLength = 2;
+ }
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ ss << setw(decLength) << i << " " << hex << setw(2) << i << dec << " " << plugins[i] << "\r\n";
+ }
+ CopyToClipboard(ss.str());
+ callback->Success("");
+ }
+ catch (loot::error &e) {
+ BOOST_LOG_TRIVIAL(error) << "Failed to copy plugin metadata. Details: " << e.what();
+ callback->Failure(e.code(), (boost::format(loc::translate("Failed to copy plugin metadata. Details: %1%")) % e.what()).str());
+ }
+ catch (std::exception& e) {
+ BOOST_LOG_TRIVIAL(error) << "Failed to copy plugin metadata. Details: " << e.what();
+ callback->Failure(-1, (boost::format(loc::translate("Failed to copy plugin metadata. Details: %1%")) % e.what()).str());
+ }
+ return true;
+ }
else if (requestName == "saveFilterState") {
// Has two args: the first is the filter ID, the second is the value.
BOOST_LOG_TRIVIAL(trace) << "Saving filter states.";