summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-11-23 22:35:08 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2019-11-23 22:35:08 -0500
commit3a085212c939ae8c5e6022a4c9bddfb7df95400f (patch)
tree9d327e5a539d1394505e9350867b577d4313575e
parent5c9de17b6376ce94b1cdff4f4edbba798e9bfd08 (diff)
added loot report to the plugin list, not used yet
split PluginList::data() into individual functions disabled loot message processing, will use report instead
-rw-r--r--src/loot.cpp131
-rw-r--r--src/loot.h62
-rw-r--r--src/pluginlist.cpp293
-rw-r--r--src/pluginlist.h17
4 files changed, 295 insertions, 208 deletions
diff --git a/src/loot.cpp b/src/loot.cpp
index 88ea8ce8..66e8a01d 100644
--- a/src/loot.cpp
+++ b/src/loot.cpp
@@ -58,10 +58,6 @@ public:
[&](auto&& lv, auto&& s){ log(lv, s); }, Qt::QueuedConnection);
QObject::connect(
- &m_loot, &Loot::information, this,
- [&](auto&& mod, auto&& i){ setInfo(mod, i); }, Qt::QueuedConnection);
-
- QObject::connect(
&m_loot, &Loot::finished, this,
[&]{ onFinished(); }, Qt::QueuedConnection);
}
@@ -116,11 +112,6 @@ public:
}
}
- void setInfo(const QString& mod, const QString& info)
- {
- m_core.pluginList()->addInformation(mod.toStdString().c_str(), info);
- }
-
bool result() const
{
return m_loot.result();
@@ -237,6 +228,7 @@ private:
if (m_cancelling) {
close();
} else {
+ handleReport();
m_report->setEnabled(true);
m_buttons->setStandardButtons(QDialogButtonBox::Close);
}
@@ -252,83 +244,55 @@ private:
addLineOutput(QString("[%1] %2").arg(log::levelToString(lv)).arg(s));
}
}
-};
-
-
-struct Loot::Message
-{
- QString type;
- QString text;
-};
-
-struct Loot::File
-{
- QString name;
- QString displayName;
-};
-
-struct Loot::Dirty
-{
- qint64 crc=0;
- qint64 itm=0;
- qint64 deletedReferences=0;
- qint64 deletedNavmesh=0;
- QString cleaningUtility;
- QString info;
- QString toString(bool isClean) const
+ void handleReport()
{
- if (isClean) {
- return QObject::tr("Verified clean by %1")
- .arg(cleaningUtility.isEmpty() ? "?" : cleaningUtility);
- }
-
- QString s = cleaningString();
+ const auto& report = m_loot.report();
- if (!info.isEmpty()) {
- s += " " + info;
+ if (!report.messages.empty()) {
+ addLineOutput("");
}
- return s;
- }
+ for (auto&& m : report.messages) {
+ log(levelFromLoot(
+ lootcli::logLevelFromString(m.type.toStdString())),
+ m.text);
+ }
- QString cleaningString() const
- {
- return QObject::tr("%1 found %2 ITM record(s), %3 deleted reference(s) and %4 deleted navmesh(es).")
- .arg(cleaningUtility.isEmpty() ? "?" : cleaningUtility)
- .arg(itm)
- .arg(deletedReferences)
- .arg(deletedNavmesh);
+ for (auto&& p : report.plugins) {
+ for (auto&& d : p.dirty) {
+ m_core.pluginList()->addInformation(p.name, d.toString(false));
+ }
+ }
}
};
-struct Loot::Plugin
-{
- QString name;
- std::vector<File> incompatibilities;
- std::vector<Message> messages;
- std::vector<Dirty> dirty, clean;
- std::vector<QString> missingMasters;
- bool loadsArchive = false;
- bool isMaster = false;
- bool isLightMaster = false;
-};
-struct Loot::Stats
+QString Loot::Dirty::toString(bool isClean) const
{
- qint64 time = 0;
- QString version;
-};
+ if (isClean) {
+ return QObject::tr("Verified clean by %1")
+ .arg(cleaningUtility.isEmpty() ? "?" : cleaningUtility);
+ }
-struct Loot::Report
-{
- std::vector<Message> messages;
- std::vector<Plugin> plugins;
- Stats stats;
-};
+ QString s = cleaningString();
+ if (!info.isEmpty()) {
+ s += " " + info;
+ }
+
+ return s;
+}
+
+QString Loot::Dirty::cleaningString() const
+{
+ return QObject::tr("%1 found %2 ITM record(s), %3 deleted reference(s) and %4 deleted navmesh(es).")
+ .arg(cleaningUtility.isEmpty() ? "?" : cleaningUtility)
+ .arg(itm)
+ .arg(deletedReferences)
+ .arg(deletedNavmesh);
+}
-class ReportFailed {};
Loot::Loot()
: m_thread(nullptr), m_cancel(false), m_result(false)
@@ -437,6 +401,11 @@ const QString& Loot::outPath() const
return m_outPath;
}
+const Loot::Report& Loot::report() const
+{
+ return m_report;
+}
+
void Loot::lootThread()
{
try {
@@ -558,7 +527,7 @@ void Loot::processStdout(const std::string &lootOut)
void Loot::processMessage(const lootcli::Message& m)
{
- static const std::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\.");
+ /*static const std::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\.");
static const std::regex exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\.");
switch (m.type)
@@ -595,7 +564,7 @@ void Loot::processMessage(const lootcli::Message& m)
emit progress(m.progress);
break;
}
- }
+ }*/
}
void Loot::processOutputFile()
@@ -623,19 +592,7 @@ void Loot::processOutputFile()
return;
}
- const auto report = createReport(doc);
-
- for (auto&& m : report.messages) {
- emit log(levelFromLoot(
- lootcli::logLevelFromString(m.type.toStdString())),
- m.text);
- }
-
- for (auto&& p : report.plugins) {
- for (auto&& d : p.dirty) {
- emit information(p.name, d.toString(false));
- }
- }
+ m_report = createReport(doc);
}
Loot::Report Loot::createReport(const QJsonDocument& doc) const
diff --git a/src/loot.h b/src/loot.h
index 95dbbe50..dc9b0d7b 100644
--- a/src/loot.h
+++ b/src/loot.h
@@ -17,6 +17,57 @@ class Loot : public QObject
Q_OBJECT;
public:
+ struct Message
+ {
+ QString type;
+ QString text;
+ };
+
+ struct File
+ {
+ QString name;
+ QString displayName;
+ };
+
+ struct Dirty
+ {
+ qint64 crc=0;
+ qint64 itm=0;
+ qint64 deletedReferences=0;
+ qint64 deletedNavmesh=0;
+ QString cleaningUtility;
+ QString info;
+
+ QString toString(bool isClean) const;
+ QString cleaningString() const;
+ };
+
+ struct Plugin
+ {
+ QString name;
+ std::vector<File> incompatibilities;
+ std::vector<Message> messages;
+ std::vector<Dirty> dirty, clean;
+ std::vector<QString> missingMasters;
+ bool loadsArchive = false;
+ bool isMaster = false;
+ bool isLightMaster = false;
+ };
+
+ struct Stats
+ {
+ qint64 time = 0;
+ QString version;
+ };
+
+ struct Report
+ {
+ std::vector<Message> messages;
+ std::vector<Plugin> plugins;
+ Stats stats;
+ };
+
+
Loot();
~Loot();
@@ -24,23 +75,15 @@ public:
void cancel();
bool result() const;
const QString& outPath() const;
+ const Report& report() const;
signals:
void output(const QString& s);
void progress(const lootcli::Progress p);
void log(MOBase::log::Levels level, const QString& s);
- void information(const QString& mod, const QString& info);
void finished();
private:
- struct Report;
- struct Stats;
- struct Message;
- struct Plugin;
- struct Dirty;
- struct File;
- class BadReport {};
-
std::unique_ptr<QThread> m_thread;
std::atomic<bool> m_cancel;
std::atomic<bool> m_result;
@@ -48,6 +91,7 @@ private:
env::HandlePtr m_lootProcess;
env::HandlePtr m_stdout;
std::string m_outputBuffer;
+ Report m_report;
std::string readFromPipe();
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index b50a51d8..ab421f2b 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -423,6 +423,17 @@ void PluginList::addInformation(const QString &name, const QString &message)
}
}
+void PluginList::addLootReport(const QString& name, Loot::Plugin plugin)
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+
+ if (iter != m_ESPsByName.end()) {
+ m_AdditionalInfo[name.toLower()].m_Loot = std::move(plugin);
+ } else {
+ log::warn("failed to associate loot report for \"{}\"", name);
+ }
+}
+
bool PluginList::isEnabled(int index)
{
return m_ESPs.at(index).m_Enabled;
@@ -908,137 +919,195 @@ void PluginList::testMasters()
QVariant PluginList::data(const QModelIndex &modelIndex, int role) const
{
int index = modelIndex.row();
- if ((role == Qt::DisplayRole)
- || (role == Qt::EditRole)) {
- switch (modelIndex.column()) {
- case COL_NAME: {
- return m_ESPs[index].m_Name;
- } break;
- case COL_PRIORITY: {
- return m_ESPs[index].m_Priority;
- } break;
- case COL_MODINDEX: {
- return m_ESPs[index].m_Index;
- } break;
- default: {
- return QVariant();
- } break;
- }
+
+ if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
+ return displayData(modelIndex);
} else if ((role == Qt::CheckStateRole) && (modelIndex.column() == 0)) {
- if (m_ESPs[index].m_ForceEnabled) {
- return QVariant();
- } else {
- return m_ESPs[index].m_Enabled ? Qt::Checked : Qt::Unchecked;
- }
+ return checkstateData(modelIndex);
} else if (role == Qt::ForegroundRole) {
- if ((modelIndex.column() == COL_NAME) &&
- m_ESPs[index].m_ForceEnabled) {
- return QBrush(Qt::gray);
- }
- } else if (role == Qt::BackgroundRole
- || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
- if (m_ESPs[index].m_ModSelected) {
- return Settings::instance().colors().pluginListContained();
- } else {
- return QVariant();
- }
+ return foregroundData(modelIndex);
+ } else if (role == Qt::BackgroundRole || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
+ return backgroundData(modelIndex);
} else if (role == Qt::FontRole) {
- QFont result;
- if (m_ESPs[index].m_IsMaster) {
- result.setItalic(true);
- result.setWeight(QFont::Bold);
- } else if (m_ESPs[index].m_IsLight || m_ESPs[index].m_IsLightFlagged) {
- result.setItalic(true);
- }
- return result;
+ return fontData(modelIndex);
} else if (role == Qt::TextAlignmentRole) {
- if (modelIndex.column() == 0) {
- return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
- } else {
- return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
- }
+ return alignmentData(modelIndex);
} else if (role == Qt::ToolTipRole) {
- QString name = m_ESPs[index].m_Name.toLower();
- auto addInfoIter = m_AdditionalInfo.find(name);
- QString toolTip;
- if (addInfoIter != m_AdditionalInfo.end()) {
- if (!addInfoIter->second.m_Messages.isEmpty()) {
- toolTip += "<ul style=\"margin-left:15px; -qt-list-indent: 0;\">";
- for (auto&& message : addInfoIter->second.m_Messages) {
- toolTip += "<li>" + message + "</li>";
- }
- toolTip += "</ul><hr>";
+ return tooltipData(modelIndex);
+ } else if (role == Qt::UserRole + 1) {
+ return iconData(modelIndex);
+ }
+ return QVariant();
+}
+
+QVariant PluginList::displayData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ switch (modelIndex.column()) {
+ case COL_NAME: {
+ return m_ESPs[index].m_Name;
+ } break;
+ case COL_PRIORITY: {
+ return m_ESPs[index].m_Priority;
+ } break;
+ case COL_MODINDEX: {
+ return m_ESPs[index].m_Index;
+ } break;
+ default: {
+ return QVariant();
+ } break;
+ }
+}
+
+QVariant PluginList::checkstateData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ if (m_ESPs[index].m_ForceEnabled) {
+ return QVariant();
+ } else {
+ return m_ESPs[index].m_Enabled ? Qt::Checked : Qt::Unchecked;
+ }
+}
+
+QVariant PluginList::foregroundData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ if ((modelIndex.column() == COL_NAME) &&
+ m_ESPs[index].m_ForceEnabled) {
+ return QBrush(Qt::gray);
+ }
+
+ return {};
+}
+
+QVariant PluginList::backgroundData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ if (m_ESPs[index].m_ModSelected) {
+ return Settings::instance().colors().pluginListContained();
+ } else {
+ return QVariant();
+ }
+}
+
+QVariant PluginList::fontData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ QFont result;
+
+ if (m_ESPs[index].m_IsMaster) {
+ result.setItalic(true);
+ result.setWeight(QFont::Bold);
+ } else if (m_ESPs[index].m_IsLight || m_ESPs[index].m_IsLightFlagged) {
+ result.setItalic(true);
+ }
+
+ return result;
+}
+
+QVariant PluginList::alignmentData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ if (modelIndex.column() == 0) {
+ return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
+ } else {
+ return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
+ }
+}
+
+QVariant PluginList::tooltipData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ QString name = m_ESPs[index].m_Name.toLower();
+ auto addInfoIter = m_AdditionalInfo.find(name);
+ QString toolTip;
+ if (addInfoIter != m_AdditionalInfo.end()) {
+ if (!addInfoIter->second.m_Messages.isEmpty()) {
+ toolTip += "<ul style=\"margin-left:15px; -qt-list-indent: 0;\">";
+ for (auto&& message : addInfoIter->second.m_Messages) {
+ toolTip += "<li>" + message + "</li>";
}
+ toolTip += "</ul><hr>";
}
- if (m_ESPs[index].m_ForceEnabled) {
- QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
- text += tr("<br><b><i>This plugin can't be disabled (enforced by the game).</i></b>");
- toolTip += text;
- } else {
- QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
- if (m_ESPs[index].m_Author.size() > 0) {
- text += "<br><b>" + tr("Author") + "</b>: " + TruncateString(m_ESPs[index].m_Author);
- }
- if (m_ESPs[index].m_Description.size() > 0) {
- text += "<br><b>" + tr("Description") + "</b>: " + TruncateString(m_ESPs[index].m_Description);
- }
- if (m_ESPs[index].m_MasterUnset.size() > 0) {
- text += "<br><b>" + tr("Missing Masters") + "</b>: <b>" + TruncateString(SetJoin(m_ESPs[index].m_MasterUnset, ", ")) + "</b>";
- }
- std::set<QString> enabledMasters;
- std::set_difference(m_ESPs[index].m_Masters.begin(), m_ESPs[index].m_Masters.end(),
- m_ESPs[index].m_MasterUnset.begin(), m_ESPs[index].m_MasterUnset.end(),
- std::inserter(enabledMasters, enabledMasters.end()));
- if (!enabledMasters.empty()) {
- text += "<br><b>" + tr("Enabled Masters") + "</b>: " + TruncateString(SetJoin(enabledMasters, ", "));
- }
- if (!m_ESPs[index].m_Archives.empty()) {
- text += "<br><b>" + tr("Loads Archives") + "</b>: " + TruncateString(SetJoin(m_ESPs[index].m_Archives, ", "));
- text += "<br>" + tr("There are Archives connected to this plugin. "
- "Their assets will be added to your game, overwriting in case of conflicts following the plugin order. "
- "Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin)");
- }
- if (m_ESPs[index].m_HasIni) {
- text += "<br><b>" + tr("Loads INI settings") + "</b>: ";
- text += "<br>" + tr("There is an ini file connected to this plugin. "
- "Its settings will be added to your game settings, overwriting in case of conflicts.");
- }
- if (m_ESPs[index].m_IsLightFlagged && !m_ESPs[index].m_IsLight) {
- text += "<br><br>" + tr("This ESP is flagged as an ESL. "
- "It will adhere to the ESP load order but the records will be loaded in ESL space.");
- }
- toolTip += text;
+ }
+ if (m_ESPs[index].m_ForceEnabled) {
+ QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
+ text += tr("<br><b><i>This plugin can't be disabled (enforced by the game).</i></b>");
+ toolTip += text;
+ } else {
+ QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
+ if (m_ESPs[index].m_Author.size() > 0) {
+ text += "<br><b>" + tr("Author") + "</b>: " + TruncateString(m_ESPs[index].m_Author);
+ }
+ if (m_ESPs[index].m_Description.size() > 0) {
+ text += "<br><b>" + tr("Description") + "</b>: " + TruncateString(m_ESPs[index].m_Description);
}
- return toolTip;
- } else if (role == Qt::UserRole + 1) {
- QVariantList result;
- QString nameLower = m_ESPs[index].m_Name.toLower();
if (m_ESPs[index].m_MasterUnset.size() > 0) {
- result.append(":/MO/gui/warning");
+ text += "<br><b>" + tr("Missing Masters") + "</b>: <b>" + TruncateString(SetJoin(m_ESPs[index].m_MasterUnset, ", ")) + "</b>";
}
- if (m_LockedOrder.find(nameLower) != m_LockedOrder.end()) {
- result.append(":/MO/gui/locked");
+ std::set<QString> enabledMasters;
+ std::set_difference(m_ESPs[index].m_Masters.begin(), m_ESPs[index].m_Masters.end(),
+ m_ESPs[index].m_MasterUnset.begin(), m_ESPs[index].m_MasterUnset.end(),
+ std::inserter(enabledMasters, enabledMasters.end()));
+ if (!enabledMasters.empty()) {
+ text += "<br><b>" + tr("Enabled Masters") + "</b>: " + TruncateString(SetJoin(enabledMasters, ", "));
}
- auto bossInfoIter = m_AdditionalInfo.find(nameLower);
- if (bossInfoIter != m_AdditionalInfo.end()) {
- if (!bossInfoIter->second.m_Messages.isEmpty()) {
- result.append(":/MO/gui/information");
- }
+ if (!m_ESPs[index].m_Archives.empty()) {
+ text += "<br><b>" + tr("Loads Archives") + "</b>: " + TruncateString(SetJoin(m_ESPs[index].m_Archives, ", "));
+ text += "<br>" + tr("There are Archives connected to this plugin. "
+ "Their assets will be added to your game, overwriting in case of conflicts following the plugin order. "
+ "Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin)");
}
if (m_ESPs[index].m_HasIni) {
- result.append(":/MO/gui/attachment");
- }
- if (!m_ESPs[index].m_Archives.empty()) {
- result.append(":/MO/gui/archive_conflict_neutral");
+ text += "<br><b>" + tr("Loads INI settings") + "</b>: ";
+ text += "<br>" + tr("There is an ini file connected to this plugin. "
+ "Its settings will be added to your game settings, overwriting in case of conflicts.");
}
if (m_ESPs[index].m_IsLightFlagged && !m_ESPs[index].m_IsLight) {
- result.append(":/MO/gui/awaiting");
+ text += "<br><br>" + tr("This ESP is flagged as an ESL. "
+ "It will adhere to the ESP load order but the records will be loaded in ESL space.");
}
- return result;
+ toolTip += text;
}
- return QVariant();
+ return toolTip;
}
+QVariant PluginList::iconData(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+
+ QVariantList result;
+ QString nameLower = m_ESPs[index].m_Name.toLower();
+ if (m_ESPs[index].m_MasterUnset.size() > 0) {
+ result.append(":/MO/gui/warning");
+ }
+ if (m_LockedOrder.find(nameLower) != m_LockedOrder.end()) {
+ result.append(":/MO/gui/locked");
+ }
+ auto bossInfoIter = m_AdditionalInfo.find(nameLower);
+ if (bossInfoIter != m_AdditionalInfo.end()) {
+ if (!bossInfoIter->second.m_Messages.isEmpty()) {
+ result.append(":/MO/gui/information");
+ }
+ }
+ if (m_ESPs[index].m_HasIni) {
+ result.append(":/MO/gui/attachment");
+ }
+ if (!m_ESPs[index].m_Archives.empty()) {
+ result.append(":/MO/gui/archive_conflict_neutral");
+ }
+ if (m_ESPs[index].m_IsLightFlagged && !m_ESPs[index].m_IsLight) {
+ result.append(":/MO/gui/awaiting");
+ }
+ return result;
+}
bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int role)
{
diff --git a/src/pluginlist.h b/src/pluginlist.h
index 092ba378..5cbe0a17 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -23,6 +23,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <directoryentry.h>
#include <ipluginlist.h>
#include "profile.h"
+#include "loot.h"
+
namespace MOBase { class IPluginGame; }
#include <QString>
@@ -155,6 +157,11 @@ public:
void addInformation(const QString &name, const QString &message);
/**
+ * adds information from a loot report
+ */
+ void addLootReport(const QString& name, Loot::Plugin plugin);
+
+ /**
* @brief test if a plugin is enabled
*
* @param index index of the plugin to look up
@@ -324,6 +331,7 @@ private:
struct AdditionalInfo {
QStringList m_Messages;
+ Loot::Plugin m_Loot;
};
friend bool ByName(const ESPInfo& LHS, const ESPInfo& RHS);
@@ -372,6 +380,15 @@ private:
const MOBase::IPluginGame *m_GamePlugin;
+
+ QVariant displayData(const QModelIndex &modelIndex) const;
+ QVariant checkstateData(const QModelIndex &modelIndex) const;
+ QVariant foregroundData(const QModelIndex &modelIndex) const;
+ QVariant backgroundData(const QModelIndex &modelIndex) const;
+ QVariant fontData(const QModelIndex &modelIndex) const;
+ QVariant alignmentData(const QModelIndex &modelIndex) const;
+ QVariant tooltipData(const QModelIndex &modelIndex) const;
+ QVariant iconData(const QModelIndex &modelIndex) const;
};
#pragma warning(pop)