Skip to content

Commit 25cc9cc

Browse files
committed
Merge pull request #112577 from timothyqiu/multiple-translations-per-locale
Add methods for querying loaded `Translation` instances
2 parents ccf414e + ec860ff commit 25cc9cc

File tree

9 files changed

+257
-82
lines changed

9 files changed

+257
-82
lines changed

core/string/translation_domain.cpp

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "core/string/translation.h"
3434
#include "core/string/translation_server.h"
35+
#include "core/variant/typed_array.h"
3536

3637
struct _character_accent_pair {
3738
const char32_t character;
@@ -252,27 +253,7 @@ PackedStringArray TranslationDomain::get_loaded_locales() const {
252253
return locales;
253254
}
254255

255-
bool TranslationDomain::has_translation_for_locale(const String &p_locale) const {
256-
for (const Ref<Translation> &E : translations) {
257-
if (E->get_locale() == p_locale) {
258-
return true;
259-
}
260-
}
261-
return false;
262-
}
263-
264-
// Translation objects that could potentially be used for the given locale.
265-
HashSet<Ref<Translation>> TranslationDomain::get_potential_translations(const String &p_locale) const {
266-
HashSet<Ref<Translation>> res;
267-
268-
for (const Ref<Translation> &E : translations) {
269-
if (TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale()) > 0) {
270-
res.insert(E);
271-
}
272-
}
273-
return res;
274-
}
275-
256+
#ifndef DISABLE_DEPRECATED
276257
Ref<Translation> TranslationDomain::get_translation_object(const String &p_locale) const {
277258
Ref<Translation> res;
278259
int best_score = 0;
@@ -289,6 +270,7 @@ Ref<Translation> TranslationDomain::get_translation_object(const String &p_local
289270
}
290271
return res;
291272
}
273+
#endif
292274

293275
void TranslationDomain::add_translation(const Ref<Translation> &p_translation) {
294276
ERR_FAIL_COND_MSG(p_translation.is_null(), "Invalid translation provided.");
@@ -303,6 +285,69 @@ void TranslationDomain::clear() {
303285
translations.clear();
304286
}
305287

288+
const HashSet<Ref<Translation>> TranslationDomain::get_translations() const {
289+
return translations;
290+
}
291+
292+
HashSet<Ref<Translation>> TranslationDomain::find_translations(const String &p_locale, bool p_exact) const {
293+
HashSet<Ref<Translation>> res;
294+
if (p_exact) {
295+
for (const Ref<Translation> &E : translations) {
296+
if (E->get_locale() == p_locale) {
297+
res.insert(E);
298+
}
299+
}
300+
} else {
301+
for (const Ref<Translation> &E : translations) {
302+
if (TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale()) > 0) {
303+
res.insert(E);
304+
}
305+
}
306+
}
307+
return res;
308+
}
309+
310+
bool TranslationDomain::has_translation(const Ref<Translation> &p_translation) const {
311+
return translations.has(p_translation);
312+
}
313+
314+
bool TranslationDomain::has_translation_for_locale(const String &p_locale, bool p_exact) const {
315+
if (p_exact) {
316+
for (const Ref<Translation> &E : translations) {
317+
if (E->get_locale() == p_locale) {
318+
return true;
319+
}
320+
}
321+
} else {
322+
for (const Ref<Translation> &E : translations) {
323+
if (TranslationServer::get_singleton()->compare_locales(p_locale, E->get_locale()) > 0) {
324+
return true;
325+
}
326+
}
327+
}
328+
return false;
329+
}
330+
331+
TypedArray<Translation> TranslationDomain::get_translations_bind() const {
332+
TypedArray<Translation> res;
333+
res.reserve(translations.size());
334+
for (const Ref<Translation> &E : translations) {
335+
res.push_back(E);
336+
}
337+
return res;
338+
}
339+
340+
TypedArray<Translation> TranslationDomain::find_translations_bind(const String &p_locale, bool p_exact) const {
341+
const HashSet<Ref<Translation>> &found = find_translations(p_locale, p_exact);
342+
343+
TypedArray<Translation> res;
344+
res.reserve(found.size());
345+
for (const Ref<Translation> &E : found) {
346+
res.push_back(E);
347+
}
348+
return res;
349+
}
350+
306351
StringName TranslationDomain::translate(const StringName &p_message, const StringName &p_context) const {
307352
if (!enabled) {
308353
return p_message;
@@ -459,10 +504,17 @@ StringName TranslationDomain::pseudolocalize(const StringName &p_message) const
459504
}
460505

461506
void TranslationDomain::_bind_methods() {
507+
#ifndef DISABLE_DEPRECATED
462508
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationDomain::get_translation_object);
509+
#endif
510+
463511
ClassDB::bind_method(D_METHOD("add_translation", "translation"), &TranslationDomain::add_translation);
464512
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationDomain::remove_translation);
465513
ClassDB::bind_method(D_METHOD("clear"), &TranslationDomain::clear);
514+
ClassDB::bind_method(D_METHOD("get_translations"), &TranslationDomain::get_translations_bind);
515+
ClassDB::bind_method(D_METHOD("has_translation_for_locale", "locale", "exact"), &TranslationDomain::has_translation_for_locale);
516+
ClassDB::bind_method(D_METHOD("has_translation", "translation"), &TranslationDomain::has_translation);
517+
ClassDB::bind_method(D_METHOD("find_translations", "locale", "exact"), &TranslationDomain::find_translations_bind);
466518
ClassDB::bind_method(D_METHOD("translate", "message", "context"), &TranslationDomain::translate, DEFVAL(StringName()));
467519
ClassDB::bind_method(D_METHOD("translate_plural", "message", "message_plural", "n", "context"), &TranslationDomain::translate_plural, DEFVAL(StringName()));
468520
ClassDB::bind_method(D_METHOD("get_locale_override"), &TranslationDomain::get_locale_override);

core/string/translation_domain.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,25 @@ class TranslationDomain : public RefCounted {
7171
StringName get_message_from_translations(const String &p_locale, const StringName &p_message, const StringName &p_context) const;
7272
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;
7373
PackedStringArray get_loaded_locales() const;
74-
bool has_translation_for_locale(const String &p_locale) const;
75-
HashSet<Ref<Translation>> get_potential_translations(const String &p_locale) const;
7674

7775
public:
76+
// These two methods are public for easier TranslationServer bindings.
77+
TypedArray<Translation> get_translations_bind() const;
78+
TypedArray<Translation> find_translations_bind(const String &p_locale, bool p_exact) const;
79+
80+
#ifndef DISABLE_DEPRECATED
7881
Ref<Translation> get_translation_object(const String &p_locale) const;
82+
#endif
7983

8084
void add_translation(const Ref<Translation> &p_translation);
8185
void remove_translation(const Ref<Translation> &p_translation);
8286
void clear();
8387

88+
bool has_translation(const Ref<Translation> &p_translation) const;
89+
const HashSet<Ref<Translation>> get_translations() const;
90+
HashSet<Ref<Translation>> find_translations(const String &p_locale, bool p_exact) const;
91+
bool has_translation_for_locale(const String &p_locale, bool p_exact) const;
92+
8493
StringName translate(const StringName &p_message, const StringName &p_context) const;
8594
StringName translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const;
8695

core/string/translation_server.cpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "core/os/main_loop.h"
3737
#include "core/os/os.h"
3838
#include "core/string/locales.h"
39+
#include "core/variant/typed_array.h"
3940

4041
void TranslationServer::init_locale_info() {
4142
// Init locale info.
@@ -503,9 +504,27 @@ void TranslationServer::remove_translation(const Ref<Translation> &p_translation
503504
main_domain->remove_translation(p_translation);
504505
}
505506

507+
#ifndef DISABLE_DEPRECATED
506508
Ref<Translation> TranslationServer::get_translation_object(const String &p_locale) {
507509
return main_domain->get_translation_object(p_locale);
508510
}
511+
#endif
512+
513+
TypedArray<Translation> TranslationServer::get_translations() const {
514+
return main_domain->get_translations_bind();
515+
}
516+
517+
TypedArray<Translation> TranslationServer::find_translations(const String &p_locale, bool p_exact) const {
518+
return main_domain->find_translations_bind(p_locale, p_exact);
519+
}
520+
521+
bool TranslationServer::has_translation(const Ref<Translation> &p_translation) const {
522+
return main_domain->has_translation(p_translation);
523+
}
524+
525+
bool TranslationServer::has_translation_for_locale(const String &p_locale, bool p_exact) const {
526+
return main_domain->has_translation_for_locale(p_locale, p_exact);
527+
}
509528

510529
void TranslationServer::clear() {
511530
main_domain->clear();
@@ -576,21 +595,27 @@ void TranslationServer::setup() {
576595
String TranslationServer::get_tool_locale() {
577596
#ifdef TOOLS_ENABLED
578597
if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) {
579-
if (editor_domain->has_translation_for_locale(locale)) {
598+
if (editor_domain->has_translation_for_locale(locale, true)) {
580599
return locale;
581600
}
582601
return "en";
583-
} else {
584-
#else
585-
{
602+
}
586603
#endif
587-
// Look for best matching loaded translation.
588-
Ref<Translation> t = main_domain->get_translation_object(locale);
589-
if (t.is_null()) {
590-
return fallback;
604+
605+
Ref<Translation> res;
606+
int best_score = 0;
607+
608+
for (const Ref<Translation> &E : main_domain->get_translations()) {
609+
int score = TranslationServer::get_singleton()->compare_locales(locale, E->get_locale());
610+
if (score > 0 && score >= best_score) {
611+
res = E;
612+
best_score = score;
613+
if (score == 10) {
614+
return locale; // Exact match.
615+
}
591616
}
592-
return t->get_locale();
593617
}
618+
return res.is_valid() ? res->get_locale() : fallback;
594619
}
595620

596621
bool TranslationServer::is_pseudolocalization_enabled() const {
@@ -676,7 +701,15 @@ void TranslationServer::_bind_methods() {
676701

677702
ClassDB::bind_method(D_METHOD("add_translation", "translation"), &TranslationServer::add_translation);
678703
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
704+
705+
#ifndef DISABLE_DEPRECATED
679706
ClassDB::bind_method(D_METHOD("get_translation_object", "locale"), &TranslationServer::get_translation_object);
707+
#endif
708+
709+
ClassDB::bind_method(D_METHOD("get_translations"), &TranslationServer::get_translations);
710+
ClassDB::bind_method(D_METHOD("find_translations", "locale", "exact"), &TranslationServer::find_translations);
711+
ClassDB::bind_method(D_METHOD("has_translation_for_locale", "locale", "exact"), &TranslationServer::has_translation_for_locale);
712+
ClassDB::bind_method(D_METHOD("has_translation", "translation"), &TranslationServer::has_translation);
680713

681714
ClassDB::bind_method(D_METHOD("has_domain", "domain"), &TranslationServer::has_domain);
682715
ClassDB::bind_method(D_METHOD("get_or_add_domain", "domain"), &TranslationServer::get_or_add_domain);

core/string/translation_server.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,15 @@ class TranslationServer : public Object {
110110
String get_locale() const;
111111
void set_fallback_locale(const String &p_locale);
112112
String get_fallback_locale() const;
113+
114+
#ifndef DISABLE_DEPRECATED
113115
Ref<Translation> get_translation_object(const String &p_locale);
116+
#endif
117+
118+
bool has_translation(const Ref<Translation> &p_translation) const;
119+
TypedArray<Translation> get_translations() const;
120+
TypedArray<Translation> find_translations(const String &p_locale, bool p_exact) const;
121+
bool has_translation_for_locale(const String &p_locale, bool p_exact) const;
114122

115123
Vector<String> get_all_languages() const;
116124
String get_language_name(const String &p_language) const;

doc/classes/TranslationDomain.xml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,48 @@
2323
Removes all translations.
2424
</description>
2525
</method>
26+
<method name="find_translations" qualifiers="const">
27+
<return type="Translation[]" />
28+
<param index="0" name="locale" type="String" />
29+
<param index="1" name="exact" type="bool" />
30+
<description>
31+
Returns the [Translation] instances that match [param locale] (see [method TranslationServer.compare_locales]). If [param exact] is [code]true[/code], only instances whose locale exactly equals [param locale] will be returned.
32+
</description>
33+
</method>
2634
<method name="get_locale_override" qualifiers="const">
2735
<return type="String" />
2836
<description>
2937
Returns the locale override of the domain. Returns an empty string if locale override is disabled.
3038
</description>
3139
</method>
32-
<method name="get_translation_object" qualifiers="const">
40+
<method name="get_translation_object" qualifiers="const" deprecated="Use [method find_translations] instead.">
3341
<return type="Translation" />
3442
<param index="0" name="locale" type="String" />
3543
<description>
3644
Returns the [Translation] instance that best matches [param locale]. Returns [code]null[/code] if there are no matches.
3745
</description>
3846
</method>
47+
<method name="get_translations" qualifiers="const">
48+
<return type="Translation[]" />
49+
<description>
50+
Returns all available [Translation] instances as added by [method add_translation].
51+
</description>
52+
</method>
53+
<method name="has_translation" qualifiers="const">
54+
<return type="bool" />
55+
<param index="0" name="translation" type="Translation" />
56+
<description>
57+
Returns [code]true[/code] if this translation domain contains the given [param translation].
58+
</description>
59+
</method>
60+
<method name="has_translation_for_locale" qualifiers="const">
61+
<return type="bool" />
62+
<param index="0" name="locale" type="String" />
63+
<param index="1" name="exact" type="bool" />
64+
<description>
65+
Returns [code]true[/code] if there are any [Translation] instances that match [param locale] (see [method TranslationServer.compare_locales]). If [param exact] is [code]true[/code], only instances whose locale exactly equals [param locale] are considered.
66+
</description>
67+
</method>
3968
<method name="pseudolocalize" qualifiers="const">
4069
<return type="StringName" />
4170
<param index="0" name="message" type="StringName" />

doc/classes/TranslationServer.xml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
Compares two locales and returns a similarity score between [code]0[/code] (no match) and [code]10[/code] (full match).
3434
</description>
3535
</method>
36+
<method name="find_translations" qualifiers="const">
37+
<return type="Translation[]" />
38+
<param index="0" name="locale" type="String" />
39+
<param index="1" name="exact" type="bool" />
40+
<description>
41+
Returns the [Translation] instances in the main translation domain that match [param locale] (see [method compare_locales]). If [param exact] is [code]true[/code], only instances whose locale exactly equals [param locale] will be returned.
42+
</description>
43+
</method>
3644
<method name="format_number" qualifiers="const">
3745
<return type="String" />
3846
<param index="0" name="number" type="String" />
@@ -128,20 +136,41 @@
128136
[b]Note:[/b] When called from an exported project returns the same value as [method get_locale].
129137
</description>
130138
</method>
131-
<method name="get_translation_object">
139+
<method name="get_translation_object" deprecated="Use [method find_translations] instead.">
132140
<return type="Translation" />
133141
<param index="0" name="locale" type="String" />
134142
<description>
135143
Returns the [Translation] instance that best matches [param locale] in the main translation domain. Returns [code]null[/code] if there are no matches.
136144
</description>
137145
</method>
146+
<method name="get_translations" qualifiers="const">
147+
<return type="Translation[]" />
148+
<description>
149+
Returns all available [Translation] instances in the main translation domain as added by [method add_translation].
150+
</description>
151+
</method>
138152
<method name="has_domain" qualifiers="const">
139153
<return type="bool" />
140154
<param index="0" name="domain" type="StringName" />
141155
<description>
142156
Returns [code]true[/code] if a translation domain with the specified name exists.
143157
</description>
144158
</method>
159+
<method name="has_translation" qualifiers="const">
160+
<return type="bool" />
161+
<param index="0" name="translation" type="Translation" />
162+
<description>
163+
Returns [code]true[/code] if the main translation domain contains the given [param translation].
164+
</description>
165+
</method>
166+
<method name="has_translation_for_locale" qualifiers="const">
167+
<return type="bool" />
168+
<param index="0" name="locale" type="String" />
169+
<param index="1" name="exact" type="bool" />
170+
<description>
171+
Returns [code]true[/code] if there are any [Translation] instances in the main translation domain that match [param locale] (see [method compare_locales]). If [param exact] is [code]true[/code], only instances whose locale exactly equals [param locale] are considered.
172+
</description>
173+
</method>
145174
<method name="parse_number" qualifiers="const">
146175
<return type="String" />
147176
<param index="0" name="number" type="String" />

0 commit comments

Comments
 (0)