mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
Add translation domain
This commit is contained in:
parent
48403b5358
commit
68d494e24e
@ -233,6 +233,7 @@ void register_core_types() {
|
|||||||
|
|
||||||
GDREGISTER_CLASS(MainLoop);
|
GDREGISTER_CLASS(MainLoop);
|
||||||
GDREGISTER_CLASS(Translation);
|
GDREGISTER_CLASS(Translation);
|
||||||
|
GDREGISTER_CLASS(TranslationDomain);
|
||||||
GDREGISTER_CLASS(OptimizedTranslation);
|
GDREGISTER_CLASS(OptimizedTranslation);
|
||||||
GDREGISTER_CLASS(UndoRedo);
|
GDREGISTER_CLASS(UndoRedo);
|
||||||
GDREGISTER_CLASS(TriangleMesh);
|
GDREGISTER_CLASS(TriangleMesh);
|
||||||
|
165
core/string/translation_domain.cpp
Normal file
165
core/string/translation_domain.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* translation_domain.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "translation_domain.h"
|
||||||
|
|
||||||
|
#include "core/string/translation.h"
|
||||||
|
#include "core/string/translation_server.h"
|
||||||
|
|
||||||
|
StringName TranslationDomain::get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_context) const {
|
||||||
|
StringName res;
|
||||||
|
int best_score = 0;
|
||||||
|
|
||||||
|
for (const Ref<Translation> &E : translations) {
|
||||||
|
ERR_CONTINUE(E.is_null());
|
||||||
|
int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
|
||||||
|
if (score > 0 && score >= best_score) {
|
||||||
|
const StringName r = E->get_message(p_message, p_context);
|
||||||
|
if (!r) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res = r;
|
||||||
|
best_score = score;
|
||||||
|
if (score == 10) {
|
||||||
|
break; // Exact match, skip the rest.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName TranslationDomain::get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
|
||||||
|
StringName res;
|
||||||
|
int best_score = 0;
|
||||||
|
|
||||||
|
for (const Ref<Translation> &E : translations) {
|
||||||
|
ERR_CONTINUE(E.is_null());
|
||||||
|
int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
|
||||||
|
if (score > 0 && score >= best_score) {
|
||||||
|
const StringName r = E->get_plural_message(p_message, p_message_plural, p_n, p_context);
|
||||||
|
if (!r) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res = r;
|
||||||
|
best_score = score;
|
||||||
|
if (score == 10) {
|
||||||
|
break; // Exact match, skip the rest.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedStringArray TranslationDomain::get_loaded_locales() const {
|
||||||
|
PackedStringArray locales;
|
||||||
|
for (const Ref<Translation> &E : translations) {
|
||||||
|
ERR_CONTINUE(E.is_null());
|
||||||
|
locales.push_back(E->get_locale());
|
||||||
|
}
|
||||||
|
return locales;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Translation> TranslationDomain::get_translation_object(const String &p_locale) const {
|
||||||
|
Ref<Translation> res;
|
||||||
|
int best_score = 0;
|
||||||
|
|
||||||
|
for (const Ref<Translation> &E : translations) {
|
||||||
|
ERR_CONTINUE(E.is_null());
|
||||||
|
|
||||||
|
int score = TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale());
|
||||||
|
if (score > 0 && score >= best_score) {
|
||||||
|
res = E;
|
||||||
|
best_score = score;
|
||||||
|
if (score == 10) {
|
||||||
|
break; // Exact match, skip the rest.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationDomain::add_translation(const Ref<Translation> &p_translation) {
|
||||||
|
translations.insert(p_translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationDomain::remove_translation(const Ref<Translation> &p_translation) {
|
||||||
|
translations.erase(p_translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationDomain::clear() {
|
||||||
|
translations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName TranslationDomain::translate(const StringName &p_message, const StringName &p_context) const {
|
||||||
|
const String &locale = TranslationServer::get_singleton()->get_locale();
|
||||||
|
StringName res = get_message_from_translations(locale, p_message, p_context);
|
||||||
|
|
||||||
|
const String &fallback = TranslationServer::get_singleton()->get_fallback_locale();
|
||||||
|
if (!res && fallback.length() >= 2) {
|
||||||
|
res = get_message_from_translations(fallback, p_message, p_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return p_message;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName TranslationDomain::translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
|
||||||
|
const String &locale = TranslationServer::get_singleton()->get_locale();
|
||||||
|
StringName res = get_message_from_translations(locale, p_message, p_message_plural, p_n, p_context);
|
||||||
|
|
||||||
|
const String &fallback = TranslationServer::get_singleton()->get_fallback_locale();
|
||||||
|
if (!res && fallback.length() >= 2) {
|
||||||
|
res = get_message_from_translations(fallback, p_message, p_message_plural, p_n, p_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
if (p_n == 1) {
|
||||||
|
return p_message;
|
||||||
|
}
|
||||||
|
return p_message_plural;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationDomain::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationDomain::get_translation_object);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_translation", "translation"), &TranslationDomain::add_translation);
|
||||||
|
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationDomain::remove_translation);
|
||||||
|
ClassDB::bind_method(D_METHOD("clear"), &TranslationDomain::clear);
|
||||||
|
ClassDB::bind_method(D_METHOD("translate", "message", "context"), &TranslationDomain::translate, DEFVAL(StringName()));
|
||||||
|
ClassDB::bind_method(D_METHOD("translate_plural", "message", "message_plural", "n", "context"), &TranslationDomain::translate_plural, DEFVAL(StringName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslationDomain::TranslationDomain() {
|
||||||
|
}
|
65
core/string/translation_domain.h
Normal file
65
core/string/translation_domain.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* translation_domain.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TRANSLATION_DOMAIN_H
|
||||||
|
#define TRANSLATION_DOMAIN_H
|
||||||
|
|
||||||
|
#include "core/object/ref_counted.h"
|
||||||
|
|
||||||
|
class Translation;
|
||||||
|
|
||||||
|
class TranslationDomain : public RefCounted {
|
||||||
|
GDCLASS(TranslationDomain, RefCounted);
|
||||||
|
|
||||||
|
HashSet<Ref<Translation>> translations;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Methods in this section are not intended for scripting.
|
||||||
|
StringName get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_context) const;
|
||||||
|
StringName get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const;
|
||||||
|
PackedStringArray get_loaded_locales() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ref<Translation> get_translation_object(const String &p_locale) const;
|
||||||
|
|
||||||
|
void add_translation(const Ref<Translation> &p_translation);
|
||||||
|
void remove_translation(const Ref<Translation> &p_translation);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
StringName translate(const StringName &p_message, const StringName &p_context) const;
|
||||||
|
StringName translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const;
|
||||||
|
|
||||||
|
TranslationDomain();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TRANSLATION_DOMAIN_H
|
@ -404,69 +404,36 @@ String TranslationServer::get_locale() const {
|
|||||||
return locale;
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String TranslationServer::get_fallback_locale() const {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
PackedStringArray TranslationServer::get_loaded_locales() const {
|
PackedStringArray TranslationServer::get_loaded_locales() const {
|
||||||
PackedStringArray locales;
|
return main_domain->get_loaded_locales();
|
||||||
for (const Ref<Translation> &E : translations) {
|
|
||||||
const Ref<Translation> &t = E;
|
|
||||||
ERR_FAIL_COND_V(t.is_null(), PackedStringArray());
|
|
||||||
String l = t->get_locale();
|
|
||||||
|
|
||||||
locales.push_back(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
return locales;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationServer::add_translation(const Ref<Translation> &p_translation) {
|
void TranslationServer::add_translation(const Ref<Translation> &p_translation) {
|
||||||
translations.insert(p_translation);
|
main_domain->add_translation(p_translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationServer::remove_translation(const Ref<Translation> &p_translation) {
|
void TranslationServer::remove_translation(const Ref<Translation> &p_translation) {
|
||||||
translations.erase(p_translation);
|
main_domain->remove_translation(p_translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Translation> TranslationServer::get_translation_object(const String &p_locale) {
|
Ref<Translation> TranslationServer::get_translation_object(const String &p_locale) {
|
||||||
Ref<Translation> res;
|
return main_domain->get_translation_object(p_locale);
|
||||||
int best_score = 0;
|
|
||||||
|
|
||||||
for (const Ref<Translation> &E : translations) {
|
|
||||||
const Ref<Translation> &t = E;
|
|
||||||
ERR_FAIL_COND_V(t.is_null(), nullptr);
|
|
||||||
String l = t->get_locale();
|
|
||||||
|
|
||||||
int score = compare_locales(p_locale, l);
|
|
||||||
if (score > 0 && score >= best_score) {
|
|
||||||
res = t;
|
|
||||||
best_score = score;
|
|
||||||
if (score == 10) {
|
|
||||||
break; // Exact match, skip the rest.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationServer::clear() {
|
void TranslationServer::clear() {
|
||||||
translations.clear();
|
main_domain->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName TranslationServer::translate(const StringName &p_message, const StringName &p_context) const {
|
StringName TranslationServer::translate(const StringName &p_message, const StringName &p_context) const {
|
||||||
// Match given message against the translation catalog for the project locale.
|
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return p_message;
|
return p_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName res = _get_message_from_translations(p_message, p_context, locale, false);
|
const StringName res = main_domain->translate(p_message, p_context);
|
||||||
|
|
||||||
if (!res && fallback.length() >= 2) {
|
|
||||||
res = _get_message_from_translations(p_message, p_context, fallback, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
return pseudolocalization_enabled ? pseudolocalize(p_message) : p_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pseudolocalization_enabled ? pseudolocalize(res) : res;
|
return pseudolocalization_enabled ? pseudolocalize(res) : res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,51 +445,7 @@ StringName TranslationServer::translate_plural(const StringName &p_message, cons
|
|||||||
return p_message_plural;
|
return p_message_plural;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName res = _get_message_from_translations(p_message, p_context, locale, true, p_message_plural, p_n);
|
return main_domain->translate_plural(p_message, p_message_plural, p_n, p_context);
|
||||||
|
|
||||||
if (!res && fallback.length() >= 2) {
|
|
||||||
res = _get_message_from_translations(p_message, p_context, fallback, true, p_message_plural, p_n);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
if (p_n == 1) {
|
|
||||||
return p_message;
|
|
||||||
}
|
|
||||||
return p_message_plural;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringName TranslationServer::_get_message_from_translations(const StringName &p_message, const StringName &p_context, const String &p_locale, bool plural, const String &p_message_plural, int p_n) const {
|
|
||||||
StringName res;
|
|
||||||
int best_score = 0;
|
|
||||||
|
|
||||||
for (const Ref<Translation> &E : translations) {
|
|
||||||
const Ref<Translation> &t = E;
|
|
||||||
ERR_FAIL_COND_V(t.is_null(), p_message);
|
|
||||||
String l = t->get_locale();
|
|
||||||
|
|
||||||
int score = compare_locales(p_locale, l);
|
|
||||||
if (score > 0 && score >= best_score) {
|
|
||||||
StringName r;
|
|
||||||
if (!plural) {
|
|
||||||
r = t->get_message(p_message, p_context);
|
|
||||||
} else {
|
|
||||||
r = t->get_plural_message(p_message, p_message_plural, p_n, p_context);
|
|
||||||
}
|
|
||||||
if (!r) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
res = r;
|
|
||||||
best_score = score;
|
|
||||||
if (score == 10) {
|
|
||||||
break; // Exact match, skip the rest.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslationServer *TranslationServer::singleton = nullptr;
|
TranslationServer *TranslationServer::singleton = nullptr;
|
||||||
@ -549,6 +472,34 @@ bool TranslationServer::_load_translations(const String &p_from) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslationServer::has_domain(const StringName &p_domain) const {
|
||||||
|
if (p_domain == StringName()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return custom_domains.has(p_domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<TranslationDomain> TranslationServer::get_or_add_domain(const StringName &p_domain) {
|
||||||
|
if (p_domain == StringName()) {
|
||||||
|
return main_domain;
|
||||||
|
}
|
||||||
|
const Ref<TranslationDomain> *domain = custom_domains.getptr(p_domain);
|
||||||
|
if (domain) {
|
||||||
|
if (domain->is_valid()) {
|
||||||
|
return *domain;
|
||||||
|
}
|
||||||
|
ERR_PRINT("Bug (please report): Found invalid translation domain.");
|
||||||
|
}
|
||||||
|
Ref<TranslationDomain> new_domain = memnew(TranslationDomain);
|
||||||
|
custom_domains[p_domain] = new_domain;
|
||||||
|
return new_domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationServer::remove_domain(const StringName &p_domain) {
|
||||||
|
ERR_FAIL_COND_MSG(p_domain == StringName(), "Cannot remove main translation domain.");
|
||||||
|
custom_domains.erase(p_domain);
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationServer::setup() {
|
void TranslationServer::setup() {
|
||||||
String test = GLOBAL_DEF("internationalization/locale/test", "");
|
String test = GLOBAL_DEF("internationalization/locale/test", "");
|
||||||
test = test.strip_edges();
|
test = test.strip_edges();
|
||||||
@ -595,24 +546,11 @@ String TranslationServer::get_tool_locale() {
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
// Look for best matching loaded translation.
|
// Look for best matching loaded translation.
|
||||||
String best_locale = "en";
|
Ref<Translation> t = main_domain->get_translation_object(locale);
|
||||||
int best_score = 0;
|
if (t.is_null()) {
|
||||||
|
return "en";
|
||||||
for (const Ref<Translation> &E : translations) {
|
|
||||||
const Ref<Translation> &t = E;
|
|
||||||
ERR_FAIL_COND_V(t.is_null(), best_locale);
|
|
||||||
String l = t->get_locale();
|
|
||||||
|
|
||||||
int score = compare_locales(locale, l);
|
|
||||||
if (score > 0 && score >= best_score) {
|
|
||||||
best_locale = l;
|
|
||||||
best_score = score;
|
|
||||||
if (score == 10) {
|
|
||||||
break; // Exact match, skip the rest.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return best_locale;
|
return t->get_locale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,6 +863,10 @@ void TranslationServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
|
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
|
||||||
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationServer::get_translation_object);
|
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationServer::get_translation_object);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("has_domain", "domain"), &TranslationServer::has_domain);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_or_add_domain", "domain"), &TranslationServer::get_or_add_domain);
|
||||||
|
ClassDB::bind_method(D_METHOD("remove_domain", "domain"), &TranslationServer::remove_domain);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("clear"), &TranslationServer::clear);
|
ClassDB::bind_method(D_METHOD("clear"), &TranslationServer::clear);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
|
ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
|
||||||
@ -947,5 +889,6 @@ void TranslationServer::load_translations() {
|
|||||||
|
|
||||||
TranslationServer::TranslationServer() {
|
TranslationServer::TranslationServer() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
|
main_domain.instantiate();
|
||||||
init_locale_info();
|
init_locale_info();
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#define TRANSLATION_SERVER_H
|
#define TRANSLATION_SERVER_H
|
||||||
|
|
||||||
#include "core/string/translation.h"
|
#include "core/string/translation.h"
|
||||||
|
#include "core/string/translation_domain.h"
|
||||||
|
|
||||||
class TranslationServer : public Object {
|
class TranslationServer : public Object {
|
||||||
GDCLASS(TranslationServer, Object);
|
GDCLASS(TranslationServer, Object);
|
||||||
@ -39,7 +40,9 @@ class TranslationServer : public Object {
|
|||||||
String locale = "en";
|
String locale = "en";
|
||||||
String fallback;
|
String fallback;
|
||||||
|
|
||||||
HashSet<Ref<Translation>> translations;
|
Ref<TranslationDomain> main_domain;
|
||||||
|
HashMap<StringName, Ref<TranslationDomain>> custom_domains;
|
||||||
|
|
||||||
Ref<Translation> tool_translation;
|
Ref<Translation> tool_translation;
|
||||||
Ref<Translation> property_translation;
|
Ref<Translation> property_translation;
|
||||||
Ref<Translation> doc_translation;
|
Ref<Translation> doc_translation;
|
||||||
@ -70,8 +73,6 @@ class TranslationServer : public Object {
|
|||||||
bool _load_translations(const String &p_from);
|
bool _load_translations(const String &p_from);
|
||||||
String _standardize_locale(const String &p_locale, bool p_add_defaults) const;
|
String _standardize_locale(const String &p_locale, bool p_add_defaults) const;
|
||||||
|
|
||||||
StringName _get_message_from_translations(const StringName &p_message, const StringName &p_context, const String &p_locale, bool plural, const String &p_message_plural = "", int p_n = 0) const;
|
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
struct LocaleScriptInfo {
|
struct LocaleScriptInfo {
|
||||||
@ -99,6 +100,7 @@ public:
|
|||||||
|
|
||||||
void set_locale(const String &p_locale);
|
void set_locale(const String &p_locale);
|
||||||
String get_locale() const;
|
String get_locale() const;
|
||||||
|
String get_fallback_locale() const;
|
||||||
Ref<Translation> get_translation_object(const String &p_locale);
|
Ref<Translation> get_translation_object(const String &p_locale);
|
||||||
|
|
||||||
Vector<String> get_all_languages() const;
|
Vector<String> get_all_languages() const;
|
||||||
@ -144,6 +146,10 @@ public:
|
|||||||
StringName extractable_translate(const StringName &p_message, const StringName &p_context = "") const;
|
StringName extractable_translate(const StringName &p_message, const StringName &p_context = "") const;
|
||||||
StringName extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
|
StringName extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
|
||||||
|
|
||||||
|
bool has_domain(const StringName &p_domain) const;
|
||||||
|
Ref<TranslationDomain> get_or_add_domain(const StringName &p_domain);
|
||||||
|
void remove_domain(const StringName &p_domain);
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
59
doc/classes/TranslationDomain.xml
Normal file
59
doc/classes/TranslationDomain.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<class name="TranslationDomain" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||||
|
<brief_description>
|
||||||
|
A self-contained collection of [Translation] resources.
|
||||||
|
</brief_description>
|
||||||
|
<description>
|
||||||
|
[TranslationDomain] is a self-contained collection of [Translation] resources. Translations can be added to or removed from it.
|
||||||
|
</description>
|
||||||
|
<tutorials>
|
||||||
|
</tutorials>
|
||||||
|
<methods>
|
||||||
|
<method name="add_translation">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="translation" type="Translation" />
|
||||||
|
<description>
|
||||||
|
Adds a translation.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="clear">
|
||||||
|
<return type="void" />
|
||||||
|
<description>
|
||||||
|
Removes all translations.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_translation_object" qualifiers="const">
|
||||||
|
<return type="Translation" />
|
||||||
|
<param index="0" name="locale" type="String" />
|
||||||
|
<description>
|
||||||
|
Returns the [Translation] instance that best matches [param locale]. Returns [code]null[/code] if there are no matches.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="remove_translation">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="translation" type="Translation" />
|
||||||
|
<description>
|
||||||
|
Removes the given translation.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="translate" qualifiers="const">
|
||||||
|
<return type="StringName" />
|
||||||
|
<param index="0" name="message" type="StringName" />
|
||||||
|
<param index="1" name="context" type="StringName" default="&""" />
|
||||||
|
<description>
|
||||||
|
Returns the current locale's translation for the given message and context.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="translate_plural" qualifiers="const">
|
||||||
|
<return type="StringName" />
|
||||||
|
<param index="0" name="message" type="StringName" />
|
||||||
|
<param index="1" name="message_plural" type="StringName" />
|
||||||
|
<param index="2" name="n" type="int" />
|
||||||
|
<param index="3" name="context" type="StringName" default="&""" />
|
||||||
|
<description>
|
||||||
|
Returns the current locale's translation for the given message, plural message and context.
|
||||||
|
The number [param n] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
</class>
|
@ -4,7 +4,8 @@
|
|||||||
The server responsible for language translations.
|
The server responsible for language translations.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
The server that manages all language translations. Translations can be added to or removed from it.
|
The translation server is the API backend that manages all language translations.
|
||||||
|
Translations are stored in [TranslationDomain]s, which can be accessed by name. The most commonly used translation domain is the main translation domain, which always exists and can be accessed using an empty [StringName]. The translation server provides wrapper methods for accessing the master translation domain directly, without having to fetch the main translation domain first.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
|
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
|
||||||
@ -15,13 +16,13 @@
|
|||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="translation" type="Translation" />
|
<param index="0" name="translation" type="Translation" />
|
||||||
<description>
|
<description>
|
||||||
Adds a [Translation] resource.
|
Adds a translation to the main translation domain.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="clear">
|
<method name="clear">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
Clears the server from all translations.
|
Removes all translations from the main translation domain.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="compare_locales" qualifiers="const">
|
<method name="compare_locales" qualifiers="const">
|
||||||
@ -84,6 +85,13 @@
|
|||||||
Returns a locale's language and its variant (e.g. [code]"en_US"[/code] would return [code]"English (United States)"[/code]).
|
Returns a locale's language and its variant (e.g. [code]"en_US"[/code] would return [code]"English (United States)"[/code]).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_or_add_domain">
|
||||||
|
<return type="TranslationDomain" />
|
||||||
|
<param index="0" name="domain" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns the translation domain with the specified name. An empty translation domain will be created and added if it does not exist.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_script_name" qualifiers="const">
|
<method name="get_script_name" qualifiers="const">
|
||||||
<return type="String" />
|
<return type="String" />
|
||||||
<param index="0" name="script" type="String" />
|
<param index="0" name="script" type="String" />
|
||||||
@ -102,8 +110,14 @@
|
|||||||
<return type="Translation" />
|
<return type="Translation" />
|
||||||
<param index="0" name="locale" type="String" />
|
<param index="0" name="locale" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Returns the [Translation] instance based on the [param locale] passed in.
|
Returns the [Translation] instance that best matches [param locale] in the main translation domain. Returns [code]null[/code] if there are no matches.
|
||||||
It will return [code]null[/code] if there is no [Translation] instance that matches the [param locale].
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="has_domain" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="domain" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if a translation domain with the specified name exists.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="pseudolocalize" qualifiers="const">
|
<method name="pseudolocalize" qualifiers="const">
|
||||||
@ -119,11 +133,19 @@
|
|||||||
Reparses the pseudolocalization options and reloads the translation.
|
Reparses the pseudolocalization options and reloads the translation.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="remove_domain">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="domain" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Removes the translation domain with the specified name.
|
||||||
|
[b]Note:[/b] Trying to remove the main translation domain is an error.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="remove_translation">
|
<method name="remove_translation">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="translation" type="Translation" />
|
<param index="0" name="translation" type="Translation" />
|
||||||
<description>
|
<description>
|
||||||
Removes the given translation from the server.
|
Removes the given translation from the main translation domain.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_locale">
|
<method name="set_locale">
|
||||||
@ -146,7 +168,8 @@
|
|||||||
<param index="0" name="message" type="StringName" />
|
<param index="0" name="message" type="StringName" />
|
||||||
<param index="1" name="context" type="StringName" default="&""" />
|
<param index="1" name="context" type="StringName" default="&""" />
|
||||||
<description>
|
<description>
|
||||||
Returns the current locale's translation for the given message (key) and context.
|
Returns the current locale's translation for the given message and context.
|
||||||
|
[b]Note:[/b] This method always uses the main translation domain.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="translate_plural" qualifiers="const">
|
<method name="translate_plural" qualifiers="const">
|
||||||
@ -156,8 +179,9 @@
|
|||||||
<param index="2" name="n" type="int" />
|
<param index="2" name="n" type="int" />
|
||||||
<param index="3" name="context" type="StringName" default="&""" />
|
<param index="3" name="context" type="StringName" default="&""" />
|
||||||
<description>
|
<description>
|
||||||
Returns the current locale's translation for the given message (key), plural message and context.
|
Returns the current locale's translation for the given message, plural message and context.
|
||||||
The number [param n] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
|
The number [param n] is the number or quantity of the plural object. It will be used to guide the translation system to fetch the correct plural form for the selected language.
|
||||||
|
[b]Note:[/b] This method always uses the main translation domain.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
Loading…
Reference in New Issue
Block a user