mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-08-03 11:27:33 -04:00
feat: make dependencies auto disable/enable
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
2b62b4281f
commit
8277fd41ae
@ -52,6 +52,9 @@
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "minecraft/Component.h"
|
||||
#include "minecraft/mod/Resource.h"
|
||||
#include "minecraft/mod/ResourceFolderModel.h"
|
||||
#include "minecraft/mod/tasks/LocalModParseTask.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
@ -260,6 +263,12 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id)
|
||||
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
|
||||
Mod* findById(QList<Mod*> mods, QString modId)
|
||||
{
|
||||
auto found = std::find_if(mods.begin(), mods.end(), [modId](Mod* m) { return m->mod_id() == modId; });
|
||||
return found != mods.end() ? *found : nullptr;
|
||||
}
|
||||
|
||||
void ModFolderModel::onParseFinished()
|
||||
{
|
||||
if (hasPendingParseTasks()) {
|
||||
@ -267,37 +276,37 @@ void ModFolderModel::onParseFinished()
|
||||
}
|
||||
auto mods = allMods();
|
||||
|
||||
auto findById = [mods](QString modId) -> Mod* {
|
||||
auto found = std::find_if(mods.begin(), mods.end(), [modId](Mod* m) { return m->mod_id() == modId; });
|
||||
return found != mods.end() ? *found : nullptr;
|
||||
};
|
||||
auto findByProjectID = [mods](QVariant modId, ModPlatform::ResourceProvider provider) -> Mod* {
|
||||
auto found = std::find_if(mods.begin(), mods.end(), [modId, provider](Mod* m) {
|
||||
return m->metadata()->provider == provider && m->metadata()->project_id == modId;
|
||||
return m->metadata() && m->metadata()->provider == provider && m->metadata()->project_id == modId;
|
||||
});
|
||||
return found != mods.end() ? *found : nullptr;
|
||||
};
|
||||
for (auto mod : mods) {
|
||||
auto id = mod->internal_id();
|
||||
auto id = mod->mod_id();
|
||||
for (auto dep : mod->dependencies()) {
|
||||
auto d = findById(dep);
|
||||
auto d = findById(mods, dep);
|
||||
if (d) {
|
||||
m_requires[id] << d;
|
||||
m_requiredBy[d->internal_id()] << mod;
|
||||
m_requiredBy[d->mod_id()] << mod;
|
||||
}
|
||||
}
|
||||
for (auto dep : mod->metadata()->dependencies) {
|
||||
auto d = findByProjectID(dep.addonId, mod->metadata()->provider);
|
||||
if (d) {
|
||||
m_requires[id] << d;
|
||||
m_requiredBy[d->internal_id()] << mod;
|
||||
if (mod->metadata()) {
|
||||
for (auto dep : mod->metadata()->dependencies) {
|
||||
if (dep.type == ModPlatform::DependencyType::REQUIRED) {
|
||||
auto d = findByProjectID(dep.addonId, mod->metadata()->provider);
|
||||
if (d) {
|
||||
m_requires[id] << d;
|
||||
m_requiredBy[d->mod_id()] << mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
auto removeDuplicates = [](QList<Mod*>& list) {
|
||||
std::set<QString> seen;
|
||||
auto it = std::remove_if(list.begin(), list.end(), [&seen](Mod* m) {
|
||||
auto id = m->internal_id();
|
||||
auto id = m->mod_id();
|
||||
if (seen.count(id) > 0) {
|
||||
return true;
|
||||
}
|
||||
@ -313,10 +322,66 @@ void ModFolderModel::onParseFinished()
|
||||
removeDuplicates(m_requires[key]);
|
||||
}
|
||||
for (auto mod : mods) {
|
||||
auto id = mod->internal_id();
|
||||
auto id = mod->mod_id();
|
||||
mod->setRequiredByCount(m_requiredBy[id].count());
|
||||
mod->setRequiresCount(m_requires[id].count());
|
||||
int row = m_resources_index[id];
|
||||
int row = m_resources_index[mod->internal_id()];
|
||||
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndexList ModFolderModel::getAffectedMods(const QModelIndexList& indexes, EnableAction action)
|
||||
{
|
||||
if (indexes.isEmpty())
|
||||
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;
|
||||
}
|
||||
|
||||
std::set<QString> seen;
|
||||
bool shouldBeEnabled = action == EnableAction::ENABLE;
|
||||
for (auto mod : indexedMods) {
|
||||
auto id = mod->mod_id();
|
||||
QList<Mod*> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// collect the affected mods until all of them are included in the list
|
||||
if (!affectedList.isEmpty()) {
|
||||
affectedList += getAffectedMods(indexes + affectedList, action);
|
||||
}
|
||||
return affectedList;
|
||||
}
|
||||
|
||||
bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAction action)
|
||||
{
|
||||
auto affected = getAffectedMods(indexes, action);
|
||||
return ResourceFolderModel::setResourceEnabled(indexes + affected, action);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#include "Mod.h"
|
||||
#include "ResourceFolderModel.h"
|
||||
#include "minecraft/Component.h"
|
||||
#include "minecraft/mod/Resource.h"
|
||||
|
||||
class BaseInstance;
|
||||
@ -89,6 +90,9 @@ class ModFolderModel : public ResourceFolderModel {
|
||||
|
||||
bool isValid();
|
||||
|
||||
bool setResourceEnabled(const QModelIndexList& indexes, EnableAction action) override;
|
||||
QModelIndexList getAffectedMods(const QModelIndexList& indexes, EnableAction action);
|
||||
|
||||
RESOURCE_HELPERS(Mod)
|
||||
|
||||
private slots:
|
||||
|
@ -882,6 +882,7 @@ QList<Resource*> ResourceFolderModel::allResources()
|
||||
result.append((resource.get()));
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<Resource*> ResourceFolderModel::selectedResources(const QModelIndexList& indexes)
|
||||
{
|
||||
QList<Resource*> result;
|
||||
|
@ -37,6 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "ModFolderPage.h"
|
||||
#include "minecraft/mod/Resource.h"
|
||||
#include "ui/dialogs/ExportToModListDialog.h"
|
||||
#include "ui_ExternalResourcesPage.h"
|
||||
|
||||
@ -90,7 +91,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
||||
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
|
||||
ui->actionVerifyItemDependencies->setVisible(!depsDisabled->get().toBool());
|
||||
connect(depsDisabled.get(), &Setting::SettingChanged, this,
|
||||
[this](const Setting& setting, const QVariant& value) { ui->actionVerifyItemDependencies->setVisible(!value.toBool()); });
|
||||
[this](const Setting&, const QVariant& value) { ui->actionVerifyItemDependencies->setVisible(!value.toBool()); });
|
||||
|
||||
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
|
||||
@ -133,7 +134,22 @@ void ModFolderPage::removeItems(const QItemSelection& selection)
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
m_model->deleteResources(selection.indexes());
|
||||
|
||||
auto indexes = selection.indexes();
|
||||
auto affected = m_model->getAffectedMods(indexes, EnableAction::DISABLE);
|
||||
if (!affected.isEmpty()) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Disable"),
|
||||
tr("The mods you are tring to disable are required by %1 mods.\n"
|
||||
"Do you want to disable them?")
|
||||
.arg(affected.length()),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes) {
|
||||
m_model->setResourceEnabled(affected, EnableAction::DISABLE);
|
||||
}
|
||||
}
|
||||
m_model->deleteResources(indexes);
|
||||
}
|
||||
|
||||
void ModFolderPage::downloadMods()
|
||||
|
Loading…
x
Reference in New Issue
Block a user