mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Fixed script includes in report, made sorting progress dialog more responsive, added setting to choose whether to display report in a BOSS window or the default browser, and added a header-only plugin reading mode for the metadata editor.
This commit is contained in:
@@ -49,21 +49,21 @@ BOSSv3 won't have a command line interface, to simplify things. It also allows B
|
||||
- [ ] Develop sorting algorithm.
|
||||
- [ ] Work out how to implement masterlist updating and write the code.
|
||||
- [x] Develop UI - metadata editor window.
|
||||
- [ ] Develop UI - report viewer.
|
||||
- [ ] Error handling.
|
||||
- [x] Develop UI - report viewer.
|
||||
- [x] Error handling.
|
||||
- [ ] Checks for cyclic dependencies and incompatibilities.
|
||||
- [ ] Setting load order.
|
||||
- [ ] Optimisations to load ordering.
|
||||
- [ ] Implement logging.
|
||||
- [ ] Add a quick header-only plugin read for use when loading the metadata editor, so that existing Bash Tags can also be displayed.
|
||||
- [ ] Make validity checks non-fatal.
|
||||
- [x] Add a quick header-only plugin read for use when loading the metadata editor, so that existing Bash Tags can also be displayed.
|
||||
- [x] Make validity checks non-fatal.
|
||||
- [ ] Add a massive "RUN THE GAME LAUNCHER IF YOUR GAME IS NOT DETECTED" message somewhere.
|
||||
- [ ] Generalise Total Conversion support, so that any TC for any of the supported 'base' games can be used with BOSS.
|
||||
- [x] Write XHTML report generator.
|
||||
- [ ] Write report CSS.
|
||||
- [ ] Write report Javascript.
|
||||
- [ ] Double-check ghosted file support.
|
||||
- [ ] Add a setting that lets users choose whether to use the viewer window or their own browser when viewing BOSS's report.
|
||||
- [x] Add a setting that lets users choose whether to use the viewer window or their own browser when viewing BOSS's report.
|
||||
- [x] Somehow implement filter settings memory for the BOSS report.
|
||||
- [ ] Implement checking of details part of report against previous report.
|
||||
|
||||
|
||||
@@ -113,11 +113,6 @@ input[type='checkbox'] {
|
||||
ul {margin-top:0.5em; margin-bottom:1em;}
|
||||
li {margin:0.75em 0;}
|
||||
|
||||
.active {
|
||||
display:block;
|
||||
color:green;
|
||||
margin-left:1.5em;
|
||||
}
|
||||
#plugins > ul {list-style:none;}
|
||||
.hidden, #summary.hidden, #plugins.hidden {
|
||||
display:none;
|
||||
@@ -146,7 +141,7 @@ li.success{background:#90ff90;display:table;padding:0.3em 0.5em;border-radius:0.
|
||||
|
||||
.crc{color:#BC8923;margin-right:1em;}
|
||||
|
||||
.active{color:#0A0;margin-right:1em;}
|
||||
.active{color:green;margin-right:1em;}
|
||||
|
||||
.tagPrefix{color:#CD5555;}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Game: auto # auto, oblivion, nehrim, skyrim, fallout3, falloutn
|
||||
Last Game: auto # auto, oblivion, nehrim, skyrim, fallout3, falloutnv
|
||||
Debug Verbosity: 0 # 0, 1, 2, 3. Logging takes place if > 0.
|
||||
Update Masterlist: true
|
||||
View Report Externally: false
|
||||
|
||||
Masterlist URLs:
|
||||
Oblivion: http://better-oblivion-sorting-software.googlecode.com/svn/data/boss-oblivion/masterlist.yaml
|
||||
|
||||
+13
-15
@@ -115,6 +115,19 @@ namespace boss {
|
||||
node.set_name("link");
|
||||
node.append_attribute("rel").set_value("stylesheet");
|
||||
node.append_attribute("href").set_value("../resource/style.css");
|
||||
|
||||
node = head.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/polyfill.js");
|
||||
node.text().set(" ");
|
||||
|
||||
node = head.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/storage.js");
|
||||
node.text().set(" ");
|
||||
|
||||
node = head.append_child(pugi::node_comment);
|
||||
node.set_value("[if IE 8]><script src='../resource/DOM-shim-ie8.js'></script><![endif]");
|
||||
}
|
||||
|
||||
void AppendNav(pugi::xml_node& body) {
|
||||
@@ -456,21 +469,6 @@ namespace boss {
|
||||
|
||||
pugi::xml_node node;
|
||||
|
||||
node = body.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/polyfill.js");
|
||||
node.text().set(" ");
|
||||
|
||||
node = body.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/storage.js");
|
||||
node.text().set(" ");
|
||||
|
||||
node = body.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/DOM-shim-ie8.js");
|
||||
node.text().set(" ");
|
||||
|
||||
node = body.append_child();
|
||||
node.set_name("script");
|
||||
node.append_attribute("src").set_value("../resource/script.js");
|
||||
|
||||
+70
-17
@@ -339,8 +339,7 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
string filename = it->path().filename().string();
|
||||
out << "Reading plugin: " << filename << endl;
|
||||
boss::Plugin plugin(_game, filename);
|
||||
//boss::Plugin plugin(filename);
|
||||
boss::Plugin plugin(_game, filename, false);
|
||||
plugins.push_back(plugin);
|
||||
|
||||
progDia->Pulse();
|
||||
@@ -424,6 +423,10 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
if (pos != ulist_plugins.end())
|
||||
it->Merge(*pos);
|
||||
|
||||
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
|
||||
end = time(NULL);
|
||||
@@ -447,6 +450,8 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
this);
|
||||
return;
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
|
||||
end = time(NULL);
|
||||
@@ -459,12 +464,17 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
for (list<boss::Plugin>::iterator it=plugins.begin(), endIt = plugins.end(); it != endIt; ++it) {
|
||||
map<string, bool> issues = it->CheckInstallValidity(_game);
|
||||
list<boss::Message> messages = it->Messages();
|
||||
for (map<string,bool>::const_iterator jt=issues.begin(), endJt=issues.end(); jt != endJt; ++jt) {
|
||||
if (jt->second)
|
||||
out << "Error: Invalid install detected! \"" << jt->first << "\" is incompatible with \"" << it->Name() << "\" and is present." << endl;
|
||||
messages.push_back(boss::Message("error", "\"" + jt->first + "\" is incompatible with \"" + it->Name() + "\" and is present."));
|
||||
else
|
||||
out << "Error: Invalid install detected! \"" << jt->first << "\" is required by \"" << it->Name() << "\" but is missing." << endl;
|
||||
messages.push_back(boss::Message("error", "\"" + jt->first + "\" is required by \"" + it->Name() + "\" but is missing."));
|
||||
}
|
||||
if (!issues.empty())
|
||||
it->Messages(messages);
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
|
||||
|
||||
@@ -502,7 +512,12 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
if (overlap > 0)
|
||||
out << '\t' << '\t' << jt->Name() << " (" << overlap << " records)" << endl;
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
@@ -516,22 +531,39 @@ void Launcher::OnSortPlugins(wxCommandEvent& event) {
|
||||
|
||||
out << "Writing results file..." << endl;
|
||||
|
||||
GenerateReport(_game.ReportPath().string(),
|
||||
messages,
|
||||
plugins,
|
||||
"4030 (2020-13-13)",
|
||||
_settings["Update Masterlist"].as<bool>(),
|
||||
true);
|
||||
try {
|
||||
GenerateReport(_game.ReportPath().string(),
|
||||
messages,
|
||||
plugins,
|
||||
"4030 (2020-13-13)",
|
||||
_settings["Update Masterlist"].as<bool>(),
|
||||
true);
|
||||
} catch (boss::error& e) {
|
||||
wxMessageBox(
|
||||
FromUTF8(format(loc::translate("Error: %1%")) % e.what()),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
out << "Tester finished. Total time taken: " << time(NULL) - t0 << endl;
|
||||
out.close();
|
||||
|
||||
progDia->Destroy();
|
||||
|
||||
//Now a results report definitely exists.
|
||||
ViewButton->Enable(true);
|
||||
|
||||
progDia->Destroy();
|
||||
|
||||
if (_settings["View Report Externally"] && _settings["View Report Externally"].as<bool>()) {
|
||||
wxLaunchDefaultApplication(_game.ReportPath().string());
|
||||
} else {
|
||||
//Create viewer window.
|
||||
Viewer *viewer = new Viewer(this, translate("BOSS: Report Viewer"), _game);
|
||||
viewer->Show();
|
||||
}
|
||||
}
|
||||
|
||||
void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
@@ -539,10 +571,15 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
//Should probably check for masterlist updates before opening metadata editor.
|
||||
vector<boss::Plugin> installed, mlist_plugins, ulist_plugins;
|
||||
|
||||
wxProgressDialog *progDia = new wxProgressDialog(translate("BOSS: Working..."),translate("BOSS working..."), 1000, this, wxPD_APP_MODAL|wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME);
|
||||
|
||||
//Scan for installed 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")) {
|
||||
installed.push_back(boss::Plugin(it->path().filename().string()));
|
||||
boss::Plugin plugin(_game, it->path().filename().string(), true);
|
||||
installed.push_back(plugin);
|
||||
|
||||
progDia->Pulse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,6 +599,8 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
if (mlist["plugins"])
|
||||
mlist_plugins = mlist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
//Parse userlist.
|
||||
if (fs::exists(_game.UserlistPath())) {
|
||||
@@ -579,6 +618,8 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
if (ulist["plugins"])
|
||||
ulist_plugins = ulist["plugins"].as< vector<boss::Plugin> >();
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
//Merge the masterlist down into the installed mods list.
|
||||
for (vector<boss::Plugin>::const_iterator it=mlist_plugins.begin(), endit=mlist_plugins.end(); it != endit; ++it) {
|
||||
@@ -588,26 +629,38 @@ void Launcher::OnEditMetadata(wxCommandEvent& event) {
|
||||
pos->Merge(*it);
|
||||
}
|
||||
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
//Add empty entries for any userlist entries that aren't installed.
|
||||
for (vector<boss::Plugin>::const_iterator it=ulist_plugins.begin(), endit=ulist_plugins.end(); it != endit; ++it) {
|
||||
if (find(installed.begin(), installed.end(), *it) == installed.end())
|
||||
installed.push_back(boss::Plugin(it->Name()));
|
||||
}
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
//Sort into alphabetical order.
|
||||
std::sort(installed.begin(), installed.end(), AlphaSortPlugins);
|
||||
|
||||
progDia->Pulse();
|
||||
|
||||
//Create editor window.
|
||||
Editor *editor = new Editor(this, translate("BOSS: Metadata Editor"), _game, installed, ulist_plugins);
|
||||
|
||||
progDia->Destroy();
|
||||
|
||||
editor->Show();
|
||||
}
|
||||
|
||||
void Launcher::OnViewLastReport(wxCommandEvent& event) {
|
||||
//Create viewer window.
|
||||
Viewer *viewer = new Viewer(this, translate("BOSS: Report Viewer"), _game);
|
||||
|
||||
viewer->Show();
|
||||
if (_settings["View Report Externally"] && _settings["View Report Externally"].as<bool>()) {
|
||||
wxLaunchDefaultApplication(_game.ReportPath().string());
|
||||
} else {
|
||||
//Create viewer window.
|
||||
Viewer *viewer = new Viewer(this, translate("BOSS: Report Viewer"), _game);
|
||||
viewer->Show();
|
||||
}
|
||||
}
|
||||
|
||||
void Launcher::OnOpenSettings(wxCommandEvent& event) {
|
||||
|
||||
@@ -70,6 +70,7 @@ SettingsFrame::SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node
|
||||
FONVURL = new wxTextCtrl(this, wxID_ANY);
|
||||
|
||||
UpdateMasterlistBox = new wxCheckBox(this, wxID_ANY, translate("Update masterlist before sorting."));
|
||||
reportViewBox = new wxCheckBox(this, wxID_ANY, translate("View reports externally in default browser."));
|
||||
|
||||
//Set up layout.
|
||||
wxSizerFlags leftItem(0);
|
||||
@@ -115,6 +116,8 @@ SettingsFrame::SettingsFrame(wxWindow *parent, const wxString& title, YAML::Node
|
||||
bigBox->Add(GridSizer, 0, wxEXPAND|wxALL, 10);
|
||||
|
||||
bigBox->Add(UpdateMasterlistBox, wholeItem);
|
||||
|
||||
bigBox->Add(reportViewBox, wholeItem);
|
||||
|
||||
bigBox->AddSpacer(10);
|
||||
bigBox->AddStretchSpacer(1);
|
||||
@@ -174,6 +177,11 @@ void SettingsFrame::SetDefaultValues() {
|
||||
UpdateMasterlistBox->SetValue(update);
|
||||
}
|
||||
|
||||
if (_settings["View Report Externally"]) {
|
||||
bool view = _settings["View Report Externally"].as<bool>();
|
||||
reportViewBox->SetValue(view);
|
||||
}
|
||||
|
||||
if (_settings["Masterlist URLs"]) {
|
||||
YAML::Node urls = _settings["Masterlist URLs"];
|
||||
|
||||
@@ -228,6 +236,8 @@ void SettingsFrame::OnQuit(wxCommandEvent& event) {
|
||||
|
||||
_settings["Update Masterlist"] = UpdateMasterlistBox->IsChecked();
|
||||
|
||||
_settings["View Report Externally"] = reportViewBox->IsChecked();
|
||||
|
||||
_settings["Masterlist URLs"]["Oblivion"] = string(OblivionURL->GetValue().ToUTF8());
|
||||
|
||||
_settings["Masterlist URLs"]["Nehrim"] = string(NehrimURL->GetValue().ToUTF8());
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
wxChoice *GameChoice;
|
||||
wxChoice *LanguageChoice;
|
||||
wxCheckBox *UpdateMasterlistBox;
|
||||
wxCheckBox *reportViewBox;
|
||||
wxTextCtrl *OblivionURL;
|
||||
wxTextCtrl *NehrimURL;
|
||||
wxTextCtrl *SkyrimURL;
|
||||
|
||||
+6
-2
@@ -246,12 +246,16 @@ namespace boss {
|
||||
Plugin::Plugin() : enabled(true), priority(0), isMaster(false), isActive(false), crc(0) {}
|
||||
Plugin::Plugin(const std::string& n) : name(n), enabled(true), priority(0), isMaster(false), isActive(false), crc(0) {}
|
||||
|
||||
Plugin::Plugin(boss::Game& game, const std::string& n)
|
||||
Plugin::Plugin(boss::Game& game, const std::string& n, const bool headerOnly)
|
||||
: name(n), enabled(true), priority(0) {
|
||||
|
||||
// Get data from file contents using libespm. Assumes libespm has already been initialised.
|
||||
boost::filesystem::path filepath = game.DataPath() / n;
|
||||
espm::File file(filepath.string(), game.espm_settings, false, false);
|
||||
espm::File file;
|
||||
if (headerOnly)
|
||||
file = espm::File(filepath.string(), game.espm_settings, false, true);
|
||||
else
|
||||
file = espm::File(filepath.string(), game.espm_settings, false, false);
|
||||
|
||||
isMaster = file.isMaster(game.espm_settings);
|
||||
masters = file.getMasters();
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ namespace boss {
|
||||
public:
|
||||
Plugin();
|
||||
Plugin(const std::string& name);
|
||||
Plugin(boss::Game& game, const std::string& name);
|
||||
Plugin(boss::Game& game, const std::string& name, const bool headerOnly);
|
||||
|
||||
void Merge(const Plugin& plugin, bool ifdDisabled = false);
|
||||
Plugin DiffMetadata(const Plugin& plugin) const;
|
||||
|
||||
Reference in New Issue
Block a user