diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-05-25 19:53:21 +0200 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-05-25 19:54:15 +0200 |
| commit | cf1bbdd13e0db8856df672c367d3ec1610f6c556 (patch) | |
| tree | 461a6b7623a186502f00b07df689ffebfea620b0 /src | |
| parent | a721347fd130fcab19f2709892093f087bfac19e (diff) | |
Switch to using the ModDataContent feature from the game plugin.
Diffstat (limited to 'src')
| -rw-r--r-- | src/filterlist.cpp | 12 | ||||
| -rw-r--r-- | src/filterlist.h | 4 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 6 | ||||
| -rw-r--r-- | src/modinfo.cpp | 27 | ||||
| -rw-r--r-- | src/modinfo.h | 40 | ||||
| -rw-r--r-- | src/modinforegular.cpp | 57 | ||||
| -rw-r--r-- | src/modinforegular.h | 2 | ||||
| -rw-r--r-- | src/modinfowithconflictinfo.cpp | 7 | ||||
| -rw-r--r-- | src/modinfowithconflictinfo.h | 15 | ||||
| -rw-r--r-- | src/modlist.cpp | 39 | ||||
| -rw-r--r-- | src/modlist.h | 12 | ||||
| -rw-r--r-- | src/modlistsortproxy.cpp | 19 | ||||
| -rw-r--r-- | src/organizercore.cpp | 10 | ||||
| -rw-r--r-- | src/organizercore.h | 8 |
14 files changed, 88 insertions, 170 deletions
diff --git a/src/filterlist.cpp b/src/filterlist.cpp index 57bc740a..142751f0 100644 --- a/src/filterlist.cpp +++ b/src/filterlist.cpp @@ -3,6 +3,7 @@ #include "categories.h" #include "categoriesdialog.h" #include "settings.h" +#include "organizercore.h" #include <utility.h> using namespace MOBase; @@ -180,8 +181,8 @@ private: }; -FilterList::FilterList(Ui::MainWindow* ui, CategoryFactory& factory) - : ui(ui), m_factory(factory) +FilterList::FilterList(Ui::MainWindow* ui, OrganizerCore* organizer, CategoryFactory& factory) + : ui(ui), m_Organizer(organizer), m_factory(factory) { auto* eventFilter = new CriteriaItemFilter( ui->filters, [&](auto* item, int dir){ return cycleItem(item, dir); }); @@ -233,11 +234,10 @@ QTreeWidgetItem* FilterList::addCriteriaItem( void FilterList::addContentCriteria() { - for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) { - QString filterName = tr("Contains %1").arg(ModInfo::getContentTypeName(i)); + for (auto &content: m_Organizer->modDataContents()) { addCriteriaItem( - nullptr, QString("<%1>").arg(filterName), - i, ModListSortProxy::TypeContent); + nullptr, QString("<%1>").arg(tr("Contains %1").arg(content.name())), + content.id(), ModListSortProxy::TypeContent); } } diff --git a/src/filterlist.h b/src/filterlist.h index b0ebc9a4..ba9dc71c 100644 --- a/src/filterlist.h +++ b/src/filterlist.h @@ -7,13 +7,14 @@ namespace Ui { class MainWindow; }; class CategoryFactory; class Settings; +class OrganizerCore; class FilterList : public QObject { Q_OBJECT; public: - FilterList(Ui::MainWindow* ui, CategoryFactory& factory); + FilterList(Ui::MainWindow* ui, OrganizerCore *organizer, CategoryFactory& factory); void restoreState(const Settings& s); void saveState(Settings& s) const; @@ -31,6 +32,7 @@ private: class CriteriaItem; Ui::MainWindow* ui; + OrganizerCore* m_Organizer; CategoryFactory& m_factory; bool onClick(QMouseEvent* e); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index de4a6b39..a720b621 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -311,7 +311,7 @@ MainWindow::MainWindow(Settings &settings ui->statusBar->setAPI(ni->getAPIStats(), ni->getAPIUserAccount()); } - m_Filters.reset(new FilterList(ui, m_CategoryFactory)); + m_Filters.reset(new FilterList(ui, &m_OrganizerCore, m_CategoryFactory)); connect( m_Filters.get(), &FilterList::criteriaChanged, @@ -5950,7 +5950,9 @@ void MainWindow::onFiltersCriteria(const std::vector<ModListSortProxy::Criteria> const auto& c = criteria[0]; if (c.type == ModListSortProxy::TypeContent) { - label = ModInfo::getContentTypeName(c.id); + auto& contents = m_OrganizerCore.modDataContents(); + auto it = std::find_if(std::begin(contents), std::end(contents), [&c](auto const& content) { return content.id() == c.id; }); + label = it != std::end(contents) ? it->name() : QString(); } else { label = m_CategoryFactory.getCategoryNameByID(c.id); } diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 15fa71da..a8e6a55b 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -108,27 +108,6 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, return result; } -QString ModInfo::getContentTypeName(int contentType) -{ - switch (contentType) { - case CONTENT_PLUGIN: return tr("Plugins"); - case CONTENT_TEXTURE: return tr("Textures"); - case CONTENT_MESH: return tr("Meshes"); - case CONTENT_BSA: return tr("Bethesda Archive"); - case CONTENT_INTERFACE: return tr("UI Changes"); - case CONTENT_SOUND: return tr("Sound Effects"); - case CONTENT_SCRIPT: return tr("Scripts"); - case CONTENT_SKSE: return tr("Script Extender"); - case CONTENT_SKSEFILES: return tr("Script Extender Files"); - case CONTENT_SKYPROC: return tr("SkyProc Tools"); - case CONTENT_MCM: return tr("MCM Data"); - case CONTENT_INI: return tr("INI files"); - case CONTENT_MODGROUP: return tr("ModGroup files"); - - default: throw MyException(tr("invalid content type: %1").arg(contentType)); - } -} - void ModInfo::createFromOverwrite(PluginContainer *pluginContainer, const MOBase::IPluginGame* game, MOShared::DirectoryEntry **directoryStructure) @@ -515,12 +494,6 @@ bool ModInfo::hasAnyOfTheseFlags(std::vector<ModInfo::EFlag> flags) const return false; } -bool ModInfo::hasContent(ModInfo::EContent content) const -{ - std::vector<EContent> contents = getContents(); - return std::find(contents.begin(), contents.end(), content) != contents.end(); -} - bool ModInfo::categorySet(int categoryID) const { for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) { diff --git a/src/modinfo.h b/src/modinfo.h index 29e6124d..c5b1cfca 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -87,24 +87,6 @@ public: FLAG_TRACKED, }; - enum EContent { - CONTENT_PLUGIN, - CONTENT_TEXTURE, - CONTENT_MESH, - CONTENT_BSA, - CONTENT_INTERFACE, - CONTENT_SOUND, - CONTENT_SCRIPT, - CONTENT_SKSE, - CONTENT_SKSEFILES, - CONTENT_SKYPROC, - CONTENT_MCM, - CONTENT_INI, - CONTENT_MODGROUP - }; - - static const int NUM_CONTENT_TYPES = CONTENT_MODGROUP + 1; - enum EHighlight { HIGHLIGHT_NONE = 0, HIGHLIGHT_INVALID = 1, @@ -248,13 +230,6 @@ public: // static bool isRegularName(const QString& name); - /** - * @brief retieve a name for one of the CONTENT_ enums - * @param contentType the content value - * @return a display string - */ - static QString getContentTypeName(int contentType); - virtual bool isRegular() const { return false; } virtual bool isEmpty() const { return false; } @@ -546,7 +521,10 @@ public: /** * @return a list of content types contained in a mod */ - virtual std::vector<EContent> getContents() const { return std::vector<EContent>(); } + virtual const std::vector<int>& getContents() const { + static std::vector<int> dummy; + return dummy; + } /** * @brief test if the specified flag is set for this mod @@ -563,11 +541,13 @@ public: bool hasAnyOfTheseFlags(std::vector<ModInfo::EFlag> flags) const; /** - * @brief test if the mods contains the specified content - * @param content the content to test - * @return true if the content is there, false otherwise + * @brief Test if the mod contains the specified content. + * + * @param content ID of the content to test. + * + * @return true if the content is there, false otherwise. */ - bool hasContent(ModInfo::EContent content) const; + virtual bool hasContent(int content) const = 0; /** * @return an indicator if and how this mod should be highlighted by the UI diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index a1f1a04d..8ad7ffe5 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -3,7 +3,7 @@ #include "categories.h" #include "messagedialog.h" #include "report.h" -#include "scriptextender.h" +#include "moddatacontent.h" #include "settings.h" #include <QApplication> @@ -653,60 +653,15 @@ std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const } -std::vector<ModInfo::EContent> ModInfoRegular::doGetContents() const +std::vector<int> ModInfoRegular::doGetContents() const { - auto tree = contentFileTree(); - std::vector<ModInfo::EContent> contents; + ModDataContent* contentFeature = m_GamePlugin->feature<ModDataContent>(); - for (auto e : *tree) { - if (e->isFile()) { - auto suffix = e->suffix().toLower(); - if (suffix == "esp" || suffix == "esm" || suffix == "esl") { - contents.push_back(CONTENT_PLUGIN); - } - else if (suffix == "bsa" || suffix == "ba2") { - contents.push_back(CONTENT_BSA); - } - else if (suffix == "ini" && e->compare("meta.ini") != 0) { - contents.push_back(CONTENT_INI); - } - else if (suffix == "modgroups") { - contents.push_back(CONTENT_MODGROUP); - } - } - else { - if (e->compare("textures") == 0 || e->compare("icons") == 0 || e->compare("bookart") == 0) - contents.push_back(CONTENT_TEXTURE); - if (e->compare("meshes") == 0) - contents.push_back(CONTENT_MESH); - if (e->compare("interface") == 0 || e->compare("menus") == 0) - contents.push_back(CONTENT_INTERFACE); - if (e->compare("music") == 0 || e->compare("sound") == 0) - contents.push_back(CONTENT_SOUND); - if (e->compare("scripts") == 0) - contents.push_back(CONTENT_SCRIPT); - if (e->compare("SkyProc Patchers") == 0) - contents.push_back(CONTENT_SKYPROC); - if (e->compare("MCM") == 0) - contents.push_back(CONTENT_MCM); - } - } - - ScriptExtender* extender = m_GamePlugin->feature<ScriptExtender>(); - if (extender != nullptr) { - auto e = tree->findDirectory(extender->PluginPath()); - if (e) { - contents.push_back(CONTENT_SKSEFILES); - for (auto f : *e) { - if (f->hasSuffix("dll")) { - contents.push_back(CONTENT_SKSE); - break; - } - } - } + if (contentFeature) { + return contentFeature->getContentsFor(contentFileTree()); } - return contents; + return {}; } diff --git a/src/modinforegular.h b/src/modinforegular.h index e63e7570..b09dcd98 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -416,7 +416,7 @@ private slots: protected: - virtual std::vector<EContent> doGetContents() const override; + virtual std::vector<int> doGetContents() const override; ModInfoRegular(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure); diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index b0edf581..14b341d2 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -331,6 +331,11 @@ bool ModInfoWithConflictInfo::isValid() const { return m_Valid.value(); } -std::vector<ModInfo::EContent> ModInfoWithConflictInfo::getContents() const { +const std::vector<int>& ModInfoWithConflictInfo::getContents() const { return m_Contents.value(); } + +bool ModInfoWithConflictInfo::hasContent(int content) const { + auto& contents = m_Contents.value(); + return std::find(std::begin(contents), std::end(contents), content) != std::end(contents); +} diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index abc9f223..b66a7444 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -24,7 +24,16 @@ public: /** * @return a list of content types contained in a mod */ - virtual std::vector<EContent> getContents() const override; + virtual const std::vector<int>& getContents() const override; + + /** + * @brief Test if the mod contains the specified content. + * + * @param content ID of the content to test. + * + * @return true if the content is there, false otherwise. + */ + virtual bool hasContent(int content) const override; /** * @brief clear all caches held for this mod @@ -66,7 +75,7 @@ protected: * * @return the contents for this mod. **/ - virtual std::vector<EContent> doGetContents() const { return {}; } + virtual std::vector<int> doGetContents() const { return {}; } /** * @brief Retrieve a file tree corresponding to the underlying disk content @@ -137,7 +146,7 @@ private: MOShared::MemoizedLocked<std::shared_ptr<const MOBase::IFileTree>> m_FileTree; MOShared::MemoizedLocked<bool> m_Valid; - MOShared::MemoizedLocked<std::vector<EContent>> m_Contents; + MOShared::MemoizedLocked<std::vector<int>> m_Contents; MOShared::DirectoryEntry **m_DirectoryStructure; diff --git a/src/modlist.cpp b/src/modlist.cpp index e8c14434..3ace0ed0 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -25,6 +25,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "modlistsortproxy.h" #include "pluginlist.h" #include "settings.h" +#include "organizercore.h" #include "modinforegular.h" #include "shared/directoryentry.h" #include "shared/fileentry.h" @@ -59,8 +60,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase; -ModList::ModList(PluginContainer *pluginContainer, QObject *parent) - : QAbstractItemModel(parent) +ModList::ModList(PluginContainer *pluginContainer, OrganizerCore *organizer) + : QAbstractItemModel(organizer) + , m_Organizer(organizer) , m_Profile(nullptr) , m_NexusInterface(nullptr) , m_Modified(false) @@ -69,19 +71,6 @@ ModList::ModList(PluginContainer *pluginContainer, QObject *parent) , m_DropOnItems(false) , m_PluginContainer(pluginContainer) { - m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(":/MO/gui/content/plugin", QT_TR_NOOP("Game Plugins (ESP/ESM/ESL)")); - m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", QT_TR_NOOP("Interface")); - m_ContentIcons[ModInfo::CONTENT_MESH] = std::make_tuple(":/MO/gui/content/mesh", QT_TR_NOOP("Meshes")); - m_ContentIcons[ModInfo::CONTENT_BSA] = std::make_tuple(":/MO/gui/content/bsa", QT_TR_NOOP("Bethesda Archive")); - m_ContentIcons[ModInfo::CONTENT_SCRIPT] = std::make_tuple(":/MO/gui/content/script", QT_TR_NOOP("Scripts (Papyrus)")); - m_ContentIcons[ModInfo::CONTENT_SKSE] = std::make_tuple(":/MO/gui/content/skse", QT_TR_NOOP("Script Extender Plugin")); - m_ContentIcons[ModInfo::CONTENT_SKYPROC] = std::make_tuple(":/MO/gui/content/skyproc", QT_TR_NOOP("SkyProc Patcher")); - m_ContentIcons[ModInfo::CONTENT_SOUND] = std::make_tuple(":/MO/gui/content/sound", QT_TR_NOOP("Sound or Music")); - m_ContentIcons[ModInfo::CONTENT_TEXTURE] = std::make_tuple(":/MO/gui/content/texture", QT_TR_NOOP("Textures")); - m_ContentIcons[ModInfo::CONTENT_MCM] = std::make_tuple(":/MO/gui/content/menu", QT_TR_NOOP("MCM Configuration")); - m_ContentIcons[ModInfo::CONTENT_INI] = std::make_tuple(":/MO/gui/content/inifile", QT_TR_NOOP("INI files")); - m_ContentIcons[ModInfo::CONTENT_MODGROUP] = std::make_tuple(":/MO/gui/content/modgroup", QT_TR_NOOP("ModGroup files")); - m_LastCheck.start(); } @@ -188,13 +177,13 @@ QString ModList::getConflictFlagText(ModInfo::EConflictFlag flag, ModInfo::Ptr m } -QVariantList ModList::contentsToIcons(const std::vector<ModInfo::EContent> &contents) const +QVariantList ModList::contentsToIcons(const std::vector<int> &contents) const { QVariantList result; - std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end()); - for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) { - if (contentsSet.find(iter->first) != contentsSet.end()) { - result.append(std::get<0>(iter->second)); + std::set<int> contentsSet(contents.begin(), contents.end()); + for (auto &content: m_Organizer->modDataContents()) { + if (contentsSet.find(content.id()) != contentsSet.end()) { + result.append(content.icon()); } else { result.append(QString()); } @@ -202,16 +191,16 @@ QVariantList ModList::contentsToIcons(const std::vector<ModInfo::EContent> &cont return result; } -QString ModList::contentsToToolTip(const std::vector<ModInfo::EContent> &contents) const +QString ModList::contentsToToolTip(const std::vector<int> &contents) const { QString result("<table cellspacing=7>"); - std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end()); - for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) { - if (contentsSet.find(iter->first) != contentsSet.end()) { + std::set<int> contentsSet(contents.begin(), contents.end()); + for (auto& content : m_Organizer->modDataContents()) { + if (contentsSet.find(content.id()) != contentsSet.end()) { result.append(QString("<tr><td><img src=\"%1\" width=32/></td>" "<td valign=\"middle\">%2</td></tr>") - .arg(std::get<0>(iter->second)).arg(tr(std::get<1>(iter->second).toStdString().c_str()))); + .arg(content.icon()).arg(content.name())); } } result.append("</table>"); diff --git a/src/modlist.h b/src/modlist.h index 4d456a9a..2abda076 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -20,7 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef MODLIST_H
#define MODLIST_H
-
+#include "moddatacontent.h"
#include "categories.h"
#include "nexusinterface.h"
#include "modinfo.h"
@@ -42,6 +42,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. class QSortFilterProxyModel;
class PluginContainer;
+class OrganizerCore;
/**
* Model presenting an overview of the installed mod
@@ -78,7 +79,7 @@ public: * @brief constructor
* @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order
**/
- ModList(PluginContainer *pluginContainer, QObject *parent = nullptr);
+ ModList(PluginContainer *pluginContainer, OrganizerCore *parent = nullptr);
~ModList();
@@ -284,9 +285,9 @@ private: static QString getColumnToolTip(int column);
- QVariantList contentsToIcons(const std::vector<ModInfo::EContent> &content) const;
+ QVariantList contentsToIcons(const std::vector<int> &contentIds) const;
- QString contentsToToolTip(const std::vector<ModInfo::EContent> &contents) const;
+ QString contentsToToolTip(const std::vector<int> &contentsIds) const;
ModList::EColumn getEnabledColumn(int index) const;
@@ -328,6 +329,7 @@ private: private:
+ OrganizerCore *m_Organizer;
Profile *m_Profile;
NexusInterface *m_NexusInterface;
@@ -352,8 +354,6 @@ private: SignalModStateChanged m_ModStateChanged;
SignalModMoved m_ModMoved;
- std::map<ModInfo::EContent, std::tuple<QString, QString> > m_ContentIcons;
-
QElapsedTimer m_LastCheck;
PluginContainer *m_PluginContainer;
diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 018b9760..99dba913 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -177,22 +177,7 @@ bool ModListSortProxy::lessThan(const QModelIndex &left, }
} break;
case ModList::COL_CONTENT: {
- std::vector<ModInfo::EContent> lContent = leftMod->getContents();
- std::vector<ModInfo::EContent> rContent = rightMod->getContents();
- if (lContent.size() != rContent.size()) {
- lt = lContent.size() < rContent.size();
- }
-
- int lValue = 0;
- int rValue = 0;
- for (ModInfo::EContent content : lContent) {
- lValue += 2 << (unsigned int)content;
- }
- for (ModInfo::EContent content : rContent) {
- rValue += 2 << (unsigned int)content;
- }
-
- lt = lValue < rValue;
+ lt = leftMod->getContents() < rightMod->getContents();
} break;
case ModList::COL_NAME: {
int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive);
@@ -449,7 +434,7 @@ bool ModListSortProxy::categoryMatchesMod( bool ModListSortProxy::contentMatchesMod(ModInfo::Ptr info, bool enabled, int content) const
{
- return info->hasContent(static_cast<ModInfo::EContent>(content));
+ return info->hasContent(content);
}
bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const
diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 6e4b3fbf..45fe5220 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -135,6 +135,16 @@ OrganizerCore::OrganizerCore(Settings &settings) connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_PluginList, SLOT(managedGameChanged(MOBase::IPluginGame const *))); + connect(this, &OrganizerCore::managedGameChanged, [this](IPluginGame const* gamePlugin) { + ModDataContent* contentFeature = gamePlugin->feature<ModDataContent>(); + if (contentFeature) { + m_Contents = contentFeature->getAllContents(); + } + else { + m_Contents = {}; + } + }); + connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, &DelayedFileWriterBase::write); diff --git a/src/organizercore.h b/src/organizercore.h index a4d1a799..af741964 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -19,6 +19,7 @@ #include <delayedfilewriter.h>
#include <boost/signals2.hpp>
#include "executableinfo.h"
+#include "moddatacontent.h"
#include <log.h>
#include <QDir>
@@ -122,6 +123,12 @@ public: MOBase::IPluginGame const *managedGame() const;
+ /**
+ * @return the list of contents for the currently managed game, or an empty vector
+ * if the game plugin does not implement the ModDataContent feature.
+ */
+ const std::vector<ModDataContent::Content>& modDataContents() const { return m_Contents; }
+
bool isArchivesInit() const { return m_ArchivesInit; }
bool saveCurrentLists();
@@ -305,6 +312,7 @@ private: PluginContainer *m_PluginContainer;
QString m_GameName;
MOBase::IPluginGame *m_GamePlugin;
+ std::vector<ModDataContent::Content> m_Contents;
Profile *m_CurrentProfile;
|
