diff --git a/src/gui/editor.cpp b/src/gui/editor.cpp index 005de5db..2b4d93ec 100644 --- a/src/gui/editor.cpp +++ b/src/gui/editor.cpp @@ -34,15 +34,130 @@ using namespace std; -MiniEditor::MiniEditor(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), _basePlugins(plugins), _game(game) { +/////////////////////////////////// +// Common Editor Class +/////////////////////////////////// + +CommonEditor::CommonEditor(const std::list& plugins, const boss::Game& game) : _basePlugins(plugins), _game(game) {} + +CommonEditor::CommonEditor(const std::list& plugins, const boss::Game& game, std::list& editedPlugins) : _basePlugins(plugins), _game(game), _editedPlugins(editedPlugins) {} + +boss::Plugin CommonEditor::GetMasterData(const wxString& plugin) const { + BOOST_LOG_TRIVIAL(debug) << "Getting hardcoded and masterlist metadata for plugin: " << plugin.ToUTF8(); + boss::Plugin p; + boss::Plugin p_in(string(plugin.ToUTF8())); + + list::const_iterator it = std::find(_basePlugins.begin(), _basePlugins.end(), p_in); + + if (it != _basePlugins.end()) + p = *it; + + return p; +} + +boss::Plugin CommonEditor::GetUserData(const wxString& plugin) const { + BOOST_LOG_TRIVIAL(debug) << "Getting userlist metadata for plugin: " << plugin.ToUTF8(); + boss::Plugin p(string(plugin.ToUTF8())); + + list::const_iterator it = std::find(_editedPlugins.begin(), _editedPlugins.end(), p); + + if (it != _editedPlugins.end()) + p = *it; + + return p; +} + +void CommonEditor::ApplyEdits(const wxString& plugin, wxListView * wxList) { + BOOST_LOG_TRIVIAL(debug) << "Applying edits to plugin: " << plugin.ToUTF8(); + + //Get recorded data. + boss::Plugin master(GetMasterData(plugin)); + boss::Plugin edited(GetNewData(plugin)); + + boss::Plugin diff = master.DiffMetadata(edited); + + list::iterator pos = std::find(_editedPlugins.begin(), _editedPlugins.end(), diff); + long i = wxList->FindItem(-1, plugin); + + if (!diff.HasNameOnly()) { + wxList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); + if (pos != _editedPlugins.end()) + *pos = diff; + else + _editedPlugins.push_back(diff); + } + else { + wxList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + if (pos != _editedPlugins.end()) + _editedPlugins.erase(pos); //Prevents unnecessary writes. + } +} + + +boss::File CommonEditor::RowToFile(wxListView * list, long row) const { + return boss::File( + string(list->GetItemText(row, 0).ToUTF8()), + string(list->GetItemText(row, 1).ToUTF8()), + string(list->GetItemText(row, 2).ToUTF8()) + ); +} + +boss::Tag CommonEditor::RowToTag(wxListView * list, long row) const { + string name = string(list->GetItemText(row, 1).ToUTF8()); + + if (list->GetItemText(row, 0) == State[1]) + return boss::Tag( + name, + false, + string(list->GetItemText(row, 2).ToUTF8()) + ); + else + return boss::Tag( + name, + true, + string(list->GetItemText(row, 2).ToUTF8()) + ); +} + +boss::PluginDirtyInfo CommonEditor::RowToPluginDirtyInfo(wxListView * list, long row) const { + string text(list->GetItemText(row, 0).ToUTF8()); + uint32_t crc = strtoul(text.c_str(), NULL, 16); + return boss::PluginDirtyInfo( + crc, + atoi(string(list->GetItemText(row, 1).ToUTF8()).c_str()), + atoi(string(list->GetItemText(row, 2).ToUTF8()).c_str()), + atoi(string(list->GetItemText(row, 3).ToUTF8()).c_str()), + string(list->GetItemText(row, 4).ToUTF8())); +} + + +/////////////////////////////////// +// Mini Editor Class +/////////////////////////////////// + + +MiniEditor::MiniEditor(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), CommonEditor(plugins, game) { //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")); //Set up list columns. pluginList->AppendColumn(translate("Plugin")); pluginList->AppendColumn(translate("Priority")); - loadAfterList->AppendColumn(translate("Load After")); + loadAfterList->AppendColumn(translate("Filename")); + loadAfterList->AppendColumn(translate("Display Name")); + loadAfterList->AppendColumn(translate("Condition")); + loadAfterList->SetColumnWidth(1, 0); //Hide this from the user. + loadAfterList->SetColumnWidth(2, 0); //Hide this from the user. + //Initialise control states. removeBtn->Enable(false); prioritySpin->Enable(false); @@ -74,6 +189,7 @@ MiniEditor::MiniEditor(wxWindow *parent, const wxString& title, const std::list< hbox2->Add(prioritySpin, 0, wxALIGN_RIGHT); mainBox->Add(hbox2, 0, wxEXPAND | wxALIGN_RIGHT | wxTOP | wxBOTTOM, 10); + //mainBox->Add(new wxStaticText(this, wxID_ANY, translate("Load After")), 0, wxTOP | wxBOTTOM, 10); mainBox->Add(loadAfterList, 1, wxEXPAND); mainBox->Add(removeBtn, 0, wxTOP | wxBOTTOM | wxALIGN_RIGHT, 10); @@ -120,40 +236,36 @@ void MiniEditor::OnPluginSelect(wxListEvent& event) { //Apply any current edits. if (!currentPlugin.empty()) - ApplyEdits(currentPlugin); + ApplyEdits(currentPlugin, pluginList); - //Merge base metadata and edits. - boss::Plugin plugin(string(selectedPlugin.ToUTF8())); - list::const_iterator it = std::find(_basePlugins.begin(), _basePlugins.end(), plugin); - if (it != _basePlugins.end()) - plugin = *it; - else - BOOST_LOG_TRIVIAL(warning) << "Could not find plugin in base list: " << plugin.Name(); - it = std::find(_editedPlugins.begin(), _editedPlugins.end(), plugin); - if (it != _editedPlugins.end()) - plugin.MergeMetadata(*it); - else - BOOST_LOG_TRIVIAL(info) << "Could not find plugin in edited list: " << plugin.Name(); + //Merge metadata. + boss::Plugin plugin = GetMasterData(selectedPlugin); + plugin.MergeMetadata(GetUserData(selectedPlugin)); //Now fill editor fields with new plugin's info and update control states. BOOST_LOG_TRIVIAL(debug) << "Filling editor fields with plugin info."; pluginText->SetLabelText(FromUTF8(plugin.Name())); prioritySpin->SetValue(plugin.Priority()); - loadAfterList->DeleteAllItems(); + loadAfterList->DeleteAllItems(); set files = plugin.LoadAfter(); int i = 0; for (set::const_iterator it = files.begin(), endit = files.end(); it != endit; ++it) { loadAfterList->InsertItem(i, FromUTF8(it->Name())); ++i; } + if (loadAfterList->GetItemCount() == 0) + loadAfterList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + loadAfterList->SetColumnWidth(0, wxLIST_AUTOSIZE); //Set control states. prioritySpin->Enable(true); filterCheckbox->Enable(true); removeBtn->Enable(false); } + Fit(); } void MiniEditor::OnFilterToggle(wxCommandEvent& event) { @@ -230,42 +342,24 @@ const std::list& MiniEditor::GetEditedPlugins() const { return _editedPlugins; } -void MiniEditor::ApplyEdits(const wxString& plugin) { - BOOST_LOG_TRIVIAL(debug) << "Applying edits to plugin: " << plugin.ToUTF8(); - - //Get recorded data. - boss::Plugin master; - list::const_iterator it = std::find(_basePlugins.begin(), _basePlugins.end(), boss::Plugin(string(plugin.ToUTF8()))); - if (it != _basePlugins.end()) - master = *it; - else - master = boss::Plugin(string(plugin.ToUTF8())); - - //Get new data. - boss::Plugin edited = boss::Plugin(string(plugin.ToUTF8())); +boss::Plugin MiniEditor::GetNewData(const wxString& plugin) const { + //Get new data. Because most of it is missing in the MiniEditor, start with the existing data. + boss::Plugin edited(GetMasterData(plugin)); edited.Priority(prioritySpin->GetValue()); - set files; - - boss::Plugin diff = master.DiffMetadata(edited); - - list::iterator pos = std::find(_editedPlugins.begin(), _editedPlugins.end(), diff); - - if (pos != _editedPlugins.end()) - *pos = diff; - else - _editedPlugins.push_back(diff); - - //Also mark plugin as edited in list. - long i = pluginList->FindItem(-1, plugin); - if (!diff.HasNameOnly()) - pluginList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); - else - pluginList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + set files; + for (int i = 0, max = loadAfterList->GetItemCount(); i < max; ++i) { + files.insert(RowToFile(loadAfterList, i)); + } + edited.LoadAfter(files); + return edited; } +/////////////////////////////////// +// Editor Class +/////////////////////////////////// -Editor::Editor(wxWindow *parent, const wxString& title, const std::string userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const boss::Game& game) : wxFrame(parent, wxID_ANY, title), _userlistPath(userlistPath), _basePlugins(basePlugins), _editedPlugins(editedPlugins), _game(game) { +Editor::Editor(wxWindow *parent, const wxString& title, const std::string userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const boss::Game& game) : wxFrame(parent, wxID_ANY, title), _userlistPath(userlistPath), CommonEditor(basePlugins, game, editedPlugins) { //Initialise child windows. listBook = new wxNotebook(this, BOOK_Lists); @@ -458,7 +552,7 @@ void Editor::OnPluginSelect(wxListEvent& event) { //Apply any current edits. if (!currentPlugin.empty()) - ApplyEdits(currentPlugin); + ApplyEdits(currentPlugin, pluginList); //Merge metadata. boss::Plugin plugin = GetMasterData(selectedPlugin); @@ -487,6 +581,10 @@ void Editor::OnPluginSelect(wxListEvent& event) { loadAfterList->SetItem(i, 2, FromUTF8(it->Condition())); ++i; } + if (loadAfterList->GetItemCount() == 0) + loadAfterList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + loadAfterList->SetColumnWidth(0, wxLIST_AUTOSIZE); files = plugin.Reqs(); i=0; @@ -496,6 +594,10 @@ void Editor::OnPluginSelect(wxListEvent& event) { reqsList->SetItem(i, 2, FromUTF8(it->Condition())); ++i; } + if (reqsList->GetItemCount() == 0) + reqsList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + reqsList->SetColumnWidth(0, wxLIST_AUTOSIZE); files = plugin.Incs(); i=0; @@ -505,6 +607,10 @@ void Editor::OnPluginSelect(wxListEvent& event) { incsList->SetItem(i, 2, FromUTF8(it->Condition())); ++i; } + if (incsList->GetItemCount() == 0) + incsList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + incsList->SetColumnWidth(0, wxLIST_AUTOSIZE); list messages = plugin.Messages(); vector vec(messages.begin(), messages.end()); @@ -521,6 +627,10 @@ void Editor::OnPluginSelect(wxListEvent& event) { tagsList->SetItem(i, 2, FromUTF8(it->Condition())); ++i; } + if (tagsList->GetItemCount() == 0) + tagsList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + tagsList->SetColumnWidth(0, wxLIST_AUTOSIZE); set dirtyInfo = plugin.DirtyInfo(); i=0; @@ -532,6 +642,10 @@ void Editor::OnPluginSelect(wxListEvent& event) { dirtyList->SetItem(i, 4, FromUTF8(it->CleaningUtility())); ++i; } + if (dirtyList->GetItemCount() == 0) + dirtyList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); + else + dirtyList->SetColumnWidth(0, wxLIST_AUTOSIZE); //Set control states. prioritySpin->Enable(true); @@ -540,6 +654,7 @@ void Editor::OnPluginSelect(wxListEvent& event) { editBtn->Enable(false); removeBtn->Enable(false); } + Fit(); } void Editor::OnPluginListRightClick(wxListEvent& event) { @@ -984,7 +1099,7 @@ void Editor::OnQuit(wxCommandEvent& event) { //Apply any current edits. wxString currentPlugin = pluginText->GetLabelText(); if (!currentPlugin.empty()) - ApplyEdits(currentPlugin); + ApplyEdits(currentPlugin, pluginList); BOOST_LOG_TRIVIAL(debug) << "Saving metadata edits to userlist."; @@ -1003,54 +1118,6 @@ void Editor::OnQuit(wxCommandEvent& event) { Close(); } -void Editor::ApplyEdits(const wxString& plugin) { - BOOST_LOG_TRIVIAL(debug) << "Applying edits to plugin: " << plugin.ToUTF8(); - boss::Plugin master = GetMasterData(plugin); - boss::Plugin edited = GetNewData(plugin); - - boss::Plugin diff = master.DiffMetadata(edited); - - list::iterator it = std::find(_editedPlugins.begin(), _editedPlugins.end(), diff); - - if (it != _editedPlugins.end()) - *it = diff; - else - _editedPlugins.push_back(diff); - - //Also mark plugin as edited in list. - long i = pluginList->FindItem(-1, plugin); - if (!diff.HasNameOnly()) - pluginList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold()); - else - pluginList->SetItemFont(i, wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - -} - -boss::Plugin Editor::GetMasterData(const wxString& plugin) const { - BOOST_LOG_TRIVIAL(debug) << "Getting hardcoded and masterlist metadata for plugin: " << plugin.ToUTF8(); - boss::Plugin p; - boss::Plugin p_in(string(plugin.ToUTF8())); - - list::const_iterator it = std::find(_basePlugins.begin(), _basePlugins.end(), p_in); - - if (it != _basePlugins.end()) - p = *it; - - return p; -} - -boss::Plugin Editor::GetUserData(const wxString& plugin) const { - BOOST_LOG_TRIVIAL(debug) << "Getting userlist metadata for plugin: " << plugin.ToUTF8(); - boss::Plugin p(string(plugin.ToUTF8())); - - list::const_iterator it = std::find(_editedPlugins.begin(), _editedPlugins.end(), p); - - if (it != _editedPlugins.end()) - p = *it; - - return p; -} - boss::Plugin Editor::GetNewData(const wxString& plugin) const { BOOST_LOG_TRIVIAL(debug) << "Getting metadata from editor fields for plugin: " << plugin.ToUTF8(); boss::Plugin p(string(plugin.ToUTF8())); @@ -1094,39 +1161,3 @@ boss::Plugin Editor::GetNewData(const wxString& plugin) const { return p; } - -boss::File Editor::RowToFile(wxListView * list, long row) const { - return boss::File( - string(list->GetItemText(row, 0).ToUTF8()), - string(list->GetItemText(row, 1).ToUTF8()), - string(list->GetItemText(row, 2).ToUTF8()) - ); -} - -boss::Tag Editor::RowToTag(wxListView * list, long row) const { - string name = string(list->GetItemText(row, 1).ToUTF8()); - - if (list->GetItemText(row, 0) == State[1]) - return boss::Tag( - name, - false, - string(list->GetItemText(row, 2).ToUTF8()) - ); - else - return boss::Tag( - name, - true, - string(list->GetItemText(row, 2).ToUTF8()) - ); -} - -boss::PluginDirtyInfo Editor::RowToPluginDirtyInfo(wxListView * list, long row) const { - string text(list->GetItemText(row, 0).ToUTF8()); - uint32_t crc = strtoul(text.c_str(), NULL, 16); - return boss::PluginDirtyInfo( - crc, - atoi(string(list->GetItemText(row, 1).ToUTF8()).c_str()), - atoi(string(list->GetItemText(row, 2).ToUTF8()).c_str()), - atoi(string(list->GetItemText(row, 3).ToUTF8()).c_str()), - string(list->GetItemText(row, 4).ToUTF8())); -} diff --git a/src/gui/editor.h b/src/gui/editor.h index 1d977016..87cb08a1 100644 --- a/src/gui/editor.h +++ b/src/gui/editor.h @@ -28,7 +28,7 @@ #include "../backend/metadata.h" #include -#include +#include #include #include #include @@ -49,7 +49,27 @@ editor), then use the immutable plugin entry's metadata for that type. */ -class MiniEditor : public wxDialog { +class CommonEditor { +public: + CommonEditor(const std::list& plugins, const boss::Game& game); + CommonEditor(const std::list& plugins, const boss::Game& game, std::list& editedPlugins); +protected: + const boss::Game& _game; + const std::list _basePlugins; + std::list _editedPlugins; + + boss::Plugin GetMasterData(const wxString& plugin) const; + boss::Plugin GetUserData(const wxString& plugin) const; + virtual boss::Plugin GetNewData(const wxString& plugin) const = 0; + + void ApplyEdits(const wxString& plugin, wxListView * list); + + boss::File RowToFile(wxListView * list, long row) const; + boss::Tag RowToTag(wxListView * list, long row) const; + boss::PluginDirtyInfo RowToPluginDirtyInfo(wxListView * list, long row) const; +}; + +class MiniEditor : public wxDialog, public CommonEditor { public: MiniEditor(wxWindow *parent, const wxString& title, const std::list& plugins, const boss::Game& game); @@ -60,21 +80,17 @@ public: const std::list& GetEditedPlugins() const; private: - wxButton * removeBtn; wxListView * pluginList; + wxButton * removeBtn; wxListView * loadAfterList; wxCheckBox * filterCheckbox; wxSpinCtrl * prioritySpin; wxStaticText * pluginText; - void MiniEditor::ApplyEdits(const wxString& plugin); - - const std::list _basePlugins; - std::list _editedPlugins; - const boss::Game& _game; + boss::Plugin GetNewData(const wxString& plugin) const; }; -class Editor : public wxFrame { +class Editor : public wxFrame, public CommonEditor { public: Editor(wxWindow *parent, const wxString& title, const std::string userlistPath, const std::list& basePlugins, std::list& editedPlugins, const unsigned int language, const boss::Game& game); @@ -90,7 +106,6 @@ public: void OnRowSelect(wxListEvent& event); void OnQuit(wxCommandEvent& event); private: - wxMenu * pluginMenu; wxButton * addBtn; wxButton * editBtn; @@ -110,18 +125,7 @@ private: wxStaticText * pluginText; const std::string _userlistPath; - const std::list _basePlugins; - std::list _editedPlugins; - const boss::Game& _game; - void ApplyEdits(const wxString& plugin); - - boss::Plugin GetMasterData(const wxString& plugin) const; - boss::Plugin GetUserData(const wxString& plugin) const; boss::Plugin GetNewData(const wxString& plugin) const; - - boss::File RowToFile(wxListView * list, long row) const; - boss::Tag RowToTag(wxListView * list, long row) const; - boss::PluginDirtyInfo RowToPluginDirtyInfo(wxListView * list, long row) const; }; #endif