diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 087f205944d..44a3127933b 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -164,9 +164,7 @@ EditorAbout::EditorAbout() { dev_sections.push_back(TTR("Project Founders")); dev_sections.push_back(TTR("Lead Developer")); // TRANSLATORS: This refers to a job title. - // The trailing space is used to distinguish with the project list application, - // you do not have to keep it in your translation. - dev_sections.push_back(TTR("Project Manager ")); + dev_sections.push_back(TTR("Project Manager", "Job Title")); dev_sections.push_back(TTR("Developers")); const char *const *dev_src[] = { AUTHORS_FOUNDERS, AUTHORS_LEAD_DEVELOPERS, AUTHORS_PROJECT_MANAGERS, AUTHORS_DEVELOPERS }; diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 7c310087680..49f2f210953 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -83,15 +83,23 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["aabb"] = "AABB"; capitalize_string_remaps["adb"] = "ADB"; capitalize_string_remaps["ao"] = "AO"; + capitalize_string_remaps["arvr"] = "ARVR"; + capitalize_string_remaps["bg"] = "BG"; + capitalize_string_remaps["bp"] = "BP"; + capitalize_string_remaps["bpc"] = "BPC"; capitalize_string_remaps["bptc"] = "BPTC"; capitalize_string_remaps["bvh"] = "BVH"; + capitalize_string_remaps["ca"] = "CA"; + capitalize_string_remaps["cd"] = "CD"; capitalize_string_remaps["cpu"] = "CPU"; capitalize_string_remaps["csg"] = "CSG"; capitalize_string_remaps["db"] = "dB"; capitalize_string_remaps["dof"] = "DoF"; capitalize_string_remaps["dpi"] = "DPI"; + capitalize_string_remaps["dtls"] = "DTLS"; capitalize_string_remaps["etc"] = "ETC"; capitalize_string_remaps["etc2"] = "ETC2"; + capitalize_string_remaps["fft"] = "FFT"; capitalize_string_remaps["fov"] = "FOV"; capitalize_string_remaps["fps"] = "FPS"; capitalize_string_remaps["fs"] = "FS"; @@ -100,29 +108,50 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["gdscript"] = "GDScript"; capitalize_string_remaps["ggx"] = "GGX"; capitalize_string_remaps["gi"] = "GI"; + capitalize_string_remaps["glb"] = "GLB"; capitalize_string_remaps["gles2"] = "GLES2"; capitalize_string_remaps["gles3"] = "GLES3"; capitalize_string_remaps["gpu"] = "GPU"; capitalize_string_remaps["gui"] = "GUI"; capitalize_string_remaps["hdr"] = "HDR"; capitalize_string_remaps["hidpi"] = "hiDPI"; + capitalize_string_remaps["hipass"] = "High-pass"; + capitalize_string_remaps["hsv"] = "HSV"; capitalize_string_remaps["http"] = "HTTP"; + capitalize_string_remaps["id"] = "ID"; capitalize_string_remaps["ik"] = "IK"; + capitalize_string_remaps["igd"] = "IGD"; capitalize_string_remaps["ios"] = "iOS"; + capitalize_string_remaps["iod"] = "IOD"; + capitalize_string_remaps["ip"] = "IP"; + capitalize_string_remaps["ipv6"] = "IPv6"; + capitalize_string_remaps["k1"] = "K1"; + capitalize_string_remaps["k2"] = "K2"; capitalize_string_remaps["kb"] = "(KB)"; // Unit. capitalize_string_remaps["lod"] = "LOD"; + capitalize_string_remaps["lowpass"] = "Low-pass"; capitalize_string_remaps["macos"] = "macOS"; + capitalize_string_remaps["mb"] = "(MB)"; // Unit. + capitalize_string_remaps["ms"] = "(ms)"; // Unit + // Not used for now as AudioEffectReverb has a `msec` property. + //capitalize_string_remaps["msec"] = "(msec)"; // Unit. capitalize_string_remaps["msaa"] = "MSAA"; + capitalize_string_remaps["normalmap"] = "Normal Map"; + capitalize_string_remaps["opengl"] = "OpenGL"; capitalize_string_remaps["opentype"] = "OpenType"; capitalize_string_remaps["openxr"] = "OpenXR"; capitalize_string_remaps["png"] = "PNG"; capitalize_string_remaps["po2"] = "(Power of 2)"; // Unit. capitalize_string_remaps["pvs"] = "PVS"; capitalize_string_remaps["pvrtc"] = "PVRTC"; + capitalize_string_remaps["rid"] = "RID"; + capitalize_string_remaps["rmb"] = "RMB"; + capitalize_string_remaps["rpc"] = "RPC"; capitalize_string_remaps["s3tc"] = "S3TC"; capitalize_string_remaps["sdf"] = "SDF"; capitalize_string_remaps["sdfgi"] = "SDFGI"; capitalize_string_remaps["sdk"] = "SDK"; + capitalize_string_remaps["sec"] = "(sec)"; // Unit. capitalize_string_remaps["ssao"] = "SSAO"; capitalize_string_remaps["ssh"] = "SSH"; capitalize_string_remaps["ssil"] = "SSIL"; @@ -133,6 +162,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["ui"] = "UI"; capitalize_string_remaps["url"] = "URL"; capitalize_string_remaps["urls"] = "URLs"; + capitalize_string_remaps["us"] = "(µs)"; // Unit. capitalize_string_remaps["usec"] = "(µsec)"; // Unit. capitalize_string_remaps["uv"] = "UV"; capitalize_string_remaps["uv1"] = "UV1"; @@ -147,6 +177,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["xr"] = "XR"; capitalize_string_remaps["xy"] = "XY"; capitalize_string_remaps["xz"] = "XZ"; + capitalize_string_remaps["yz"] = "YZ"; } EditorPropertyNameProcessor::~EditorPropertyNameProcessor() { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 4f32e2db3a7..d464697b206 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -2442,7 +2442,7 @@ ProjectManager::ProjectManager() { String cp; cp += 0xA9; // TRANSLATORS: This refers to the application where users manage their Godot projects. - OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager")); + OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager", "Application")); Control *center_box = memnew(Control); center_box->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/translations/extract.py b/editor/translations/extract.py index 299dfbcddb9..e26016d108b 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import enum import fnmatch import os import re @@ -63,16 +64,24 @@ msgstr "" """ +class ExtractType(enum.IntEnum): + TEXT = 1 + PROPERTY_PATH = 2 + GROUP = 3 + + # Regex "(?P(?:[^"\\]|\\.)*)" creates a group named `name` that matches a string. message_patterns = { - re.compile(r'RTR\("(?P(?:[^"\\]|\\.)*)"\)'): False, - re.compile(r'TTR\("(?P(?:[^"\\]|\\.)*)"(?:, "(?P(?:[^"\\]|\\.)*)")?\)'): False, - re.compile(r'TTRC\("(?P(?:[^"\\]|\\.)*)"\)'): False, - re.compile(r'_initial_set\("(?P[^"]+?)",'): True, - re.compile(r'GLOBAL_DEF(?:_RST)?\("(?P[^".]+?)",'): True, - re.compile(r'EDITOR_DEF(?:_RST)?\("(?P[^"]+?)",'): True, - re.compile(r'ADD_PROPERTY\(PropertyInfo\(Variant::[A-Z]+,\s*"(?P[^"]+?)",'): True, - re.compile(r'ADD_GROUP\("(?P[^"]+?)",'): False, + re.compile(r'RTR\("(?P(?:[^"\\]|\\.)*)"\)'): ExtractType.TEXT, + re.compile(r'TTR\("(?P(?:[^"\\]|\\.)*)"(?:, "(?P(?:[^"\\]|\\.)*)")?\)'): ExtractType.TEXT, + re.compile(r'TTRC\("(?P(?:[^"\\]|\\.)*)"\)'): ExtractType.TEXT, + re.compile(r'_initial_set\("(?P[^"]+?)",'): ExtractType.PROPERTY_PATH, + re.compile(r'GLOBAL_DEF(?:_RST)?\("(?P[^".]+?)",'): ExtractType.PROPERTY_PATH, + re.compile(r'EDITOR_DEF(?:_RST)?\("(?P[^"]+?)",'): ExtractType.PROPERTY_PATH, + re.compile( + r'ADD_PROPERTY\(PropertyInfo\(Variant::[_A-Z0-9]+, "(?P[^"]+?)"[,)]' + ): ExtractType.PROPERTY_PATH, + re.compile(r'ADD_GROUP\("(?P[^"]+?)", "(?P[^"]*?)"\)'): ExtractType.GROUP, } @@ -228,6 +237,7 @@ def process_file(f, fname): reading_translator_comment = False is_block_translator_comment = False translator_comment = "" + current_group = "" while l: @@ -246,21 +256,29 @@ def process_file(f, fname): translator_comment = translator_comment[:-1] # Remove extra \n at the end. if not reading_translator_comment: - for pattern, is_property_path in message_patterns.items(): + for pattern, extract_type in message_patterns.items(): for m in pattern.finditer(l): location = os.path.relpath(fname).replace("\\", "/") if line_nb: location += ":" + str(lc) - groups = m.groupdict("") - msg = groups.get("message", "") - msgctx = groups.get("context", "") + captures = m.groupdict("") + msg = captures.get("message", "") + msgctx = captures.get("context", "") - if is_property_path: + if extract_type == ExtractType.TEXT: + _add_message(msg, msgctx, location, translator_comment) + elif extract_type == ExtractType.PROPERTY_PATH: + if current_group: + if msg.startswith(current_group): + msg = msg[len(current_group) :] + else: + current_group = "" for part in msg.split("/"): _add_message(_process_editor_string(part), msgctx, location, translator_comment) - else: + elif extract_type == ExtractType.GROUP: _add_message(msg, msgctx, location, translator_comment) + current_group = captures["prefix"] translator_comment = "" l = f.readline()