mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
VCMI will now check whether translations are complete
This commit is contained in:
parent
623cae7d47
commit
f57a77c2fe
@ -410,10 +410,49 @@ void CGeneralTextHandler::registerStringOverride(const std::string & modContext,
|
|||||||
entry.modContext = modContext;
|
entry.modContext = modContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGeneralTextHandler::loadTranslationOverrides(const std::string & language, const JsonNode & config)
|
bool CGeneralTextHandler::validateTranslation(const std::string & language, const std::string & modContext, const JsonNode & config) const
|
||||||
|
{
|
||||||
|
bool allPresent = true;
|
||||||
|
|
||||||
|
for (auto const & string : stringsLocalizations)
|
||||||
|
{
|
||||||
|
if (string.second.modContext != modContext)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (string.second.baseLanguage == language && !string.second.baseValue.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (config.Struct().count(string.first) > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (allPresent)
|
||||||
|
logMod->warn("Translation into language '%s' in mod '%s' is incomplete! Missing lines:", language, modContext);
|
||||||
|
|
||||||
|
logMod->warn(R"( "%s" : "",)", string.first);
|
||||||
|
allPresent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool allFound = true;
|
||||||
|
|
||||||
|
for (auto const & string : config.Struct())
|
||||||
|
{
|
||||||
|
if (stringsLocalizations.count(string.first) > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (allFound)
|
||||||
|
logMod->warn("Translation into language '%s' in mod '%s' has unused lines:", language, modContext);
|
||||||
|
|
||||||
|
logMod->warn(R"( "%s" : "",)", string.first);
|
||||||
|
allFound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allPresent && allFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGeneralTextHandler::loadTranslationOverrides(const std::string & language, const std::string & modContext, const JsonNode & config)
|
||||||
{
|
{
|
||||||
for ( auto const & node : config.Struct())
|
for ( auto const & node : config.Struct())
|
||||||
registerStringOverride(node.second.meta, language, node.first, node.second.String());
|
registerStringOverride(modContext, language, node.first, node.second.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
CGeneralTextHandler::CGeneralTextHandler():
|
CGeneralTextHandler::CGeneralTextHandler():
|
||||||
@ -619,7 +658,7 @@ CGeneralTextHandler::CGeneralTextHandler():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CGeneralTextHandler::pluralText(const int32_t textIndex, const int32_t count) const
|
int32_t CGeneralTextHandler::pluralText(int32_t textIndex, int32_t count) const
|
||||||
{
|
{
|
||||||
if(textIndex == 0)
|
if(textIndex == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -41,7 +41,7 @@ namespace Unicode
|
|||||||
std::string DLL_LINKAGE fromUnicode(const std::string & text, const std::string & encoding);
|
std::string DLL_LINKAGE fromUnicode(const std::string & text, const std::string & encoding);
|
||||||
|
|
||||||
///delete (amount) UTF characters from right
|
///delete (amount) UTF characters from right
|
||||||
DLL_LINKAGE void trimRight(std::string & text, const size_t amount = 1);
|
DLL_LINKAGE void trimRight(std::string & text, size_t amount = 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CInputStream;
|
class CInputStream;
|
||||||
@ -87,8 +87,8 @@ public:
|
|||||||
/// end current line
|
/// end current line
|
||||||
bool endLine();
|
bool endLine();
|
||||||
|
|
||||||
CLegacyConfigParser(std::string URI);
|
explicit CLegacyConfigParser(std::string URI);
|
||||||
CLegacyConfigParser(const std::unique_ptr<CInputStream> & input);
|
explicit CLegacyConfigParser(const std::unique_ptr<CInputStream> & input);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CGeneralTextHandler;
|
class CGeneralTextHandler;
|
||||||
@ -175,9 +175,14 @@ class DLL_LINKAGE CGeneralTextHandler
|
|||||||
std::string getModLanguage(const std::string & modContext);
|
std::string getModLanguage(const std::string & modContext);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// validates translation of specified language for specified mod
|
||||||
|
/// returns true if localization is valid and complete
|
||||||
|
/// any error messages will be written to log file
|
||||||
|
bool validateTranslation(const std::string & language, const std::string & modContext, JsonNode const & file) const;
|
||||||
|
|
||||||
/// Loads translation from provided json
|
/// Loads translation from provided json
|
||||||
/// Any entries loaded by this will have priority over texts registered normally
|
/// Any entries loaded by this will have priority over texts registered normally
|
||||||
void loadTranslationOverrides(const std::string & language, JsonNode const & file);
|
void loadTranslationOverrides(const std::string & language, const std::string & modContext, JsonNode const & file);
|
||||||
|
|
||||||
/// add selected string to internal storage
|
/// add selected string to internal storage
|
||||||
void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized);
|
void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized);
|
||||||
@ -240,7 +245,7 @@ public:
|
|||||||
|
|
||||||
std::vector<std::string> findStringsWithPrefix(std::string const & prefix);
|
std::vector<std::string> findStringsWithPrefix(std::string const & prefix);
|
||||||
|
|
||||||
int32_t pluralText(const int32_t textIndex, const int32_t count) const;
|
int32_t pluralText(int32_t textIndex, int32_t count) const;
|
||||||
|
|
||||||
size_t getCampaignLength(size_t campaignID) const;
|
size_t getCampaignLength(size_t campaignID) const;
|
||||||
|
|
||||||
|
@ -1118,32 +1118,55 @@ void CModHandler::initializeConfig()
|
|||||||
loadConfigFromFile("defaultMods.json");
|
loadConfigFromFile("defaultMods.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModHandler::validateTranslations(TModID modName) const
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
const auto & mod = allMods.at(modName);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto fileList = mod.config["translations"].convertTo<std::vector<std::string> >();
|
||||||
|
JsonNode json = JsonUtils::assembleFromFiles(fileList);
|
||||||
|
result |= VLC->generaltexth->validateTranslation(mod.baseLanguage, modName, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: unify language lists in mod handler, general text handler, launcher and json validation
|
||||||
|
static const std::vector<std::string> languagesList =
|
||||||
|
{ "english", "german", "polish", "russian", "ukrainian" };
|
||||||
|
|
||||||
|
for (auto const & language : languagesList)
|
||||||
|
{
|
||||||
|
if (mod.config[language].isNull())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto fileList = mod.config[language]["translations"].convertTo<std::vector<std::string> >();
|
||||||
|
JsonNode json = JsonUtils::assembleFromFiles(fileList);
|
||||||
|
result |= VLC->generaltexth->validateTranslation(language, modName, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void CModHandler::loadTranslation(TModID modName)
|
void CModHandler::loadTranslation(TModID modName)
|
||||||
{
|
{
|
||||||
auto const & mod = allMods[modName];
|
auto & mod = allMods[modName];
|
||||||
|
|
||||||
std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage();
|
std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage();
|
||||||
std::string modBaseLanguage = allMods[modName].baseLanguage;
|
std::string modBaseLanguage = allMods[modName].baseLanguage;
|
||||||
|
|
||||||
for (auto const & config : mod.config["translations"].Vector())
|
auto baseTranslationList = mod.config["translations"].convertTo<std::vector<std::string> >();
|
||||||
{
|
auto extraTranslationList = mod.config[preferredLanguage]["translations"].convertTo<std::vector<std::string> >();
|
||||||
JsonNode json(ResourceID(config.String(), EResType::TEXT));
|
|
||||||
json.setMeta(modName);
|
|
||||||
|
|
||||||
VLC->generaltexth->loadTranslationOverrides(modBaseLanguage, json);
|
JsonNode baseTranslation = JsonUtils::assembleFromFiles(baseTranslationList);
|
||||||
}
|
JsonNode extraTranslation = JsonUtils::assembleFromFiles(extraTranslationList);
|
||||||
|
|
||||||
for (auto const & config : mod.config[preferredLanguage]["translations"].Vector())
|
VLC->generaltexth->loadTranslationOverrides(modBaseLanguage, modName, baseTranslation);
|
||||||
{
|
VLC->generaltexth->loadTranslationOverrides(preferredLanguage, modName, extraTranslation);
|
||||||
JsonNode json(ResourceID(config.String(), EResType::TEXT));
|
|
||||||
json.setMeta(modName);
|
|
||||||
|
|
||||||
VLC->generaltexth->loadTranslationOverrides(preferredLanguage, json);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModHandler::load()
|
void CModHandler::load()
|
||||||
{
|
{
|
||||||
CStopWatch totalTime, timer;
|
CStopWatch totalTime;
|
||||||
|
CStopWatch timer;
|
||||||
|
|
||||||
logMod->info("\tInitializing content handler: %d ms", timer.getDiff());
|
logMod->info("\tInitializing content handler: %d ms", timer.getDiff());
|
||||||
|
|
||||||
@ -1166,15 +1189,19 @@ void CModHandler::load()
|
|||||||
for(const TModID & modName : activeMods)
|
for(const TModID & modName : activeMods)
|
||||||
content->load(allMods[modName]);
|
content->load(allMods[modName]);
|
||||||
|
|
||||||
for(const TModID & modName : activeMods)
|
|
||||||
loadTranslation(modName);
|
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
VLC->scriptHandler->performRegistration(VLC);//todo: this should be done before any other handlers load
|
VLC->scriptHandler->performRegistration(VLC);//todo: this should be done before any other handlers load
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
content->loadCustom();
|
content->loadCustom();
|
||||||
|
|
||||||
|
for(const TModID & modName : activeMods)
|
||||||
|
loadTranslation(modName);
|
||||||
|
|
||||||
|
for(const TModID & modName : activeMods)
|
||||||
|
if (!validateTranslations(modName))
|
||||||
|
allMods[modName].validation = CModInfo::FAILED;
|
||||||
|
|
||||||
logMod->info("\tLoading mod data: %d ms", timer.getDiff());
|
logMod->info("\tLoading mod data: %d ms", timer.getDiff());
|
||||||
|
|
||||||
VLC->creh->loadCrExpBon();
|
VLC->creh->loadCrExpBon();
|
||||||
|
@ -286,6 +286,8 @@ class DLL_LINKAGE CModHandler
|
|||||||
void loadMods(std::string path, std::string parent, const JsonNode & modSettings, bool enableMods);
|
void loadMods(std::string path, std::string parent, const JsonNode & modSettings, bool enableMods);
|
||||||
void loadOneMod(std::string modName, std::string parent, const JsonNode & modSettings, bool enableMods);
|
void loadOneMod(std::string modName, std::string parent, const JsonNode & modSettings, bool enableMods);
|
||||||
void loadTranslation(TModID modName);
|
void loadTranslation(TModID modName);
|
||||||
|
|
||||||
|
bool validateTranslations(TModID modName) const;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// returns true if scope is reserved for internal use and can not be used by mods
|
/// returns true if scope is reserved for internal use and can not be used by mods
|
||||||
|
Loading…
x
Reference in New Issue
Block a user