summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorHaoyu Qiu <timothyqiu32@gmail.com>2021-12-15 23:01:06 +0800
committerHaoyu Qiu <timothyqiu32@gmail.com>2021-12-16 17:49:22 +0800
commite4e4e475f8f1a1d8b82ef7ad636da8536e8c6554 (patch)
tree584197a87c47a265d71a97df3fcd69d8e5a57783 /editor
parentedd3ca45016a4ee8cc5f7c1108e1c71bfa2a86ab (diff)
Make `--doctool` locale aware
* Adds `indent(str)` to `String`: * Indent the (multiline) string with the given indentation. * This method is added in order to keep the translated XML correctly indented. * Moves the loading of tool/doc translation into `editor/editor_translation.{h,cpp}`. * This will be used from both `EditorSettings` and the doc tool from `main`. * Makes use of doc translation when generating XML class references, and setup the translation locale based on `-l LOCALE` CLI parameter. The XML class reference won't be translated if `-l LOCALE` parameter is not given, or when it's `-l en`.
Diffstat (limited to 'editor')
-rw-r--r--editor/doc_tools.cpp42
-rw-r--r--editor/editor_settings.cpp59
-rw-r--r--editor/editor_translation.cpp99
-rw-r--r--editor/editor_translation.h41
4 files changed, 180 insertions, 61 deletions
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 8191b343f7..b9491998a0 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -37,12 +37,42 @@
#include "core/io/dir_access.h"
#include "core/io/marshalls.h"
#include "core/object/script_language.h"
+#include "core/string/translation.h"
#include "core/version.h"
#include "scene/resources/theme.h"
// Used for a hack preserving Mono properties on non-Mono builds.
#include "modules/modules_enabled.gen.h" // For mono.
+static String _get_indent(const String &p_text) {
+ String indent;
+ bool has_text = false;
+ int line_start = 0;
+
+ for (int i = 0; i < p_text.length(); i++) {
+ const char32_t c = p_text[i];
+ if (c == '\n') {
+ line_start = i + 1;
+ } else if (c > 32) {
+ has_text = true;
+ indent = p_text.substr(line_start, i - line_start);
+ break; // Indentation of the first line that has text.
+ }
+ }
+ if (!has_text) {
+ return p_text;
+ }
+ return indent;
+}
+
+static String _translate_doc_string(const String &p_text) {
+ const String indent = _get_indent(p_text);
+ const String message = p_text.dedent().strip_edges();
+ const String translated = TranslationServer::get_singleton()->doc_translate(message, "");
+ // No need to restore stripped edges because they'll be stripped again later.
+ return translated.indent(indent);
+}
+
void DocTools::merge_from(const DocTools &p_data) {
for (KeyValue<String, DocData::ClassDoc> &E : class_list) {
DocData::ClassDoc &c = E.value;
@@ -1289,7 +1319,7 @@ static void _write_method_doc(FileAccess *f, const String &p_name, Vector<DocDat
}
_write_string(f, 3, "<description>");
- _write_string(f, 4, m.description.strip_edges().xml_escape());
+ _write_string(f, 4, _translate_doc_string(m.description).strip_edges().xml_escape());
_write_string(f, 3, "</description>");
_write_string(f, 2, "</" + p_name + ">");
@@ -1327,11 +1357,11 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 0, header);
_write_string(f, 1, "<brief_description>");
- _write_string(f, 2, c.brief_description.strip_edges().xml_escape());
+ _write_string(f, 2, _translate_doc_string(c.brief_description).strip_edges().xml_escape());
_write_string(f, 1, "</brief_description>");
_write_string(f, 1, "<description>");
- _write_string(f, 2, c.description.strip_edges().xml_escape());
+ _write_string(f, 2, _translate_doc_string(c.description).strip_edges().xml_escape());
_write_string(f, 1, "</description>");
_write_string(f, 1, "<tutorials>");
@@ -1366,7 +1396,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" overrides=\"" + p.overrides + "\"" + additional_attributes + " />");
} else {
_write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + additional_attributes + ">");
- _write_string(f, 3, p.description.strip_edges().xml_escape());
+ _write_string(f, 3, _translate_doc_string(p.description).strip_edges().xml_escape());
_write_string(f, 2, "</member>");
}
}
@@ -1392,7 +1422,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"platform-dependent\">");
}
}
- _write_string(f, 3, k.description.strip_edges().xml_escape());
+ _write_string(f, 3, _translate_doc_string(k.description).strip_edges().xml_escape());
_write_string(f, 2, "</constant>");
}
@@ -1412,7 +1442,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 2, "<theme_item name=\"" + ti.name + "\" data_type=\"" + ti.data_type + "\" type=\"" + ti.type + "\">");
}
- _write_string(f, 3, ti.description.strip_edges().xml_escape());
+ _write_string(f, 3, _translate_doc_string(ti.description).strip_edges().xml_escape());
_write_string(f, 2, "</theme_item>");
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 95248b22b5..68ac122e63 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -33,21 +33,17 @@
#include "core/config/project_settings.h"
#include "core/input/input_map.h"
#include "core/io/certs_compressed.gen.h"
-#include "core/io/compression.h"
#include "core/io/config_file.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
-#include "core/io/file_access_memory.h"
#include "core/io/ip.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
-#include "core/io/translation_loader_po.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/version.h"
-#include "editor/doc_translations.gen.h"
#include "editor/editor_node.h"
-#include "editor/editor_translations.gen.h"
+#include "editor/editor_translation.h"
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"
@@ -369,16 +365,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
}
String best;
- EditorTranslationList *etl = _editor_translations;
-
- while (etl->data) {
- const String &locale = etl->lang;
-
+ for (const String &locale : get_editor_locales()) {
// Skip locales which we can't render properly (see above comment).
// Test against language code without regional variants (e.g. ur_PK).
String lang_code = locale.get_slice("_", 0);
if (locales_to_skip.find(lang_code) != -1) {
- etl++;
continue;
}
@@ -392,8 +383,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
if (best.is_empty() && host_lang.begins_with(locale)) {
best = locale;
}
-
- etl++;
}
if (best.is_empty()) {
@@ -922,50 +911,10 @@ void EditorSettings::setup_language() {
return; // Default, nothing to do.
}
// Load editor translation for configured/detected locale.
- EditorTranslationList *etl = _editor_translations;
- while (etl->data) {
- if (etl->lang == lang) {
- Vector<uint8_t> data;
- data.resize(etl->uncomp_size);
- Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE);
-
- FileAccessMemory *fa = memnew(FileAccessMemory);
- fa->open_custom(data.ptr(), data.size());
-
- Ref<Translation> tr = TranslationLoaderPO::load_translation(fa);
-
- if (tr.is_valid()) {
- tr->set_locale(etl->lang);
- TranslationServer::get_singleton()->set_tool_translation(tr);
- break;
- }
- }
-
- etl++;
- }
+ load_editor_translations(lang);
// Load class reference translation.
- DocTranslationList *dtl = _doc_translations;
- while (dtl->data) {
- if (dtl->lang == lang) {
- Vector<uint8_t> data;
- data.resize(dtl->uncomp_size);
- Compression::decompress(data.ptrw(), dtl->uncomp_size, dtl->data, dtl->comp_size, Compression::MODE_DEFLATE);
-
- FileAccessMemory *fa = memnew(FileAccessMemory);
- fa->open_custom(data.ptr(), data.size());
-
- Ref<Translation> tr = TranslationLoaderPO::load_translation(fa);
-
- if (tr.is_valid()) {
- tr->set_locale(dtl->lang);
- TranslationServer::get_singleton()->set_doc_translation(tr);
- break;
- }
- }
-
- dtl++;
- }
+ load_doc_translations(lang);
}
void EditorSettings::setup_network() {
diff --git a/editor/editor_translation.cpp b/editor/editor_translation.cpp
new file mode 100644
index 0000000000..23145c27c8
--- /dev/null
+++ b/editor/editor_translation.cpp
@@ -0,0 +1,99 @@
+/*************************************************************************/
+/* editor_translation.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "editor/editor_translation.h"
+
+#include "core/io/compression.h"
+#include "core/io/file_access_memory.h"
+#include "core/io/translation_loader_po.h"
+#include "editor/doc_translations.gen.h"
+#include "editor/editor_translations.gen.h"
+
+Vector<String> get_editor_locales() {
+ Vector<String> locales;
+
+ EditorTranslationList *etl = _editor_translations;
+ while (etl->data) {
+ const String &locale = etl->lang;
+ locales.push_back(locale);
+
+ etl++;
+ }
+
+ return locales;
+}
+
+void load_editor_translations(const String &p_locale) {
+ EditorTranslationList *etl = _editor_translations;
+ while (etl->data) {
+ if (etl->lang == p_locale) {
+ Vector<uint8_t> data;
+ data.resize(etl->uncomp_size);
+ Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE);
+
+ FileAccessMemory *fa = memnew(FileAccessMemory);
+ fa->open_custom(data.ptr(), data.size());
+
+ Ref<Translation> tr = TranslationLoaderPO::load_translation(fa);
+
+ if (tr.is_valid()) {
+ tr->set_locale(etl->lang);
+ TranslationServer::get_singleton()->set_tool_translation(tr);
+ break;
+ }
+ }
+
+ etl++;
+ }
+}
+
+void load_doc_translations(const String &p_locale) {
+ DocTranslationList *dtl = _doc_translations;
+ while (dtl->data) {
+ if (dtl->lang == p_locale) {
+ Vector<uint8_t> data;
+ data.resize(dtl->uncomp_size);
+ Compression::decompress(data.ptrw(), dtl->uncomp_size, dtl->data, dtl->comp_size, Compression::MODE_DEFLATE);
+
+ FileAccessMemory *fa = memnew(FileAccessMemory);
+ fa->open_custom(data.ptr(), data.size());
+
+ Ref<Translation> tr = TranslationLoaderPO::load_translation(fa);
+
+ if (tr.is_valid()) {
+ tr->set_locale(dtl->lang);
+ TranslationServer::get_singleton()->set_doc_translation(tr);
+ break;
+ }
+ }
+
+ dtl++;
+ }
+}
diff --git a/editor/editor_translation.h b/editor/editor_translation.h
new file mode 100644
index 0000000000..41703f0fd0
--- /dev/null
+++ b/editor/editor_translation.h
@@ -0,0 +1,41 @@
+/*************************************************************************/
+/* editor_translation.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 EDITOR_TRANSLATION_H
+#define EDITOR_TRANSLATION_H
+
+#include "core/string/ustring.h"
+#include "core/templates/vector.h"
+
+Vector<String> get_editor_locales();
+void load_editor_translations(const String &p_locale);
+void load_doc_translations(const String &p_locale);
+
+#endif // EDITOR_TRANSLATION_H