summaryrefslogtreecommitdiffstats
path: root/core/string
diff options
context:
space:
mode:
Diffstat (limited to 'core/string')
-rw-r--r--core/string/node_path.cpp33
-rw-r--r--core/string/node_path.h2
-rw-r--r--core/string/translation.cpp38
-rw-r--r--core/string/translation.h10
-rw-r--r--core/string/ustring.cpp21
-rw-r--r--core/string/ustring.h37
6 files changed, 117 insertions, 24 deletions
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index 32e4564c5e..8ae2efb787 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -92,6 +92,14 @@ StringName NodePath::get_subname(int p_idx) const {
return data->subpath[p_idx];
}
+int NodePath::get_total_name_count() const {
+ if (!data) {
+ return 0;
+ }
+
+ return data->path.size() + data->subpath.size();
+}
+
void NodePath::unref() {
if (data && data->refcount.unref()) {
memdelete(data);
@@ -229,6 +237,27 @@ StringName NodePath::get_concatenated_subnames() const {
return data->concatenated_subpath;
}
+NodePath NodePath::slice(int p_begin, int p_end) const {
+ const int name_count = get_name_count();
+ const int total_count = get_total_name_count();
+
+ int begin = CLAMP(p_begin, -total_count, total_count);
+ if (begin < 0) {
+ begin += total_count;
+ }
+ int end = CLAMP(p_end, -total_count, total_count);
+ if (end < 0) {
+ end += total_count;
+ }
+ const int sub_begin = MAX(begin - name_count - 1, 0);
+ const int sub_end = MAX(end - name_count, 0);
+
+ const Vector<StringName> names = get_names().slice(begin, end);
+ const Vector<StringName> sub_names = get_subnames().slice(sub_begin, sub_end);
+ const bool absolute = is_absolute() && (begin == 0);
+ return NodePath(names, sub_names, absolute);
+}
+
NodePath NodePath::rel_path_to(const NodePath &p_np) const {
ERR_FAIL_COND_V(!is_absolute(), NodePath());
ERR_FAIL_COND_V(!p_np.is_absolute(), NodePath());
@@ -331,7 +360,7 @@ NodePath NodePath::simplified() const {
}
NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
- if (p_path.size() == 0) {
+ if (p_path.size() == 0 && !p_absolute) {
return;
}
@@ -343,7 +372,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
}
NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
- if (p_path.size() == 0 && p_subpath.size() == 0) {
+ if (p_path.size() == 0 && p_subpath.size() == 0 && !p_absolute) {
return;
}
diff --git a/core/string/node_path.h b/core/string/node_path.h
index 876d69924e..56799839d7 100644
--- a/core/string/node_path.h
+++ b/core/string/node_path.h
@@ -57,10 +57,12 @@ public:
StringName get_name(int p_idx) const;
int get_subname_count() const;
StringName get_subname(int p_idx) const;
+ int get_total_name_count() const;
Vector<StringName> get_names() const;
Vector<StringName> get_subnames() const;
StringName get_concatenated_names() const;
StringName get_concatenated_subnames() const;
+ NodePath slice(int p_begin, int p_end = INT_MAX) const;
NodePath rel_path_to(const NodePath &p_np) const;
NodePath get_as_property_path() const;
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index db0c3f6006..2f25f56eac 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -772,6 +772,20 @@ StringName TranslationServer::tool_translate_plural(const StringName &p_message,
return p_message_plural;
}
+void TranslationServer::set_property_translation(const Ref<Translation> &p_translation) {
+ property_translation = p_translation;
+}
+
+StringName TranslationServer::property_translate(const StringName &p_message) const {
+ if (property_translation.is_valid()) {
+ StringName r = property_translation->get_message(p_message);
+ if (r) {
+ return r;
+ }
+ }
+ return p_message;
+}
+
void TranslationServer::set_doc_translation(const Ref<Translation> &p_translation) {
doc_translation = p_translation;
}
@@ -800,13 +814,13 @@ StringName TranslationServer::doc_translate_plural(const StringName &p_message,
return p_message_plural;
}
-void TranslationServer::set_property_translation(const Ref<Translation> &p_translation) {
- property_translation = p_translation;
+void TranslationServer::set_extractable_translation(const Ref<Translation> &p_translation) {
+ extractable_translation = p_translation;
}
-StringName TranslationServer::property_translate(const StringName &p_message) const {
- if (property_translation.is_valid()) {
- StringName r = property_translation->get_message(p_message);
+StringName TranslationServer::extractable_translate(const StringName &p_message, const StringName &p_context) const {
+ if (extractable_translation.is_valid()) {
+ StringName r = extractable_translation->get_message(p_message, p_context);
if (r) {
return r;
}
@@ -814,6 +828,20 @@ StringName TranslationServer::property_translate(const StringName &p_message) co
return p_message;
}
+StringName TranslationServer::extractable_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
+ if (extractable_translation.is_valid()) {
+ StringName r = extractable_translation->get_plural_message(p_message, p_message_plural, p_n, p_context);
+ if (r) {
+ return r;
+ }
+ }
+
+ if (p_n == 1) {
+ return p_message;
+ }
+ return p_message_plural;
+}
+
bool TranslationServer::is_pseudolocalization_enabled() const {
return pseudolocalization_enabled;
}
diff --git a/core/string/translation.h b/core/string/translation.h
index 4eca37f6be..bd7082dc9d 100644
--- a/core/string/translation.h
+++ b/core/string/translation.h
@@ -82,8 +82,9 @@ class TranslationServer : public Object {
HashSet<Ref<Translation>> translations;
Ref<Translation> tool_translation;
- Ref<Translation> doc_translation;
Ref<Translation> property_translation;
+ Ref<Translation> doc_translation;
+ Ref<Translation> extractable_translation;
bool enabled = true;
@@ -181,11 +182,14 @@ public:
Ref<Translation> get_tool_translation() const;
StringName tool_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName tool_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
+ void set_property_translation(const Ref<Translation> &p_translation);
+ StringName property_translate(const StringName &p_message) const;
void set_doc_translation(const Ref<Translation> &p_translation);
StringName doc_translate(const StringName &p_message, const StringName &p_context = "") const;
StringName doc_translate_plural(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const;
- void set_property_translation(const Ref<Translation> &p_translation);
- StringName property_translate(const StringName &p_message) const;
+ void set_extractable_translation(const Ref<Translation> &p_translation);
+ 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;
void setup();
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index a8a96e6e3f..f4b00255a1 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -5391,9 +5391,7 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
/**
* "Run-time TRanslate". Performs string replacement for internationalization
- * within a running project. The translation string must be supplied by the
- * project, as Godot does not provide built-in translations for `RTR()` strings
- * to keep binary size low. A translation context can optionally be specified to
+ * without the editor. A translation context can optionally be specified to
* disambiguate between identical source strings in translations. When
* placeholders are desired, use `vformat(RTR("Example: %s"), some_string)`.
* If a string mentions a quantity (and may therefore need a dynamic plural form),
@@ -5407,9 +5405,8 @@ String RTR(const String &p_text, const String &p_context) {
String rtr = TranslationServer::get_singleton()->tool_translate(p_text, p_context);
if (rtr.is_empty() || rtr == p_text) {
return TranslationServer::get_singleton()->translate(p_text, p_context);
- } else {
- return rtr;
}
+ return rtr;
}
return p_text;
@@ -5417,13 +5414,10 @@ String RTR(const String &p_text, const String &p_context) {
/**
* "Run-time TRanslate for N items". Performs string replacement for
- * internationalization within a running project. The translation string must be
- * supplied by the project, as Godot does not provide built-in translations for
- * `RTRN()` strings to keep binary size low. A translation context can
- * optionally be specified to disambiguate between identical source strings in
- * translations. Use `RTR()` if the string doesn't need dynamic plural form.
- * When placeholders are desired, use
- * `vformat(RTRN("%d item", "%d items", some_integer), some_integer)`.
+ * internationalization without the editor. A translation context can optionally
+ * be specified to disambiguate between identical source strings in translations.
+ * Use `RTR()` if the string doesn't need dynamic plural form. When placeholders
+ * are desired, use `vformat(RTRN("%d item", "%d items", some_integer), some_integer)`.
* The placeholder must be present in both strings to avoid run-time warnings in `vformat()`.
*
* NOTE: Do not use `RTRN()` in editor-only code (typically within the `editor/`
@@ -5434,9 +5428,8 @@ String RTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String rtr = TranslationServer::get_singleton()->tool_translate_plural(p_text, p_text_plural, p_n, p_context);
if (rtr.is_empty() || rtr == p_text || rtr == p_text_plural) {
return TranslationServer::get_singleton()->translate_plural(p_text, p_text_plural, p_n, p_context);
- } else {
- return rtr;
}
+ return rtr;
}
// Return message based on English plural rule if translation is not possible.
diff --git a/core/string/ustring.h b/core/string/ustring.h
index b1348ceb48..468a015302 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -556,6 +556,43 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St
String RTR(const String &p_text, const String &p_context = "");
String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
+/**
+ * "Extractable TRanslate". Used for strings that can appear inside an exported
+ * project (such as the ones in nodes like `FileDialog`), which are made possible
+ * to add in the POT generator. A translation context can optionally be specified
+ * to disambiguate between identical source strings in translations.
+ * When placeholders are desired, use vformat(ETR("Example: %s"), some_string)`.
+ * If a string mentions a quantity (and may therefore need a dynamic plural form),
+ * use `ETRN()` instead of `ETR()`.
+ *
+ * NOTE: This function is for string extraction only, and will just return the
+ * string it was given. The translation itself should be done internally by nodes
+ * with `atr()` instead.
+ */
+_FORCE_INLINE_ String ETR(const String &p_text, const String &p_context = "") {
+ return p_text;
+}
+
+/**
+ * "Extractable TRanslate for N items". Used for strings that can appear inside an
+ * exported project (such as the ones in nodes like `FileDialog`), which are made
+ * possible to add in the POT generator. A translation context can optionally be
+ * specified to disambiguate between identical source strings in translations.
+ * Use `ETR()` if the string doesn't need dynamic plural form. When placeholders
+ * are desired, use `vformat(ETRN("%d item", "%d items", some_integer), some_integer)`.
+ * The placeholder must be present in both strings to avoid run-time warnings in `vformat()`.
+ *
+ * NOTE: This function is for string extraction only, and will just return the
+ * string it was given. The translation itself should be done internally by nodes
+ * with `atr()` instead.
+ */
+_FORCE_INLINE_ String ETRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "") {
+ if (p_n == 1) {
+ return p_text;
+ }
+ return p_text_plural;
+}
+
bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {