From 54b18e88159738a3054c71d5a4827646caad4ded Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 23 Nov 2019 23:54:19 -0500 Subject: added loot info to tooltip --- src/loot.cpp | 51 +++++-------- src/loot.h | 2 +- src/pluginlist.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++---------- src/pluginlist.h | 4 + 4 files changed, 195 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/loot.cpp b/src/loot.cpp index 66e8a01d..c315056b 100644 --- a/src/loot.cpp +++ b/src/loot.cpp @@ -254,15 +254,11 @@ private: } for (auto&& m : report.messages) { - log(levelFromLoot( - lootcli::logLevelFromString(m.type.toStdString())), - m.text); + log(m.type, m.text); } for (auto&& p : report.plugins) { - for (auto&& d : p.dirty) { - m_core.pluginList()->addInformation(p.name, d.toString(false)); - } + m_core.pluginList()->addLootReport(p.name, p); } } }; @@ -527,35 +523,11 @@ 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 exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\."); - switch (m.type) { case lootcli::MessageType::Log: { - if (m.logLevel == lootcli::LogLevels::Error) { - std::smatch match; - - if (std::regex_match(m.log, match, exRequires)) { - std::string modName(match[1].first, match[1].second); - std::string dependency(match[2].first, match[2].second); - emit information( - QString::fromStdString(modName), - tr("depends on missing \"%1\"").arg(dependency.c_str())); - } else if (std::regex_match(m.log, match, exIncompatible)) { - std::string modName(match[1].first, match[1].second); - std::string dependency(match[2].first, match[2].second); - emit information( - QString::fromStdString(modName), - tr("incompatible with \"%1\"").arg(dependency.c_str())); - } else { - emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); - } - } else { - emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); - } - + emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); break; } @@ -564,7 +536,7 @@ void Loot::processMessage(const lootcli::Message& m) emit progress(m.progress); break; } - }*/ + } } void Loot::processOutputFile() @@ -674,7 +646,20 @@ std::vector Loot::reportMessages(const QJsonArray& array) const } Message m; - m.type = getWarn(o, "type"); + + const auto type = getWarn(o, "type"); + + if (type == "info") { + m.type = log::Info; + } else if (type == "warn") { + m.type = log::Warning; + } else if (type == "error") { + m.type = log::Error; + } else { + log::error("unknown message type '{}'", type); + m.type = log::Info; + } + m.text = getWarn(o, "text"); if (!m.text.isEmpty()) { diff --git a/src/loot.h b/src/loot.h index dc9b0d7b..3a7c6aa9 100644 --- a/src/loot.h +++ b/src/loot.h @@ -19,7 +19,7 @@ class Loot : public QObject public: struct Message { - QString type; + MOBase::log::Levels type; QString text; }; diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 52c3fc3c..e91d820d 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1034,36 +1034,30 @@ QVariant PluginList::tooltipData(const QModelIndex &modelIndex) const QString toolTip; - // additional info - auto itor = m_AdditionalInfo.find(esp.name.toLower()); - - if (itor != m_AdditionalInfo.end()) { - if (!itor->second.messages.isEmpty()) { - toolTip += "
    "; - - for (auto&& message : itor->second.messages) { - toolTip += "
  • " + message + "
  • "; - } - - toolTip += "

"; - } - } - - toolTip += tr("Origin: %1").arg(esp.originName); + toolTip += "" + tr("Origin") + ": " + esp.originName; if (esp.forceEnabled) { - toolTip += tr("
This plugin can't be disabled (enforced by the game)."); + toolTip += + "
" + + tr("This plugin can't be disabled (enforced by the game).") + + ""; } else { if (!esp.author.isEmpty()) { - toolTip += "
" + tr("Author") + ": " + TruncateString(esp.author); + toolTip += + "
" + tr("Author") + ": " + + TruncateString(esp.author); } if (esp.description.size() > 0) { - toolTip += "
" + tr("Description") + ": " + TruncateString(esp.description); + toolTip += + "
" + tr("Description") + ": " + + TruncateString(esp.description); } if (esp.masterUnset.size() > 0) { - toolTip += "
" + tr("Missing Masters") + ": " + TruncateString(SetJoin(esp.masterUnset, ", ")) + ""; + toolTip += + "
" + tr("Missing Masters") + ": " + + "" + TruncateString(SetJoin(esp.masterUnset, ", ")) + ""; } std::set enabledMasters; @@ -1072,61 +1066,199 @@ QVariant PluginList::tooltipData(const QModelIndex &modelIndex) const std::inserter(enabledMasters, enabledMasters.end())); if (!enabledMasters.empty()) { - toolTip += "
" + tr("Enabled Masters") + ": " + TruncateString(SetJoin(enabledMasters, ", ")); + toolTip += + "
" + tr("Enabled Masters") + ": " + + TruncateString(SetJoin(enabledMasters, ", ")); } if (!esp.archives.empty()) { - toolTip += "
" + tr("Loads Archives") + ": " + TruncateString(SetJoin(esp.archives, ", ")); - toolTip += "
" + 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)"); + toolTip += + "
" + tr("Loads Archives") + ": " + + TruncateString(SetJoin(esp.archives, ", ")) + + "
" + 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 (esp.hasIni) { - toolTip += "
" + tr("Loads INI settings") + ": "; - toolTip += "
" + tr("There is an ini file connected to this plugin. " - "Its settings will be added to your game settings, overwriting in case of conflicts."); + toolTip += + "
" + tr("Loads INI settings") + ": " + "
" + 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 (esp.isLightFlagged && !esp.isLight) { - toolTip += "

" + 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 += + "

" + 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."); } } + + // additional info + auto itor = m_AdditionalInfo.find(esp.name.toLower()); + + if (itor != m_AdditionalInfo.end()) { + if (!itor->second.messages.isEmpty()) { + toolTip += "
    "; + + for (auto&& message : itor->second.messages) { + toolTip += "
  • " + message + "
  • "; + } + + toolTip += "
"; + } + + // loot + toolTip += makeLootTooltip(itor->second.loot); + } + return toolTip; } +QString PluginList::makeLootTooltip(const Loot::Plugin& loot) const +{ + QString s; + + for (auto&& f : loot.incompatibilities) { + s += + "
  • " + tr("Incompatible with %1") + .arg(f.displayName.isEmpty() ? f.name : f.displayName) + + "
  • "; + } + + for (auto&& m : loot.missingMasters) { + s += "
  • " + tr("Depends on missing %1").arg(m) + "
  • "; + } + + for (auto&& m : loot.messages) { + s += "
  • "; + + switch (m.type) + { + case log::Warning: + s += tr("Warning") + ": "; + break; + + case log::Error: + s += tr("Error") + ": "; + break; + + case log::Info: // fall-through + case log::Debug: + default: + // nothing + break; + } + + s += m.text + "
  • "; + } + + for (auto&& d : loot.dirty) { + s += "
  • " + d.toString(false) + "
  • "; + } + + for (auto&& c : loot.clean) { + s += "
  • " + c.toString(true) + "
  • "; + } + + if (!s.isEmpty()) { + s = + "
    " + "
      " + + s + + "
    "; + } + + return s; +} + QVariant PluginList::iconData(const QModelIndex &modelIndex) const { int index = modelIndex.row(); QVariantList result; - QString nameLower = m_ESPs[index].name.toLower(); - if (m_ESPs[index].masterUnset.size() > 0) { + + const auto& esp = m_ESPs[index]; + const QString nameLower = esp.name.toLower(); + + auto infoItor = m_AdditionalInfo.find(nameLower); + + const AdditionalInfo* info = nullptr; + if (infoItor != m_AdditionalInfo.end()) { + info = &infoItor->second; + } + + if (isProblematic(esp, info)) { 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.messages.isEmpty()) { - result.append(":/MO/gui/information"); - } + + if (hasInfo(esp, info)) { + result.append(":/MO/gui/information"); } - if (m_ESPs[index].hasIni) { + + if (esp.hasIni) { result.append(":/MO/gui/attachment"); } - if (!m_ESPs[index].archives.empty()) { + + if (!esp.archives.empty()) { result.append(":/MO/gui/archive_conflict_neutral"); } - if (m_ESPs[index].isLightFlagged && !m_ESPs[index].isLight) { + + if (esp.isLightFlagged && !m_ESPs[index].isLight) { result.append(":/MO/gui/awaiting"); } + return result; } +bool PluginList::isProblematic(const ESPInfo& esp, const AdditionalInfo* info) const +{ + if (esp.masterUnset.size() > 0) { + return true; + } + + if (info) { + if (!info->loot.incompatibilities.empty()) { + return true; + } + + if (!info->loot.missingMasters.empty()) { + return true; + } + } + + return false; +} + +bool PluginList::hasInfo(const ESPInfo& esp, const AdditionalInfo* info) const +{ + if (info) { + if (!info->messages.empty()) { + return true; + } + + if (!info->loot.messages.empty()) { + return true; + } + + if (!info->loot.dirty.empty()) { + return true; + } + } + + return false; +} + bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int role) { QString modName = modIndex.data().toString(); diff --git a/src/pluginlist.h b/src/pluginlist.h index 8b1ce90c..004b1590 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -394,6 +394,10 @@ private: QVariant alignmentData(const QModelIndex &modelIndex) const; QVariant tooltipData(const QModelIndex &modelIndex) const; QVariant iconData(const QModelIndex &modelIndex) const; + + QString makeLootTooltip(const Loot::Plugin& loot) const; + bool isProblematic(const ESPInfo& esp, const AdditionalInfo* info) const; + bool hasInfo(const ESPInfo& esp, const AdditionalInfo* info) const; }; #pragma warning(pop) -- cgit v1.3.1