Make some enhancements to the POT generation

This commit is contained in:
Michael Alexsander 2021-08-01 02:53:36 -03:00
parent 29a3300c6a
commit ee4b0108e0
6 changed files with 58 additions and 19 deletions

View File

@ -921,7 +921,8 @@
Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top offset updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true">
Toggles if any text should automatically change to its translated version depending on the current locale.
Toggles if any text should automatically change to its translated version depending on the current locale. Note that this will not affect any internal nodes (e.g. the popup of a [MenuButton]).
Also decides if the node's strings should be parsed for POT generation.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0">
The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals.

View File

@ -31,6 +31,7 @@
#include "packed_scene_translation_parser_plugin.h"
#include "core/io/resource_loader.h"
#include "scene/gui/option_button.h"
#include "scene/resources/packed_scene.h"
void PackedSceneEditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_extensions) const {
@ -50,21 +51,31 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
Ref<SceneState> state = Ref<PackedScene>(loaded_res)->get_state();
Vector<String> parsed_strings;
String property_name;
Variant property_value;
for (int i = 0; i < state->get_node_count(); i++) {
if (!ClassDB::is_parent_class(state->get_node_type(i), "Control") && !ClassDB::is_parent_class(state->get_node_type(i), "Viewport")) {
String node_type = state->get_node_type(i);
if (!ClassDB::is_parent_class(node_type, "Control") && !ClassDB::is_parent_class(node_type, "Window")) {
continue;
}
// Find the `auto_translate` property, and abort the string parsing of the node if disabled.
bool auto_translating = true;
for (int j = 0; j < state->get_node_property_count(i); j++) {
if (state->get_node_property_name(i, j) == "auto_translate" && (bool)state->get_node_property_value(i, j) == false) {
auto_translating = false;
break;
}
}
if (!auto_translating) {
continue;
}
for (int j = 0; j < state->get_node_property_count(i); j++) {
property_name = state->get_node_property_name(i, j);
if (!lookup_properties.has(property_name)) {
String property_name = state->get_node_property_name(i, j);
if (!lookup_properties.has(property_name) || (exception_list.has(node_type) && exception_list[node_type].has(property_name))) {
continue;
}
property_value = state->get_node_property_value(i, j);
Variant property_value = state->get_node_property_value(i, j);
if (property_name == "script" && property_value.get_type() == Variant::OBJECT && !property_value.is_null()) {
// Parse built-in script.
Ref<Script> s = Object::cast_to<Script>(property_value);
@ -76,7 +87,16 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
parsed_strings.append_array(temp);
r_ids_ctx_plural->append_array(ids_context_plural);
}
} else if (property_name == "filters") {
} else if ((node_type == "MenuButton" || node_type == "OptionButton") && property_name == "items") {
Vector<String> str_values = property_value;
int incr_value = node_type == "MenuButton" ? PopupMenu::ITEM_PROPERTY_SIZE : OptionButton::ITEM_PROPERTY_SIZE;
for (int k = 0; k < str_values.size(); k += incr_value) {
String desc = str_values[k].get_slice(";", 1).strip_edges();
if (!desc.is_empty()) {
parsed_strings.push_back(desc);
}
}
} else if (node_type == "FileDialog" && property_name == "filters") {
// Extract FileDialog's filters property with values in format "*.png ; PNG Images","*.gd ; GDScript Files".
Vector<String> str_values = property_value;
for (int k = 0; k < str_values.size(); k++) {
@ -105,12 +125,17 @@ PackedSceneEditorTranslationParserPlugin::PackedSceneEditorTranslationParserPlug
lookup_properties.insert("text");
lookup_properties.insert("hint_tooltip");
lookup_properties.insert("placeholder_text");
lookup_properties.insert("items");
lookup_properties.insert("title");
lookup_properties.insert("dialog_text");
lookup_properties.insert("filters");
lookup_properties.insert("script");
//Add exception list (to prevent false positives)
//line edit, text edit, richtextlabel
//Set<String> exception_list;
//exception_list.insert("RichTextLabel");
// Exception list (to prevent false positives).
exception_list.insert("LineEdit", Vector<StringName>());
exception_list["LineEdit"].append("text");
exception_list.insert("TextEdit", Vector<StringName>());
exception_list["TextEdit"].append("text");
exception_list.insert("CodeEdit", Vector<StringName>());
exception_list["CodeEdit"].append("text");
}

View File

@ -37,7 +37,9 @@ class PackedSceneEditorTranslationParserPlugin : public EditorTranslationParserP
GDCLASS(PackedSceneEditorTranslationParserPlugin, EditorTranslationParserPlugin);
// Scene Node's properties that contain translation strings.
Set<String> lookup_properties;
Set<StringName> lookup_properties;
// Properties from specific Nodes that should be ignored.
Map<StringName, Vector<StringName>> exception_list;
public:
virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) override;

View File

@ -108,7 +108,6 @@ void POTGenerator::_write_to_pot(const String &p_file) {
const String header =
"# LANGUAGE translation for " + project_name + " for the following files:\n" + extracted_files +
"#\n"
"#\n"
"# FIRST AUTHOR < EMAIL @ADDRESS>, YEAR.\n"
"#\n"
"#, fuzzy\n"
@ -116,8 +115,9 @@ void POTGenerator::_write_to_pot(const String &p_file) {
"msgstr \"\"\n"
"\"Project-Id-Version: " +
project_name + "\\n\"\n"
"\"MIME-Version: 1.0\\n\"\n"
"\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
"\"Content-Transfer-Encoding: 8-bit\\n\"\n\n";
"\"Content-Transfer-Encoding: 8-bit\\n\"\n";
file->store_string(header);
@ -129,6 +129,9 @@ void POTGenerator::_write_to_pot(const String &p_file) {
String plural = v_msgid_data[i].plural;
const Set<String> &locations = v_msgid_data[i].locations;
// Put the blank line at the start, to avoid a double at the end when closing the file.
file->store_line("");
// Write file locations.
for (Set<String>::Element *E = locations.front(); E; E = E->next()) {
file->store_line("#: " + E->get().trim_prefix("res://"));
@ -142,13 +145,13 @@ void POTGenerator::_write_to_pot(const String &p_file) {
// Write msgid.
_write_msgid(file, msgid, false);
// Write msgid_plural
// Write msgid_plural.
if (!plural.is_empty()) {
_write_msgid(file, plural, true);
file->store_line("msgstr[0] \"\"");
file->store_line("msgstr[1] \"\"\n");
file->store_line("msgstr[1] \"\"");
} else {
file->store_line("msgstr \"\"\n");
file->store_line("msgstr \"\"");
}
}
}

View File

@ -56,6 +56,10 @@ protected:
static void _bind_methods();
public:
// ATTENTION: This is used by the POT generator's scene parser. If the number of properties returned by `_get_items()` ever changes,
// this value should be updated to reflect the new size.
static const int ITEM_PROPERTY_SIZE = 5;
void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1);
void add_item(const String &p_label, int p_id = -1);

View File

@ -144,6 +144,10 @@ protected:
static void _bind_methods();
public:
// ATTENTION: This is used by the POT generator's scene parser. If the number of properties returned by `_get_items()` ever changes,
// this value should be updated to reflect the new size.
static const int ITEM_PROPERTY_SIZE = 10;
void add_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0);
void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0);
void add_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0);