Selaa lähdekoodia

Allow configuring which translation domain Object.tr uses

Haoyu Qiu 1 vuosi sitten
vanhempi
commit
c5d147b9b5
6 muutettua tiedostoa jossa 94 lisäystä ja 2 poistoa
  1. 14 2
      core/object/object.cpp
  2. 5 0
      core/object/object.h
  3. 7 0
      doc/classes/Node.xml
  4. 13 0
      doc/classes/Object.xml
  5. 47 0
      scene/main/node.cpp
  6. 8 0
      scene/main/node.h

+ 14 - 2
core/object/object.cpp

@@ -1527,6 +1527,14 @@ void Object::initialize_class() {
 	initialized = true;
 	initialized = true;
 }
 }
 
 
+StringName Object::get_translation_domain() const {
+	return _translation_domain;
+}
+
+void Object::set_translation_domain(const StringName &p_domain) {
+	_translation_domain = p_domain;
+}
+
 String Object::tr(const StringName &p_message, const StringName &p_context) const {
 String Object::tr(const StringName &p_message, const StringName &p_context) const {
 	if (!_can_translate || !TranslationServer::get_singleton()) {
 	if (!_can_translate || !TranslationServer::get_singleton()) {
 		return p_message;
 		return p_message;
@@ -1541,7 +1549,8 @@ String Object::tr(const StringName &p_message, const StringName &p_context) cons
 		return TranslationServer::get_singleton()->tool_translate(p_message, p_context);
 		return TranslationServer::get_singleton()->tool_translate(p_message, p_context);
 	}
 	}
 
 
-	return TranslationServer::get_singleton()->translate(p_message, p_context);
+	const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain(get_translation_domain());
+	return domain->translate(p_message, p_context);
 }
 }
 
 
 String Object::tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
 String Object::tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context) const {
@@ -1562,7 +1571,8 @@ String Object::tr_n(const StringName &p_message, const StringName &p_message_plu
 		return TranslationServer::get_singleton()->tool_translate_plural(p_message, p_message_plural, p_n, p_context);
 		return TranslationServer::get_singleton()->tool_translate_plural(p_message, p_message_plural, p_n, p_context);
 	}
 	}
 
 
-	return TranslationServer::get_singleton()->translate_plural(p_message, p_message_plural, p_n, p_context);
+	const Ref<TranslationDomain> domain = TranslationServer::get_singleton()->get_or_add_domain(get_translation_domain());
+	return domain->translate_plural(p_message, p_message_plural, p_n, p_context);
 }
 }
 
 
 void Object::_clear_internal_resource_paths(const Variant &p_var) {
 void Object::_clear_internal_resource_paths(const Variant &p_var) {
@@ -1714,6 +1724,8 @@ void Object::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages);
 	ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages);
 	ClassDB::bind_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(StringName()));
 	ClassDB::bind_method(D_METHOD("tr", "message", "context"), &Object::tr, DEFVAL(StringName()));
 	ClassDB::bind_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(StringName()));
 	ClassDB::bind_method(D_METHOD("tr_n", "message", "plural_message", "n", "context"), &Object::tr_n, DEFVAL(StringName()));
+	ClassDB::bind_method(D_METHOD("get_translation_domain"), &Object::get_translation_domain);
+	ClassDB::bind_method(D_METHOD("set_translation_domain", "domain"), &Object::set_translation_domain);
 
 
 	ClassDB::bind_method(D_METHOD("is_queued_for_deletion"), &Object::is_queued_for_deletion);
 	ClassDB::bind_method(D_METHOD("is_queued_for_deletion"), &Object::is_queued_for_deletion);
 	ClassDB::bind_method(D_METHOD("cancel_free"), &Object::cancel_free);
 	ClassDB::bind_method(D_METHOD("cancel_free"), &Object::cancel_free);

+ 5 - 0
core/object/object.h

@@ -665,6 +665,8 @@ private:
 	Object(bool p_reference);
 	Object(bool p_reference);
 
 
 protected:
 protected:
+	StringName _translation_domain;
+
 	_FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) {
 	_FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) {
 		bool can_die = true;
 		bool can_die = true;
 		if (_instance_bindings) {
 		if (_instance_bindings) {
@@ -954,6 +956,9 @@ public:
 	_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; }
 	_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; }
 	_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
 	_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
 
 
+	virtual StringName get_translation_domain() const;
+	virtual void set_translation_domain(const StringName &p_domain);
+
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 	virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 	virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
 	void editor_set_section_unfold(const String &p_section, bool p_unfolded);
 	void editor_set_section_unfold(const String &p_section, bool p_unfolded);

+ 7 - 0
doc/classes/Node.xml

@@ -973,6 +973,13 @@
 				Similar to [method call_thread_safe], but for setting properties.
 				Similar to [method call_thread_safe], but for setting properties.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="set_translation_domain_inherited">
+			<return type="void" />
+			<description>
+				Makes this node inherit the translation domain from its parent node. If this node has no parent, the main translation domain will be used.
+				This is the default behavior for all nodes. Calling [method Object.set_translation_domain] disables this behavior.
+			</description>
+		</method>
 		<method name="update_configuration_warnings">
 		<method name="update_configuration_warnings">
 			<return type="void" />
 			<return type="void" />
 			<description>
 			<description>

+ 13 - 0
doc/classes/Object.xml

@@ -818,6 +818,12 @@
 				[b]Note:[/b] Due of the implementation, each [Dictionary] is formatted very similarly to the returned values of [method get_method_list].
 				[b]Note:[/b] Due of the implementation, each [Dictionary] is formatted very similarly to the returned values of [method get_method_list].
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_translation_domain" qualifiers="const">
+			<return type="StringName" />
+			<description>
+				Returns the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer].
+			</description>
+		</method>
 		<method name="has_meta" qualifiers="const">
 		<method name="has_meta" qualifiers="const">
 			<return type="bool" />
 			<return type="bool" />
 			<param index="0" name="name" type="StringName" />
 			<param index="0" name="name" type="StringName" />
@@ -1070,6 +1076,13 @@
 				If a script already exists, its instance is detached, and its property values and state are lost. Built-in property values are still kept.
 				If a script already exists, its instance is detached, and its property values and state are lost. Built-in property values are still kept.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="set_translation_domain">
+			<return type="void" />
+			<param index="0" name="domain" type="StringName" />
+			<description>
+				Sets the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer].
+			</description>
+		</method>
 		<method name="to_string">
 		<method name="to_string">
 			<return type="String" />
 			<return type="String" />
 			<description>
 			<description>

+ 47 - 0
scene/main/node.cpp

@@ -111,6 +111,7 @@ void Node::_notification(int p_notification) {
 				data.auto_translate_mode = AUTO_TRANSLATE_MODE_ALWAYS;
 				data.auto_translate_mode = AUTO_TRANSLATE_MODE_ALWAYS;
 			}
 			}
 			data.is_auto_translate_dirty = true;
 			data.is_auto_translate_dirty = true;
+			data.is_translation_domain_dirty = true;
 
 
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 			// Don't translate UI elements when they're being edited.
 			// Don't translate UI elements when they're being edited.
@@ -1320,6 +1321,51 @@ bool Node::can_auto_translate() const {
 	return data.is_auto_translating;
 	return data.is_auto_translating;
 }
 }
 
 
+StringName Node::get_translation_domain() const {
+	ERR_READ_THREAD_GUARD_V(StringName());
+
+	if (data.is_translation_domain_inherited && data.is_translation_domain_dirty) {
+		const_cast<Node *>(this)->_translation_domain = data.parent ? data.parent->get_translation_domain() : StringName();
+		data.is_translation_domain_dirty = false;
+	}
+	return _translation_domain;
+}
+
+void Node::set_translation_domain(const StringName &p_domain) {
+	ERR_THREAD_GUARD
+
+	if (!data.is_translation_domain_inherited && _translation_domain == p_domain) {
+		return;
+	}
+
+	_translation_domain = p_domain;
+	data.is_translation_domain_inherited = false;
+	data.is_translation_domain_dirty = false;
+	_propagate_translation_domain_dirty();
+}
+
+void Node::set_translation_domain_inherited() {
+	ERR_THREAD_GUARD
+
+	if (data.is_translation_domain_inherited) {
+		return;
+	}
+	data.is_translation_domain_inherited = true;
+	data.is_translation_domain_dirty = true;
+	_propagate_translation_domain_dirty();
+}
+
+void Node::_propagate_translation_domain_dirty() {
+	for (KeyValue<StringName, Node *> &K : data.children) {
+		Node *child = K.value;
+		if (child->data.is_translation_domain_inherited) {
+			child->data.is_translation_domain_dirty = true;
+			child->_propagate_translation_domain_dirty();
+		}
+	}
+	notification(NOTIFICATION_TRANSLATION_CHANGED);
+}
+
 StringName Node::get_name() const {
 StringName Node::get_name() const {
 	return data.name;
 	return data.name;
 }
 }
@@ -3610,6 +3656,7 @@ void Node::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
 	ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
 	ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
 	ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
+	ClassDB::bind_method(D_METHOD("set_translation_domain_inherited"), &Node::set_translation_domain_inherited);
 
 
 	ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
 	ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
 	ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
 	ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);

+ 8 - 0
scene/main/node.h

@@ -255,6 +255,9 @@ private:
 		mutable bool is_auto_translating = true;
 		mutable bool is_auto_translating = true;
 		mutable bool is_auto_translate_dirty = true;
 		mutable bool is_auto_translate_dirty = true;
 
 
+		mutable bool is_translation_domain_inherited = true;
+		mutable bool is_translation_domain_dirty = true;
+
 		mutable NodePath *path_cache = nullptr;
 		mutable NodePath *path_cache = nullptr;
 
 
 	} data;
 	} data;
@@ -281,6 +284,7 @@ private:
 	void _propagate_physics_interpolation_reset_requested(bool p_requested);
 	void _propagate_physics_interpolation_reset_requested(bool p_requested);
 	void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification);
 	void _propagate_process_owner(Node *p_owner, int p_pause_notification, int p_enabled_notification);
 	void _propagate_groups_dirty();
 	void _propagate_groups_dirty();
+	void _propagate_translation_domain_dirty();
 	Array _get_node_and_resource(const NodePath &p_path);
 	Array _get_node_and_resource(const NodePath &p_path);
 
 
 	void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
 	void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const;
@@ -735,6 +739,10 @@ public:
 	AutoTranslateMode get_auto_translate_mode() const;
 	AutoTranslateMode get_auto_translate_mode() const;
 	bool can_auto_translate() const;
 	bool can_auto_translate() const;
 
 
+	virtual StringName get_translation_domain() const override;
+	virtual void set_translation_domain(const StringName &p_domain) override;
+	void set_translation_domain_inherited();
+
 	_FORCE_INLINE_ String atr(const String p_message, const StringName p_context = "") const { return can_auto_translate() ? tr(p_message, p_context) : p_message; }
 	_FORCE_INLINE_ String atr(const String p_message, const StringName p_context = "") const { return can_auto_translate() ? tr(p_message, p_context) : p_message; }
 	_FORCE_INLINE_ String atr_n(const String p_message, const StringName &p_message_plural, int p_n, const StringName p_context = "") const { return can_auto_translate() ? tr_n(p_message, p_message_plural, p_n, p_context) : p_message; }
 	_FORCE_INLINE_ String atr_n(const String p_message, const StringName &p_message_plural, int p_n, const StringName p_context = "") const { return can_auto_translate() ? tr_n(p_message, p_message_plural, p_n, p_context) : p_message; }