diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 3a7962e50..5e217e90c 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -38,6 +38,7 @@ #include "ModFolderModel.h" #include +#include #include #include #include @@ -311,6 +312,29 @@ void ModFolderModel::onParseFinished() emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); } } +QList collectMods(QList mods, QHash> relation, std::set& seen) +{ + QList affectedList = {}; + for (auto mod : mods) { + auto id = mod->mod_id(); + if (seen.count(id) == 0) { + seen.insert(id); + for (auto affected : relation[id]) { + auto affectedId = affected->mod_id(); + + if (findById(mods, affectedId) == nullptr && seen.count(affectedId) == 0) { + seen.insert(affectedId); + affectedList << affected; + } + } + } + } + // collect the affected mods until all of them are included in the list + if (!affectedList.isEmpty()) { + affectedList += collectMods(affectedList, relation, seen); + } + return affectedList; +} QModelIndexList ModFolderModel::getAffectedMods(const QModelIndexList& indexes, EnableAction action) { @@ -318,54 +342,84 @@ QModelIndexList ModFolderModel::getAffectedMods(const QModelIndexList& indexes, return {}; QModelIndexList affectedList = {}; - auto indexedMods = selectedMods(indexes); - if (action == EnableAction::TOGGLE) { - if (indexedMods.length() != 1) { - return {}; // not sure how to handle a bunch of rows that are toggled(not even sure it is posible) - } - action = indexedMods.first()->enabled() ? EnableAction::DISABLE : EnableAction::ENABLE; - } - + auto affectedMods = selectedMods(indexes); std::set seen; - bool shouldBeEnabled = action == EnableAction::ENABLE; - for (auto mod : indexedMods) { - auto id = mod->mod_id(); - QSet mods; - switch (action) { - case EnableAction::DISABLE: { - mods = m_requiredBy[id]; - break; - } - case EnableAction::ENABLE: { - mods = m_requires[id]; - break; - } - case EnableAction::TOGGLE: - break; - } - for (auto affected : mods) { - auto affectedId = affected->mod_id(); - if (findById(indexedMods, affectedId) == nullptr && seen.count(affectedId) == 0) { - seen.insert(affectedId); - if (shouldBeEnabled != affected->enabled()) { - auto row = m_resources_index[affected->internal_id()]; - affectedList << index(row, 0); - } - } + switch (action) { + case EnableAction::ENABLE: { + affectedMods << collectMods(affectedMods, m_requires, seen); + break; + } + case EnableAction::DISABLE: { + affectedMods << collectMods(affectedMods, m_requiredBy, seen); + break; + } + case EnableAction::TOGGLE: { + return {}; // this function should not be called with TOGGLE } } - // collect the affected mods until all of them are included in the list - if (!affectedList.isEmpty()) { - affectedList += getAffectedMods(indexes + affectedList, action); + bool shouldBeEnabled = action == EnableAction::ENABLE; + for (auto affected : affectedMods) { + auto affectedId = affected->mod_id(); + if (shouldBeEnabled != affected->enabled()) { + auto row = m_resources_index[affected->internal_id()]; + affectedList << index(row, 0); + } } return affectedList; } bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAction action) { - auto affected = getAffectedMods(indexes, action); - return ResourceFolderModel::setResourceEnabled(indexes + affected, action); + if (indexes.isEmpty()) + return {}; + + QModelIndexList affectedList = {}; + auto indexedMods = selectedMods(indexes); + + QList toEnable = {}; + QList toDisable = {}; + std::set seen; + + switch (action) { + case EnableAction::ENABLE: { + toEnable = indexedMods; + break; + } + case EnableAction::DISABLE: { + toDisable = indexedMods; + break; + } + case EnableAction::TOGGLE: { + for (auto mod : indexedMods) { + if (mod->enabled()) { + toDisable << mod; + } else { + toEnable << mod; + } + } + break; + } + } + + toEnable << collectMods(toEnable, m_requires, seen); + toDisable << collectMods(toDisable, m_requiredBy, seen); + + toDisable.removeIf([toEnable](Mod* m) { return toEnable.contains(m); }); + auto toList = [this](QList mods, bool shouldBeEnabled) { + QModelIndexList list; + for (auto mod : mods) { + if (shouldBeEnabled != mod->enabled()) { + auto row = m_resources_index[mod->internal_id()]; + list << index(row, 0); + } + } + return list; + }; + + auto disableStatus = ResourceFolderModel::setResourceEnabled(toList(toDisable, false), EnableAction::DISABLE); + auto enableStatus = ResourceFolderModel::setResourceEnabled(toList(toEnable, true), EnableAction::ENABLE); + return disableStatus && enableStatus; } QStringList reqToList(QSet l)