mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-08-03 19:37:45 -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 "Application.h"
|
||||||
|
|
||||||
|
#include "minecraft/Component.h"
|
||||||
|
#include "minecraft/mod/Resource.h"
|
||||||
|
#include "minecraft/mod/ResourceFolderModel.h"
|
||||||
#include "minecraft/mod/tasks/LocalModParseTask.h"
|
#include "minecraft/mod/tasks/LocalModParseTask.h"
|
||||||
#include "modplatform/ModIndex.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));
|
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()
|
void ModFolderModel::onParseFinished()
|
||||||
{
|
{
|
||||||
if (hasPendingParseTasks()) {
|
if (hasPendingParseTasks()) {
|
||||||
@ -267,37 +276,37 @@ void ModFolderModel::onParseFinished()
|
|||||||
}
|
}
|
||||||
auto mods = allMods();
|
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 findByProjectID = [mods](QVariant modId, ModPlatform::ResourceProvider provider) -> Mod* {
|
||||||
auto found = std::find_if(mods.begin(), mods.end(), [modId, provider](Mod* m) {
|
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;
|
return found != mods.end() ? *found : nullptr;
|
||||||
};
|
};
|
||||||
for (auto mod : mods) {
|
for (auto mod : mods) {
|
||||||
auto id = mod->internal_id();
|
auto id = mod->mod_id();
|
||||||
for (auto dep : mod->dependencies()) {
|
for (auto dep : mod->dependencies()) {
|
||||||
auto d = findById(dep);
|
auto d = findById(mods, dep);
|
||||||
if (d) {
|
if (d) {
|
||||||
m_requires[id] << d;
|
m_requires[id] << d;
|
||||||
m_requiredBy[d->internal_id()] << mod;
|
m_requiredBy[d->mod_id()] << mod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mod->metadata()) {
|
||||||
for (auto dep : mod->metadata()->dependencies) {
|
for (auto dep : mod->metadata()->dependencies) {
|
||||||
|
if (dep.type == ModPlatform::DependencyType::REQUIRED) {
|
||||||
auto d = findByProjectID(dep.addonId, mod->metadata()->provider);
|
auto d = findByProjectID(dep.addonId, mod->metadata()->provider);
|
||||||
if (d) {
|
if (d) {
|
||||||
m_requires[id] << d;
|
m_requires[id] << d;
|
||||||
m_requiredBy[d->internal_id()] << mod;
|
m_requiredBy[d->mod_id()] << mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto removeDuplicates = [](QList<Mod*>& list) {
|
auto removeDuplicates = [](QList<Mod*>& list) {
|
||||||
std::set<QString> seen;
|
std::set<QString> seen;
|
||||||
auto it = std::remove_if(list.begin(), list.end(), [&seen](Mod* m) {
|
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) {
|
if (seen.count(id) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -313,10 +322,66 @@ void ModFolderModel::onParseFinished()
|
|||||||
removeDuplicates(m_requires[key]);
|
removeDuplicates(m_requires[key]);
|
||||||
}
|
}
|
||||||
for (auto mod : mods) {
|
for (auto mod : mods) {
|
||||||
auto id = mod->internal_id();
|
auto id = mod->mod_id();
|
||||||
mod->setRequiredByCount(m_requiredBy[id].count());
|
mod->setRequiredByCount(m_requiredBy[id].count());
|
||||||
mod->setRequiresCount(m_requires[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));
|
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 "Mod.h"
|
||||||
#include "ResourceFolderModel.h"
|
#include "ResourceFolderModel.h"
|
||||||
|
#include "minecraft/Component.h"
|
||||||
#include "minecraft/mod/Resource.h"
|
#include "minecraft/mod/Resource.h"
|
||||||
|
|
||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
@ -89,6 +90,9 @@ class ModFolderModel : public ResourceFolderModel {
|
|||||||
|
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
|
bool setResourceEnabled(const QModelIndexList& indexes, EnableAction action) override;
|
||||||
|
QModelIndexList getAffectedMods(const QModelIndexList& indexes, EnableAction action);
|
||||||
|
|
||||||
RESOURCE_HELPERS(Mod)
|
RESOURCE_HELPERS(Mod)
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -882,6 +882,7 @@ QList<Resource*> ResourceFolderModel::allResources()
|
|||||||
result.append((resource.get()));
|
result.append((resource.get()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Resource*> ResourceFolderModel::selectedResources(const QModelIndexList& indexes)
|
QList<Resource*> ResourceFolderModel::selectedResources(const QModelIndexList& indexes)
|
||||||
{
|
{
|
||||||
QList<Resource*> result;
|
QList<Resource*> result;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ModFolderPage.h"
|
#include "ModFolderPage.h"
|
||||||
|
#include "minecraft/mod/Resource.h"
|
||||||
#include "ui/dialogs/ExportToModListDialog.h"
|
#include "ui/dialogs/ExportToModListDialog.h"
|
||||||
#include "ui_ExternalResourcesPage.h"
|
#include "ui_ExternalResourcesPage.h"
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
|||||||
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
|
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
|
||||||
ui->actionVerifyItemDependencies->setVisible(!depsDisabled->get().toBool());
|
ui->actionVerifyItemDependencies->setVisible(!depsDisabled->get().toBool());
|
||||||
connect(depsDisabled.get(), &Setting::SettingChanged, this,
|
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);
|
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
|
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
|
||||||
@ -133,7 +134,22 @@ void ModFolderPage::removeItems(const QItemSelection& selection)
|
|||||||
if (response != QMessageBox::Yes)
|
if (response != QMessageBox::Yes)
|
||||||
return;
|
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()
|
void ModFolderPage::downloadMods()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user