1/**************************************************************************/
2/* translation.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef TRANSLATION_H
32#define TRANSLATION_H
33
34#include "core/io/resource.h"
35#include "core/object/gdvirtual.gen.inc"
36
37class Translation : public Resource {
38 GDCLASS(Translation, Resource);
39 OBJ_SAVE_TYPE(Translation);
40 RES_BASE_EXTENSION("translation");
41
42 String locale = "en";
43 HashMap<StringName, StringName> translation_map;
44
45 virtual Vector<String> _get_message_list() const;
46 virtual Dictionary _get_messages() const;
47 virtual void _set_messages(const Dictionary &p_messages);
48
49 void _notify_translation_changed_if_applies();
50
51protected:
52 static void _bind_methods();
53
54 GDVIRTUAL2RC(StringName, _get_message, StringName, StringName);
55 GDVIRTUAL4RC(StringName, _get_plural_message, StringName, StringName, int, StringName);
56
57public:
58 void set_locale(const String &p_locale);
59 _FORCE_INLINE_ String get_locale() const { return locale; }
60
61 virtual void add_message(const StringName &p_src_text, const StringName &p_xlated_text, const StringName &p_context = "");
62 virtual void add_plural_message(const StringName &p_src_text, const Vector<String> &p_plural_xlated_texts, const StringName &p_context = "");
63 virtual StringName get_message(const StringName &p_src_text, const StringName &p_context = "") const; //overridable for other implementations
64 virtual StringName get_plural_message(const StringName &p_src_text, const StringName &p_plural_text, int p_n, const StringName &p_context = "") const;
65 virtual void erase_message(const StringName &p_src_text, const StringName &p_context = "");
66 virtual void get_message_list(List<StringName> *r_messages) const;
67 virtual int get_message_count() const;
68 virtual Vector<String> get_translated_message_list() const;
69
70 Translation() {}
71};
72
73class TranslationServer : public Object {
74 GDCLASS(TranslationServer, Object);
75
76 String locale = "en";
77 String fallback;
78
79 HashSet<Ref<Translation>> translations;
80 Ref<Translation> tool_translation;
81 Ref<Translation> doc_translation;
82 Ref<Translation> property_translation;
83
84 bool enabled = true;
85
86 bool pseudolocalization_enabled = false;
87 bool pseudolocalization_accents_enabled = false;
88 bool pseudolocalization_double_vowels_enabled = false;
89 bool pseudolocalization_fake_bidi_enabled = false;
90 bool pseudolocalization_override_enabled = false;
91 bool pseudolocalization_skip_placeholders_enabled = false;
92 bool editor_pseudolocalization = false;
93 float expansion_ratio = 0.0;
94 String pseudolocalization_prefix;
95 String pseudolocalization_suffix;
96
97 StringName tool_pseudolocalize(const StringName &p_message) const;
98 String get_override_string(String &p_message) const;
99 String double_vowels(String &p_message) const;
100 String replace_with_accented_string(String &p_message) const;
101 String wrap_with_fakebidi_characters(String &p_message) const;
102 String add_padding(const String &p_message, int p_length) const;
103 const char32_t *get_accented_version(char32_t p_character) const;
104 bool is_placeholder(String &p_message, int p_index) const;
105
106 static TranslationServer *singleton;
107 bool _load_translations(const String &p_from);
108 String _standardize_locale(const String &p_locale, bool p_add_defaults) const;
109
110 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;
111
112 static void _bind_methods();
113
114 struct LocaleScriptInfo {
115 String name;
116 String script;
117 String default_country;
118 HashSet<String> supported_countries;
119 };
120 static Vector<LocaleScriptInfo> locale_script_info;
121
122 static HashMap<String, String> language_map;
123 static HashMap<String, String> script_map;
124 static HashMap<String, String> locale_rename_map;
125 static HashMap<String, String> country_name_map;
126 static HashMap<String, String> country_rename_map;
127 static HashMap<String, String> variant_map;
128
129 void init_locale_info();
130
131public:
132 _FORCE_INLINE_ static TranslationServer *get_singleton() { return singleton; }
133
134 void set_enabled(bool p_enabled) { enabled = p_enabled; }
135 _FORCE_INLINE_ bool is_enabled() const { return enabled; }
136
137 void set_locale(const String &p_locale);
138 String get_locale() const;
139 Ref<Translation> get_translation_object(const String &p_locale);
140
141 Vector<String> get_all_languages() const;
142 String get_language_name(const String &p_language) const;
143
144 Vector<String> get_all_scripts() const;
145 String get_script_name(const String &p_script) const;
146
147 Vector<String> get_all_countries() const;
148 String get_country_name(const String &p_country) const;
149
150 String get_locale_name(const String &p_locale) const;
151
152 PackedStringArray get_loaded_locales() const;
153
154 void add_translation(const Ref<Translation> &p_translation);
155 void remove_translation(const Ref<Translation> &p_translation);
156
157 StringName translate(const StringName &p_message, const StringName &p_context = "") const;
158 StringName translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
159
160 StringName pseudolocalize(const StringName &p_message) const;
161
162 bool is_pseudolocalization_enabled() const;
163 void set_pseudolocalization_enabled(bool p_enabled);
164 void set_editor_pseudolocalization(bool p_enabled);
165 void reload_pseudolocalization();
166
167 String standardize_locale(const String &p_locale) const;
168
169 int compare_locales(const String &p_locale_a, const String &p_locale_b) const;
170
171 String get_tool_locale();
172 void set_tool_translation(const Ref<Translation> &p_translation);
173 Ref<Translation> get_tool_translation() const;
174 StringName tool_translate(const StringName &p_message, const StringName &p_context = "") const;
175 StringName tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
176 void set_doc_translation(const Ref<Translation> &p_translation);
177 StringName doc_translate(const StringName &p_message, const StringName &p_context = "") const;
178 StringName doc_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
179 void set_property_translation(const Ref<Translation> &p_translation);
180 StringName property_translate(const StringName &p_message) const;
181
182 void setup();
183
184 void clear();
185
186 void load_translations();
187
188 TranslationServer();
189};
190
191#endif // TRANSLATION_H
192