mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Implemented plugin version extraction from description field and started to implement the metadata editor window.
This commit is contained in:
+1
-1
@@ -71,7 +71,7 @@ ENDIF ()
|
||||
# More General Settings
|
||||
##############################
|
||||
|
||||
set (BOSS_GUI_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/gui/ids.cpp" "${CMAKE_SOURCE_DIR}/src/gui/main.cpp" "${CMAKE_SOURCE_DIR}/src/gui/settings.cpp")
|
||||
set (BOSS_GUI_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/gui/ids.cpp" "${CMAKE_SOURCE_DIR}/src/gui/main.cpp" "${CMAKE_SOURCE_DIR}/src/gui/settings.cpp" "${CMAKE_SOURCE_DIR}/src/gui/editor.cpp")
|
||||
|
||||
set (BOSS_API_SRC ${BOSS_SRC} "${CMAKE_SOURCE_DIR}/src/api.cpp")
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ Roadmap/To Do
|
||||
- Remove game detection override.
|
||||
- Checks for cyclic dependencies and incompatibilities.
|
||||
- Setting load order.
|
||||
- Include libespm initialisation into Game constructor.
|
||||
- Include libespm initialisation into Game constructor. DONE
|
||||
- Optimisations to load ordering.
|
||||
- Implement logging.
|
||||
- Implement reading of plugin versions from their description field.
|
||||
- Implement reading of plugin versions from their description field. DONE
|
||||
|
||||
|
||||
Sorting Algorithm
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2013 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
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "editor.h"
|
||||
|
||||
#include <wx/statline.h>
|
||||
|
||||
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);
|
||||
|
||||
wxPanel * reqsTab = new wxPanel(filesBook);
|
||||
wxPanel * incsTab = new wxPanel(filesBook);
|
||||
wxPanel * loadAfterTab = new wxPanel(filesBook);
|
||||
wxPanel * messagesTab = new wxPanel(messagesBook);
|
||||
wxPanel * tagsTab = new wxPanel(messagesBook);
|
||||
|
||||
//Tie together notebooks and panels.
|
||||
filesBook->AddPage(reqsTab, translate("Requirements"), true);
|
||||
filesBook->AddPage(incsTab, translate("Incompatibilities"));
|
||||
filesBook->AddPage(loadAfterTab, translate("Load After"));
|
||||
|
||||
messagesBook->AddPage(messagesTab, translate("Messages"), true);
|
||||
messagesBook->AddPage(tagsTab, translate("Bash Tags"));
|
||||
|
||||
//Initialise controls.
|
||||
pluginList = new wxListBox(this, LIST_Plugins);
|
||||
pluginText = new wxStaticText(this, wxID_ANY, "");
|
||||
prioritySpin = new wxSpinCtrl(this, SPIN_Priority, "0");
|
||||
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"));
|
||||
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);
|
||||
|
||||
//Set up list columns.
|
||||
reqsList->AppendColumn(translate("Filename"));
|
||||
reqsList->AppendColumn(translate("Display Name"));
|
||||
reqsList->AppendColumn(translate("Condition"));
|
||||
|
||||
incsList->AppendColumn(translate("Filename"));
|
||||
incsList->AppendColumn(translate("Display Name"));
|
||||
incsList->AppendColumn(translate("Condition"));
|
||||
|
||||
loadAfterList->AppendColumn(translate("Filename"));
|
||||
loadAfterList->AppendColumn(translate("Display Name"));
|
||||
loadAfterList->AppendColumn(translate("Condition"));
|
||||
|
||||
messageList->AppendColumn(translate("Type"));
|
||||
messageList->AppendColumn(translate("Content"));
|
||||
messageList->AppendColumn(translate("Condition"));
|
||||
messageList->AppendColumn(translate("Language"));
|
||||
|
||||
tagsList->AppendColumn(translate("Add/Remove"));
|
||||
tagsList->AppendColumn(translate("Bash Tag"));
|
||||
tagsList->AppendColumn(translate("Condition"));
|
||||
|
||||
//Set up layout.
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxBoxSizer *vbox1 = new wxBoxSizer(wxVERTICAL);
|
||||
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);
|
||||
|
||||
wxBoxSizer * mainBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
mainBox->Add(pluginText, 0, wxALL, 5);
|
||||
|
||||
wxBoxSizer * hbox1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
hbox1->Add(new wxStaticText(this, wxID_ANY, translate("Priority: ")), 0, wxALL, 5);
|
||||
hbox1->Add(prioritySpin, 0, wxALL, 5);
|
||||
|
||||
mainBox->Add(hbox1);
|
||||
|
||||
wxBoxSizer * tabBox1 = new wxBoxSizer(wxVERTICAL);
|
||||
tabBox1->Add(reqsList, 1, wxEXPAND);
|
||||
reqsTab->SetSizer(tabBox1);
|
||||
|
||||
wxBoxSizer * tabBox2 = new wxBoxSizer(wxVERTICAL);
|
||||
tabBox2->Add(incsList, 1, wxEXPAND);
|
||||
incsTab->SetSizer(tabBox2);
|
||||
|
||||
wxBoxSizer * tabBox3 = new wxBoxSizer(wxVERTICAL);
|
||||
tabBox3->Add(loadAfterList, 1, wxEXPAND);
|
||||
loadAfterTab->SetSizer(tabBox3);
|
||||
|
||||
mainBox->Add(filesBook, 1, wxEXPAND);
|
||||
|
||||
wxBoxSizer * hbox2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox2->Add(addFileBtn, 0, wxALL, 10);
|
||||
hbox2->Add(editFileBtn, 0, wxALL, 10);
|
||||
hbox2->Add(removeFileBtn, 0, wxALL, 10);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
tagsTab->SetSizer(tabBox5);
|
||||
|
||||
mainBox->Add(messagesBook, 1, wxEXPAND);
|
||||
|
||||
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->AddSpacer(20);
|
||||
|
||||
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);
|
||||
|
||||
SetBackgroundColour(wxColour(255,255,255));
|
||||
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2013 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
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __BOSS_GUI_EDITOR__
|
||||
#define __BOSS_GUI_EDITOR__
|
||||
|
||||
#include "ids.h"
|
||||
#include "../metadata.h"
|
||||
|
||||
#include <vector>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
class Editor : public wxFrame {
|
||||
public:
|
||||
Editor(const wxString title, wxFrame *parent);
|
||||
|
||||
private:
|
||||
wxListBox * pluginList;
|
||||
|
||||
wxButton * addFileBtn;
|
||||
wxButton * editFileBtn;
|
||||
wxButton * removeFileBtn;
|
||||
|
||||
wxButton * addMsgBtn;
|
||||
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 * reqsList;
|
||||
wxListCtrl * incsList;
|
||||
wxListCtrl * loadAfterList;
|
||||
wxListCtrl * messageList;
|
||||
wxListCtrl * tagsList;
|
||||
|
||||
std::vector<boss::Plugin> plugins;
|
||||
};
|
||||
|
||||
#endif
|
||||
+23
-1
@@ -53,7 +53,29 @@ enum {
|
||||
MENU_FalloutNewVegas,
|
||||
//Settings window.
|
||||
OPTION_OKExitSettings,
|
||||
OPTION_CancelExitSettings
|
||||
OPTION_CancelExitSettings,
|
||||
//Editor window.
|
||||
LIST_Plugins,
|
||||
LIST_Reqs,
|
||||
LIST_Incs,
|
||||
LIST_LoadAfter,
|
||||
LIST_Messages,
|
||||
LIST_BashTags,
|
||||
SPIN_Priority,
|
||||
BUTTON_AddFile,
|
||||
BUTTON_EditFile,
|
||||
BUTTON_RemoveFile,
|
||||
BUTTON_AddMessage,
|
||||
BUTTON_EditMessage,
|
||||
BUTTON_RemoveMessage,
|
||||
BUTTON_AddTag,
|
||||
BUTTON_EditTag,
|
||||
BUTTON_RemoveTag,
|
||||
BUTTON_SaveEdits,
|
||||
BUTTON_UndoEdits,
|
||||
BUTTON_Recalc,
|
||||
BUTTON_Apply,
|
||||
BUTTON_Cancel
|
||||
};
|
||||
|
||||
wxString translate(const std::string& str);
|
||||
|
||||
+48
-1
@@ -26,6 +26,7 @@
|
||||
#include "../parsers.h"
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "editor.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <algorithm>
|
||||
@@ -490,7 +491,54 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
}
|
||||
|
||||
void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
//Parse the userlist and masterlist and get a list of installed plugins.
|
||||
|
||||
list<boss::Plugin> plugins;
|
||||
YAML::Node mlist, ulist;
|
||||
list<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")) {
|
||||
|
||||
boss::Plugin plugin(it->path().filename().string());
|
||||
plugins.push_back(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
if (fs::exists(_game.MasterlistPath())) {
|
||||
try {
|
||||
mlist = YAML::LoadFile(_game.MasterlistPath().string());
|
||||
} catch (YAML::ParserException& e) {
|
||||
//LOG_ERROR("Error: %s", e.getString().c_str());
|
||||
wxMessageBox(
|
||||
FromUTF8(format(loc::translate("Error: Masterlist parsing failed. %1%")) % e.what()),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
NULL);
|
||||
}
|
||||
if (mlist["plugins"])
|
||||
mlist_plugins = mlist["plugins"].as< list<boss::Plugin> >();
|
||||
}
|
||||
|
||||
if (fs::exists(_game.UserlistPath())) {
|
||||
try {
|
||||
ulist = YAML::LoadFile(_game.UserlistPath().string());
|
||||
} catch (YAML::ParserException& e) {
|
||||
//LOG_ERROR("Error: %s", e.getString().c_str());
|
||||
wxMessageBox(
|
||||
FromUTF8(format(loc::translate("Error: Userlist parsing failed. %1%")) % e.what()),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
NULL);
|
||||
}
|
||||
if (ulist["plugins"])
|
||||
ulist_plugins = ulist["plugins"].as< list<boss::Plugin> >();
|
||||
}
|
||||
|
||||
|
||||
Editor *editor = new Editor(translate("BOSS: Metadata Editor"), this);
|
||||
editor->SetIcon(wxIconLocation("BOSS.exe"));
|
||||
editor->Show();
|
||||
}
|
||||
|
||||
void Launcher::OnViewLastReport(wxCommandEvent& event) {
|
||||
@@ -498,7 +546,6 @@ void Launcher::OnViewLastReport(wxCommandEvent& event) {
|
||||
}
|
||||
|
||||
void Launcher::OnOpenSettings(wxCommandEvent& event) {
|
||||
//Tell the user that stuff is happenining.
|
||||
SettingsFrame *settings = new SettingsFrame(translate("BOSS: Settings"), this, _settings);
|
||||
settings->SetIcon(wxIconLocation("BOSS.exe"));
|
||||
settings->Show();
|
||||
|
||||
+8
-9
@@ -106,15 +106,14 @@ namespace boss {
|
||||
|
||||
/// Array used to try each of the expressions defined above using
|
||||
/// an iteration for each of them.
|
||||
boost::regex* version_checks[] = {
|
||||
new boost::regex(regex1, boost::regex::icase),
|
||||
new boost::regex(regex2, boost::regex::icase),
|
||||
new boost::regex(regex3, boost::regex::icase),
|
||||
new boost::regex(regex4, boost::regex::icase),
|
||||
new boost::regex(regex5, boost::regex::icase), //This incorrectly identifies "OBSE v19" where 19 is any integer.
|
||||
new boost::regex(regex6, boost::regex::icase), //This is responsible for metallicow's false positive.
|
||||
new boost::regex(regex7, boost::regex::icase),
|
||||
0
|
||||
boost::regex version_checks[7] = {
|
||||
boost::regex(regex1, boost::regex::icase),
|
||||
boost::regex(regex2, boost::regex::icase),
|
||||
boost::regex(regex3, boost::regex::icase),
|
||||
boost::regex(regex4, boost::regex::icase),
|
||||
boost::regex(regex5, boost::regex::icase), //This incorrectly identifies "OBSE v19" where 19 is any integer.
|
||||
boost::regex(regex6, boost::regex::icase), //This is responsible for metallicow's false positive.
|
||||
boost::regex(regex7, boost::regex::icase)
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ namespace boss {
|
||||
|
||||
/// Array used to try each of the expressions defined using
|
||||
/// an iteration for each of them.
|
||||
extern boost::regex* version_checks[];
|
||||
extern boost::regex version_checks[7];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions
|
||||
|
||||
+5
-5
@@ -29,7 +29,7 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -217,9 +217,9 @@ namespace boss {
|
||||
begin = text.begin();
|
||||
end = text.end();
|
||||
|
||||
/* for(int j = 0; boost::regex* re = version_checks[j]; j++) {
|
||||
for(int j = 0; j < 7 && version.empty(); j++) {
|
||||
boost::smatch what;
|
||||
while (boost::regex_search(begin, end, what, *re)) {
|
||||
while (boost::regex_search(begin, end, what, version_checks[j])) {
|
||||
if (what.empty())
|
||||
continue;
|
||||
|
||||
@@ -228,9 +228,9 @@ namespace boss {
|
||||
continue;
|
||||
|
||||
version = boost::trim_copy(string(match.first, match.second));
|
||||
break;
|
||||
}
|
||||
cout << "Checking regex: " << j << endl;
|
||||
}*/
|
||||
}
|
||||
|
||||
size_t pos1 = text.find("{{BASH:");
|
||||
if (pos1 == string::npos)
|
||||
|
||||
Reference in New Issue
Block a user