I18n: Translate GN Add > Input > Import menu items

Geometry Nodes' Add > Input > Import menu includes file format items
such as "Standford PLY (.ply)", "STL (.stl)", "Text (.txt)". The
latter needs to be translated because "Text" is a generic format.

These items are declared using a custom function
`node_add_menu.add_node_type`, with a `label` argument. This commit
adds the `label` argument to the function arguments that can be
extracted from specific node declaration functions, and specifies the
argument position for each:

"add_node_type", "add_node_type_with_outputs", "add_simulation_zone",
"add_repeat_zone", "add_foreach_geometry_element_zone",
"add_closure_zone".

There is currently no facility to specify a translation context but it
could be easily added if the need arises.

Most of these functions do not actually declare new, unique messages,
but it could happen in the future. In addition, two messages were
extracted using manual `iface_()` calls, which are no longer needed
after this change.

Reported by Ye Gui in #43295.
This commit is contained in:
Damien Picard
2025-06-30 11:31:45 +02:00
committed by Bastien Montagne
parent 1b499bdffb
commit 0ba83d8958
4 changed files with 26 additions and 12 deletions

View File

@@ -615,6 +615,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
"msgid": ((("msgctxt",), _ctxt_to_ctxt),
),
"message": (),
"label": (),
"heading": ((("heading_ctxt",), _ctxt_to_ctxt),),
"placeholder": ((("text_ctxt",), _ctxt_to_ctxt),),
}
@@ -664,6 +665,16 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
func_translate_args[func_id] = pgettext_variants_args
for sub_func_id in func_ids:
func_translate_args[sub_func_id] = pgettext_variants_args
# Manually add functions from node_add_menu.py.
for func_id, arg_pos in (
("add_node_type", 3),
("add_node_type_with_outputs", 5),
("add_simulation_zone", 1),
("add_repeat_zone", 1),
("add_foreach_geometry_element_zone", 1),
("add_closure_zone", 1),
):
func_translate_args[func_id] = {"label": (arg_pos, {})}
# print(func_translate_args)
# Break recursive nodes look up on some kind of nodes.
@@ -710,7 +721,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
# Skip function if it's marked as not translatable.
do_translate = True
for kw in node.keywords:
if kw.arg == "translate" and not kw.value.value:
if kw.arg == "translate" and not getattr(kw.value, "value", False):
do_translate = False
break
if not do_translate:

View File

@@ -11,7 +11,7 @@ from bpy.app.translations import (
)
def add_node_type(layout, node_type, *, label=None, poll=None, search_weight=0.0):
def add_node_type(layout, node_type, *, label=None, poll=None, search_weight=0.0, translate=True):
"""Add a node type to a menu."""
bl_rna = bpy.types.Node.bl_rna_get_subclass(node_type)
if not label:
@@ -19,7 +19,12 @@ def add_node_type(layout, node_type, *, label=None, poll=None, search_weight=0.0
if poll is True or poll is None:
translation_context = bl_rna.translation_context if bl_rna else i18n_contexts.default
props = layout.operator("node.add_node", text=label, text_ctxt=translation_context, search_weight=search_weight)
props = layout.operator(
"node.add_node",
text=label,
text_ctxt=translation_context,
translate=translate,
search_weight=search_weight)
props.type = node_type
props.use_transform = True
return props
@@ -94,12 +99,11 @@ def add_node_type_with_searchable_enum(context, layout, node_idname, property_na
if getattr(context, "is_menu_search", False):
node_type = getattr(bpy.types, node_idname)
for item in node_type.bl_rna.properties[property_name].enum_items_static:
label = "{}{}".format(node_type.bl_rna.name, item.name)
props = add_node_type(
layout,
node_idname,
label=node_type.bl_rna.name +
"" +
item.name,
label=label,
search_weight=search_weight)
prop = props.settings.add()
prop.name = property_name
@@ -115,7 +119,8 @@ def add_color_mix_node(context, layout):
if getattr(context, "is_menu_search", False):
for item in bpy.types.ShaderNodeMix.bl_rna.properties["blend_type"].enum_items_static:
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=label + "" + item.name)
sublabel = "{}{}".format(label, item.name)
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=sublabel)
prop = props.settings.add()
prop.name = "data_type"
prop.value = "'RGBA'"

View File

@@ -5,7 +5,6 @@
from bpy.types import Menu
from bl_ui import node_add_menu
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,
)
@@ -306,7 +305,7 @@ class NODE_MT_category_compositor_utilities(Menu):
node_add_menu.add_node_type(layout, "CompositorNodeSwitch")
node_add_menu.add_node_type(
layout, "CompositorNodeSwitchView",
label=iface_("Switch Stereo View"))
label="Switch Stereo View")
layout.separator()
node_add_menu.add_node_type(layout, "CompositorNodeRelativeToPixel")
@@ -322,7 +321,7 @@ class NODE_MT_category_compositor_vector(Menu):
node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ")
layout.separator()
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Vector"))
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label="Mix Vector")
ops = props.settings.add()
ops.name = "data_type"
ops.value = "'VECTOR'"

View File

@@ -6,7 +6,6 @@ import bpy
from bpy.types import Menu
from bl_ui import node_add_menu
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,
)
@@ -783,7 +782,7 @@ class NODE_MT_category_GEO_VECTOR(Menu):
node_add_menu.add_node_type(layout, "ShaderNodeVectorRotate")
layout.separator()
node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Vector"))
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label="Mix Vector")
ops = props.settings.add()
ops.name = "data_type"
ops.value = "'VECTOR'"