diff --git a/src/backend/game.cpp b/src/backend/game.cpp index e29e08ac..b40ffd56 100644 --- a/src/backend/game.cpp +++ b/src/backend/game.cpp @@ -85,7 +85,7 @@ namespace loot { // MetadataList member functions //------------------------------ - void MetadataList::Load(boost::filesystem::path& filepath) { + void MetadataList::Load(const boost::filesystem::path& filepath) { plugins.clear(); messages.clear(); @@ -103,7 +103,7 @@ namespace loot { BOOST_LOG_TRIVIAL(debug) << "File loaded successfully."; } - void MetadataList::Save(boost::filesystem::path& filepath) { + void MetadataList::Save(const boost::filesystem::path& filepath) { YAML::Emitter yout; yout.SetIndent(2); yout << YAML::BeginMap @@ -116,6 +116,38 @@ namespace loot { uout.close(); } + bool MetadataList::operator == (const MetadataList& rhs) const { + if (this->plugins.size() != rhs.plugins.size() || this->messages.size() != rhs.messages.size()) { + BOOST_LOG_TRIVIAL(info) << "Metadata edited for some plugin, new and old userlists differ in size."; + return false; + } + else { + for (const auto& rhsPlugin : rhs.plugins) { + const auto it = std::find(this->plugins.begin(), this->plugins.end(), rhsPlugin); + + if (it == this->plugins.end()) { + BOOST_LOG_TRIVIAL(info) << "Metadata added for plugin: " << it->Name(); + return false; + } + + if (!it->DiffMetadata(rhsPlugin).HasNameOnly()) { + BOOST_LOG_TRIVIAL(info) << "Metadata edited for plugin: " << it->Name(); + return false; + } + } + // Messages are compared exactly by the '==' operator, so there's no need to do a more + // fine-grained check. + for (const auto& rhsMessage : rhs.messages) { + const auto it = std::find(this->messages.begin(), this->messages.end(), rhsMessage); + + if (it == this->messages.end()) { + return false; + } + } + } + return true; + } + // Masterlist member functions //---------------------------- @@ -135,14 +167,14 @@ namespace loot { } } - std::string Masterlist::GetRevision(boost::filesystem::path& path) { + std::string Masterlist::GetRevision(const boost::filesystem::path& path) { if (revision.empty()) GetGitInfo(path); return revision; } - std::string Masterlist::GetDate(boost::filesystem::path& path) { + std::string Masterlist::GetDate(const boost::filesystem::path& path) { if (date.empty()) GetGitInfo(path); diff --git a/src/backend/game.h b/src/backend/game.h index 540c53b1..7da286de 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -55,8 +55,10 @@ namespace loot { class MetadataList { public: - void Load(boost::filesystem::path& filepath); - void Save(boost::filesystem::path& filepath); + void Load(const boost::filesystem::path& filepath); + void Save(const boost::filesystem::path& filepath); + + bool operator == (const MetadataList& rhs) const; //Compares content. std::list plugins; std::list messages; @@ -68,11 +70,11 @@ namespace loot { void Load(Game& game, const unsigned int language); //Handles update with load fallback. void Update(Game& game, const unsigned int language); - std::string GetRevision(boost::filesystem::path& path); - std::string GetDate(boost::filesystem::path& path); + std::string GetRevision(const boost::filesystem::path& path); + std::string GetDate(const boost::filesystem::path& path); private: - void GetGitInfo(boost::filesystem::path& path); + void GetGitInfo(const boost::filesystem::path& path); std::string revision; std::string date; diff --git a/src/backend/git.cpp b/src/backend/git.cpp index e28b0ff3..8202403e 100644 --- a/src/backend/git.cpp +++ b/src/backend/git.cpp @@ -109,7 +109,7 @@ namespace loot { return git_repository_open_ext(NULL, path.string().c_str(), GIT_REPOSITORY_OPEN_NO_SEARCH, NULL) == 0; } - void Masterlist::GetGitInfo(boost::filesystem::path& path) { + void Masterlist::GetGitInfo(const boost::filesystem::path& path) { if (!fs::exists(path.parent_path() / ".git")) { revision = "Unknown: Git repository missing"; date = "Unknown: Git repository missing"; diff --git a/src/gui/editor.cpp b/src/gui/editor.cpp index 7b45d834..1d9d78c1 100644 --- a/src/gui/editor.cpp +++ b/src/gui/editor.cpp @@ -1041,8 +1041,10 @@ void EditorPanel::ApplyCurrentEdits() { ApplyEdits(currentPlugin); } -const std::list& EditorPanel::GetNewUserlist() const { - return _editedPlugins; +loot::MetadataList EditorPanel::GetNewUserlist() const { + loot::MetadataList newUserlist; + newUserlist.plugins = _editedPlugins; + return newUserlist; } loot::Plugin EditorPanel::GetMasterData(const wxString& plugin) const { @@ -1197,7 +1199,7 @@ void MiniEditor::OnResize(wxSizeEvent& event) { event.Skip(); } -const std::list& MiniEditor::GetNewUserlist() const { +loot::MetadataList MiniEditor::GetNewUserlist() const { return editorPanel->GetNewUserlist(); } @@ -1206,7 +1208,7 @@ const std::list& MiniEditor::GetNewUserlist() const { // Full Editor Class /////////////////////////////////// -FullEditor::FullEditor(wxWindow *parent, const wxString& title, wxPoint pos, wxSize size, const std::string userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const loot::Game& game, YAML::Node &settings) : wxFrame(parent, wxID_ANY, title, pos, size), _userlistPath(userlistPath), _settings(settings) { +FullEditor::FullEditor(wxWindow *parent, const wxString& title, wxPoint pos, wxSize size, const boost::filesystem::path& userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const loot::Game& game, YAML::Node &settings) : wxFrame(parent, wxID_ANY, title, pos, size), _userlistPath(userlistPath), _settings(settings) { //Set up content. editorPanel = new EditorPanel(this, basePlugins, editedPlugins, language, game); applyBtn = new wxButton(this, BUTTON_Apply, translate("Save Changes")); @@ -1245,17 +1247,8 @@ void FullEditor::OnQuit(wxCommandEvent& event) { BOOST_LOG_TRIVIAL(debug) << "Saving metadata edits to userlist."; - //Save edits to userlist. - YAML::Emitter yout; - yout.SetIndent(2); - yout << YAML::BeginMap - << YAML::Key << "plugins" << YAML::Value << editorPanel->GetNewUserlist() - << YAML::EndMap; - - boost::filesystem::path p(_userlistPath); - loot::ofstream out(p); - out << yout.c_str(); - out.close(); + loot::MetadataList userlist = editorPanel->GetNewUserlist(); + userlist.Save(_userlistPath); } Close(); } diff --git a/src/gui/editor.h b/src/gui/editor.h index 21e1971a..ef18a0cc 100644 --- a/src/gui/editor.h +++ b/src/gui/editor.h @@ -26,7 +26,9 @@ #include "ids.h" #include "misc.h" + #include "../backend/metadata.h" +#include "../backend/game.h" #include #include @@ -69,7 +71,7 @@ public: void SetSimpleView(bool on = true); void ApplyCurrentEdits(); - const std::list& GetNewUserlist() const; + loot::MetadataList GetNewUserlist() const; void OnPluginSelect(wxListEvent& event); void OnPluginListRightClick(wxListEvent& event); @@ -134,7 +136,7 @@ public: void OnApply(wxCommandEvent& event); void OnResize(wxSizeEvent& event); - const std::list& GetNewUserlist() const; + loot::MetadataList GetNewUserlist() const; private: EditorPanel * editorPanel; wxStaticText * descText; @@ -144,7 +146,7 @@ private: class FullEditor : public wxFrame { public: - FullEditor(wxWindow *parent, const wxString& title, wxPoint pos, wxSize size, const std::string userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const loot::Game& game, YAML::Node &settings); + FullEditor(wxWindow *parent, const wxString& title, wxPoint pos, wxSize size, const boost::filesystem::path& userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const loot::Game& game, YAML::Node &settings); void OnQuit(wxCommandEvent& event); void OnClose(wxCloseEvent &event); @@ -153,7 +155,7 @@ private: wxButton * applyBtn; wxButton * cancelBtn; - const std::string _userlistPath; + const boost::filesystem::path _userlistPath; YAML::Node& _settings; }; #endif diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 15ea9edf..0c559f40 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -259,7 +259,7 @@ bool LOOT::OnInit() { try { gameIndex = SelectGame(_settings, _games, target); } - catch (exception &e) { + catch (exception &) { BOOST_LOG_TRIVIAL(error) << "None of the supported games were detected."; wxMessageBox( translate("Error: None of the supported games were detected."), @@ -615,13 +615,13 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { */ - //Check for back-edges, then perform a topological sort. list plugins; try { bool applyLoadOrder = false; do { + // Perform sort. plugins = _games[_currentGame].Sort(lang, messages, progressCallback); progDia->Destroy(); @@ -636,10 +636,11 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { GetWindowSizePos(_settings["windows"]["editor"], pos, size); } + // Display mini editor. MiniEditor editor(this, translate("LOOT: Calculated Load Order"), pos, size, plugins, _games[_currentGame].userlist.plugins, _games[_currentGame]); long ret = editor.ShowModal(); - const std::list& newUserlist = editor.GetNewUserlist(); + MetadataList newUserlist = editor.GetNewUserlist(); //Record window settings. YAML::Node node; @@ -650,34 +651,11 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { _settings["windows"]["editor"] = node; - //Need to determine if any new edits have been made. - bool haveNewEdits = false; - if (newUserlist.size() != _games[_currentGame].userlist.plugins.size()) { - BOOST_LOG_TRIVIAL(info) << "Metadata edited for some plugin, new and old userlists differ in size."; - haveNewEdits = true; - } - else { - for (const auto& newEdit : newUserlist) { - const auto it = std::find(_games[_currentGame].userlist.plugins.begin(), _games[_currentGame].userlist.plugins.end(), newEdit); - if (it == _games[_currentGame].userlist.plugins.end()) { - BOOST_LOG_TRIVIAL(info) << "Metadata added for plugin: " << it->Name(); - haveNewEdits = true; - break; - } - - if (!it->DiffMetadata(newEdit).HasNameOnly()) { - BOOST_LOG_TRIVIAL(info) << "Metadata edited for plugin: " << it->Name(); - haveNewEdits = true; - break; - } - } - } - if (ret != wxID_APPLY) { applyLoadOrder = false; break; } - else if (!haveNewEdits) { + else if (_games[_currentGame].userlist == newUserlist) { applyLoadOrder = true; break; } @@ -686,7 +664,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { progDia = new wxProgressDialog(translate("LOOT: Working..."), translate("Recalculating load order..."), 1000, this, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_ELAPSED_TIME); //User accepted edits, now apply them, then loop. - _games[_currentGame].userlist.plugins = newUserlist; + _games[_currentGame].userlist = newUserlist; //Save edits to userlist. _games[_currentGame].userlist.Save(_games[_currentGame].UserlistPath());