mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Forgot to add UI code to last commit, so all UI changes mentioned in its log are actually in this. Clicking on a plugin in the metadata editor now loads its values into the editor fields, with checks for edits and saving of edits when a new plugin is selected. Terminology is a bit confusing though, since edits aren't really 'saved' until the 'Apply Load Order' button is pressed. Maybe I should change that...
This commit is contained in:
+183
-40
@@ -24,12 +24,20 @@
|
||||
#include "editor.h"
|
||||
|
||||
#include <wx/statline.h>
|
||||
#include <algorithm>
|
||||
|
||||
BEGIN_EVENT_TABLE( Editor, wxFrame )
|
||||
EVT_LIST_ITEM_SELECTED( LIST_Plugins, Editor::OnPluginSelect )
|
||||
EVT_SPINCTRL( SPIN_Priority, Editor::OnPriorityChange )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
using namespace std;
|
||||
|
||||
Editor::Editor(const wxString title, wxFrame *parent) : wxFrame(parent, wxID_ANY, title) {
|
||||
|
||||
//Initialise child windows.
|
||||
filesBook = new wxNotebook(this, wxID_ANY);
|
||||
wxNotebook * messagesBook = new wxNotebook(this, wxID_ANY);
|
||||
messagesBook = new wxNotebook(this, wxID_ANY);
|
||||
|
||||
wxPanel * reqsTab = new wxPanel(filesBook);
|
||||
wxPanel * incsTab = new wxPanel(filesBook);
|
||||
@@ -43,36 +51,36 @@ Editor::Editor(const wxString title, wxFrame *parent) : wxFrame(parent, wxID_ANY
|
||||
filesBook->AddPage(loadAfterTab, translate("Load After"));
|
||||
|
||||
messagesBook->AddPage(messagesTab, translate("Messages"), true);
|
||||
messagesBook->AddPage(tagsTab, translate("Bash Tags"));
|
||||
messagesBook->AddPage(tagsTab, translate("Bash Tag Suggestions"));
|
||||
|
||||
//Initialise controls.
|
||||
pluginList = new wxListBox(this, LIST_Plugins);
|
||||
pluginText = new wxStaticText(this, wxID_ANY, "");
|
||||
prioritySpin = new wxSpinCtrl(this, SPIN_Priority, "0");
|
||||
prioritySpin->SetRange(-10,10);
|
||||
enableUserEditsBox = new wxCheckBox(this, wxID_ANY, translate("Enable User Changes"));
|
||||
|
||||
addFileBtn = new wxButton(this, BUTTON_AddFile, translate("Add File"));
|
||||
editFileBtn = new wxButton(this, BUTTON_EditFile, translate("Edit File"));
|
||||
removeFileBtn = new wxButton(this, BUTTON_RemoveFile, translate("Remove File"));
|
||||
addMsgBtn = new wxButton(messagesTab, BUTTON_AddMessage, translate("Add Message"));
|
||||
editMsgBtn = new wxButton(messagesTab, BUTTON_EditMessage, translate("Edit Message"));
|
||||
removeMsgBtn = new wxButton(messagesTab, BUTTON_RemoveMessage, translate("Remove Message"));
|
||||
addTagBtn = new wxButton(tagsTab, BUTTON_AddTag, translate("Add Tag"));
|
||||
editTagBtn = new wxButton(tagsTab, BUTTON_EditTag, translate("Edit Tag"));
|
||||
removeTagBtn = new wxButton(tagsTab, BUTTON_RemoveTag, translate("Remove Tag"));
|
||||
addMsgBtn = new wxButton(this, BUTTON_AddMessage, translate("Add Message"));
|
||||
editMsgBtn = new wxButton(this, BUTTON_EditMessage, translate("Edit Message"));
|
||||
removeMsgBtn = new wxButton(this, BUTTON_RemoveMessage, translate("Remove Message"));
|
||||
saveEditsBtn = new wxButton(this, BUTTON_SaveEdits, translate("Save Edits"));
|
||||
undoEditsBtn = new wxButton(this, BUTTON_UndoEdits, translate("Undo Edits"));
|
||||
recalcBtn = new wxButton(this, BUTTON_Recalc, translate("Recalculate Load Order"));
|
||||
applyBtn = new wxButton(this, BUTTON_Apply, translate("Apply Load Order"));
|
||||
cancelBtn = new wxButton(this, BUTTON_Cancel, translate("Cancel"));
|
||||
|
||||
reqsList = new wxListCtrl(reqsTab, LIST_Reqs, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
|
||||
incsList = new wxListCtrl(incsTab, LIST_Incs, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
|
||||
loadAfterList = new wxListCtrl(loadAfterTab, LIST_LoadAfter, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
|
||||
messageList = new wxListCtrl(messagesTab, LIST_Messages, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
|
||||
tagsList = new wxListCtrl(tagsTab, LIST_BashTags, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);
|
||||
pluginList = new wxListCtrl(this, LIST_Plugins, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
reqsList = new wxListCtrl(reqsTab, LIST_Reqs, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
incsList = new wxListCtrl(incsTab, LIST_Incs, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
loadAfterList = new wxListCtrl(loadAfterTab, LIST_LoadAfter, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
messageList = new wxListCtrl(messagesTab, LIST_Messages, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
tagsList = new wxListCtrl(tagsTab, LIST_BashTags, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL);
|
||||
|
||||
//Set up list columns.
|
||||
pluginList->AppendColumn(translate("Plugins"));
|
||||
|
||||
reqsList->AppendColumn(translate("Filename"));
|
||||
reqsList->AppendColumn(translate("Display Name"));
|
||||
reqsList->AppendColumn(translate("Condition"));
|
||||
@@ -101,7 +109,7 @@ Editor::Editor(const wxString title, wxFrame *parent) : wxFrame(parent, wxID_ANY
|
||||
vbox1->Add(new wxStaticText(this, wxID_ANY, translate("Plugins")), 0, wxALL, 5);
|
||||
vbox1->Add(pluginList, 1, wxEXPAND|wxALL, 5);
|
||||
|
||||
bigBox->Add(vbox1, 0, wxEXPAND|wxALL, 5);
|
||||
bigBox->Add(vbox1, 1, wxEXPAND|wxALL, 5);
|
||||
|
||||
wxBoxSizer * mainBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
@@ -135,48 +143,183 @@ Editor::Editor(const wxString title, wxFrame *parent) : wxFrame(parent, wxID_ANY
|
||||
mainBox->Add(hbox2);
|
||||
|
||||
wxBoxSizer * tabBox4 = new wxBoxSizer(wxVERTICAL);
|
||||
tabBox4->Add(messageList, 0, wxEXPAND|wxALL, 5);
|
||||
|
||||
wxBoxSizer * hbox3 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox3->Add(addMsgBtn, 0, wxALL, 10);
|
||||
hbox3->Add(editMsgBtn, 0, wxALL, 10);
|
||||
hbox3->Add(removeMsgBtn, 0, wxALL, 10);
|
||||
tabBox4->Add(hbox3);
|
||||
|
||||
tabBox4->Add(messageList, 0, wxEXPAND);
|
||||
messagesTab->SetSizer(tabBox4);
|
||||
|
||||
wxBoxSizer * tabBox5 = new wxBoxSizer(wxVERTICAL);
|
||||
tabBox5->Add(tagsList, 0, wxEXPAND|wxALL, 5);
|
||||
|
||||
wxBoxSizer * hbox4 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox4->Add(addTagBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
hbox4->Add(editTagBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
hbox4->Add(removeTagBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
tabBox5->Add(hbox4);
|
||||
|
||||
tabBox5->Add(tagsList, 0, wxEXPAND);
|
||||
tagsTab->SetSizer(tabBox5);
|
||||
|
||||
mainBox->Add(messagesBook, 1, wxEXPAND);
|
||||
|
||||
wxBoxSizer * hbox3 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox3->Add(addMsgBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
hbox3->Add(editMsgBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
hbox3->Add(removeMsgBtn, 0, wxTOP|wxLEFT|wxRIGHT, 10);
|
||||
mainBox->Add(hbox3);
|
||||
|
||||
mainBox->AddSpacer(20);
|
||||
|
||||
wxBoxSizer * hbox5 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox5->Add(enableUserEditsBox, 0, wxALL, 5);
|
||||
hbox5->Add(saveEditsBtn, 0, wxALL, 5);
|
||||
hbox5->Add(undoEditsBtn, 0, wxALL, 5);
|
||||
mainBox->Add(hbox5);
|
||||
mainBox->Add(hbox5, 0, wxBOTTOM, 20);
|
||||
|
||||
mainBox->AddSpacer(20);
|
||||
sortingButtons = new wxBoxSizer(wxHORIZONTAL);
|
||||
sortingButtons->Add(recalcBtn, 0, wxALL, 5);
|
||||
sortingButtons->Add(applyBtn, 0, wxALL, 5);
|
||||
sortingButtons->Add(cancelBtn, 0, wxALL, 5);
|
||||
mainBox->Add(sortingButtons);
|
||||
|
||||
wxBoxSizer * hbox6 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox6->Add(recalcBtn, 0, wxALL, 5);
|
||||
hbox6->Add(applyBtn, 0, wxALL, 5);
|
||||
hbox6->Add(cancelBtn, 0, wxALL, 5);
|
||||
mainBox->Add(hbox6);
|
||||
|
||||
bigBox->Add(mainBox, 1, wxEXPAND|wxALL, 5);
|
||||
bigBox->Add(mainBox, 2, wxEXPAND|wxALL, 5);
|
||||
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void Editor::SetList(const std::vector<boss::Plugin>& basePlugins, const std::vector<boss::Plugin>& editedPlugins) {
|
||||
_basePlugins = basePlugins;
|
||||
_editedPlugins = editedPlugins;
|
||||
|
||||
//Fill pluginList with the contents of basePlugins.
|
||||
for (int i=0, max=_basePlugins.size(); i < max; ++i) {
|
||||
pluginList->InsertItem(i, _basePlugins[i].Name());
|
||||
}
|
||||
pluginList->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void Editor::IsSorted(bool sorted) {
|
||||
sortingButtons->ShowItems(sorted);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void Editor::OnPluginSelect(wxListEvent& event) {
|
||||
//Create Plugin object for selected plugin.
|
||||
boss::Plugin plugin = boss::Plugin(string(pluginList->GetItemText(event.GetIndex()).ToUTF8()));
|
||||
|
||||
//Check if the selected plugin is the same as the current plugin.
|
||||
if (currentPlugin != plugin) {
|
||||
//Check if there are edits made to the current plugin compared to its original.
|
||||
if (IsCurrentPluginEdited()) {
|
||||
//Ask if changes should be saved.
|
||||
wxMessageDialog *dlg = new wxMessageDialog(this,
|
||||
translate("The current edits are not saved. Do you want to save them?"),
|
||||
translate("BOSS: Metadata Editor"), wxYES_NO);
|
||||
|
||||
if (dlg->ShowModal() == wxID_YES) {
|
||||
//Save changes.
|
||||
boss::Plugin diff = currentPlugin.DiffMetadata(GetOriginal(currentPlugin, false));
|
||||
|
||||
vector<boss::Plugin>::iterator it = std::find(_editedPlugins.begin(), _editedPlugins.end(), diff);
|
||||
|
||||
if (it != _editedPlugins.end())
|
||||
*it = diff;
|
||||
else
|
||||
_editedPlugins.push_back(diff);
|
||||
}
|
||||
}
|
||||
|
||||
plugin = GetOriginal(plugin, true);
|
||||
|
||||
//Now fill editor fields with new plugin's info.
|
||||
pluginText->SetLabelText(wxString(plugin.Name().c_str(), wxConvUTF8));
|
||||
|
||||
prioritySpin->SetValue(plugin.Priority());
|
||||
|
||||
enableUserEditsBox->SetValue(plugin.Enabled());
|
||||
|
||||
loadAfterList->DeleteAllItems();
|
||||
reqsList->DeleteAllItems();
|
||||
incsList->DeleteAllItems();
|
||||
messageList->DeleteAllItems();
|
||||
tagsList->DeleteAllItems();
|
||||
|
||||
set<boss::File> files = plugin.LoadAfter();
|
||||
int i=0;
|
||||
for (set<boss::File>::const_iterator it=files.begin(), endit=files.end(); it != endit; ++it) {
|
||||
loadAfterList->InsertItem(i, wxString(it->Name().c_str(), wxConvUTF8));
|
||||
loadAfterList->SetItem(i, 1, wxString(it->DisplayName().c_str(), wxConvUTF8));
|
||||
loadAfterList->SetItem(i, 2, wxString(it->Condition().c_str(), wxConvUTF8));
|
||||
++i;
|
||||
}
|
||||
|
||||
files = plugin.Reqs();
|
||||
i=0;
|
||||
for (set<boss::File>::const_iterator it=files.begin(), endit=files.end(); it != endit; ++it) {
|
||||
reqsList->InsertItem(i, wxString(it->Name().c_str(), wxConvUTF8));
|
||||
reqsList->SetItem(i, 1, wxString(it->DisplayName().c_str(), wxConvUTF8));
|
||||
reqsList->SetItem(i, 2, wxString(it->Condition().c_str(), wxConvUTF8));
|
||||
++i;
|
||||
}
|
||||
|
||||
files = plugin.Incs();
|
||||
i=0;
|
||||
for (set<boss::File>::const_iterator it=files.begin(), endit=files.end(); it != endit; ++it) {
|
||||
incsList->InsertItem(i, wxString(it->Name().c_str(), wxConvUTF8));
|
||||
incsList->SetItem(i, 1, wxString(it->DisplayName().c_str(), wxConvUTF8));
|
||||
incsList->SetItem(i, 2, wxString(it->Condition().c_str(), wxConvUTF8));
|
||||
++i;
|
||||
}
|
||||
|
||||
list<boss::Message> messages = plugin.Messages();
|
||||
i=0;
|
||||
for (list<boss::Message>::const_iterator it=messages.begin(), endit=messages.end(); it != endit; ++it) {
|
||||
messageList->InsertItem(i, wxString(it->Type().c_str(), wxConvUTF8));
|
||||
messageList->SetItem(i, 1, wxString(it->Content().c_str(), wxConvUTF8));
|
||||
messageList->SetItem(i, 2, wxString(it->Condition().c_str(), wxConvUTF8));
|
||||
messageList->SetItem(i, 2, wxString(it->Language().c_str(), wxConvUTF8));
|
||||
++i;
|
||||
}
|
||||
|
||||
set<boss::Tag> tags = plugin.Tags();
|
||||
i=0;
|
||||
for (set<boss::Tag>::const_iterator it=tags.begin(), endit=tags.end(); it != endit; ++it) {
|
||||
if (it->IsAddition())
|
||||
tagsList->InsertItem(i, translate("Add"));
|
||||
else
|
||||
tagsList->InsertItem(i, translate("Remove"));
|
||||
tagsList->SetItem(i, 1, wxString(it->Name().c_str(), wxConvUTF8));
|
||||
tagsList->SetItem(i, 2, wxString(it->Condition().c_str(), wxConvUTF8));
|
||||
++i;
|
||||
}
|
||||
|
||||
currentPlugin = plugin;
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::OnPriorityChange(wxSpinEvent& event) {
|
||||
currentPlugin.Priority(event.GetPosition());
|
||||
}
|
||||
|
||||
bool Editor::IsCurrentPluginEdited() const {
|
||||
boss::Plugin original = GetOriginal(currentPlugin, true);
|
||||
|
||||
return (original.Priority() != currentPlugin.Priority()
|
||||
|| original.Enabled() != currentPlugin.Enabled()
|
||||
|| original.LoadAfter() != currentPlugin.LoadAfter()
|
||||
|| original.Reqs() != currentPlugin.Reqs()
|
||||
|| original.Incs() != currentPlugin.Incs()
|
||||
|| original.Messages() != currentPlugin.Messages()
|
||||
|| original.Tags() != currentPlugin.Tags());
|
||||
}
|
||||
|
||||
boss::Plugin Editor::GetOriginal(const boss::Plugin& plugin, bool withEdits) const {
|
||||
//Merges together the base and (saved) edited plugin info.
|
||||
boss::Plugin p;
|
||||
vector<boss::Plugin>::const_iterator it = std::find(_basePlugins.begin(), _basePlugins.end(), plugin);
|
||||
|
||||
if (it != _basePlugins.end())
|
||||
p = *it;
|
||||
|
||||
if (withEdits) {
|
||||
it = std::find(_editedPlugins.begin(), _editedPlugins.end(), plugin);
|
||||
|
||||
if (it != _editedPlugins.end())
|
||||
p.Merge(*it, true);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
+22
-10
@@ -35,8 +35,16 @@ class Editor : public wxFrame {
|
||||
public:
|
||||
Editor(const wxString title, wxFrame *parent);
|
||||
|
||||
void SetList(const std::vector<boss::Plugin>& basePlugins, const std::vector<boss::Plugin>& editedPlugins);
|
||||
void IsSorted(bool sorted);
|
||||
|
||||
void OnPluginSelect(wxListEvent& event);
|
||||
void OnPriorityChange(wxSpinEvent& event);
|
||||
DECLARE_EVENT_TABLE()
|
||||
private:
|
||||
wxListBox * pluginList;
|
||||
|
||||
bool IsCurrentPluginEdited() const;
|
||||
boss::Plugin GetOriginal(const boss::Plugin& plugin, bool withEdits) const;
|
||||
|
||||
wxButton * addFileBtn;
|
||||
wxButton * editFileBtn;
|
||||
@@ -46,27 +54,31 @@ private:
|
||||
wxButton * editMsgBtn;
|
||||
wxButton * removeMsgBtn;
|
||||
|
||||
wxButton * addTagBtn;
|
||||
wxButton * editTagBtn;
|
||||
wxButton * removeTagBtn;
|
||||
|
||||
wxButton * saveEditsBtn;
|
||||
wxButton * undoEditsBtn;
|
||||
wxButton * recalcBtn;
|
||||
wxButton * applyBtn;
|
||||
wxButton * cancelBtn;
|
||||
|
||||
wxCheckBox * enableUserEditsBox;
|
||||
wxSpinCtrl * prioritySpin;
|
||||
wxStaticText * pluginText;
|
||||
wxNotebook * filesBook;
|
||||
wxListCtrl * pluginList;
|
||||
wxListCtrl * reqsList;
|
||||
wxListCtrl * incsList;
|
||||
wxListCtrl * loadAfterList;
|
||||
wxListCtrl * messageList;
|
||||
wxListCtrl * tagsList;
|
||||
|
||||
wxNotebook * filesBook;
|
||||
wxNotebook * messagesBook;
|
||||
|
||||
wxCheckBox * enableUserEditsBox;
|
||||
wxSpinCtrl * prioritySpin;
|
||||
wxStaticText * pluginText;
|
||||
|
||||
std::vector<boss::Plugin> plugins;
|
||||
wxBoxSizer * sortingButtons;
|
||||
|
||||
std::vector<boss::Plugin> _basePlugins, _editedPlugins;
|
||||
|
||||
boss::Plugin currentPlugin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,9 +68,6 @@ enum {
|
||||
BUTTON_AddMessage,
|
||||
BUTTON_EditMessage,
|
||||
BUTTON_RemoveMessage,
|
||||
BUTTON_AddTag,
|
||||
BUTTON_EditTag,
|
||||
BUTTON_RemoveTag,
|
||||
BUTTON_SaveEdits,
|
||||
BUTTON_UndoEdits,
|
||||
BUTTON_Recalc,
|
||||
|
||||
+86
-34
@@ -181,20 +181,8 @@ bool BossGUI::OnInit() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Game(GAME_NEHRIM, false).IsInstalledLocally()) //Before Oblivion because Nehrim installs can have Oblivion.esm for porting mods.
|
||||
targetGame = GAME_NEHRIM;
|
||||
else if (Game(GAME_TES4, false).IsInstalledLocally())
|
||||
targetGame = GAME_TES4;
|
||||
else if (Game(GAME_TES5, false).IsInstalledLocally())
|
||||
targetGame = GAME_TES5;
|
||||
else if (Game(GAME_FONV, false).IsInstalledLocally()) //Before Fallout 3 because some mods for New Vegas require Fallout3.esm.
|
||||
targetGame = GAME_FONV;
|
||||
else if (Game(GAME_FO3, false).IsInstalledLocally())
|
||||
targetGame = GAME_FO3;
|
||||
else
|
||||
targetGame = detected[0];
|
||||
}
|
||||
} else
|
||||
targetGame = detected[0];
|
||||
targetGame = GAME_TES5;
|
||||
Game game(targetGame);
|
||||
|
||||
@@ -210,30 +198,37 @@ bool BossGUI::OnInit() {
|
||||
|
||||
Launcher::Launcher(const wxChar *title, const YAML::Node& settings, const Game& game, const vector<unsigned int>& detectedGames) : wxFrame(NULL, wxID_ANY, title), _game(game), _detectedGames(detectedGames), _settings(settings) {
|
||||
|
||||
//Set up menu bar first.
|
||||
MenuBar = new wxMenuBar();
|
||||
// File Menu
|
||||
FileMenu = new wxMenu();
|
||||
//Initialise menu items.
|
||||
wxMenuBar * MenuBar = new wxMenuBar();
|
||||
wxMenu * FileMenu = new wxMenu();
|
||||
wxMenu * EditMenu = new wxMenu();
|
||||
GameMenu = new wxMenu();
|
||||
wxMenu * HelpMenu = new wxMenu();
|
||||
|
||||
//Initialise controls.
|
||||
wxButton * EditButton = new wxButton(this,OPTION_EditMetadata, translate("Edit Metadata"));
|
||||
wxButton * SortButton = new wxButton(this,OPTION_SortPlugins, translate("Sort Plugins"));
|
||||
ViewButton = new wxButton(this,OPTION_ViewLastReport, translate("View Last Report"));
|
||||
|
||||
//Construct menus.
|
||||
//File Menu
|
||||
FileMenu->Append(OPTION_ViewLastReport, translate("&View Last Report"), translate("Opens your last report."));
|
||||
FileMenu->Append(OPTION_SortPlugins, translate("&Sort Plugins"), translate("Sorts your installed plugins."));
|
||||
FileMenu->AppendSeparator();
|
||||
FileMenu->Append(MENU_Quit, translate("&Quit"), translate("Quit BOSS."));
|
||||
MenuBar->Append(FileMenu, translate("&File"));
|
||||
//Edit Menu
|
||||
EditMenu = new wxMenu();
|
||||
EditMenu->Append(OPTION_EditMetadata, translate("&Metadata..."), translate("Opens a window where you can edit plugin metadata."));
|
||||
EditMenu->Append(MENU_ShowSettings, translate("&Settings..."), translate("Opens the Settings window."));
|
||||
MenuBar->Append(EditMenu, translate("&Edit"));
|
||||
//Game menu
|
||||
GameMenu = new wxMenu();
|
||||
GameMenu->AppendRadioItem(MENU_Oblivion, wxT("&Oblivion"), translate("Switch to running BOSS for Oblivion."));
|
||||
GameMenu->AppendRadioItem(MENU_Nehrim, wxT("&Nehrim"), translate("Switch to running BOSS for Nehrim."));
|
||||
GameMenu->AppendRadioItem(MENU_Skyrim, wxT("&Skyrim"), translate("Switch to running BOSS for Skyrim."));
|
||||
GameMenu->AppendRadioItem(MENU_Fallout3, wxT("&Fallout 3"), translate("Switch to running BOSS for Fallout 3."));
|
||||
GameMenu->AppendRadioItem(MENU_FalloutNewVegas, wxT("&Fallout: New Vegas"), translate("Switch to running BOSS for Fallout: New Vegas."));
|
||||
MenuBar->Append(GameMenu, translate("&Active Game"));
|
||||
// About menu
|
||||
HelpMenu = new wxMenu();
|
||||
//About menu
|
||||
HelpMenu->Append(MENU_OpenMainReadMe, translate("Open &Main Readme"), translate("Opens the main BOSS readme in your default web browser."));
|
||||
HelpMenu->Append(MENU_OpenSyntaxReadMe, translate("Open &Metadata File Syntax Doc"), translate("Opens the BOSS metadata file syntax documentation in your default web browser."));
|
||||
HelpMenu->Append(MENU_OpenAPIReadMe, translate("&Open API Readme"), translate("Opens the BOSS API readme in your default web browser."));
|
||||
@@ -242,17 +237,14 @@ Launcher::Launcher(const wxChar *title, const YAML::Node& settings, const Game&
|
||||
HelpMenu->AppendSeparator();
|
||||
HelpMenu->Append(MENU_ShowAbout, translate("&About BOSS..."), translate("Shows information about BOSS."));
|
||||
MenuBar->Append(HelpMenu, translate("&Help"));
|
||||
SetMenuBar(MenuBar);
|
||||
|
||||
//Set up stuff in the frame.
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
|
||||
//Add the three buttons.
|
||||
//Set up layout.
|
||||
wxBoxSizer *buttonBox = new wxBoxSizer(wxVERTICAL);
|
||||
buttonBox->Add(EditButton = new wxButton(this,OPTION_EditMetadata, translate("Edit Metadata")), 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
|
||||
buttonBox->Add(SortButton = new wxButton(this,OPTION_SortPlugins, translate("Sort Plugins")), 1, wxEXPAND|wxALIGN_CENTRE|wxLEFT|wxRIGHT, 10);
|
||||
buttonBox->Add(ViewButton = new wxButton(this,OPTION_ViewLastReport, translate("View Last Report")), 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
|
||||
buttonBox->Add(EditButton, 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
|
||||
buttonBox->Add(SortButton, 1, wxEXPAND|wxALIGN_CENTRE|wxLEFT|wxRIGHT, 10);
|
||||
buttonBox->Add(ViewButton, 1, wxEXPAND|wxALIGN_CENTRE|wxALL, 10);
|
||||
|
||||
//Set up initial state.
|
||||
SortButton->SetDefault();
|
||||
|
||||
if (_game.Id() == GAME_TES4)
|
||||
@@ -265,10 +257,15 @@ Launcher::Launcher(const wxChar *title, const YAML::Node& settings, const Game&
|
||||
GameMenu->FindItem(MENU_Fallout3)->Check();
|
||||
else if (_game.Id() == GAME_FONV)
|
||||
GameMenu->FindItem(MENU_FalloutNewVegas)->Check();
|
||||
|
||||
if (!fs::exists(_game.ResultsPath()))
|
||||
ViewButton->Enable(false);
|
||||
|
||||
DisableUndetectedGames();
|
||||
|
||||
//Now set the layout and sizes.
|
||||
SetMenuBar(MenuBar);
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
SetSizerAndFit(buttonBox);
|
||||
SetSize(wxSize(250, 200));
|
||||
}
|
||||
@@ -488,14 +485,41 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
out.close();
|
||||
|
||||
progDia->Destroy();
|
||||
|
||||
//Create editor window.
|
||||
Editor *editor = new Editor(translate("BOSS: Metadata Editor"), this);
|
||||
editor->SetIcon(wxIconLocation("BOSS.exe"));
|
||||
|
||||
//The 'plugins' list contains the merged plugin info, but we want to pass a vector of plugins with only masterlist info in its place, so have to construct that.
|
||||
vector<boss::Plugin> pluginVec;
|
||||
for (list<boss::Plugin>::const_iterator it=plugins.begin(), endit=plugins.end(); it != endit; ++it) {
|
||||
boss::Plugin p = *it;
|
||||
list<boss::Plugin>::iterator pos = std::find(mlist_plugins.begin(), mlist_plugins.end(), *it);
|
||||
|
||||
if (pos != mlist_plugins.end())
|
||||
p.Merge(*pos);
|
||||
|
||||
pluginVec.push_back(p);
|
||||
}
|
||||
vector<boss::Plugin> ulistPluginVec(ulist_plugins.begin(), ulist_plugins.end());
|
||||
|
||||
//Pass plugin lists to editor window.
|
||||
editor->SetList(pluginVec, ulistPluginVec);
|
||||
|
||||
//Tell the editor that it's not being shown as part of the load order sort process.
|
||||
editor->IsSorted(true);
|
||||
|
||||
editor->Show();
|
||||
|
||||
ViewButton->Enable(true);
|
||||
}
|
||||
|
||||
void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
//Parse the userlist and masterlist and get a list of installed plugins.
|
||||
|
||||
list<boss::Plugin> plugins;
|
||||
vector<boss::Plugin> plugins;
|
||||
YAML::Node mlist, ulist;
|
||||
list<boss::Plugin> mlist_plugins, ulist_plugins;
|
||||
vector<boss::Plugin> mlist_plugins, ulist_plugins;
|
||||
|
||||
for (fs::directory_iterator it(_game.DataPath()); it != fs::directory_iterator(); ++it) {
|
||||
if (fs::is_regular_file(it->status()) && (it->path().extension().string() == ".esp" || it->path().extension().string() == ".esm")) {
|
||||
@@ -517,7 +541,7 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
NULL);
|
||||
}
|
||||
if (mlist["plugins"])
|
||||
mlist_plugins = mlist["plugins"].as< list<boss::Plugin> >();
|
||||
mlist_plugins = mlist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
if (fs::exists(_game.UserlistPath())) {
|
||||
@@ -532,12 +556,36 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
NULL);
|
||||
}
|
||||
if (ulist["plugins"])
|
||||
ulist_plugins = ulist["plugins"].as< list<boss::Plugin> >();
|
||||
ulist_plugins = ulist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
//Cut out any plugins in the masterlist that aren't installed or in the userlist.
|
||||
//Merge down to the plugin list so that it holds all uneditable metadata.
|
||||
list<boss::Plugin> slim_mlist;
|
||||
|
||||
for (vector<boss::Plugin>::const_iterator it=mlist_plugins.begin(), endit=mlist_plugins.end(); it != endit; ++it) {
|
||||
vector<boss::Plugin>::iterator pos = std::find(plugins.begin(), plugins.end(), *it);
|
||||
|
||||
if (pos != plugins.end())
|
||||
pos->Merge(*it);
|
||||
else if (std::find(ulist_plugins.begin(), ulist_plugins.end(), *it) != ulist_plugins.end())
|
||||
plugins.push_back(*it);
|
||||
}
|
||||
|
||||
//Sort into alphabetical order.
|
||||
std::sort(plugins.begin(), plugins.end(), AlphaSortPlugins);
|
||||
std::sort(ulist_plugins.begin(), ulist_plugins.end(), AlphaSortPlugins);
|
||||
|
||||
//Create editor window.
|
||||
Editor *editor = new Editor(translate("BOSS: Metadata Editor"), this);
|
||||
editor->SetIcon(wxIconLocation("BOSS.exe"));
|
||||
|
||||
//Pass plugin lists to editor window.
|
||||
editor->SetList(plugins, ulist_plugins);
|
||||
|
||||
//Tell the editor that it's not being shown as part of the load order sort process.
|
||||
editor->IsSorted(false);
|
||||
|
||||
editor->Show();
|
||||
}
|
||||
|
||||
@@ -648,3 +696,7 @@ void Launcher::DisableUndetectedGames() {
|
||||
|
||||
SetTitle(wxT("BOSS - " + _game.Name())); //Don't need to convert name, known to be only ASCII chars.
|
||||
}
|
||||
|
||||
bool Launcher::AlphaSortPlugins(const boss::Plugin& lhs, const boss::Plugin& rhs) {
|
||||
return boost::to_lower_copy(lhs.Name()) < boost::to_lower_copy(rhs.Name());
|
||||
}
|
||||
|
||||
+4
-8
@@ -54,20 +54,16 @@ public:
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
private:
|
||||
wxMenuBar *MenuBar;
|
||||
wxMenu *FileMenu;
|
||||
wxMenu *EditMenu;
|
||||
wxMenu *GameMenu;
|
||||
wxMenu *HelpMenu;
|
||||
wxButton *SortButton;
|
||||
wxButton *ViewButton;
|
||||
wxButton *EditButton;
|
||||
wxMenu * GameMenu;
|
||||
wxButton * ViewButton;
|
||||
|
||||
std::vector<unsigned int> _detectedGames;
|
||||
boss::Game _game;
|
||||
YAML::Node _settings; //BOSS Settings.
|
||||
|
||||
void DisableUndetectedGames();
|
||||
|
||||
static bool AlphaSortPlugins(const boss::Plugin& lhs, const boss::Plugin& rhs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+34
-24
@@ -34,6 +34,7 @@ using namespace std;
|
||||
|
||||
SettingsFrame::SettingsFrame(const wxString title, wxFrame *parent, YAML::Node& settings) : wxFrame(parent, wxID_ANY, title), _settings(settings) {
|
||||
|
||||
//Initialise drop-down list contents.
|
||||
wxString DebugVerbosity[] = {
|
||||
translate("None"),
|
||||
translate("Low"),
|
||||
@@ -58,9 +59,24 @@ SettingsFrame::SettingsFrame(const wxString title, wxFrame *parent, YAML::Node&
|
||||
wxString("简体中文", wxConvUTF8)*/
|
||||
};
|
||||
|
||||
//Set up stuff in the frame.
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
//Initialise controls.
|
||||
GameChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 6, Game);
|
||||
LanguageChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, Language);
|
||||
LanguageChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, Language);
|
||||
DebugVerbosityChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 4, DebugVerbosity);
|
||||
|
||||
OblivionURL = new wxTextCtrl(this, wxID_ANY);
|
||||
NehrimURL = new wxTextCtrl(this, wxID_ANY);
|
||||
SkyrimURL = new wxTextCtrl(this, wxID_ANY);
|
||||
FO3URL = new wxTextCtrl(this, wxID_ANY);
|
||||
FONVURL = new wxTextCtrl(this, wxID_ANY);
|
||||
|
||||
UpdateMasterlistBox = new wxCheckBox(this, wxID_ANY, translate("Update masterlist before sorting."));
|
||||
|
||||
wxButton * okBtn = new wxButton(this, OPTION_OKExitSettings, translate("OK"), wxDefaultPosition, wxSize(70, 30));
|
||||
wxButton * cancelBtn = new wxButton(this, OPTION_CancelExitSettings, translate("Cancel"), wxDefaultPosition, wxSize(70, 30));
|
||||
|
||||
//Set up layout.
|
||||
wxSizerFlags leftItem(1);
|
||||
leftItem.Border(wxALL, 10).Expand().Left();
|
||||
|
||||
@@ -70,45 +86,44 @@ SettingsFrame::SettingsFrame(const wxString title, wxFrame *parent, YAML::Node&
|
||||
wxSizerFlags wholeItem(1);
|
||||
wholeItem.Border(wxALL, 10).Expand();
|
||||
|
||||
wxBoxSizer *bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxFlexGridSizer *GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
wxFlexGridSizer * GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Default Game:")), leftItem);
|
||||
GridSizer->Add(GameChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 6, Game), rightItem);
|
||||
GridSizer->Add(GameChoice, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Language:")), leftItem);
|
||||
GridSizer->Add(LanguageChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, Language), rightItem);
|
||||
GridSizer->Add(LanguageChoice, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Debug Verbosity:")), leftItem);
|
||||
GridSizer->Add(DebugVerbosityChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 4, DebugVerbosity), rightItem);
|
||||
GridSizer->Add(DebugVerbosityChoice, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Oblivion Masterlist URL:")), leftItem);
|
||||
GridSizer->Add(OblivionURL = new wxTextCtrl(this, wxID_ANY), rightItem);
|
||||
GridSizer->Add(OblivionURL, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Nehrim Masterlist URL:")), leftItem);
|
||||
GridSizer->Add(NehrimURL = new wxTextCtrl(this, wxID_ANY), rightItem);
|
||||
GridSizer->Add(NehrimURL, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Skyrim Masterlist URL:")), leftItem);
|
||||
GridSizer->Add(SkyrimURL = new wxTextCtrl(this, wxID_ANY), rightItem);
|
||||
GridSizer->Add(SkyrimURL, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Fallout 3 Masterlist URL:")), leftItem);
|
||||
GridSizer->Add(FO3URL = new wxTextCtrl(this, wxID_ANY), rightItem);
|
||||
GridSizer->Add(FO3URL, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Fallout: New Vegas Masterlist URL:")), leftItem);
|
||||
GridSizer->Add(FONVURL = new wxTextCtrl(this, wxID_ANY), rightItem);
|
||||
GridSizer->Add(FONVURL, rightItem);
|
||||
|
||||
bigBox->Add(GridSizer);
|
||||
|
||||
bigBox->Add(UpdateMasterlistBox = new wxCheckBox(this, wxID_ANY, translate("Update masterlist before sorting.")), wholeItem);
|
||||
bigBox->Add(UpdateMasterlistBox, wholeItem);
|
||||
|
||||
wxString text = translate("Language settings will be applied after the BOSS GUI is restarted.");
|
||||
bigBox->Add(new wxStaticText(this, wxID_ANY, text), wholeItem);
|
||||
bigBox->Add(new wxStaticText(this, wxID_ANY, translate("Settings are applied after BOSS is restarted.")), wholeItem);
|
||||
|
||||
//Need to add 'OK' and 'Cancel' buttons.
|
||||
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox->Add(new wxButton(this, OPTION_OKExitSettings, translate("OK"), wxDefaultPosition, wxSize(70, 30)));
|
||||
hbox->Add(new wxButton(this, OPTION_CancelExitSettings, translate("Cancel"), wxDefaultPosition, wxSize(70, 30)), 0, wxLEFT, 20);
|
||||
wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox->Add(okBtn);
|
||||
hbox->Add(cancelBtn, 0, wxLEFT, 20);
|
||||
|
||||
//Now add TabHolder and OK button to window sizer.
|
||||
bigBox->Add(hbox, 0, wxCENTER|wxALL, 10);
|
||||
@@ -120,6 +135,7 @@ SettingsFrame::SettingsFrame(const wxString title, wxFrame *parent, YAML::Node&
|
||||
DebugVerbosityChoice->SetToolTip(translate("The output is logged to the BOSSDebugLog.txt file"));
|
||||
|
||||
//Now set the layout and sizes.
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
@@ -221,12 +237,6 @@ void SettingsFrame::OnQuit(wxCommandEvent& event) {
|
||||
|
||||
_settings["Masterlist URLs"]["Fallout New Vegas"] = string(FONVURL->GetValue().ToUTF8());
|
||||
|
||||
//Also set the logger settings now.
|
||||
/* g_logger.setOriginTracking(gl_debug_with_source);
|
||||
g_logger.setVerbosity(static_cast<LogVerbosity>(LV_WARN + gl_debug_verbosity));
|
||||
if (gl_log_debug_output)
|
||||
g_logger.setStream(debug_log_path.string().c_str());*/
|
||||
|
||||
YAML::Emitter yout;
|
||||
yout.SetIndent(2);
|
||||
yout << _settings;
|
||||
|
||||
+64
-13
@@ -52,7 +52,7 @@ namespace boss {
|
||||
}
|
||||
|
||||
bool FormID::operator == (const FormID& rhs) const {
|
||||
return (plugin == rhs.Plugin() && id == rhs.Id());
|
||||
return (boost::iequals(plugin, rhs.Plugin()) && id == rhs.Id());
|
||||
}
|
||||
|
||||
bool FormID::operator != (const FormID& rhs) const {
|
||||
@@ -114,6 +114,14 @@ namespace boss {
|
||||
Message::Message(const std::string& t, const std::string& cont,
|
||||
const std::string& cond, const std::string& l)
|
||||
: type(t), language(l), ConditionalData(cond, cont) {}
|
||||
|
||||
bool Message::operator < (const Message& rhs) const {
|
||||
return (Content() < rhs.Content());
|
||||
}
|
||||
|
||||
bool Message::operator == (const Message& rhs) const {
|
||||
return (boost::iequals(Type(), rhs.Type()) && boost::iequals(Content(), rhs.Content()));
|
||||
}
|
||||
|
||||
std::string Message::Type() const {
|
||||
return type;
|
||||
@@ -136,6 +144,10 @@ namespace boss {
|
||||
return (Name() < rhs.Name());
|
||||
}
|
||||
|
||||
bool File::operator == (const File& rhs) const {
|
||||
return boost::iequals(Name(), rhs.Name());
|
||||
}
|
||||
|
||||
std::string File::Name() const {
|
||||
return Data();
|
||||
}
|
||||
@@ -174,6 +186,10 @@ namespace boss {
|
||||
return (PrefixedName() < rhs.PrefixedName());
|
||||
}
|
||||
|
||||
bool Tag::operator == (const Tag& rhs) const {
|
||||
return boost::iequals(PrefixedName(), rhs.PrefixedName());
|
||||
}
|
||||
|
||||
bool Tag::IsAddition() const {
|
||||
return addTag;
|
||||
}
|
||||
@@ -260,6 +276,7 @@ namespace boss {
|
||||
return;
|
||||
|
||||
//The following should be replaced.
|
||||
enabled = plugin.Enabled();
|
||||
priority = plugin.Priority();
|
||||
masters = plugin.Masters();
|
||||
formIDs = plugin.FormIDs();
|
||||
@@ -285,6 +302,42 @@ namespace boss {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Plugin Plugin::DiffMetadata(const Plugin& plugin) const {
|
||||
Plugin p(name);
|
||||
p.Priority(priority);
|
||||
|
||||
//Compare this plugin against the given plugin.
|
||||
set<File> files = plugin.LoadAfter();
|
||||
set<File> filesDiff;
|
||||
set_difference(files.begin(), files.end(), loadAfter.begin(), loadAfter.end(), inserter(filesDiff, filesDiff.begin()));
|
||||
p.LoadAfter(filesDiff);
|
||||
|
||||
filesDiff.clear();
|
||||
files = plugin.Reqs();
|
||||
set_difference(files.begin(), files.end(), requirements.begin(), requirements.end(), inserter(filesDiff, filesDiff.begin()));
|
||||
p.Reqs(filesDiff);
|
||||
|
||||
filesDiff.clear();
|
||||
files = plugin.Incs();
|
||||
set_difference(files.begin(), files.end(), incompatibilities.begin(), incompatibilities.end(), inserter(filesDiff, filesDiff.begin()));
|
||||
p.Incs(filesDiff);
|
||||
|
||||
list<Message> msgs1 = plugin.Messages();
|
||||
list<Message> msgs2 = messages;
|
||||
msgs1.sort();
|
||||
msgs2.sort();
|
||||
list<Message> mDiff;
|
||||
set_difference(msgs1.begin(), msgs1.end(), msgs2.begin(), msgs2.end(), inserter(mDiff, mDiff.begin()));
|
||||
p.Messages(mDiff);
|
||||
|
||||
set<Tag> bashTags = plugin.Tags();
|
||||
set<Tag> tagDiff;
|
||||
set_difference(bashTags.begin(), bashTags.end(), tags.begin(), tags.end(), inserter(tagDiff, tagDiff.begin()));
|
||||
p.Tags(tagDiff);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string Plugin::Name() const {
|
||||
return name;
|
||||
@@ -454,10 +507,8 @@ namespace boss {
|
||||
boost::unordered_set<FormID,FormID_hash> Plugin::OverlapFormIDs(const Plugin& plugin) const {
|
||||
boost::unordered_set<FormID,FormID_hash> otherFormIDs = plugin.FormIDs();
|
||||
boost::unordered_set<FormID,FormID_hash> overlap;
|
||||
for (boost::unordered_set<FormID,FormID_hash>::const_iterator it=formIDs.begin(), endIt=formIDs.end(); it != endIt; ++it) {
|
||||
if (otherFormIDs.find(*it) != otherFormIDs.end())
|
||||
overlap.insert(*it);
|
||||
}
|
||||
|
||||
set_intersection(formIDs.begin(), formIDs.end(), otherFormIDs.begin(), otherFormIDs.end(), inserter(overlap, overlap.begin()));
|
||||
|
||||
return overlap;
|
||||
}
|
||||
@@ -479,14 +530,10 @@ namespace boss {
|
||||
if (boost::iequals(*it, plugin.Name()))
|
||||
return true;
|
||||
}
|
||||
for (set<File>::const_iterator it=requirements.begin(), endIt=requirements.end(); it != endIt; ++it) {
|
||||
if (boost::iequals(it->Name(), plugin.Name()))
|
||||
return true;
|
||||
}
|
||||
for (set<File>::const_iterator it=loadAfter.begin(), endIt=loadAfter.end(); it != endIt; ++it) {
|
||||
if (boost::iequals(it->Name(), plugin.Name()))
|
||||
return true;
|
||||
}
|
||||
if (find(requirements.begin(), requirements.end(), plugin) != requirements.end())
|
||||
return true;
|
||||
if (find(loadAfter.begin(), loadAfter.end(), plugin) != requirements.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -508,4 +555,8 @@ namespace boss {
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
|
||||
bool operator == (const File& lhs, const Plugin& rhs) {
|
||||
return boost::iequals(lhs.Name(), rhs.Name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,9 @@ namespace boss {
|
||||
Message(const std::string& type, const std::string& content);
|
||||
Message(const std::string& type, const std::string& content,
|
||||
const std::string& condition, const std::string& language);
|
||||
|
||||
bool operator < (const Message& rhs) const;
|
||||
bool operator == (const Message& rhs) const;
|
||||
|
||||
std::string Type() const;
|
||||
std::string Language() const;
|
||||
@@ -113,6 +116,7 @@ namespace boss {
|
||||
const std::string& condition);
|
||||
|
||||
bool operator < (const File& rhs) const;
|
||||
bool operator == (const File& rhs) const;
|
||||
|
||||
std::string Name() const;
|
||||
std::string DisplayName() const;
|
||||
@@ -127,6 +131,7 @@ namespace boss {
|
||||
Tag(const std::string& tag, const std::string& condition);
|
||||
|
||||
bool operator < (const Tag& rhs) const;
|
||||
bool operator == (const Tag& rhs) const;
|
||||
|
||||
bool IsAddition() const;
|
||||
std::string Name() const;
|
||||
@@ -142,6 +147,7 @@ namespace boss {
|
||||
Plugin(const boss::Game& game, const std::string& name);
|
||||
|
||||
void Merge(const Plugin& plugin, bool ifdDisabled = false);
|
||||
Plugin DiffMetadata(const Plugin& plugin) const;
|
||||
|
||||
std::string Name() const;
|
||||
bool Enabled() const;
|
||||
@@ -201,6 +207,8 @@ namespace boss {
|
||||
std::string version; //Obtained from description field.
|
||||
bool isMaster;
|
||||
};
|
||||
|
||||
bool operator == (const File& lhs, const Plugin& rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user