diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp index 240424344..0846c9b61 100644 --- a/launcher/modManager/cmodlistview_moc.cpp +++ b/launcher/modManager/cmodlistview_moc.cpp @@ -464,7 +464,7 @@ void CModListView::selectMod(const QModelIndex & index) ui->disableButton->setEnabled(true); ui->enableButton->setEnabled(!hasInvalidDeps); ui->installButton->setEnabled(!hasInvalidDeps); - ui->uninstallButton->setEnabled(!hasDependentMods && !mod.isHidden()); + ui->uninstallButton->setEnabled(true); ui->updateButton->setEnabled(!hasInvalidDeps && !hasDependentMods); loadScreenshots(); @@ -610,6 +610,7 @@ void CModListView::on_uninstallButton_clicked() if(modStateModel->isModEnabled(modName)) manager->disableMod(modName); manager->uninstallMod(modName); + modModel->reloadRepositories(); } checkManagerErrors(); diff --git a/launcher/modManager/modstate.cpp b/launcher/modManager/modstate.cpp index 796ed2336..7b4bc1db9 100644 --- a/launcher/modManager/modstate.cpp +++ b/launcher/modManager/modstate.cpp @@ -32,7 +32,7 @@ QString ModState::getType() const QString ModState::getDescription() const { - return QString::fromStdString(impl.getValue("description").String()); + return QString::fromStdString(impl.getLocalizedValue("description").String()); } QString ModState::getID() const @@ -47,7 +47,7 @@ QString ModState::getParentID() const QString ModState::getTopParentID() const { - return QString::fromStdString(impl.getParentID()); // TODO + return QString::fromStdString(impl.getTopParentID()); } template @@ -71,7 +71,7 @@ QStringList ModState::getConflicts() const QStringList ModState::getScreenshots() const { - return stringListStdToQt(impl.getValue("screenshots").convertTo>()); + return stringListStdToQt(impl.getLocalizedValue("screenshots").convertTo>()); } QString ModState::getBaseLanguage() const @@ -97,7 +97,7 @@ QStringList ModState::getSupportedLanguages() const QMap ModState::getChangelog() const { QMap result; - const JsonNode & changelog = impl.getValue("changelog"); + const JsonNode & changelog = impl.getLocalizedValue("changelog"); for (const auto & entry : changelog.Struct()) { @@ -142,7 +142,7 @@ QString ModState::getDownloadSizeFormatted() const QString ModState::getAuthors() const { - return QString::fromStdString(impl.getValue("author").String()); + return QString::fromStdString(impl.getLocalizedValue("author").String()); } QString ModState::getContact() const diff --git a/launcher/modManager/modstatecontroller.cpp b/launcher/modManager/modstatecontroller.cpp index 8c8676429..a4ef32152 100644 --- a/launcher/modManager/modstatecontroller.cpp +++ b/launcher/modManager/modstatecontroller.cpp @@ -234,8 +234,7 @@ bool ModStateController::doInstallMod(QString modname, QString archivePath) removeModDir(destDir + upperLevel); CResourceHandler::get("initial")->updateFilteredFiles([](const std::string &) { return true; }); - //loadMods(); - //modList->reloadRepositories(); + //modList->reloadLocalMods(); return true; } @@ -254,8 +253,7 @@ bool ModStateController::doUninstallMod(QString modname) return addError(modname, tr("Mod is located in protected directory, please remove it manually:\n") + modFullDir.absolutePath()); CResourceHandler::get("initial")->updateFilteredFiles([](const std::string &){ return true; }); - //loadMods(); - //modList->reloadRepositories(); + modList->reloadLocalState(); return true; } diff --git a/launcher/modManager/modstatemodel.cpp b/launcher/modManager/modstatemodel.cpp index 31f2975e7..e320be196 100644 --- a/launcher/modManager/modstatemodel.cpp +++ b/launcher/modManager/modstatemodel.cpp @@ -10,8 +10,9 @@ #include "StdInc.h" #include "modstatemodel.h" -#include "../../lib/modding/ModManager.h" +#include "../../lib/filesystem/Filesystem.h" #include "../../lib/json/JsonUtils.h" +#include "../../lib/modding/ModManager.h" ModStateModel::ModStateModel() : repositoryData(std::make_unique()) @@ -28,6 +29,12 @@ void ModStateModel::appendRepositories(const JsonNode & repositoriesList) modManager = std::make_unique(*repositoryData); } +void ModStateModel::reloadLocalState() +{ + CResourceHandler::get("initial")->updateFilteredFiles([](const std::string &){ return true; }); + modManager = std::make_unique(*repositoryData); +} + const JsonNode & ModStateModel::getRepositoryData() const { return *repositoryData; diff --git a/launcher/modManager/modstatemodel.h b/launcher/modManager/modstatemodel.h index 750fd2297..d20f73d6c 100644 --- a/launcher/modManager/modstatemodel.h +++ b/launcher/modManager/modstatemodel.h @@ -28,6 +28,7 @@ public: ~ModStateModel(); void appendRepositories(const JsonNode & repositoriesList); + void reloadLocalState(); const JsonNode & getRepositoryData() const; ModState getMod(QString modName) const; diff --git a/lib/modding/ModDescription.cpp b/lib/modding/ModDescription.cpp index df89c45a1..5ab5797e8 100644 --- a/lib/modding/ModDescription.cpp +++ b/lib/modding/ModDescription.cpp @@ -14,6 +14,7 @@ #include "ModVerificationInfo.h" #include "../json/JsonNode.h" +#include "../texts/CGeneralTextHandler.h" VCMI_LIB_NAMESPACE_BEGIN @@ -57,6 +58,16 @@ TModID ModDescription::getParentID() const return identifier.substr(0, dotPos); } +TModID ModDescription::getTopParentID() const +{ + size_t dotPos = identifier.find('.'); + + if(dotPos == std::string::npos) + return {}; + + return identifier.substr(0, dotPos); +} + const TModSet & ModDescription::getDependencies() const { return dependencies; @@ -81,7 +92,7 @@ const std::string & ModDescription::getBaseLanguage() const const std::string & ModDescription::getName() const { - return getValue("name").String(); + return getLocalizedValue("name").String(); } const JsonNode & ModDescription::getFilesystemConfig() const @@ -94,6 +105,19 @@ const JsonNode & ModDescription::getLocalConfig() const return *localConfig; } +const JsonNode & ModDescription::getLocalizedValue(const std::string & keyName) const +{ + const std::string language = CGeneralTextHandler::getPreferredLanguage(); + const JsonNode & languageNode = getValue(language); + const JsonNode & baseValue = getValue(keyName); + const JsonNode & localizedValue = languageNode[keyName]; + + if (localizedValue.isNull()) + return baseValue; + else + return localizedValue; +} + const JsonNode & ModDescription::getValue(const std::string & keyName) const { const JsonNode & localValue = getLocalValue(keyName); diff --git a/lib/modding/ModDescription.h b/lib/modding/ModDescription.h index c46abb823..0f7324a6a 100644 --- a/lib/modding/ModDescription.h +++ b/lib/modding/ModDescription.h @@ -38,6 +38,7 @@ public: const TModID & getID() const; TModID getParentID() const; + TModID getTopParentID() const; const TModSet & getDependencies() const; const TModSet & getSoftDependencies() const; @@ -49,6 +50,7 @@ public: const JsonNode & getFilesystemConfig() const; const JsonNode & getLocalConfig() const; const JsonNode & getValue(const std::string & keyName) const; + const JsonNode & getLocalizedValue(const std::string & keyName) const; const JsonNode & getLocalValue(const std::string & keyName) const; const JsonNode & getRepositoryValue(const std::string & keyName) const; diff --git a/lib/modding/ModManager.cpp b/lib/modding/ModManager.cpp index f7e4602c3..b59d0b579 100644 --- a/lib/modding/ModManager.cpp +++ b/lib/modding/ModManager.cpp @@ -479,11 +479,15 @@ TModList ModManager::collectDependenciesRecursive(const TModID & modID) const toTest.push_back(modID); while (!toTest.empty()) { - TModID currentMod = toTest.back(); + TModID currentModID = toTest.back(); + const auto & currentMod = getModDescription(currentModID); toTest.pop_back(); - result.push_back(currentMod); + result.push_back(currentModID); - for (const auto & dependency : getModDescription(currentMod).getDependencies()) + if (!currentMod.isInstalled()) + return {}; // failure. TODO: better handling? + + for (const auto & dependency : currentMod.getDependencies()) { if (!vstd::contains(result, dependency)) toTest.push_back(dependency); @@ -499,6 +503,7 @@ void ModManager::tryEnableMod(const TModID & modName) auto additionalActiveMods = getActiveMods(); assert(!vstd::contains(additionalActiveMods, modName)); + assert(vstd::contains(requiredActiveMods, modName)); ModDependenciesResolver testResolver(requiredActiveMods, *modsStorage); assert(testResolver.getBrokenMods().empty()); @@ -539,7 +544,10 @@ void ModManager::updatePreset(const ModDependenciesResolver & testResolver) const auto & newBrokenMods = testResolver.getBrokenMods(); for (const auto & modID : newActiveMods) + { + assert(vstd::contains(modsState->getInstalledMods(), modID)); modsPreset->setModActive(modID, true); + } for (const auto & modID : newBrokenMods) modsPreset->setModActive(modID, false);