mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 16:29:55 +00:00
Support links to GMST in l10n files
This commit is contained in:
parent
efebb8efd8
commit
58fdd687a8
6 changed files with 42 additions and 4 deletions
|
@ -777,6 +777,18 @@ void OMW::Engine::prepareEngine()
|
||||||
mEnvironment.setWorldModel(mWorld->getWorldModel());
|
mEnvironment.setWorldModel(mWorld->getWorldModel());
|
||||||
mEnvironment.setWorldScene(mWorld->getWorldScene());
|
mEnvironment.setWorldScene(mWorld->getWorldScene());
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::GameSetting>* gmst = &mWorld->getStore().get<ESM::GameSetting>();
|
||||||
|
mL10nManager->setGmstLoader([gmst](std::string_view gmstName) {
|
||||||
|
const ESM::GameSetting* res = gmst->search(gmstName);
|
||||||
|
if (res && res->mValue.getType() == ESM::VT_String)
|
||||||
|
return res->mValue.getString();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "GMST " << gmstName << " not found";
|
||||||
|
return std::string("GMST:") + std::string(gmstName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mWindowManager->setStore(mWorld->getStore());
|
mWindowManager->setStore(mWorld->getStore());
|
||||||
mWindowManager->initUI();
|
mWindowManager->initUI();
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
internal::CaptureStdout();
|
internal::CaptureStdout();
|
||||||
l10n::Manager l10nManager(mVFS.get());
|
l10n::Manager l10nManager(mVFS.get());
|
||||||
l10nManager.setPreferredLocales({ "de", "en" });
|
l10nManager.setPreferredLocales({ "de", "en" });
|
||||||
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: de en\n");
|
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
|
||||||
|
|
||||||
l["l10n"] = LuaUtil::initL10nLoader(l, &l10nManager);
|
l["l10n"] = LuaUtil::initL10nLoader(l, &l10nManager);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
internal::CaptureStdout();
|
internal::CaptureStdout();
|
||||||
l10nManager.setPreferredLocales({ "en", "de" });
|
l10nManager.setPreferredLocales({ "en", "de" });
|
||||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||||
"Preferred locales: en de\n"
|
"Preferred locales: gmst en de\n"
|
||||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||||
|
@ -152,7 +152,7 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
internal::CaptureStdout();
|
internal::CaptureStdout();
|
||||||
l10nManager.setPreferredLocales({ "en-GB-oed", "de" });
|
l10nManager.setPreferredLocales({ "en-GB-oed", "de" });
|
||||||
EXPECT_THAT(internal::GetCapturedStdout(),
|
EXPECT_THAT(internal::GetCapturedStdout(),
|
||||||
"Preferred locales: en_GB_OED de\n"
|
"Preferred locales: gmst en_GB_OED de\n"
|
||||||
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
"Language file \"l10n/Test1/en.yaml\" is enabled\n"
|
||||||
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
"Language file \"l10n/Test1/de.yaml\" is enabled\n"
|
||||||
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
"Language file \"l10n/Test2/en.yaml\" is enabled\n");
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace l10n
|
||||||
void Manager::setPreferredLocales(const std::vector<std::string>& langs)
|
void Manager::setPreferredLocales(const std::vector<std::string>& langs)
|
||||||
{
|
{
|
||||||
mPreferredLocales.clear();
|
mPreferredLocales.clear();
|
||||||
|
mPreferredLocales.push_back(icu::Locale("gmst"));
|
||||||
std::set<std::string> langSet;
|
std::set<std::string> langSet;
|
||||||
for (const auto& lang : langs)
|
for (const auto& lang : langs)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +91,7 @@ namespace l10n
|
||||||
throw std::runtime_error(std::string("Invalid l10n context name: ") + contextName);
|
throw std::runtime_error(std::string("Invalid l10n context name: ") + contextName);
|
||||||
icu::Locale fallbackLocale(fallbackLocaleName.c_str());
|
icu::Locale fallbackLocale(fallbackLocaleName.c_str());
|
||||||
std::shared_ptr<MessageBundles> ctx = std::make_shared<MessageBundles>(mPreferredLocales, fallbackLocale);
|
std::shared_ptr<MessageBundles> ctx = std::make_shared<MessageBundles>(mPreferredLocales, fallbackLocale);
|
||||||
|
ctx->setGmstLoader(mGmstLoader);
|
||||||
updateContext(contextName, *ctx);
|
updateContext(contextName, *ctx);
|
||||||
mCache.emplace(key, ctx);
|
mCache.emplace(key, ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace l10n
|
||||||
void dropCache() { mCache.clear(); }
|
void dropCache() { mCache.clear(); }
|
||||||
void setPreferredLocales(const std::vector<std::string>& locales);
|
void setPreferredLocales(const std::vector<std::string>& locales);
|
||||||
const std::vector<icu::Locale>& getPreferredLocales() const { return mPreferredLocales; }
|
const std::vector<icu::Locale>& getPreferredLocales() const { return mPreferredLocales; }
|
||||||
|
void setGmstLoader(std::function<std::string(std::string_view)> fn) { mGmstLoader = std::move(fn); }
|
||||||
|
|
||||||
std::shared_ptr<const MessageBundles> getContext(
|
std::shared_ptr<const MessageBundles> getContext(
|
||||||
const std::string& contextName, const std::string& fallbackLocale = "en");
|
const std::string& contextName, const std::string& fallbackLocale = "en");
|
||||||
|
@ -35,6 +36,7 @@ namespace l10n
|
||||||
const VFS::Manager* mVFS;
|
const VFS::Manager* mVFS;
|
||||||
std::vector<icu::Locale> mPreferredLocales;
|
std::vector<icu::Locale> mPreferredLocales;
|
||||||
std::map<std::pair<std::string, std::string>, std::shared_ptr<MessageBundles>> mCache;
|
std::map<std::pair<std::string, std::string>, std::shared_ptr<MessageBundles>> mCache;
|
||||||
|
std::function<std::string(std::string_view)> mGmstLoader;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace l10n
|
||||||
{
|
{
|
||||||
YAML::Node data = YAML::Load(input);
|
YAML::Node data = YAML::Load(input);
|
||||||
std::string localeName = lang.getName();
|
std::string localeName = lang.getName();
|
||||||
|
const icu::Locale& langOrEn = localeName == "gmst" ? icu::Locale::getEnglish() : lang;
|
||||||
for (const auto& it : data)
|
for (const auto& it : data)
|
||||||
{
|
{
|
||||||
const auto key = it.first.as<std::string>();
|
const auto key = it.first.as<std::string>();
|
||||||
|
@ -79,7 +80,7 @@ namespace l10n
|
||||||
icu::UnicodeString pattern = icu::UnicodeString::fromUTF8(icu::StringPiece(value.data(), value.size()));
|
icu::UnicodeString pattern = icu::UnicodeString::fromUTF8(icu::StringPiece(value.data(), value.size()));
|
||||||
icu::ErrorCode status;
|
icu::ErrorCode status;
|
||||||
UParseError parseError;
|
UParseError parseError;
|
||||||
icu::MessageFormat message(pattern, lang, parseError, status);
|
icu::MessageFormat message(pattern, langOrEn, parseError, status);
|
||||||
if (checkSuccess(status,
|
if (checkSuccess(status,
|
||||||
std::string("Failed to create message ") + key + " for locale " + lang.getName(), parseError))
|
std::string("Failed to create message ") + key + " for locale " + lang.getName(), parseError))
|
||||||
{
|
{
|
||||||
|
@ -120,6 +121,20 @@ namespace l10n
|
||||||
return formatMessage(key, argNames, argValues);
|
return formatMessage(key, argNames, argValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string loadGmst(
|
||||||
|
const std::function<std::string(std::string_view)> gmstLoader, const icu::MessageFormat* message)
|
||||||
|
{
|
||||||
|
icu::UnicodeString gmstNameUnicode;
|
||||||
|
std::string gmstName;
|
||||||
|
icu::ErrorCode success;
|
||||||
|
message->format(nullptr, nullptr, 0, gmstNameUnicode, success);
|
||||||
|
gmstNameUnicode.toUTF8String(gmstName);
|
||||||
|
if (gmstLoader)
|
||||||
|
return gmstLoader(gmstName);
|
||||||
|
else
|
||||||
|
return "GMST:" + gmstName;
|
||||||
|
}
|
||||||
|
|
||||||
std::string MessageBundles::formatMessage(std::string_view key, const std::vector<icu::UnicodeString>& argNames,
|
std::string MessageBundles::formatMessage(std::string_view key, const std::vector<icu::UnicodeString>& argNames,
|
||||||
const std::vector<icu::Formattable>& args) const
|
const std::vector<icu::Formattable>& args) const
|
||||||
{
|
{
|
||||||
|
@ -132,7 +147,11 @@ namespace l10n
|
||||||
{
|
{
|
||||||
message = findMessage(key, loc);
|
message = findMessage(key, loc);
|
||||||
if (message)
|
if (message)
|
||||||
|
{
|
||||||
|
if (loc == "gmst")
|
||||||
|
return loadGmst(mGmstLoader, message);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If no requested locales included the message, try the fallback locale
|
// If no requested locales included the message, try the fallback locale
|
||||||
if (!message)
|
if (!message)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef COMPONENTS_L10N_MESSAGEBUNDLES_H
|
#ifndef COMPONENTS_L10N_MESSAGEBUNDLES_H
|
||||||
#define COMPONENTS_L10N_MESSAGEBUNDLES_H
|
#define COMPONENTS_L10N_MESSAGEBUNDLES_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -42,6 +43,7 @@ namespace l10n
|
||||||
void load(std::istream& input, const icu::Locale& lang, const std::string& path);
|
void load(std::istream& input, const icu::Locale& lang, const std::string& path);
|
||||||
bool isLoaded(const icu::Locale& loc) const { return mBundles.find(loc.getName()) != mBundles.end(); }
|
bool isLoaded(const icu::Locale& loc) const { return mBundles.find(loc.getName()) != mBundles.end(); }
|
||||||
const icu::Locale& getFallbackLocale() const { return mFallbackLocale; }
|
const icu::Locale& getFallbackLocale() const { return mFallbackLocale; }
|
||||||
|
void setGmstLoader(std::function<std::string(std::string_view)> fn) { mGmstLoader = std::move(fn); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// icu::Locale isn't hashable (or comparable), so we use the string form instead, which is canonicalized
|
// icu::Locale isn't hashable (or comparable), so we use the string form instead, which is canonicalized
|
||||||
|
@ -49,6 +51,7 @@ namespace l10n
|
||||||
const icu::Locale mFallbackLocale;
|
const icu::Locale mFallbackLocale;
|
||||||
std::vector<std::string> mPreferredLocaleStrings;
|
std::vector<std::string> mPreferredLocaleStrings;
|
||||||
std::vector<icu::Locale> mPreferredLocales;
|
std::vector<icu::Locale> mPreferredLocales;
|
||||||
|
std::function<std::string(std::string_view)> mGmstLoader;
|
||||||
const icu::MessageFormat* findMessage(std::string_view key, const std::string& localeName) const;
|
const icu::MessageFormat* findMessage(std::string_view key, const std::string& localeName) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue