mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-30 19:22:14 +00:00
Expand Translations class to include language information
This commit is contained in:
parent
e7c6525d47
commit
027a2a67b7
5 changed files with 114 additions and 64 deletions
|
@ -36,45 +36,60 @@ void Translations::clear()
|
|||
m_plural_translations.clear();
|
||||
}
|
||||
|
||||
const std::wstring &Translations::getTranslation(const std::vector<std::wstring> &langlist,
|
||||
const std::wstring &textdomain, const std::wstring &s) const
|
||||
{
|
||||
auto basekey = L"|" + textdomain + L"|" + s;
|
||||
for (const auto &lang: langlist) {
|
||||
auto it = m_translations.find(lang + basekey);
|
||||
if (it != m_translations.end())
|
||||
return it->second;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::wstring &Translations::getTranslation(
|
||||
const std::wstring &textdomain, const std::wstring &s) const
|
||||
{
|
||||
std::wstring key = textdomain + L"|" + s;
|
||||
auto it = m_translations.find(key);
|
||||
if (it != m_translations.end())
|
||||
return it->second;
|
||||
return getTranslation(get_effective_locale(), textdomain, s);
|
||||
}
|
||||
|
||||
const std::wstring &Translations::getPluralTranslation(const std::vector<std::wstring> &langlist,
|
||||
const std::wstring &textdomain, const std::wstring &s, unsigned long int number) const
|
||||
{
|
||||
auto basekey = L"|" + textdomain + L"|" + s;
|
||||
for (const auto &lang: langlist) {
|
||||
auto it = m_plural_translations.find(lang + basekey);
|
||||
if (it != m_plural_translations.end()) {
|
||||
auto n = (*(it->second.first))(number);
|
||||
const std::vector<std::wstring> &v = it->second.second;
|
||||
if (n < v.size()) {
|
||||
if (v[n].empty())
|
||||
return s;
|
||||
return v[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::wstring &Translations::getPluralTranslation(
|
||||
const std::wstring &textdomain, const std::wstring &s, unsigned long int number) const
|
||||
{
|
||||
std::wstring key = textdomain + L"|" + s;
|
||||
auto it = m_plural_translations.find(key);
|
||||
if (it != m_plural_translations.end()) {
|
||||
auto n = (*(it->second.first))(number);
|
||||
const std::vector<std::wstring> &v = it->second.second;
|
||||
if (n < v.size()) {
|
||||
if (v[n].empty())
|
||||
return s;
|
||||
return v[n];
|
||||
}
|
||||
}
|
||||
return s;
|
||||
return getPluralTranslation(get_effective_locale(), textdomain, s, number);
|
||||
}
|
||||
|
||||
|
||||
void Translations::addTranslation(
|
||||
const std::wstring &textdomain, const std::wstring &original, const std::wstring &translated)
|
||||
void Translations::addTranslation(const std::wstring &lang, const std::wstring &textdomain,
|
||||
const std::wstring &original, const std::wstring &translated)
|
||||
{
|
||||
std::wstring key = textdomain + L"|" + original;
|
||||
std::wstring key = lang + L"|" + textdomain + L"|" + original;
|
||||
if (!translated.empty()) {
|
||||
m_translations.emplace(std::move(key), std::move(translated));
|
||||
}
|
||||
}
|
||||
|
||||
void Translations::addPluralTranslation(
|
||||
const std::wstring &textdomain, const GettextPluralForm::Ptr &plural, const std::wstring &original, std::vector<std::wstring> &translated)
|
||||
void Translations::addPluralTranslation(const std::wstring &lang, const std::wstring &textdomain,
|
||||
const GettextPluralForm::Ptr &plural, const std::wstring &original, std::vector<std::wstring> &translated)
|
||||
{
|
||||
static bool warned = false;
|
||||
if (!plural) {
|
||||
|
@ -86,12 +101,12 @@ void Translations::addPluralTranslation(
|
|||
errorstream << "Translations: incorrect number of plural translations (expected " << plural->size() << ", got " << translated.size() << ")" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::wstring key = textdomain + L"|" + original;
|
||||
std::wstring key = lang + L"|" + textdomain + L"|" + original;
|
||||
m_plural_translations.emplace(std::move(key), std::pair(plural, translated));
|
||||
}
|
||||
|
||||
|
||||
void Translations::loadTrTranslation(const std::string &data)
|
||||
void Translations::loadTrTranslation(const std::wstring &lang, const std::string &data)
|
||||
{
|
||||
std::istringstream is(data);
|
||||
std::string textdomain_narrow;
|
||||
|
@ -191,7 +206,7 @@ void Translations::loadTrTranslation(const std::string &data)
|
|||
}
|
||||
}
|
||||
|
||||
addTranslation(textdomain, word1.str(), word2.str());
|
||||
addTranslation(lang, textdomain, word1.str(), word2.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +333,8 @@ std::wstring Translations::unescapeC(const std::wstring &str)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Translations::loadPoEntry(const std::wstring &basefilename, const GettextPluralForm::Ptr &plural_form, const std::map<std::wstring, std::wstring> &entry)
|
||||
void Translations::loadPoEntry(const std::wstring &lang, const std::wstring &basefilename,
|
||||
const GettextPluralForm::Ptr &plural_form, const std::map<std::wstring, std::wstring> &entry)
|
||||
{
|
||||
// Process an entry from a PO file and add it to the translation table
|
||||
// Assumes that entry[L"msgid"] is always defined
|
||||
|
@ -338,7 +354,7 @@ void Translations::loadPoEntry(const std::wstring &basefilename, const GettextPl
|
|||
errorstream << "Could not load translation: entry for msgid \"" << wide_to_utf8(original) << "\" does not contain a msgstr field" << std::endl;
|
||||
return;
|
||||
}
|
||||
addTranslation(textdomain, original, translated->second);
|
||||
addTranslation(lang, textdomain, original, translated->second);
|
||||
} else {
|
||||
std::vector<std::wstring> translations;
|
||||
for (int i = 0; ; i++) {
|
||||
|
@ -347,8 +363,8 @@ void Translations::loadPoEntry(const std::wstring &basefilename, const GettextPl
|
|||
break;
|
||||
translations.push_back(translated->second);
|
||||
}
|
||||
addPluralTranslation(textdomain, plural_form, original, translations);
|
||||
addPluralTranslation(textdomain, plural_form, plural->second, translations);
|
||||
addPluralTranslation(lang, textdomain, plural_form, original, translations);
|
||||
addPluralTranslation(lang, textdomain, plural_form, plural->second, translations);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,7 +431,7 @@ std::optional<std::pair<std::wstring, std::wstring>> Translations::parsePoLine(c
|
|||
return std::pair(prefix, s);
|
||||
}
|
||||
|
||||
void Translations::loadPoTranslation(const std::string &basefilename, const std::string &data)
|
||||
void Translations::loadPoTranslation(const std::wstring &lang, const std::string &basefilename, const std::string &data)
|
||||
{
|
||||
std::istringstream is(data);
|
||||
std::string line;
|
||||
|
@ -481,7 +497,7 @@ void Translations::loadPoTranslation(const std::string &basefilename, const std:
|
|||
}
|
||||
}
|
||||
} else {
|
||||
loadPoEntry(wbasefilename, plural, last_entry);
|
||||
loadPoEntry(lang, wbasefilename, plural, last_entry);
|
||||
}
|
||||
}
|
||||
last_entry.clear();
|
||||
|
@ -505,13 +521,14 @@ void Translations::loadPoTranslation(const std::string &basefilename, const std:
|
|||
|
||||
if (last_entry.find(L"msgid") != last_entry.end()) {
|
||||
if (!skip_last && !last_entry[L"msgid"].empty())
|
||||
loadPoEntry(wbasefilename, plural, last_entry);
|
||||
loadPoEntry(lang, wbasefilename, plural, last_entry);
|
||||
} else if (!last_entry.empty()) {
|
||||
errorstream << "Unable to parse po file: Last entry has no \"msgid\" field" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Translations::loadMoEntry(const std::wstring &basefilename, const GettextPluralForm::Ptr &plural_form, const std::string &original, const std::string &translated)
|
||||
void Translations::loadMoEntry(const std::wstring &lang, const std::wstring &basefilename,
|
||||
const GettextPluralForm::Ptr &plural_form, const std::string &original, const std::string &translated)
|
||||
{
|
||||
std::wstring textdomain = L"";
|
||||
size_t found;
|
||||
|
@ -527,10 +544,10 @@ void Translations::loadMoEntry(const std::wstring &basefilename, const GettextPl
|
|||
found = noriginal.find('\0');
|
||||
if (found != std::string::npos) {
|
||||
std::vector<std::wstring> translations = str_split(utf8_to_wide(translated), L'\0');
|
||||
addPluralTranslation(textdomain, plural_form, utf8_to_wide(noriginal.substr(0, found)), translations);
|
||||
addPluralTranslation(textdomain, plural_form, utf8_to_wide(noriginal.substr(found + 1)), translations);
|
||||
addPluralTranslation(lang, textdomain, plural_form, utf8_to_wide(noriginal.substr(0, found)), translations);
|
||||
addPluralTranslation(lang, textdomain, plural_form, utf8_to_wide(noriginal.substr(found + 1)), translations);
|
||||
} else {
|
||||
addTranslation(textdomain, utf8_to_wide(noriginal), utf8_to_wide(translated));
|
||||
addTranslation(lang, textdomain, utf8_to_wide(noriginal), utf8_to_wide(translated));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,7 +566,7 @@ inline u32 readVarEndian(bool is_be, std::string_view data, size_t pos = 0)
|
|||
}
|
||||
}
|
||||
|
||||
void Translations::loadMoTranslation(const std::string &basefilename, const std::string &data)
|
||||
void Translations::loadMoTranslation(const std::wstring &lang, const std::string &basefilename, const std::string &data)
|
||||
{
|
||||
size_t length = data.length();
|
||||
std::wstring wbasefilename = utf8_to_wide(basefilename);
|
||||
|
@ -619,7 +636,7 @@ void Translations::loadMoTranslation(const std::string &basefilename, const std:
|
|||
}
|
||||
}
|
||||
} else {
|
||||
loadMoEntry(wbasefilename, plural_form, original, translated);
|
||||
loadMoEntry(lang, wbasefilename, plural_form, original, translated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,17 +645,18 @@ void Translations::loadMoTranslation(const std::string &basefilename, const std:
|
|||
|
||||
void Translations::loadTranslation(const std::string &filename, const std::string &data)
|
||||
{
|
||||
auto lang = utf8_to_wide(getFileLanguage(filename));
|
||||
const char *trExtension[] = { ".tr", NULL };
|
||||
const char *poExtension[] = { ".po", NULL };
|
||||
const char *moExtension[] = { ".mo", NULL };
|
||||
if (!removeStringEnd(filename, trExtension).empty()) {
|
||||
loadTrTranslation(data);
|
||||
loadTrTranslation(lang, data);
|
||||
} else if (!removeStringEnd(filename, poExtension).empty()) {
|
||||
std::string basefilename = str_split(filename, '.')[0];
|
||||
loadPoTranslation(basefilename, data);
|
||||
loadPoTranslation(lang, basefilename, data);
|
||||
} else if (!removeStringEnd(filename, moExtension).empty()) {
|
||||
std::string basefilename = str_split(filename, '.')[0];
|
||||
loadMoTranslation(basefilename, data);
|
||||
loadMoTranslation(lang, basefilename, data);
|
||||
} else {
|
||||
errorstream << "loadTranslation called with invalid filename: \"" << filename << "\"" << std::endl;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue