From 1771c0830fdb84ca4d5a43f5702409a055b25f17 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Sun, 9 Feb 2014 09:55:26 +0000 Subject: [PATCH] Initial work on #106. Moved the load order preview window to a new header/source file, and cut out the move up/down buttons. Started to implement mini editor. --- CMakeLists.txt | 1 + src/gui/editor.h | 3 - src/gui/main.cpp | 201 +------------------------------------------- src/gui/main.h | 19 ----- src/gui/sorting.cpp | 168 ++++++++++++++++++++++++++++++++++++ src/gui/sorting.h | 66 +++++++++++++++ 6 files changed, 239 insertions(+), 219 deletions(-) create mode 100644 src/gui/sorting.cpp create mode 100644 src/gui/sorting.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 70cedffb..d5820139 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set (BOSS_GUI_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/gui/settings.cpp" "${CMAKE_SOURCE_DIR}/src/gui/editor.cpp" "${CMAKE_SOURCE_DIR}/src/gui/viewer.cpp" + "${CMAKE_SOURCE_DIR}/src/gui/sorting.cpp" "${CMAKE_SOURCE_DIR}/src/resource.rc") set (BOSS_API_SRC ${BOSS_SRC} diff --git a/src/gui/editor.h b/src/gui/editor.h index 55f565b2..3d94c292 100644 --- a/src/gui/editor.h +++ b/src/gui/editor.h @@ -61,13 +61,10 @@ public: void OnPluginCopyName(wxCommandEvent& event); void OnPluginCopyMetadata(wxCommandEvent& event); void OnPluginClearMetadata(wxCommandEvent& event); - void OnEnabledToggle(wxCommandEvent& event); - void OnPriorityChange(wxSpinEvent& event); void OnListBookChange(wxBookCtrlEvent& event); void OnAddRow(wxCommandEvent& event); void OnEditRow(wxCommandEvent& event); void OnRemoveRow(wxCommandEvent& event); - void OnRecalc(wxCommandEvent& event); void OnRowSelect(wxListEvent& event); void OnQuit(wxCommandEvent& event); private: diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 1e957dd5..0e3d692e 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -24,6 +24,7 @@ #include "settings.h" #include "editor.h" #include "viewer.h" +#include "sorting.h" #include "../backend/globals.h" #include "../backend/metadata.h" @@ -680,7 +681,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { if (preview.ShowModal() == wxID_OK) { BOOST_LOG_TRIVIAL(debug) << "Load order accepted."; list newPluginsList, editedPlugins; - newPluginsList = preview.GetLoadOrder(); + /*newPluginsList = preview.GetLoadOrder(); BOOST_LOG_TRIVIAL(trace) << "Building list of edited plugins."; for (list::iterator it=newPluginsList.begin(),endit=newPluginsList.end(); it != endit; ++it) { @@ -746,7 +747,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) { uout << yout.c_str(); uout.close(); } - + */ //Now set load order. BOOST_LOG_TRIVIAL(debug) << "Setting load order."; try { @@ -1093,198 +1094,4 @@ void Launcher::OnAbout(wxCommandEvent& event) { "along with this program. If not, see ."); aboutInfo.SetIcon(wxIconLocation("BOSS.exe")); wxAboutBox(aboutInfo); -} - -LoadOrderPreview::LoadOrderPreview(wxWindow *parent, const wxString title, const std::list& plugins, const boss::Game& game) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), _plugins(plugins), _game(game) { - - //Init controls. - _loadOrder = new wxListView(this, LIST_LoadOrder, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); - - _moveUp = new wxButton(this, BUTTON_MoveUp, translate("Up")); - _moveDown = new wxButton(this, BUTTON_MoveDown, translate("Down")); - - //Populate list. - _loadOrder->AppendColumn(translate("Load Order")); - size_t i=0; - for (list::const_iterator it=plugins.begin(), endit=plugins.end(); it != endit; ++it, ++i) { - _loadOrder->InsertItem(i, FromUTF8(it->Name())); - if (it->FormIDs().empty()) { - _loadOrder->SetItemTextColour(i, wxColour(122, 122, 122)); - } - else if (it->LoadsBSA(_game)) { - _loadOrder->SetItemTextColour(i, wxColour(0, 142, 219)); - } - } - _loadOrder->SetColumnWidth(0, wxLIST_AUTOSIZE); - - //Set up event handling. - Bind(wxEVT_BUTTON, &LoadOrderPreview::OnMoveUp, this, BUTTON_MoveUp); - Bind(wxEVT_BUTTON, &LoadOrderPreview::OnMoveDown, this, BUTTON_MoveDown); - Bind(wxEVT_LIST_ITEM_SELECTED, &LoadOrderPreview::OnPluginSelect, this, LIST_LoadOrder); - - //Set up layout. - wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL); - - bigBox->Add(_loadOrder, 1, wxEXPAND|wxALL, 15); - - wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL); - hbox->Add(_moveUp, 0, wxRIGHT, 5); - hbox->Add(_moveDown, 0, wxLEFT, 5); - bigBox->Add(hbox, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT, 15); - - bigBox->Add(new wxStaticText(this, wxID_ANY, translate("Please submit any alterations made for reasons other than user preference \nto the BOSS team so that they may include the changes in the masterlist.")), 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 15); - - //Need to add 'OK' and 'Cancel' buttons. - wxSizer * sizer = CreateSeparatedButtonSizer(wxOK|wxCANCEL); - - //Now add TabHolder and OK button to window sizer. - if (sizer != NULL) - bigBox->Add(sizer, 0, wxEXPAND|wxLEFT|wxBOTTOM|wxRIGHT, 15); - - //Set initial up/down button states. - _moveUp->Enable(false); - _moveDown->Enable(false); - - //Now set the layout and sizes. - SetBackgroundColour(wxColour(255,255,255)); - SetIcon(wxIconLocation("BOSS.exe")); - SetSizerAndFit(bigBox); -} - -void LoadOrderPreview::OnPluginSelect(wxListEvent& event) { - _moveUp->Enable(true); - _moveDown->Enable(true); -} - -void LoadOrderPreview::OnMoveUp(wxCommandEvent& event) { - BOOST_LOG_TRIVIAL(debug) << "Moving plugin(s) up the load order."; - long selected = _loadOrder->GetFirstSelected(); - - if (selected == 0) - return; - - while (selected != -1) { - wxString selectedText = _loadOrder->GetItemText(selected); - wxString aboveText = _loadOrder->GetItemText(selected - 1); - - BOOST_LOG_TRIVIAL(trace) << "Moving plugin \"" << string(selectedText.ToUTF8()); - - //Check that move is OK. - list::const_iterator selectedPlugin = find(_plugins.begin(), _plugins.end(), boss::Plugin(string(selectedText.ToUTF8()))); - list::const_iterator abovePlugin = find(_plugins.begin(), _plugins.end(), boss::Plugin(string(aboveText.ToUTF8()))); - - if (selectedPlugin != _plugins.end() && abovePlugin != _plugins.end()) { - if (selectedPlugin->MustLoadAfter(*abovePlugin)) { - BOOST_LOG_TRIVIAL(error) << "Cannot load \"" << selectedPlugin->Name() << "\" before \"" << abovePlugin->Name() << "\"."; - wxMessageBox( - FromUTF8(format(loc::translate("Error: Cannot load \"%1%\" before \"%2%\".")) % selectedPlugin->Name() % abovePlugin->Name()), - translate("BOSS: Error"), - wxOK | wxICON_ERROR, - NULL); - selected = _loadOrder->GetNextSelected(selected); - continue; - } - } - - _loadOrder->SetItemText(selected, aboveText); - _loadOrder->SetItemText(selected - 1, selectedText); - - _movedPlugins.insert(string(selectedText.ToUTF8())); - - _loadOrder->Select(selected, false); - _loadOrder->Select(selected - 1, true); - - selected = _loadOrder->GetNextSelected(selected); - } - BOOST_LOG_TRIVIAL(debug) << "Plugin(s) moved up."; -} - -void LoadOrderPreview::OnMoveDown(wxCommandEvent& event) { - BOOST_LOG_TRIVIAL(debug) << "Moving plugin(s) down the load order."; - long i=_loadOrder->GetItemCount() - 1; - - if (_loadOrder->IsSelected(i)) - return; - --i; - - for (i; i > -1; --i) { - if (_loadOrder->IsSelected(i)) { - wxString selectedText = _loadOrder->GetItemText(i); - wxString belowText = _loadOrder->GetItemText(i + 1); - - BOOST_LOG_TRIVIAL(trace) << "Moving plugin \"" << string(selectedText.ToUTF8()); - - //Check that move is OK. - list::const_iterator selectedPlugin = find(_plugins.begin(), _plugins.end(), boss::Plugin(string(selectedText.ToUTF8()))); - list::const_iterator belowPlugin = find(_plugins.begin(), _plugins.end(), boss::Plugin(string(belowText.ToUTF8()))); - - if (selectedPlugin != _plugins.end() && belowPlugin != _plugins.end()) { - if (belowPlugin->MustLoadAfter(*selectedPlugin)) { - BOOST_LOG_TRIVIAL(error) << "Cannot load \"" << belowPlugin->Name() << "\" before \"" << selectedPlugin->Name() << "\"."; - wxMessageBox( - FromUTF8(format(loc::translate("Error: Cannot load \"%1%\" before \"%2%\".")) % belowPlugin->Name() % selectedPlugin->Name()), - translate("BOSS: Error"), - wxOK | wxICON_ERROR, - NULL); - continue; - } - } - - _loadOrder->SetItemText(i, belowText); - _loadOrder->SetItemText(i + 1, selectedText); - - _movedPlugins.insert(string(selectedText.ToUTF8())); - - _loadOrder->Select(i, false); - _loadOrder->Select(i + 1, true); - } - } - BOOST_LOG_TRIVIAL(debug) << "Plugin(s) moved down."; -} - -std::list LoadOrderPreview::GetLoadOrder() const { - BOOST_LOG_TRIVIAL(debug) << "Getting full load order from preview window."; - list plugins; - bool wasMovedUp = false; - for (size_t i=0,max=_loadOrder->GetItemCount(); i < max; ++i) { - string name = string(_loadOrder->GetItemText(i).ToUTF8()); - - list::const_iterator it = find(_plugins.begin(), _plugins.end(), boss::Plugin(name)); - - if (it == _plugins.end()) - continue; - - plugins.push_back(*it); - - if (wasMovedUp) { - BOOST_LOG_TRIVIAL(trace) << "The previous plugin was moved up in the load order, so adding it to the 'load after' set for the current plugin."; - list::const_iterator jt = ----plugins.end(); - set loadAfter = plugins.back().LoadAfter(); - loadAfter.insert(File(jt->Name())); - plugins.back().LoadAfter(loadAfter); - wasMovedUp = false; - } - - if (_movedPlugins.find(name) != _movedPlugins.end()) { - BOOST_LOG_TRIVIAL(trace) << "The current plugin was moved - checking if it was moved up or down."; - //Check if this plugin has been moved earlier or later by comparing distances in the original list and the new one. - size_t newDist = plugins.size() - 1; - size_t oldDist = distance(_plugins.begin(), it); - - if (newDist > oldDist) { - BOOST_LOG_TRIVIAL(trace) << "The current plugin was moved down, add the preceding plugin to the current plugin's 'load after' set."; - //Record the preceding plugin in this plugin's "load after" set. - list::const_iterator jt = ----plugins.end(); - set loadAfter = plugins.back().LoadAfter(); - loadAfter.insert(File(jt->Name())); - plugins.back().LoadAfter(loadAfter); - } else { - BOOST_LOG_TRIVIAL(trace) << "The current plugin was moved up."; - //Record this plugin in the following plugin's "load after" set. - wasMovedUp = true; - } - } - } - - return plugins; -} +} \ No newline at end of file diff --git a/src/gui/main.h b/src/gui/main.h index f682cdd3..ce6d59a7 100644 --- a/src/gui/main.h +++ b/src/gui/main.h @@ -70,23 +70,4 @@ private: std::vector& _games; }; -class LoadOrderPreview : public wxDialog { -public: - LoadOrderPreview(wxWindow *parent, const wxString title, const std::list& plugins, const boss::Game& game); - - void OnPluginSelect(wxListEvent& event); - void OnMoveUp(wxCommandEvent& event); - void OnMoveDown(wxCommandEvent& event); - - std::list GetLoadOrder() const; -private: - wxListView * _loadOrder; - wxButton * _moveUp; - wxButton * _moveDown; - - const std::list _plugins; - std::set _movedPlugins; - const boss::Game& _game; -}; - #endif diff --git a/src/gui/sorting.cpp b/src/gui/sorting.cpp new file mode 100644 index 00000000..e3881f87 --- /dev/null +++ b/src/gui/sorting.cpp @@ -0,0 +1,168 @@ +/* BOSS + +A plugin load order optimiser for games that use the esp/esm plugin system. + +Copyright (C) 2013-2014 WrinklyNinja + +This file is part of BOSS. + +BOSS is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +BOSS is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BOSS. If not, see +. +*/ + +#include "sorting.h" +#include "../backend/helpers.h" + +using namespace std; + +MiniEditor::MiniEditor(wxWindow *parent, const wxString& title, const std::vector& plugins, const boss::Game& game) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), _basePlugins(plugins) { + //Initialise controls. + pluginText = new wxStaticText(this, wxID_ANY, ""); + prioritySpin = new wxSpinCtrl(this, wxID_ANY, "0"); + prioritySpin->SetRange(std::numeric_limits::min(), std::numeric_limits::max()); + filterCheckbox = new wxCheckBox(this, wxID_ANY, translate("Show only conflicting plugins.")); + + pluginList = new wxListView(this, LIST_Plugins, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL); + loadAfterList = new wxListView(this, LIST_LoadAfter, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL); + + removeBtn = new wxButton(this, BUTTON_RemoveRow, translate("Remove")); + applyBtn = new wxButton(this, BUTTON_Apply, translate("Apply Changes")); + cancelBtn = new wxButton(this, BUTTON_Cancel, translate("Cancel")); + + wxMenu * pluginMenu = new wxMenu(); + + //Set up list columns. + pluginList->AppendColumn(translate("Plugin")); + pluginList->AppendColumn(translate("Priority")); + loadAfterList->AppendColumn(translate("Filename")); + + //Set up plugin right-click menu. + pluginMenu->Append(MENU_CopyName, translate("Copy Name")); + pluginMenu->Append(MENU_CopyMetadata, translate("Copy Metadata As Text")); + pluginMenu->Append(MENU_ClearMetadata, translate("Remove All User-Added Metadata")); + + //Initialise control states. + removeBtn->Enable(false); + prioritySpin->Enable(false); + filterCheckbox->Enable(false); + + //Make plugin name bold text. + pluginText->SetFont(pluginText->GetFont().Bold()); + + //Set up layout. + wxBoxSizer * bigBox = new wxBoxSizer(wxHORIZONTAL); + + bigBox->Add(pluginList, 1, wxEXPAND | wxALL, 10); + + wxBoxSizer * mainBox = new wxBoxSizer(wxVERTICAL); + + mainBox->Add(pluginText, 0, wxTOP | wxBOTTOM, 10); + + wxBoxSizer * hbox1 = new wxBoxSizer(wxHORIZONTAL); + hbox1->Add(new wxStaticText(this, wxID_ANY, translate("Priority: ")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 5); + hbox1->Add(prioritySpin, 0, wxALIGN_RIGHT); + mainBox->Add(hbox1, 0, wxEXPAND | wxALIGN_RIGHT | wxTOP | wxBOTTOM, 5); + + + mainBox->Add(loadAfterList, 1, wxEXPAND); + mainBox->Add(removeBtn, 0, wxALIGN_RIGHT, 5); + + bigBox->Add(mainBox, 2, wxEXPAND | wxTOP | wxBOTTOM | wxRIGHT, 10); + + //Need to add 'Yes' and 'No' buttons. + wxSizer * sizer = CreateSeparatedButtonSizer(wxYES | wxNO | wxCANCEL); + + //Now add buttons to window sizer. + if (sizer != NULL) + bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15); + + //Fill pluginList with the contents of basePlugins. + for (int i = 0, max = _basePlugins.size(); i < max; ++i) { + pluginList->InsertItem(i, FromUTF8(_basePlugins[i].Name())); + pluginList->SetItem(i, 2, FromUTF8(boss::IntToString(_basePlugins[i].Priority()))); + if (_basePlugins[i].LoadsBSA(game)) { + pluginList->SetItemTextColour(i, wxColour(0, 142, 219)); + } + if (std::find(_editedPlugins.begin(), _editedPlugins.end(), _basePlugins[i]) != _editedPlugins.end()) { + pluginList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); + } + } + pluginList->SetColumnWidth(0, wxLIST_AUTOSIZE); + + SetBackgroundColour(wxColour(255, 255, 255)); + SetIcon(wxIconLocation("BOSS.exe")); + + SetSizerAndFit(bigBox); + Layout(); +} + +void MiniEditor::OnPluginSelect(wxListEvent& event) { + +} + +void MiniEditor::OnPluginListRightClick(wxListEvent& event) { + +} + +void MiniEditor::OnPluginCopy(wxCommandEvent& event) { + +} + +void MiniEditor::OnFilterToggle(wxCommandEvent& event) { + +} + +void MiniEditor::OnQuit(wxCommandEvent& event) { + +} + + +LoadOrderPreview::LoadOrderPreview(wxWindow *parent, const wxString title, const std::list& plugins, const boss::Game& game) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { + + //Init controls. + _loadOrder = new wxListView(this, LIST_LoadOrder, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); + + //Populate list. + _loadOrder->AppendColumn(translate("Load Order")); + size_t i = 0; + for (list::const_iterator it = plugins.begin(), endit = plugins.end(); it != endit; ++it, ++i) { + _loadOrder->InsertItem(i, FromUTF8(it->Name())); + if (it->FormIDs().empty()) { + _loadOrder->SetItemTextColour(i, wxColour(122, 122, 122)); + } + else if (it->LoadsBSA(game)) { + _loadOrder->SetItemTextColour(i, wxColour(0, 142, 219)); + } + } + _loadOrder->SetColumnWidth(0, wxLIST_AUTOSIZE); + + //Set up layout. + wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL); + + bigBox->Add(_loadOrder, 1, wxEXPAND | wxALL, 15); + + bigBox->Add(new wxStaticText(this, wxID_ANY, translate("Do you wish to make any changes to the load order above?")), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 15); + + //Need to add 'Yes' and 'No' buttons. + wxSizer * sizer = CreateSeparatedButtonSizer(wxYES | wxNO | wxCANCEL); + + //Now add buttons to window sizer. + if (sizer != NULL) + bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15); + + //Now set the layout and sizes. + SetBackgroundColour(wxColour(255, 255, 255)); + SetIcon(wxIconLocation("BOSS.exe")); + SetSizerAndFit(bigBox); +} diff --git a/src/gui/sorting.h b/src/gui/sorting.h new file mode 100644 index 00000000..4d371a09 --- /dev/null +++ b/src/gui/sorting.h @@ -0,0 +1,66 @@ +/* BOSS + +A plugin load order optimiser for games that use the esp/esm plugin system. + +Copyright (C) 2013-2014 WrinklyNinja + +This file is part of BOSS. + +BOSS is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +BOSS is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BOSS. If not, see +. +*/ +#ifndef __BOSS_GUI_SORTING__ +#define __BOSS_GUI_SORTING__ + +#include "ids.h" +#include "../backend/metadata.h" + +#include +#include +#include +#include +#include + +class MiniEditor : public wxDialog { +public: + MiniEditor(wxWindow *parent, const wxString& title, const std::vector& plugins, const boss::Game& game); + + void OnPluginSelect(wxListEvent& event); + void OnPluginListRightClick(wxListEvent& event); + void OnPluginCopy(wxCommandEvent& event); + void OnFilterToggle(wxCommandEvent& event); + void OnQuit(wxCommandEvent& event); +private: + wxButton * removeBtn; + wxButton * applyBtn; + wxButton * cancelBtn; + wxListView * pluginList; + wxListView * loadAfterList; + wxCheckBox * filterCheckbox; + wxSpinCtrl * prioritySpin; + wxStaticText * pluginText; + + + const std::vector& _basePlugins; + std::list _editedPlugins; +}; + +class LoadOrderPreview : public wxDialog { +public: + LoadOrderPreview(wxWindow *parent, const wxString title, const std::list& plugins, const boss::Game& game); +private: + wxListView * _loadOrder; +}; + +#endif