From d0512da75805be194d949a6d6bac8184314da0e6 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Sun, 27 Dec 2020 14:55:20 +0100 Subject: Use an intermediate structure to store the separator tree. --- src/modinfo.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/modinfo.h') diff --git a/src/modinfo.h b/src/modinfo.h index 42abe51e..d04f6657 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -378,6 +378,11 @@ public: // IModInterface implementations / Re-declaration */ virtual std::shared_ptr fileTree() const = 0; + /** + * @return true if this object represents a regular mod. + */ + virtual bool isRegular() const { return false; } + /** * @return true if this object represents the overwrite mod. */ @@ -491,11 +496,6 @@ public: // Mutable operations: public: // Methods after this do not come from IModInterface: - /** - * @return true if this mod is a regular mod, false otherwise. - */ - virtual bool isRegular() const { return false; } - /** * @return true if this mod is empty, false otherwise. */ -- cgit v1.3.1 From addb38645b41507ae8e0536bb83d3b99d365f664 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 28 Dec 2020 13:44:26 +0100 Subject: Clean drag&drop of URLs and mods/archives. --- src/mainwindow.cpp | 4 - src/modinfo.cpp | 15 ++-- src/modinfo.h | 8 +- src/modlist.cpp | 172 +++++++++++++++++++++++------------------ src/modlist.h | 26 ++++--- src/modlistbypriorityproxy.cpp | 72 +++++++---------- src/modlistbypriorityproxy.h | 1 - src/modlistview.cpp | 38 --------- src/modlistview.h | 6 -- 9 files changed, 156 insertions(+), 186 deletions(-) (limited to 'src/modinfo.h') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ea7d5967..df571a2d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -578,10 +578,6 @@ void MainWindow::setupModList() ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); - connect( - ui->modList, SIGNAL(dropModeUpdate(bool)), - m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool))); - connect( ui->modList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(modListSortIndicatorChanged(int,Qt::SortOrder))); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index a0382fe8..509c3837 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -47,6 +47,7 @@ using namespace MOShared; std::vector ModInfo::s_Collection; +ModInfo::Ptr ModInfo::s_Overwrite; std::map ModInfo::s_ModsByName; std::map, std::vector> ModInfo::s_ModsByModID; int ModInfo::s_NextID; @@ -108,13 +109,14 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, return result; } -void ModInfo::createFromOverwrite(PluginContainer *pluginContainer, - const MOBase::IPluginGame* game, - MOShared::DirectoryEntry **directoryStructure) +ModInfo::Ptr ModInfo::createFromOverwrite( + PluginContainer *pluginContainer, const MOBase::IPluginGame* game, + MOShared::DirectoryEntry **directoryStructure) { QMutexLocker locker(&s_Mutex); - - s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite(pluginContainer, game, directoryStructure))); + ModInfo::Ptr overwrite = ModInfo::Ptr(new ModInfoOverwrite(pluginContainer, game, directoryStructure)); + s_Collection.push_back(overwrite); + return overwrite; } unsigned int ModInfo::getNumMods() @@ -237,6 +239,7 @@ void ModInfo::updateFromDisc(const QString &modDirectory, QMutexLocker lock(&s_Mutex); s_Collection.clear(); s_NextID = 0; + s_Overwrite = nullptr; { // list all directories in the mod directory and make a mod out of each QDir mods(QDir::fromNativeSeparators(modDirectory)); @@ -263,7 +266,7 @@ void ModInfo::updateFromDisc(const QString &modDirectory, } } - createFromOverwrite(pluginContainer, game, directoryStructure); + s_Overwrite = createFromOverwrite(pluginContainer, game, directoryStructure); std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); diff --git a/src/modinfo.h b/src/modinfo.h index d04f6657..3981be18 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -177,6 +177,11 @@ public: // Static functions: */ static unsigned int getIndex(const QString &name); + /** + * @brief Retrieve the overwrite mod. + */ + static ModInfo::Ptr getOverwrite() { return s_Overwrite; } + /** * @brief Find the first mod that fulfills the filter function (after no particular order). * @@ -981,6 +986,7 @@ protected: protected: static std::vector s_Collection; + static ModInfo::Ptr s_Overwrite; static std::map s_ModsByName; int m_PrimaryCategory; @@ -992,7 +998,7 @@ protected: private: - static void createFromOverwrite(PluginContainer* pluginContainer, + static ModInfo::Ptr createFromOverwrite(PluginContainer* pluginContainer, const MOBase::IPluginGame* game, MOShared::DirectoryEntry** directoryStructure); diff --git a/src/modlist.cpp b/src/modlist.cpp index ca4741e6..b79f0b0e 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -69,7 +69,6 @@ ModList::ModList(PluginContainer *pluginContainer, OrganizerCore *organizer) , m_Modified(false) , m_InNotifyChange(false) , m_FontMetrics(QFont()) - , m_DropOnItems(false) , m_PluginContainer(pluginContainer) { m_LastCheck.start(); @@ -689,14 +688,10 @@ Qt::ItemFlags ModList::flags(const QModelIndex &modelIndex) const result |= Qt::ItemIsEditable; } } - if (m_DropOnItems - && (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end())) { - result |= Qt::ItemIsDropEnabled; - } - } else { - if (!m_DropOnItems) result |= Qt::ItemIsDropEnabled; } - return result; + + // drop check is handled by canDropMimeData + return result | Qt::ItemIsDropEnabled; } @@ -1113,6 +1108,52 @@ int ModList::dropPriority(int row, const QModelIndex& parent) const return newPriority; } +std::vector ModList::sourceRows(const QMimeData* mimeData) const +{ + QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist"); + QDataStream stream(&encoded, QIODevice::ReadOnly); + std::vector sourceRows; + + while (!stream.atEnd()) { + int sourceRow, col; + QMap roleDataMap; + stream >> sourceRow >> col >> roleDataMap; + if (col == 0) { + sourceRows.push_back(sourceRow); + } + } + return sourceRows; +} + +std::optional> ModList::relativeUrl(const QUrl& url) const +{ + if (!url.isLocalFile()) { + return {}; + } + + QDir allModsDir(Settings::instance().paths().mods()); + QDir overwriteDir(Settings::instance().paths().overwrite()); + + QFileInfo sourceInfo(url.toLocalFile()); + QString sourceFile = sourceInfo.canonicalFilePath(); + + QString relativePath; + QString originName; + + if (sourceFile.startsWith(allModsDir.canonicalPath())) { + QDir relativeDir(allModsDir.relativeFilePath(sourceFile)); + QStringList splitPath = relativeDir.path().split("/"); + originName = splitPath[0]; + splitPath.pop_front(); + return { { splitPath.join("/"), originName } }; + } + else if (sourceFile.startsWith(overwriteDir.canonicalPath())) { + return { { overwriteDir.relativeFilePath(sourceFile), ModInfo::getOverwrite()->name() } }; + } + + return {}; +} + bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent) { if (row == -1) { @@ -1121,45 +1162,23 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa ModInfo::Ptr modInfo = ModInfo::getByIndex(row); QDir modDir = QDir(modInfo->absolutePath()); - QDir allModsDir(Settings::instance().paths().mods()); - QDir overwriteDir(Settings::instance().paths().overwrite()); - QStringList sourceList; QStringList targetList; QList> relativePathList; - unsigned int overwriteIndex = ModInfo::findMod([] (ModInfo::Ptr mod) -> bool { - std::vector flags = mod->getFlags(); - return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); }); - - QString overwriteName = ModInfo::getByIndex(overwriteIndex)->name(); - for (auto url : mimeData->urls()) { - if (!url.isLocalFile()) { - log::debug("URL drop ignored: \"{}\" is not a local file", url.url()); + auto p = relativeUrl(url); + + if (!p) { + log::debug("URL drop ignored: \"{}\" is not a local file or not a known file to MO", url.url()); continue; } + auto [relativePath, originName] = *p; + QFileInfo sourceInfo(url.toLocalFile()); QString sourceFile = sourceInfo.canonicalFilePath(); - QString relativePath; - QString originName; - - if (sourceFile.startsWith(allModsDir.canonicalPath())) { - QDir relativeDir(allModsDir.relativeFilePath(sourceFile)); - QStringList splitPath = relativeDir.path().split("/"); - originName = splitPath[0]; - splitPath.pop_front(); - relativePath = splitPath.join("/"); - } else if (sourceFile.startsWith(overwriteDir.canonicalPath())) { - originName = overwriteName; - relativePath = overwriteDir.relativeFilePath(sourceFile); - } else { - log::debug("URL drop ignored: \"{}\" is not a known file to MO", sourceFile); - continue; - } - QFileInfo targetInfo(modDir.absoluteFilePath(relativePath)); sourceList << sourceFile; targetList << targetInfo.absoluteFilePath(); @@ -1186,24 +1205,13 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa bool ModList::dropMod(const QMimeData *mimeData, int row, const QModelIndex &parent) { - try { - QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist"); - QDataStream stream(&encoded, QIODevice::ReadOnly); - std::vector sourceRows; - - while (!stream.atEnd()) { - int sourceRow, col; - QMap roleDataMap; - stream >> sourceRow >> col >> roleDataMap; - if (col == 0) { - sourceRows.push_back(sourceRow); - } - } + int newPriority = dropPriority(row, parent); + if (newPriority == -1) { + return false; + } - int newPriority = dropPriority(row, parent); - if (newPriority == -1) { - return false; - } + try { + std::vector sourceRows = this->sourceRows(mimeData); changeModPriority(sourceRows, newPriority); } catch (const std::exception &e) { @@ -1221,19 +1229,7 @@ bool ModList::dropArchive(const QMimeData* mimeData, int row, const QModelIndex& } try { - QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist"); - QDataStream stream(&encoded, QIODevice::ReadOnly); - std::vector sourceRows; - - while (!stream.atEnd()) { - int sourceRow, col; - QMap roleDataMap; - stream >> sourceRow >> col >> roleDataMap; - if (col == 0) { - sourceRows.push_back(sourceRow); - } - } - + std::vector sourceRows = this->sourceRows(mimeData); if (sourceRows.size() == 1) { emit downloadArchiveDropped(sourceRows[0], priority); } @@ -1245,6 +1241,41 @@ bool ModList::dropArchive(const QMimeData* mimeData, int row, const QModelIndex& return false; } +bool ModList::canDropMimeData(const QMimeData* mimeData, Qt::DropAction action, int row, int column, const QModelIndex& parent) const +{ + if (action == Qt::IgnoreAction) { + return false; + } + + if (mimeData->hasUrls()) { + for (auto& url : mimeData->urls()) { + if (!relativeUrl(url)) { + return false; + } + } + if (row == -1 && parent.isValid()) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(parent.row()); + return modInfo->isRegular() && !modInfo->isSeparator(); + } + } + else if (mimeData->hasText()) { + // drop on item + if (row == -1 && parent.isValid()) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(parent.row()); + return modInfo->isSeparator(); + } + else if (hasIndex(row, column, parent)) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(row); + return modInfo->isSeparator() || !parent.isValid(); + } + else { + return true; + } + } + + return false; +} + bool ModList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int, const QModelIndex &parent) { if (action == Qt::IgnoreAction) { @@ -1407,15 +1438,6 @@ QMap ModList::itemData(const QModelIndex &index) const return result; } - -void ModList::dropModeUpdate(bool dropOnItems) -{ - if (m_DropOnItems != dropOnItems) { - m_DropOnItems = dropOnItems; - } -} - - QString ModList::getColumnName(int column) { switch (column) { diff --git a/src/modlist.h b/src/modlist.h index 2ca2fff1..b2eb6be6 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -199,11 +199,13 @@ public: // implementation of virtual functions of QAbstractItemModel virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const; - virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; } - virtual QStringList mimeTypes() const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - virtual bool removeRows(int row, int count, const QModelIndex &parent); + virtual bool removeRows(int row, int count, const QModelIndex& parent); + + Qt::DropActions supportedDropActions() const override { return Qt::MoveAction | Qt::CopyAction; } + QStringList mimeTypes() const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; @@ -213,10 +215,8 @@ public: // implementation of virtual functions of QAbstractItemModel public slots: - void dropModeUpdate(bool dropOnItems); void enableSelected(const QItemSelectionModel *selectionModel); - void disableSelected(const QItemSelectionModel *selectionModel); signals: @@ -369,6 +369,16 @@ private: private: + // retrieve the relative path of file and its origin given a URL from Mime data + // returns an empty optional if the URL is not a valid file for dropping + // + std::optional> relativeUrl(const QUrl&) const; + + // return the source rows from the given mime data for drag&drop of mods or + // installation archives + // + std::vector sourceRows(const QMimeData* mimeData) const; + bool dropURLs(const QMimeData* mimeData, int row, const QModelIndex& parent); bool dropMod(const QMimeData* mimeData, int row, const QModelIndex& parent); bool dropArchive(const QMimeData* mimeData, int row, const QModelIndex& parent); @@ -392,8 +402,6 @@ private: QFontMetrics m_FontMetrics; - bool m_DropOnItems; - std::set m_Overwrite; std::set m_Overwritten; std::set m_ArchiveOverwrite; diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index 1bbf9459..dc51617e 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -210,64 +210,44 @@ bool ModListByPriorityProxy::canDropMimeData(const QMimeData* data, Qt::DropActi bool ModListByPriorityProxy::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) { - // we need to fix the source row + // we need to fix the source model row int sourceRow = -1; - if (row >= 0) { - if (!parent.isValid()) { - if (row < m_Root.children.size()) { - sourceRow = m_Root.children[row]->index; - } - else { - sourceRow = ModInfo::getNumMods(); - } + if (data->hasUrls()) { + if (parent.isValid()) { + sourceRow = static_cast(parent.internalPointer())->index; } - else { - auto* item = static_cast(parent.internalPointer()); - QStringList what; - for (auto& child : item->children) { - what.append(QString::number(child->index)); + } + else { + if (row >= 0) { + if (!parent.isValid()) { + if (row < m_Root.children.size()) { + sourceRow = m_Root.children[row]->index; + } + else { + sourceRow = ModInfo::getNumMods(); + } } + else { + auto* item = static_cast(parent.internalPointer()); - if (row < item->children.size()) { - sourceRow = item->children[row]->index; - } - else if (parent.row() + 1 < m_Root.children.size()) { - sourceRow = m_Root.children[parent.row() + 1]->index; + if (row < item->children.size()) { + sourceRow = item->children[row]->index; + } + else if (parent.row() + 1 < m_Root.children.size()) { + sourceRow = m_Root.children[parent.row() + 1]->index; + } } } - } - else if (parent.isValid()) { - // this is a drop in a separator - sourceRow = m_Root.children[parent.row() + 1]->index; + else if (parent.isValid()) { + // this is a drop in a separator + sourceRow = m_Root.children[parent.row() + 1]->index; + } } return sourceModel()->dropMimeData(data, action, sourceRow, column, QModelIndex()); } -Qt::ItemFlags ModListByPriorityProxy::flags(const QModelIndex& idx) const -{ - if (!idx.isValid()) { - return sourceModel()->flags(QModelIndex()); - } - - // we check the flags of the root node and if drop is not enabled, it - // means we are dragging files. - Qt::ItemFlags rootFlags = sourceModel()->flags(QModelIndex()); - if (!rootFlags.testFlag(Qt::ItemIsDropEnabled)) { - return sourceModel()->flags(mapToSource(idx)); - } - - auto flags = sourceModel()->flags(mapToSource(idx)); - auto* item = static_cast(idx.internalPointer()); - - if (item->mod->isSeparator()) { - flags |= Qt::ItemIsDropEnabled; - } - - return flags; -} - QModelIndex ModListByPriorityProxy::index(int row, int column, const QModelIndex& parent) const { if (!hasIndex(row, column, parent)) { diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index fdf59182..725a3242 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -31,7 +31,6 @@ public: int rowCount(const QModelIndex& parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex& child) const override; - Qt::ItemFlags flags(const QModelIndex& idx) const override; QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& index) const override; bool hasChildren(const QModelIndex& parent) const override; diff --git a/src/modlistview.cpp b/src/modlistview.cpp index fcf34749..27e23417 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -2,37 +2,6 @@ #include #include #include -#include - -class ModListViewStyle: public QProxyStyle { -public: - ModListViewStyle(QStyle *style, int indentation); - - void drawPrimitive (PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = 0) const; -private: - int m_Indentation; -}; - -ModListViewStyle::ModListViewStyle(QStyle *style, int indentation) - : QProxyStyle(style), m_Indentation(indentation) -{ -} - -void ModListViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget) const -{ - if (element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull()) { - QStyleOption opt(*option); - opt.rect.setLeft(m_Indentation); - if (widget) { - opt.rect.setRight(widget->width() - 5); // 5 is an arbitrary value that seems to work ok - } - QProxyStyle::drawPrimitive(element, &opt, painter, widget); - } else { - QProxyStyle::drawPrimitive(element, option, painter, widget); - } -} ModListView::ModListView(QWidget *parent) : QTreeView(parent) @@ -43,13 +12,6 @@ ModListView::ModListView(QWidget *parent) setAutoExpandDelay(500); } -void ModListView::dragEnterEvent(QDragEnterEvent *event) -{ - emit dropModeUpdate(event->mimeData()->hasUrls()); - - QTreeView::dragEnterEvent(event); -} - void ModListView::setModel(QAbstractItemModel *model) { QTreeView::setModel(model); diff --git a/src/modlistview.h b/src/modlistview.h index 982591a3..bc5654ce 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -12,11 +12,6 @@ public: explicit ModListView(QWidget *parent = 0); void setModel(QAbstractItemModel *model) override; -signals: - void dropModeUpdate(bool dropOnRows); - -public slots: - protected: // replace the auto-expand timer from QTreeView to avoid @@ -25,7 +20,6 @@ protected: void timerEvent(QTimerEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override; - void dragEnterEvent(QDragEnterEvent* event) override; private: -- cgit v1.3.1 From 740c383f632712e378c7cfbafea6414a23f58e09 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Sat, 2 Jan 2021 16:28:55 +0100 Subject: Add index attribute to ModInfo. --- src/modinfo.cpp | 4 +++ src/modinfo.h | 72 ++++++++++++++++++++++++++------------------------ src/modinforegular.cpp | 6 +++-- src/organizercore.cpp | 2 ++ 4 files changed, 48 insertions(+), 36 deletions(-) (limited to 'src/modinfo.h') diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 509c3837..6f3b530e 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -91,6 +91,7 @@ ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, const MOBase: } else { result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, game, dir, directoryStructure)); } + result->m_Index = s_Collection.size(); s_Collection.push_back(result); return result; } @@ -105,6 +106,7 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, QMutexLocker locker(&s_Mutex); ModInfo::Ptr result = ModInfo::Ptr( new ModInfoForeign(modName, espName, bsaNames, modType, game, directoryStructure, pluginContainer)); + result->m_Index = s_Collection.size(); s_Collection.push_back(result); return result; } @@ -115,6 +117,7 @@ ModInfo::Ptr ModInfo::createFromOverwrite( { QMutexLocker locker(&s_Mutex); ModInfo::Ptr overwrite = ModInfo::Ptr(new ModInfoOverwrite(pluginContainer, game, directoryStructure)); + overwrite->m_Index = s_Collection.size(); s_Collection.push_back(overwrite); return overwrite; } @@ -286,6 +289,7 @@ void ModInfo::updateIndices() QString modName = s_Collection[i]->internalName(); QString game = s_Collection[i]->gameName(); int modID = s_Collection[i]->nexusId(); + s_Collection[i]->m_Index = i; s_ModsByName[modName] = i; s_ModsByModID[std::pair(game, modID)].push_back(i); } diff --git a/src/modinfo.h b/src/modinfo.h index 3981be18..f0c7bcb5 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -210,30 +210,6 @@ public: // Static functions: static std::set filteredMods( QString gameName, QVariantList updateData, bool addOldMods = false, bool markUpdated = false); - /** - * @brief Create a new mod from the specified directory and add it to the collection. - * - * @param dir Directory to create from. - * - * @return pointer to the info-structure of the newly created/added mod. - */ - static ModInfo::Ptr createFrom( - PluginContainer *pluginContainer, const MOBase::IPluginGame *game, - const QDir &dir, MOShared::DirectoryEntry **directoryStructure); - - /** - * @brief Create a new "foreign-managed" mod from a tuple of plugin and archives. - * - * @param espName Name of the plugin. - * @param bsaNames Names of archives. - * - * @return a new mod. - */ - static ModInfo::Ptr createFromPlugin( - const QString &modName, const QString &espName, const QStringList &bsaNames, - ModInfo::EModType modType, const MOBase::IPluginGame* game, - MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); - /** * @brief Check wheter a name corresponds to a separator or not, * @@ -979,33 +955,61 @@ protected: * using multiple threads for all the mods. */ virtual void prefetch() = 0; - - static void updateIndices(); static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS); protected: - static std::vector s_Collection; - static ModInfo::Ptr s_Overwrite; - static std::map s_ModsByName; + // the index of the mod in s_Collection, only valid after updateIndices() + int m_Index; int m_PrimaryCategory; std::set m_Categories; - MOBase::VersionInfo m_Version; - bool m_PluginSelected = false; -private: +protected: + + friend class OrganizerCore; + + /** + * @brief Create a new mod from the specified directory and add it to the collection. + * + * @param dir Directory to create from. + * + * @return pointer to the info-structure of the newly created/added mod. + */ + static ModInfo::Ptr createFrom( + PluginContainer* pluginContainer, const MOBase::IPluginGame* game, + const QDir& dir, MOShared::DirectoryEntry** directoryStructure); + + /** + * @brief Create a new "foreign-managed" mod from a tuple of plugin and archives. + * + * @param espName Name of the plugin. + * @param bsaNames Names of archives. + * + * @return a new mod. + */ + static ModInfo::Ptr createFromPlugin( + const QString& modName, const QString& espName, const QStringList& bsaNames, + ModInfo::EModType modType, const MOBase::IPluginGame* game, + MOShared::DirectoryEntry** directoryStructure, PluginContainer* pluginContainer); static ModInfo::Ptr createFromOverwrite(PluginContainer* pluginContainer, const MOBase::IPluginGame* game, MOShared::DirectoryEntry** directoryStructure); -private: + // update the m_Index attribute of all mods and the various mapping + // + static void updateIndices(); + +protected: static QMutex s_Mutex; - static std::map, std::vector > s_ModsByModID; + static std::vector s_Collection; + static ModInfo::Ptr s_Overwrite; + static std::map s_ModsByName; + static std::map, std::vector> s_ModsByModID; static int s_NextID; }; diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index c712adb1..6363dd6e 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -254,7 +254,7 @@ void ModInfoRegular::saveMeta() if (m_TrackedState != TrackedState::TRACKED_UNKNOWN) { metaFile.setValue("tracked", static_cast>(m_TrackedState)); } - + metaFile.remove("installedFiles"); metaFile.beginWriteArray("installedFiles"); int idx = 0; @@ -462,6 +462,8 @@ bool ModInfoRegular::setName(const QString &name) std::map::iterator nameIter = s_ModsByName.find(m_Name); if (nameIter != s_ModsByName.end()) { + QMutexLocker locker(&s_Mutex); + unsigned int index = nameIter->second; s_ModsByName.erase(nameIter); @@ -879,7 +881,7 @@ std::vector ModInfoRegular::getIniTweaks() const } -std::map ModInfoRegular::pluginSettings(const QString& pluginName) const +std::map ModInfoRegular::pluginSettings(const QString& pluginName) const { auto itp = m_PluginSettings.find(pluginName); if (itp == std::end(m_PluginSettings)) { diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 6eb81792..bf9308b8 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -690,6 +690,8 @@ MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) settingsFile.endArray(); } + // shouldn't this use the existing mod in case of a merge? also, this does not refresh the indices + // in the ModInfo structure return ModInfo::createFrom(m_PluginContainer, m_GamePlugin, QDir(targetDirectory), &m_DirectoryStructure) .data(); } -- cgit v1.3.1 From d96dcf02b131808a25045afc23667ed6a26274a6 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Sat, 2 Jan 2021 19:07:50 +0100 Subject: Refactoring of ModInfo to give access to the core. Remove ModInfo::remove() completely. --- src/modinfo.cpp | 69 ++++++++++++++++++++--------------------- src/modinfo.h | 34 +++++++------------- src/modinfobackup.cpp | 4 +-- src/modinfobackup.h | 2 +- src/modinfoforeign.cpp | 13 +++----- src/modinfoforeign.h | 6 ++-- src/modinfooverwrite.cpp | 5 ++- src/modinfooverwrite.h | 3 +- src/modinforegular.cpp | 23 ++++++-------- src/modinforegular.h | 8 +---- src/modinfoseparator.cpp | 4 +-- src/modinfoseparator.h | 5 +-- src/modinfowithconflictinfo.cpp | 26 ++++++++-------- src/modinfowithconflictinfo.h | 10 +----- src/modlist.cpp | 11 +------ src/organizercore.cpp | 15 +++------ 16 files changed, 91 insertions(+), 147 deletions(-) (limited to 'src/modinfo.h') diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 6f3b530e..d5be538a 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -27,6 +27,8 @@ along with Mod Organizer. If not, see . #include "categories.h" #include "modinfodialog.h" +#include "organizercore.h" +#include "modlist.h" #include "overwriteinfodialog.h" #include "versioninfo.h" #include "thread_utils.h" @@ -37,6 +39,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include @@ -79,17 +82,17 @@ bool ModInfo::isRegularName(const QString& name) } -ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &dir, DirectoryEntry **directoryStructure) +ModInfo::Ptr ModInfo::createFrom(const QDir &dir, OrganizerCore& core) { QMutexLocker locker(&s_Mutex); ModInfo::Ptr result; if (isBackupName(dir.dirName())) { - result = ModInfo::Ptr(new ModInfoBackup(pluginContainer, game, dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoBackup(dir, core)); } else if (isSeparatorName(dir.dirName())) { - result = Ptr(new ModInfoSeparator(pluginContainer, game, dir, directoryStructure)); + result = Ptr(new ModInfoSeparator(dir, core)); } else { - result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, game, dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoRegular(dir, core)); } result->m_Index = s_Collection.size(); s_Collection.push_back(result); @@ -100,23 +103,18 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, - const MOBase::IPluginGame* game, - DirectoryEntry **directoryStructure, - PluginContainer *pluginContainer) { + OrganizerCore& core) { QMutexLocker locker(&s_Mutex); - ModInfo::Ptr result = ModInfo::Ptr( - new ModInfoForeign(modName, espName, bsaNames, modType, game, directoryStructure, pluginContainer)); + ModInfo::Ptr result = ModInfo::Ptr(new ModInfoForeign(modName, espName, bsaNames, modType, core)); result->m_Index = s_Collection.size(); s_Collection.push_back(result); return result; } -ModInfo::Ptr ModInfo::createFromOverwrite( - PluginContainer *pluginContainer, const MOBase::IPluginGame* game, - MOShared::DirectoryEntry **directoryStructure) +ModInfo::Ptr ModInfo::createFromOverwrite(OrganizerCore& core) { QMutexLocker locker(&s_Mutex); - ModInfo::Ptr overwrite = ModInfo::Ptr(new ModInfoOverwrite(pluginContainer, game, directoryStructure)); + ModInfo::Ptr overwrite = ModInfo::Ptr(new ModInfoOverwrite(core)); overwrite->m_Index = s_Collection.size(); s_Collection.push_back(overwrite); return overwrite; @@ -179,10 +177,20 @@ bool ModInfo::removeMod(unsigned int index) QMutexLocker locker(&s_Mutex); if (index >= s_Collection.size()) { - throw MyException(tr("remove: invalid mod index %1").arg(index)); + throw Exception(tr("remove: invalid mod index %1").arg(index)); } - // update the indices first + ModInfo::Ptr modInfo = s_Collection[index]; + + // remove the actual mod (this is the most likely to fail so we do this first) + if (modInfo->isRegular()) { + if (!shellDelete(QStringList(modInfo->absolutePath()), true)) { + reportError(tr("remove: failed to delete mod '%1' directory").arg(modInfo->name())); + return false; + } + } + + // update the indices s_ModsByName.erase(s_ModsByName.find(modInfo->name())); auto iter = s_ModsByModID.find(std::pair(modInfo->gameName(), modInfo->nexusId())); @@ -192,12 +200,6 @@ bool ModInfo::removeMod(unsigned int index) s_ModsByModID[std::pair(modInfo->gameName(), modInfo->nexusId())] = indices; } - // physically remove the mod directory - //TODO the return value is ignored because the indices were already removed here, so stopping - // would cause data inconsistencies. Instead we go through with the removal but the mod will show up - // again if the user refreshes - modInfo->remove(); - // finally, remove the mod from the collection s_Collection.erase(s_Collection.begin() + index); @@ -230,12 +232,9 @@ unsigned int ModInfo::findMod(const boost::function &filter } -void ModInfo::updateFromDisc(const QString &modDirectory, - DirectoryEntry **directoryStructure, - PluginContainer *pluginContainer, - bool displayForeign, - std::size_t refreshThreadCount, - MOBase::IPluginGame const *game) +void ModInfo::updateFromDisc( + const QString& modsDirectory, OrganizerCore& core, + bool displayForeign, std::size_t refreshThreadCount) { TimeThis tt("ModInfo::updateFromDisc()"); @@ -245,14 +244,15 @@ void ModInfo::updateFromDisc(const QString &modDirectory, s_Overwrite = nullptr; { // list all directories in the mod directory and make a mod out of each - QDir mods(QDir::fromNativeSeparators(modDirectory)); + QDir mods(QDir::fromNativeSeparators(modsDirectory)); mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QDirIterator modIter(mods); while (modIter.hasNext()) { - createFrom(pluginContainer, game, QDir(modIter.next()), directoryStructure); + createFrom(QDir(modIter.next()), core); } } + auto* game = core.managedGame(); UnmanagedMods *unmanaged = game->feature(); if (unmanaged != nullptr) { for (const QString &modName : unmanaged->mods(!displayForeign)) { @@ -262,14 +262,11 @@ void ModInfo::updateFromDisc(const QString &modDirectory, createFromPlugin(unmanaged->displayName(modName), unmanaged->referenceFile(modName).absoluteFilePath(), unmanaged->secondaryFiles(modName), - modType, - game, - directoryStructure, - pluginContainer); + modType, core); } } - s_Overwrite = createFromOverwrite(pluginContainer, game, directoryStructure); + s_Overwrite = createFromOverwrite(core); std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); @@ -296,8 +293,8 @@ void ModInfo::updateIndices() } -ModInfo::ModInfo(PluginContainer *pluginContainer) - : m_PrimaryCategory(-1) +ModInfo::ModInfo(OrganizerCore& core) + : m_PrimaryCategory(-1), m_Core(core) { } diff --git a/src/modinfo.h b/src/modinfo.h index f0c7bcb5..08ed94f8 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "imodinterface.h" #include "versioninfo.h" +class OrganizerCore; class PluginContainer; class QDir; class QDateTime; @@ -107,12 +108,9 @@ public: // Static functions: /** * @brief Read the mod directory and Mod ModInfo objects for all subdirectories. */ - static void updateFromDisc(const QString &modDirectory, - MOShared::DirectoryEntry **directoryStructure, - PluginContainer *pluginContainer, - bool displayForeign, - std::size_t refreshThreadCount, - MOBase::IPluginGame const *game); + static void updateFromDisc( + const QString &modDirectory, OrganizerCore& core, + bool displayForeign, std::size_t refreshThreadCount); static void clear() { s_Collection.clear(); s_ModsByName.clear(); s_ModsByModID.clear(); } @@ -467,14 +465,6 @@ public: // Mutable operations: */ virtual bool setName(const QString& name) = 0; - /** - * @brief Deletes the mod from the disc. This does not update the global ModInfo structure or - * indices. - * - * @return true on success, false otherwise. - */ - virtual bool remove() = 0; - public: // Methods after this do not come from IModInterface: /** @@ -945,7 +935,7 @@ protected: /** * */ - ModInfo(PluginContainer *pluginContainer); + ModInfo(OrganizerCore& core); /** * @brief Prefetch content for this mod. @@ -959,6 +949,9 @@ protected: protected: + // the mod list + OrganizerCore& m_Core; + // the index of the mod in s_Collection, only valid after updateIndices() int m_Index; @@ -978,9 +971,7 @@ protected: * * @return pointer to the info-structure of the newly created/added mod. */ - static ModInfo::Ptr createFrom( - PluginContainer* pluginContainer, const MOBase::IPluginGame* game, - const QDir& dir, MOShared::DirectoryEntry** directoryStructure); + static ModInfo::Ptr createFrom(const QDir& dir, OrganizerCore& core); /** * @brief Create a new "foreign-managed" mod from a tuple of plugin and archives. @@ -992,12 +983,9 @@ protected: */ static ModInfo::Ptr createFromPlugin( const QString& modName, const QString& espName, const QStringList& bsaNames, - ModInfo::EModType modType, const MOBase::IPluginGame* game, - MOShared::DirectoryEntry** directoryStructure, PluginContainer* pluginContainer); + ModInfo::EModType modType, OrganizerCore& core); - static ModInfo::Ptr createFromOverwrite(PluginContainer* pluginContainer, - const MOBase::IPluginGame* game, - MOShared::DirectoryEntry** directoryStructure); + static ModInfo::Ptr createFromOverwrite(OrganizerCore& core); // update the m_Index attribute of all mods and the various mapping // diff --git a/src/modinfobackup.cpp b/src/modinfobackup.cpp index 6a34b86a..603e74f6 100644 --- a/src/modinfobackup.cpp +++ b/src/modinfobackup.cpp @@ -15,7 +15,7 @@ QString ModInfoBackup::getDescription() const } -ModInfoBackup::ModInfoBackup(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure) - : ModInfoRegular(pluginContainer, game, path, directoryStructure) +ModInfoBackup::ModInfoBackup(const QDir& path, OrganizerCore& core) + : ModInfoRegular(path, core) { } diff --git a/src/modinfobackup.h b/src/modinfobackup.h index bf5dc5e6..f25ee9cf 100644 --- a/src/modinfobackup.h +++ b/src/modinfobackup.h @@ -42,7 +42,7 @@ public: private: - ModInfoBackup(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoBackup(const QDir& path, OrganizerCore& core); }; diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp index 19413891..97d3f4e1 100644 --- a/src/modinfoforeign.cpp +++ b/src/modinfoforeign.cpp @@ -42,14 +42,11 @@ QString ModInfoForeign::getDescription() const return tr("This pseudo mod represents content managed outside MO. It isn't modified by MO."); } -ModInfoForeign::ModInfoForeign(const QString &modName, - const QString &referenceFile, - const QStringList &archives, - ModInfo::EModType modType, - const MOBase::IPluginGame* gamePlugin, - DirectoryEntry **directoryStructure, - PluginContainer *pluginContainer) - : ModInfoWithConflictInfo(pluginContainer, gamePlugin, directoryStructure), +ModInfoForeign::ModInfoForeign( + const QString &modName, const QString &referenceFile, + const QStringList &archives, ModInfo::EModType modType, + OrganizerCore& core) + : ModInfoWithConflictInfo(core), m_ReferenceFile(referenceFile), m_Archives(archives), m_ModType(modType) { m_CreationTime = QFileInfo(referenceFile).birthTime(); diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h index 0a4ec42a..31fd13aa 100644 --- a/src/modinfoforeign.h +++ b/src/modinfoforeign.h @@ -32,7 +32,6 @@ public: virtual void setIsEndorsed(bool) override {} virtual void setNeverEndorse() override {} virtual void setIsTracked(bool) override {} - virtual bool remove() override { return false; } virtual void endorse(bool) override {} virtual void track(bool) override {} virtual bool isEmpty() const override { return false; } @@ -81,9 +80,8 @@ public: protected: ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, ModInfo::EModType modType, - const MOBase::IPluginGame *gamePlugin, - MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); - + OrganizerCore &core); + private: QString m_Name; diff --git a/src/modinfooverwrite.cpp b/src/modinfooverwrite.cpp index 8aad6209..5ee7a0d9 100644 --- a/src/modinfooverwrite.cpp +++ b/src/modinfooverwrite.cpp @@ -6,8 +6,7 @@ #include #include -ModInfoOverwrite::ModInfoOverwrite(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, MOShared::DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(pluginContainer, game, directoryStructure) +ModInfoOverwrite::ModInfoOverwrite(OrganizerCore& core) : ModInfoWithConflictInfo(core) { } @@ -60,7 +59,7 @@ QString ModInfoOverwrite::getDescription() const "modified (i.e. by the construction kit)"); } -QStringList ModInfoOverwrite::archives(bool checkOnDisk) +QStringList ModInfoOverwrite::archives(bool checkOnDisk) { QStringList result; QDir dir(this->absolutePath()); diff --git a/src/modinfooverwrite.h b/src/modinfooverwrite.h index 7236d3bf..065a3ba2 100644 --- a/src/modinfooverwrite.h +++ b/src/modinfooverwrite.h @@ -34,7 +34,6 @@ public: virtual void setIsEndorsed(bool) override {} virtual void setNeverEndorse() override {} virtual void setIsTracked(bool) override {} - virtual bool remove() override { return false; } virtual void endorse(bool) override {} virtual void track(bool) override {} virtual bool alwaysEnabled() const override { return true; } @@ -78,7 +77,7 @@ public: virtual std::map clearPluginSettings(const QString& pluginName) override { return {}; } private: - ModInfoOverwrite(PluginContainer *pluginContainer, const MOBase::IPluginGame* game, MOShared::DirectoryEntry **directoryStructure); + ModInfoOverwrite(OrganizerCore& core); }; diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 6363dd6e..94f2fc31 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -5,6 +5,9 @@ #include "report.h" #include "moddatacontent.h" #include "settings.h" +#include "organizercore.h" +#include "plugincontainer.h" +#include #include #include @@ -24,25 +27,25 @@ namespace { } } -ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, const IPluginGame *game, const QDir &path, DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(pluginContainer, game, directoryStructure) +ModInfoRegular::ModInfoRegular(const QDir &path, OrganizerCore& core) + : ModInfoWithConflictInfo(core) , m_Name(path.dirName()) , m_Path(path.absolutePath()) , m_Repository() - , m_GameName(game->gameShortName()) + , m_GameName(core.managedGame()->gameShortName()) , m_IsAlternate(false) , m_Converted(false) , m_Validated(false) , m_MetaInfoChanged(false) , m_EndorsedState(EndorsedState::ENDORSED_UNKNOWN) , m_TrackedState(TrackedState::TRACKED_UNKNOWN) - , m_NexusBridge(pluginContainer) + , m_NexusBridge(&core.pluginContainer()) { m_CreationTime = QFileInfo(path.absolutePath()).birthTime(); // read out the meta-file for information readMeta(); - if (m_GameName.compare(game->gameShortName(), Qt::CaseInsensitive) != 0) - if (!game->primarySources().contains(m_GameName, Qt::CaseInsensitive)) + if (m_GameName.compare(core.managedGame()->gameShortName(), Qt::CaseInsensitive) != 0) + if (!core.managedGame()->primarySources().contains(m_GameName, Qt::CaseInsensitive)) m_IsAlternate = true; //populate m_Archives @@ -588,12 +591,6 @@ QColor ModInfoRegular::color() const return m_Color; } -bool ModInfoRegular::remove() -{ - m_MetaInfoChanged = false; - return shellDelete(QStringList(absolutePath()), true); -} - void ModInfoRegular::endorse(bool doEndorse) { if (doEndorse != (m_EndorsedState == EndorsedState::ENDORSED_TRUE)) { @@ -684,7 +681,7 @@ std::vector ModInfoRegular::getFlags() const std::set ModInfoRegular::doGetContents() const { - ModDataContent* contentFeature = m_GamePlugin->feature(); + ModDataContent* contentFeature = m_Core.managedGame()->feature(); if (contentFeature) { auto result = contentFeature->getContentsFor(fileTree()); diff --git a/src/modinforegular.h b/src/modinforegular.h index f2e0b82d..08660993 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -186,12 +186,6 @@ public: */ virtual void setIsTracked(bool tracked) override; - /** - * @brief delete the mod from the disc. This does not update the global ModInfo structure or indices - * @return true if the mod was successfully removed - **/ - bool remove() override; - /** * @brief endorse or un-endorse the mod * @param doEndorse if true, the mod is endorsed, if false, it's un-endorsed. @@ -424,7 +418,7 @@ protected: virtual std::set doGetContents() const override; - ModInfoRegular(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoRegular(const QDir& path, OrganizerCore& core); private: diff --git a/src/modinfoseparator.cpp b/src/modinfoseparator.cpp index 58c8310a..02a67ecd 100644 --- a/src/modinfoseparator.cpp +++ b/src/modinfoseparator.cpp @@ -30,7 +30,7 @@ QString ModInfoSeparator::name() const } -ModInfoSeparator::ModInfoSeparator(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure) - : ModInfoRegular(pluginContainer, game, path, directoryStructure) +ModInfoSeparator::ModInfoSeparator(const QDir& path, OrganizerCore& core) + : ModInfoRegular(path, core) { } diff --git a/src/modinfoseparator.h b/src/modinfoseparator.h index c7df7184..eaff7c42 100644 --- a/src/modinfoseparator.h +++ b/src/modinfoseparator.h @@ -54,10 +54,7 @@ protected: private: - ModInfoSeparator( - PluginContainer* pluginContainer, - const MOBase::IPluginGame* game, const QDir& path, - MOShared::DirectoryEntry** directoryStructure); + ModInfoSeparator(const QDir& path, OrganizerCore& core); }; #endif diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index ad7eda3f..7a51a727 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -5,6 +5,7 @@ #include "shared/fileentry.h" #include +#include "organizercore.h" #include "iplugingame.h" #include "moddatachecker.h" #include "qdirfiletree.h" @@ -13,13 +14,12 @@ using namespace MOBase; using namespace MOShared; namespace fs = std::filesystem; -ModInfoWithConflictInfo::ModInfoWithConflictInfo( - PluginContainer *pluginContainer, const MOBase::IPluginGame* gamePlugin, DirectoryEntry **directoryStructure) - : ModInfo(pluginContainer), m_GamePlugin(gamePlugin), +ModInfoWithConflictInfo::ModInfoWithConflictInfo(OrganizerCore& core) : + ModInfo(core), m_FileTree([this]() { return QDirFileTree::makeTree(absolutePath()); }), m_Valid([this]() { return doIsValid(); }), m_Contents([this]() { return doGetContents(); }), - m_DirectoryStructure(directoryStructure), m_HasLooseOverwrite(false), m_HasHiddenFiles(false) {} + m_HasLooseOverwrite(false), m_HasHiddenFiles(false) {} void ModInfoWithConflictInfo::clearCaches() { @@ -95,8 +95,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const bool hasHiddenFiles = false; int dataID = 0; - if ((*m_DirectoryStructure)->originExists(L"data")) { - dataID = (*m_DirectoryStructure)->getOriginByName(L"data").getID(); + if (m_Core.directoryStructure()->originExists(L"data")) { + dataID = m_Core.directoryStructure()->getOriginByName(L"data").getID(); } std::wstring name = ToWString(this->name()); @@ -106,8 +106,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const m_ArchiveConflictState = CONFLICT_NONE; m_ArchiveConflictLooseState = CONFLICT_NONE; - if ((*m_DirectoryStructure)->originExists(name)) { - FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); + if (m_Core.directoryStructure()->originExists(name)) { + FilesOrigin &origin = m_Core.directoryStructure()->getOriginByName(name); std::vector files = origin.getFiles(); std::set checkedDirs; @@ -164,7 +164,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const // If this is not the origin then determine the correct overwrite if (file->getOrigin() != origin.getID()) { - FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin()); + FilesOrigin &altOrigin = m_Core.directoryStructure()->getOriginByID(file->getOrigin()); unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); if (!file->isFromArchive()) { if (!archiveData.isValid()) @@ -182,7 +182,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const // Sort out the alternatives for (const auto& altInfo : alternatives) { if ((altInfo.originID() != dataID) && (altInfo.originID() != origin.getID())) { - FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.originID()); + FilesOrigin &altOrigin = m_Core.directoryStructure()->getOriginByID(altInfo.originID()); QString altOriginName = ToQString(altOrigin.getName()); unsigned int altIndex = ModInfo::getIndex(altOriginName); if (!altInfo.isFromArchive()) { @@ -276,8 +276,8 @@ ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isLooseArchiveCo bool ModInfoWithConflictInfo::isRedundant() const { std::wstring name = ToWString(this->name()); - if ((*m_DirectoryStructure)->originExists(name)) { - FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name); + if (m_Core.directoryStructure()->originExists(name)) { + FilesOrigin &origin = m_Core.directoryStructure()->getOriginByName(name); std::vector files = origin.getFiles(); bool ignore = false; for (auto iter = files.begin(); iter != files.end(); ++iter) { @@ -315,7 +315,7 @@ void ModInfoWithConflictInfo::prefetch() { } bool ModInfoWithConflictInfo::doIsValid() const { - auto mdc = m_GamePlugin->feature(); + auto mdc = m_Core.managedGame()->feature(); if (mdc) { auto qdirfiletree = fileTree(); diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index 0d11fcb1..889f1246 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -91,10 +91,7 @@ protected: **/ virtual std::set doGetContents() const { return {}; } - ModInfoWithConflictInfo( - PluginContainer* pluginContainer, - const MOBase::IPluginGame* gamePlugin, - MOShared::DirectoryEntry** directoryStructure); + ModInfoWithConflictInfo(OrganizerCore& core); private: @@ -142,17 +139,12 @@ protected: */ virtual void prefetch() override; - // Current game plugin running in MO2: - MOBase::IPluginGame const * const m_GamePlugin; - private: MOBase::MemoizedLocked> m_FileTree; MOBase::MemoizedLocked m_Valid; MOBase::MemoizedLocked> m_Contents; - MOShared::DirectoryEntry **m_DirectoryStructure; - mutable EConflictType m_CurrentConflictState; mutable EConflictType m_ArchiveConflictState; mutable EConflictType m_ArchiveConflictLooseState; diff --git a/src/modlist.cpp b/src/modlist.cpp index 6d53c4f5..a2e59b62 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -1009,16 +1009,7 @@ MOBase::IModInterface* ModList::getMod(const QString& name) const bool ModList::removeMod(MOBase::IModInterface* mod) { - unsigned int index = ModInfo::getIndex(mod->name()); - bool result = false; - if (index == UINT_MAX) { - if (auto* p = dynamic_cast(mod)) { - result = p->remove(); - } - } - else { - result = ModInfo::removeMod(index); - } + bool result = ModInfo::removeMod(ModInfo::getIndex(mod->name())); if (result) { notifyModRemoved(mod->name()); } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index bf9308b8..d952bc4c 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -219,9 +219,9 @@ void OrganizerCore::updateExecutablesList() void OrganizerCore::updateModInfoFromDisc() { ModInfo::updateFromDisc( - m_Settings.paths().mods(), &m_DirectoryStructure, - m_PluginContainer, m_Settings.interface().displayForeign(), - m_Settings.refreshThreadCount(), managedGame()); + m_Settings.paths().mods(), *this, + m_Settings.interface().displayForeign(), + m_Settings.refreshThreadCount()); } void OrganizerCore::setUserInterface(IUserInterface* ui) @@ -692,8 +692,7 @@ MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) // shouldn't this use the existing mod in case of a merge? also, this does not refresh the indices // in the ModInfo structure - return ModInfo::createFrom(m_PluginContainer, m_GamePlugin, QDir(targetDirectory), &m_DirectoryStructure) - .data(); + return ModInfo::createFrom(QDir(targetDirectory), *this).data(); } void OrganizerCore::modDataChanged(MOBase::IModInterface *) @@ -1219,11 +1218,7 @@ void OrganizerCore::refresh(bool saveChanges) m_CurrentProfile->writeModlistNow(true); } - ModInfo::updateFromDisc( - m_Settings.paths().mods(), &m_DirectoryStructure, - m_PluginContainer, m_Settings.interface().displayForeign(), - m_Settings.refreshThreadCount(), managedGame()); - + updateModInfoFromDisc(); m_CurrentProfile->refreshModStatus(); m_ModList.notifyChange(-1); -- cgit v1.3.1