summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaoyu Qiu <timothyqiu32@gmail.com>2024-08-15 09:14:41 +0800
committerHaoyu Qiu <timothyqiu32@gmail.com>2024-09-17 13:09:44 +0800
commit68d494e24e2d6704ae95b1d00fa91b440311e8c3 (patch)
tree0216a77378d717873d4fbf7c71f405e0cc02081b
parent48403b5358c11ffff702da82c48464db8c536ee3 (diff)
downloadredot-engine-68d494e24e2d6704ae95b1d00fa91b440311e8c3.tar.gz
Add translation domain
-rw-r--r--core/register_core_types.cpp1
-rw-r--r--core/string/translation_domain.cpp165
-rw-r--r--core/string/translation_domain.h65
-rw-r--r--core/string/translation_server.cpp153
-rw-r--r--core/string/translation_server.h12
-rw-r--r--doc/classes/TranslationDomain.xml59
-rw-r--r--doc/classes/TranslationServer.xml40
7 files changed, 379 insertions, 116 deletions
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index c866ff0415..3a578d01a6 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -233,6 +233,7 @@ void register_core_types() {
GDREGISTER_CLASS(MainLoop);
GDREGISTER_CLASS(Translation);
+ GDREGISTER_CLASS(TranslationDomain);
GDREGISTER_CLASS(OptimizedTranslation);
GDREGISTER_CLASS(UndoRedo);
GDREGISTER_CLASS(TriangleMesh);
diff --git a/core/string/translation_domain.cpp b/core/string/translation_domain.cpp
new file mode 100644
index 0000000000..b44eb40366
--- /dev/null
+++ b/core/string/translation_domain.cpp
@@ -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() {
+}
diff --git a/core/string/translation_domain.h b/core/string/translation_domain.h
new file mode 100644
index 0000000000..6139967217
--- /dev/null
+++ b/core/string/translation_domain.h
@@ -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
diff --git a/core/string/translation_server.cpp b/core/string/translation_server.cpp
index d4aa152340..ae822b43fb 100644
--- a/core/string/translation_server.cpp
+++ b/core/string/translation_server.cpp
@@ -404,69 +404,36 @@ String TranslationServer::get_locale() const {
return locale;
}
-PackedStringArray TranslationServer::get_loaded_locales() const {
- PackedStringArray 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);
- }
+String TranslationServer::get_fallback_locale() const {
+ return fallback;
+}
- return locales;
+PackedStringArray TranslationServer::get_loaded_locales() const {
+ return main_domain->get_loaded_locales();
}
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) {
- translations.erase(p_translation);
+ main_domain->remove_translation(p_translation);
}
Ref<Translation> TranslationServer::get_translation_object(const String &p_locale) {
- Ref<Translation> res;
- 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;
+ return main_domain->get_translation_object(p_locale);
}
void TranslationServer::clear() {
- translations.clear();
+ main_domain->clear();
}
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) {
return p_message;
}
- StringName res = _get_message_from_translations(p_message, p_context, locale, false);
-
- 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;
- }
-
+ const StringName res = main_domain->translate(p_message, p_context);
return pseudolocalization_enabled ? pseudolocalize(res) : res;
}
@@ -478,51 +445,7 @@ StringName TranslationServer::translate_plural(const StringName &p_message, cons
return p_message_plural;
}
- StringName res = _get_message_from_translations(p_message, p_context, locale, true, p_message_plural, p_n);
-
- 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;
+ return main_domain->translate_plural(p_message, p_message_plural, p_n, p_context);
}
TranslationServer *TranslationServer::singleton = nullptr;
@@ -549,6 +472,34 @@ bool TranslationServer::_load_translations(const String &p_from) {
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() {
String test = GLOBAL_DEF("internationalization/locale/test", "");
test = test.strip_edges();
@@ -595,24 +546,11 @@ String TranslationServer::get_tool_locale() {
{
#endif
// Look for best matching loaded translation.
- String best_locale = "en";
- int best_score = 0;
-
- 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.
- }
- }
+ Ref<Translation> t = main_domain->get_translation_object(locale);
+ if (t.is_null()) {
+ return "en";
}
- 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("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("get_loaded_locales"), &TranslationServer::get_loaded_locales);
@@ -947,5 +889,6 @@ void TranslationServer::load_translations() {
TranslationServer::TranslationServer() {
singleton = this;
+ main_domain.instantiate();
init_locale_info();
}
diff --git a/core/string/translation_server.h b/core/string/translation_server.h
index bb285ab19c..1271abec99 100644
--- a/core/string/translation_server.h
+++ b/core/string/translation_server.h
@@ -32,6 +32,7 @@
#define TRANSLATION_SERVER_H
#include "core/string/translation.h"
+#include "core/string/translation_domain.h"
class TranslationServer : public Object {
GDCLASS(TranslationServer, Object);
@@ -39,7 +40,9 @@ class TranslationServer : public Object {
String locale = "en";
String fallback;
- HashSet<Ref<Translation>> translations;
+ Ref<TranslationDomain> main_domain;
+ HashMap<StringName, Ref<TranslationDomain>> custom_domains;
+
Ref<Translation> tool_translation;
Ref<Translation> property_translation;
Ref<Translation> doc_translation;
@@ -70,8 +73,6 @@ class TranslationServer : public Object {
bool _load_translations(const String &p_from);
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();
struct LocaleScriptInfo {
@@ -99,6 +100,7 @@ public:
void set_locale(const String &p_locale);
String get_locale() const;
+ String get_fallback_locale() const;
Ref<Translation> get_translation_object(const String &p_locale);
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_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 clear();
diff --git a/doc/classes/TranslationDomain.xml b/doc/classes/TranslationDomain.xml
new file mode 100644
index 0000000000..8079685885
--- /dev/null
+++ b/doc/classes/TranslationDomain.xml
@@ -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="&amp;&quot;&quot;" />
+ <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="&amp;&quot;&quot;" />
+ <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>
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index db1a65278c..39afa2c0d2 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -4,7 +4,8 @@
The server responsible for language translations.
</brief_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>
<tutorials>
<link title="Internationalizing games">$DOCS_URL/tutorials/i18n/internationalizing_games.html</link>
@@ -15,13 +16,13 @@
<return type="void" />
<param index="0" name="translation" type="Translation" />
<description>
- Adds a [Translation] resource.
+ Adds a translation to the main translation domain.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
- Clears the server from all translations.
+ Removes all translations from the main translation domain.
</description>
</method>
<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]).
</description>
</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">
<return type="String" />
<param index="0" name="script" type="String" />
@@ -102,8 +110,14 @@
<return type="Translation" />
<param index="0" name="locale" type="String" />
<description>
- Returns the [Translation] instance based on the [param locale] passed in.
- It will return [code]null[/code] if there is no [Translation] instance that matches the [param locale].
+ Returns the [Translation] instance that best matches [param locale] in the main translation domain. Returns [code]null[/code] if there are no matches.
+ </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>
</method>
<method name="pseudolocalize" qualifiers="const">
@@ -119,11 +133,19 @@
Reparses the pseudolocalization options and reloads the translation.
</description>
</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">
<return type="void" />
<param index="0" name="translation" type="Translation" />
<description>
- Removes the given translation from the server.
+ Removes the given translation from the main translation domain.
</description>
</method>
<method name="set_locale">
@@ -146,7 +168,8 @@
<param index="0" name="message" type="StringName" />
<param index="1" name="context" type="StringName" default="&amp;&quot;&quot;" />
<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>
</method>
<method name="translate_plural" qualifiers="const">
@@ -156,8 +179,9 @@
<param index="2" name="n" type="int" />
<param index="3" name="context" type="StringName" default="&amp;&quot;&quot;" />
<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.
+ [b]Note:[/b] This method always uses the main translation domain.
</description>
</method>
</methods>