1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Fix installation of multiple mods at once

This commit is contained in:
Ivan Savenko 2024-11-19 22:15:05 +00:00
parent 00f97fb8cd
commit fef19f4846
7 changed files with 52 additions and 38 deletions

View File

@ -451,8 +451,8 @@ void CModListView::selectMod(const QModelIndex & index)
//FIXME: ensure that this is also reflected correctly in "Notes" section of mod description
bool hasInvalidDeps = !findInvalidDependencies(modName).empty();
ui->disableButton->setVisible(modStateModel->isModEnabled(mod.getID()));
ui->enableButton->setVisible(!modStateModel->isModEnabled(mod.getID()));
ui->disableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && modStateModel->isModEnabled(mod.getID()));
ui->enableButton->setVisible(modStateModel->isModInstalled(mod.getID()) && !modStateModel->isModEnabled(mod.getID()));
ui->installButton->setVisible(mod.isAvailable() && !mod.isSubmod());
ui->uninstallButton->setVisible(mod.isInstalled() && !mod.isSubmod());
ui->updateButton->setVisible(mod.isUpdateAvailable());
@ -531,7 +531,7 @@ void CModListView::on_enableButton_clicked()
void CModListView::enableModByName(QString modName)
{
manager->enableMod(modName);
manager->enableMods({modName});
modModel->reloadRepositories();
}
@ -577,10 +577,11 @@ QStringList CModListView::getModsToInstall(QString mod)
QStringList dependencies = modStateModel->getMod(potentialToInstall).getDependencies();
for (const auto & dependency : dependencies)
{
if (!processed.contains(dependency))
if (!processed.contains(dependency) && !candidates.contains(dependency))
candidates.push_back(dependency);
}
}
assert(result.removeDuplicates() == 0);
return result;
}
@ -900,13 +901,15 @@ void CModListView::installMods(QStringList archives)
{
if(modStateModel->getMod(mod).isInstalled())
{
if (modStateModel->isModEnabled(mod))
modsToEnable.push_back(mod);
manager->uninstallMod(mod);
}
else
{
// installation of previously not present mod -> enable it
if (modStateModel->isModEnabled(mod))
modsToEnable.push_back(mod);
modsToEnable.push_back(mod);
}
}
@ -916,10 +919,7 @@ void CModListView::installMods(QStringList archives)
manager->installMod(modNames[i], archives[i]);
}
for(QString mod : modsToEnable)
{
manager->enableMod(mod); // TODO: make it as a single action, so if mod 1 depends on mod 2 it would still activate
}
manager->enableMods(modsToEnable);
checkManagerErrors();

View File

@ -99,14 +99,22 @@ bool ModStateController::uninstallMod(QString modname)
return canUninstallMod(modname) && doUninstallMod(modname);
}
bool ModStateController::enableMod(QString modname)
bool ModStateController::enableMods(QStringList modlist)
{
return canEnableMod(modname) && doEnableMod(modname, true);
for (const auto & modname : modlist)
if (!canEnableMod(modname))
return false;
modList->doEnableMods(modlist);
return true;
}
bool ModStateController::disableMod(QString modname)
{
return canDisableMod(modname) && doEnableMod(modname, false);
if (!canDisableMod(modname))
return false;
modList->doDisableMod(modname);
return true;
}
bool ModStateController::canInstallMod(QString modname)
@ -170,16 +178,6 @@ bool ModStateController::canDisableMod(QString modname)
return true;
}
bool ModStateController::doEnableMod(QString mod, bool on)
{
if (on)
modList->doEnableMod(mod);
else
modList->doDisableMod(mod);
return true;
}
bool ModStateController::doInstallMod(QString modname, QString archivePath)
{
const auto destDir = CLauncherDirs::modsPath() + QChar{'/'};

View File

@ -24,7 +24,6 @@ class ModStateController : public QObject, public boost::noncopyable
std::shared_ptr<ModStateModel> modList;
// check-free version of public method
bool doEnableMod(QString mod, bool on);
bool doInstallMod(QString mod, QString archivePath);
bool doUninstallMod(QString mod);
@ -47,7 +46,7 @@ public:
/// installs mod from zip archive located at archivePath
bool installMod(QString mod, QString archivePath);
bool uninstallMod(QString mod);
bool enableMod(QString mod);
bool enableMods(QStringList mod);
bool disableMod(QString mod);
bool canInstallMod(QString mod);

View File

@ -95,9 +95,14 @@ double ModStateModel::getInstalledModSizeMegabytes(QString modName) const
return modManager->getInstalledModSizeMegabytes(modName.toStdString());
}
void ModStateModel::doEnableMod(QString modname)
void ModStateModel::doEnableMods(QStringList modList)
{
modManager->tryEnableMod(modname.toStdString());
std::vector<std::string> stdList;
for (const auto & entry : modList)
stdList.push_back(entry.toStdString());
modManager->tryEnableMods(stdList);
}
void ModStateModel::doDisableMod(QString modname)

View File

@ -43,7 +43,7 @@ public:
bool isModUpdateAvailable(QString modName) const;
bool isModVisible(QString modName) const;
void doEnableMod(QString modname);
void doEnableMods(QStringList modList);
void doDisableMod(QString modname);
bool isSubmod(QString modname);

View File

@ -495,24 +495,34 @@ TModList ModManager::collectDependenciesRecursive(const TModID & modID) const
return result;
}
void ModManager::tryEnableMod(const TModID & modName)
void ModManager::tryEnableMods(const TModList & modList)
{
auto requiredActiveMods = collectDependenciesRecursive(modName);
auto additionalActiveMods = getActiveMods();
TModList requiredActiveMods;
TModList additionalActiveMods = getActiveMods();
assert(!vstd::contains(additionalActiveMods, modName));
assert(vstd::contains(requiredActiveMods, modName));// FIXME: fails on attempt to enable broken mod / translation to other language
for (const auto & modName : modList)
{
for (const auto & dependency : collectDependenciesRecursive(modName))
if (!vstd::contains(requiredActiveMods, dependency))
requiredActiveMods.push_back(dependency);
assert(!vstd::contains(additionalActiveMods, modName));
assert(vstd::contains(requiredActiveMods, modName));// FIXME: fails on attempt to enable broken mod / translation to other language
}
ModDependenciesResolver testResolver(requiredActiveMods, *modsStorage);
assert(testResolver.getBrokenMods().empty());
assert(vstd::contains(testResolver.getActiveMods(), modName));
testResolver.tryAddMods(additionalActiveMods, *modsStorage);
if (!vstd::contains(testResolver.getActiveMods(), modName))
for (const auto & modName : modList)
{
// FIXME: report?
return;
assert(vstd::contains(testResolver.getActiveMods(), modName));
if (!vstd::contains(testResolver.getActiveMods(), modName))
{
// FIXME: report?
return;
}
}
updatePreset(testResolver);

View File

@ -117,6 +117,8 @@ class DLL_LINKAGE ModManager : boost::noncopyable
TModList collectDependenciesRecursive(const TModID & modID) const;
void tryEnableMod(const TModID & modList);
public:
ModManager(const JsonNode & repositoryList);
ModManager();
@ -133,7 +135,7 @@ public:
void saveConfigurationState() const;
double getInstalledModSizeMegabytes(const TModID & modName) const;
void tryEnableMod(const TModID & modName);
void tryEnableMods(const TModList & modList);
void tryDisableMod(const TModID & modName);
};