ソースを参照

Restored mod uninstall functionality, restored translatable mod fields,
added more fields to translatable list

Ivan Savenko 11 ヶ月 前
コミット
30ed066cea

+ 2 - 1
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();

+ 5 - 5
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<typename Container>
@@ -71,7 +71,7 @@ QStringList ModState::getConflicts() const
 
 QStringList ModState::getScreenshots() const
 {
-	return stringListStdToQt(impl.getValue("screenshots").convertTo<std::vector<std::string>>());
+	return stringListStdToQt(impl.getLocalizedValue("screenshots").convertTo<std::vector<std::string>>());
 }
 
 QString ModState::getBaseLanguage() const
@@ -97,7 +97,7 @@ QStringList ModState::getSupportedLanguages() const
 QMap<QString, QStringList> ModState::getChangelog() const
 {
 	QMap<QString, QStringList> 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

+ 2 - 4
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;
 }

+ 8 - 1
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<JsonNode>())
@@ -28,6 +29,12 @@ void ModStateModel::appendRepositories(const JsonNode & repositoriesList)
 	modManager = std::make_unique<ModManager>(*repositoryData);
 }
 
+void ModStateModel::reloadLocalState()
+{
+	CResourceHandler::get("initial")->updateFilteredFiles([](const std::string &){ return true; });
+	modManager = std::make_unique<ModManager>(*repositoryData);
+}
+
 const JsonNode & ModStateModel::getRepositoryData() const
 {
 	return *repositoryData;

+ 1 - 0
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;

+ 25 - 1
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);

+ 2 - 0
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;
 

+ 11 - 3
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);