From a189a4670fa32a4ae2c2b8e6be1e66f2a24b6ad0 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Sun, 10 Aug 2014 17:48:36 +0100 Subject: [PATCH] Updated how games are handled in settings window. * Game menu now gets updated when settings are changed to reflect any changes in games available. * The current game can no longer be deleted in the settings window. * Changing game settings updates rather than replaces existing entries (fixes #199). Also removed a few unused wxIDs. --- src/backend/game.cpp | 4 ++++ src/backend/game.h | 1 + src/gui/ids.h | 5 +---- src/gui/main.cpp | 19 ++++++++++++++++- src/gui/settings.cpp | 51 ++++++++++++++++++++++++++++++++------------ src/gui/settings.h | 3 ++- 6 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/backend/game.cpp b/src/backend/game.cpp index b40ffd56..c4426e05 100644 --- a/src/backend/game.cpp +++ b/src/backend/game.cpp @@ -310,6 +310,10 @@ namespace loot { return (boost::iequals(_name, rhs.Name()) || boost::iequals(lootFolderName, rhs.FolderName())); } + bool Game::operator == (const std::string& nameOrFolderName) const { + return (boost::iequals(_name, nameOrFolderName) || boost::iequals(lootFolderName, nameOrFolderName)); + } + unsigned int Game::Id() const { return id; } diff --git a/src/backend/game.h b/src/backend/game.h index 7da286de..de47ec9d 100644 --- a/src/backend/game.h +++ b/src/backend/game.h @@ -95,6 +95,7 @@ namespace loot { bool IsInstalled() const; bool operator == (const Game& rhs) const; //Compares names and folder names. + bool operator == (const std::string& nameOrFolderName) const; unsigned int Id() const; std::string Name() const; //Returns the game's name, eg. "TES IV: Oblivion". diff --git a/src/gui/ids.h b/src/gui/ids.h index 8549ecda..8230c7e2 100644 --- a/src/gui/ids.h +++ b/src/gui/ids.h @@ -69,12 +69,9 @@ enum { MENU_CopyMetadata, MENU_ClearPluginMetadata, MENU_ClearAllMetadata, + CHECKBOX_Filter, //Main window - dynamically created IDs. MENU_LowestDynamicGameID, - LIST_LoadOrder, - BUTTON_MoveUp, - BUTTON_MoveDown, - CHECKBOX_Filter }; wxString translate(const std::string& str); diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 0c559f40..dfde8c53 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -482,7 +482,7 @@ void Launcher::OnOpenSettings(wxCommandEvent& event) { GetWindowSizePos(_settings["windows"]["settings"], pos, size); } - SettingsFrame settings = SettingsFrame(this, translate("LOOT: Settings"), _settings, _games, pos, size); + SettingsFrame settings = SettingsFrame(this, translate("LOOT: Settings"), _settings, _games, _currentGame, pos, size); BOOST_LOG_TRIVIAL(debug) << "Settings window opened."; settings.ShowModal(); @@ -494,6 +494,23 @@ void Launcher::OnOpenSettings(wxCommandEvent& event) { node["yPos"] = settings.GetPosition().y; _settings["windows"]["settings"] = node; + + // Clear existing games menu items. + for (size_t i = 0, max = GameMenu->GetMenuItemCount(); i < max; ++i) { + GameMenu->Delete(MENU_LowestDynamicGameID + i); + } + // Fill games list again. + for (size_t i = 0, max = _games.size(); i < max; ++i) { + wxMenuItem * item = GameMenu->AppendRadioItem(MENU_LowestDynamicGameID + i, FromUTF8(_games[i].Name())); + if (_games[_currentGame] == _games[i]) + item->Check(); + + if (_games[i].IsInstalled()) + Bind(wxEVT_MENU, &Launcher::OnGameChange, this, MENU_LowestDynamicGameID + i); + else + item->Enable(false); + } + } void Launcher::OnGameChange(wxCommandEvent& event) { diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 0b46bdb1..b23b6861 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -34,7 +34,7 @@ using namespace std; -SettingsFrame::SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node& settings, std::vector& games, wxPoint pos, wxSize size) : wxDialog(parent, wxID_ANY, title, pos, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), _settings(settings), _games(games) { +SettingsFrame::SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node& settings, std::vector& games, size_t currentGameIndex, wxPoint pos, wxSize size) : wxDialog(parent, wxID_ANY, title, pos, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), _settings(settings), _games(games), _currentGameIndex(currentGameIndex) { //Initialise drop-down list contents. wxString DebugVerbosity[] = { @@ -224,19 +224,25 @@ void SettingsFrame::OnQuit(wxCommandEvent& event) { _settings["Update Masterlist"] = UpdateMasterlistBox->IsChecked(); - _games.clear(); + unordered_set newGameFolders; for (size_t i=0,max=gamesList->GetItemCount(); i < max; ++i) { - string name, folder, master, repo, branch, path, registry; + /* We want to avoid overwriting existing game objects as doing so + clears the game caches. Instead, recognise that game folder names + must be unique. Therefore, use Game::SetDetails() to set + the settings for each existing game, and add new games on. + For any games that have been deleted, check against the newGameNames + hashset and remove any not in it. + */ + + string name = gamesList->GetItemText(i, 0).ToUTF8(); + string folder = gamesList->GetItemText(i, 2).ToUTF8(); + string master = gamesList->GetItemText(i, 3).ToUTF8(); + string repo = gamesList->GetItemText(i, 4).ToUTF8(); + string branch = gamesList->GetItemText(i, 5).ToUTF8(); + string path = gamesList->GetItemText(i, 6).ToUTF8(); + string registry = gamesList->GetItemText(i, 7).ToUTF8(); + unsigned int id; - - name = gamesList->GetItemText(i, 0).ToUTF8(); - folder = gamesList->GetItemText(i, 2).ToUTF8(); - master = gamesList->GetItemText(i, 3).ToUTF8(); - repo = gamesList->GetItemText(i, 4).ToUTF8(); - branch = gamesList->GetItemText(i, 5).ToUTF8(); - path = gamesList->GetItemText(i, 6).ToUTF8(); - registry = gamesList->GetItemText(i, 7).ToUTF8(); - if (gamesList->GetItemText(i, 1).ToUTF8() == loot::Game(loot::Game::tes4).FolderName()) id = loot::Game::tes4; else if (gamesList->GetItemText(i, 1).ToUTF8() == loot::Game(loot::Game::tes5).FolderName()) @@ -246,7 +252,23 @@ void SettingsFrame::OnQuit(wxCommandEvent& event) { else id = loot::Game::fonv; - _games.push_back(loot::Game(id, folder).SetDetails(name, master, repo, branch, path, registry)); + auto pos = find(_games.begin(), _games.end(), folder); + + if (pos != _games.end()) { + pos->SetDetails(name, master, repo, branch, path, registry); + } + else { + _games.push_back(loot::Game(id, folder).SetDetails(name, master, repo, branch, path, registry)); + } + + newGameFolders.insert(folder); + } + + for (auto it = _games.begin(); it != _games.end();) { + if (newGameFolders.find(it->FolderName()) == newGameFolders.end()) + it = _games.erase(it); + else + ++it; } } @@ -258,7 +280,8 @@ void SettingsFrame::OnGameSelect(wxListEvent& event) { if (name == loot::Game(loot::Game::tes4).Name() || name == loot::Game(loot::Game::tes5).Name() || name == loot::Game(loot::Game::fo3).Name() - || name == loot::Game(loot::Game::fonv).Name()) { + || name == loot::Game(loot::Game::fonv).Name() + || event.GetIndex() == _currentGameIndex) { removeBtn->Enable(false); } else { removeBtn->Enable(true); diff --git a/src/gui/settings.h b/src/gui/settings.h index bc67d870..43e8a2f7 100644 --- a/src/gui/settings.h +++ b/src/gui/settings.h @@ -33,7 +33,7 @@ class SettingsFrame : public wxDialog { public: - SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node& settings, std::vector& games, wxPoint pos, wxSize size); + SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node& settings, std::vector& games, size_t currentGameIndex, wxPoint pos, wxSize size); void OnQuit(wxCommandEvent& event); void OnGameSelect(wxListEvent& event); @@ -55,6 +55,7 @@ private: YAML::Node& _settings; std::vector& _games; + size_t _currentGameIndex; }; class GameEditDialog : public wxDialog {