From e6cd9ea087d7bc5e027d67fc328014b604fbe25d Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 8 Feb 2013 14:29:38 +0000 Subject: RNA ui API: fix long-standing annoying glitches when using 'text' property of UI functions: * No context-aware at all. * Always translated (when i18n was enabled). Now, it will try tu use RNA struct/property context if available, unless you specify a context within optional "text_ctxt" parameter. And you can prevent translation by setting 'translate' parameter to False (is True by default). Will clean up code in a later commit (remove PROP_STRING_PY_TRANSLATE flag and related code), and also fix uilist templates to translate no more materials/textures/etc. names! --- source/blender/makesrna/intern/rna_ui_api.c | 201 +++++++++++++++++++++++++--- 1 file changed, 184 insertions(+), 17 deletions(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 787a5d6487e..82776894450 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -32,12 +32,17 @@ #include #include +#include "BLI_utildefines.h" + +#include "BLF_translation.h" + #include "RNA_define.h" #include "RNA_enum_types.h" #include "DNA_screen_types.h" #include "UI_resources.h" +#include "UI_interface.h" #include "UI_interface_icons.h" #include "rna_internal.h" @@ -55,9 +60,33 @@ EnumPropertyItem icon_items[] = { #ifdef RNA_RUNTIME -static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, int icon, - int expand, int slider, int toggle, int icon_only, int event, int full_event, - int emboss, int index) +static const char *rna_translate_ui_text(const char *text, const char *text_ctxt, StructRNA *type, PropertyRNA *prop, + int translate) +{ + if (!text || !text[0] || !translate) { + return text; + } + + /* If a text_ctxt is specified, use it! */ + if (text_ctxt && text_ctxt[0]) { + return CTX_IFACE_(text_ctxt, text); + } + + /* Else, if an RNA type or property is specified, use its context. */ + if (prop) { + return CTX_IFACE_(RNA_property_translation_context(prop), text); + } + if (type) { + return CTX_IFACE_(RNA_struct_translation_context(type), text); + } + + /* Else, no context! */ + return IFACE_(text); +} + +static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, const char *text_ctxt, + int translate, int icon, int expand, int slider, int toggle, int icon_only, int event, + int full_event, int emboss, int index) { PropertyRNA *prop = RNA_struct_find_property(ptr, propname); int flag = 0; @@ -67,6 +96,9 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, return; } + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + flag |= (slider) ? UI_ITEM_R_SLIDER : 0; flag |= (expand) ? UI_ITEM_R_EXPAND : 0; flag |= (toggle) ? UI_ITEM_R_TOGGLE : 0; @@ -78,15 +110,100 @@ static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, uiItemFullR(layout, ptr, prop, index, 0, flag, name, icon); } -static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, int icon, int emboss) +static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, + const char *text_ctxt, int translate, int icon) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + + /* XXX This will search property again :( */ + uiItemMenuEnumR(layout, ptr, propname, name, icon); +} + +static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value, + const char *name, const char *text_ctxt, int translate, int icon) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + + /* XXX This will search property again :( */ + uiItemEnumR_string(layout, ptr, propname, value, name, icon); +} + +static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, + struct PointerRNA *searchptr, const char *searchpropname, + const char *name, const char *text_ctxt, int translate, int icon) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + + /* XXX This will search property again :( */ + uiItemPointerR(layout, ptr, propname, searchptr, searchpropname, name, icon); +} + +static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt, + int translate, int icon, int emboss) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + + if (!ot || !ot->srna) { + RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); + return PointerRNA_NULL; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate); + int flag = UI_ITEM_O_RETURN_PROPS; flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG; - return uiItemFullO(layout, opname, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag); + + return uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag); } -static void rna_uiItemL(uiLayout *layout, const char *name, int icon, int icon_value) +static void rna_uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, const char *name, + const char *text_ctxt, int translate, int icon) { + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + + if (!ot || !ot->srna) { + RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate); + + /* XXX This will search operator again :( */ + uiItemMenuEnumO(layout, opname, propname, name, icon); +} + +static void rna_uiItemL(uiLayout *layout, const char *name, const char *text_ctxt, int translate, + int icon, int icon_value) +{ + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate); + if (icon_value && !icon) { icon = icon_value; } @@ -94,6 +211,49 @@ static void rna_uiItemL(uiLayout *layout, const char *name, int icon, int icon_v uiItemL(layout, name, icon); } +static void rna_uiItemM(uiLayout *layout, bContext *C, const char *menuname, const char *name, const char *text_ctxt, + int translate, int icon) +{ + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, NULL, translate); + + uiItemM(layout, C, menuname, name, icon); +} + +static void rna_uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename, + const char *name, const char *text_ctxt, int translate) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + + /* XXX This will search property again :( */ + uiTemplateAnyID(layout, ptr, propname, proptypename, name); +} + +static void rna_uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *root_ptr, + const char *name, const char *text_ctxt, int translate) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + /* Get translated name (label). */ + name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate); + + /* XXX This will search property again :( */ + uiTemplatePathBuilder(layout, ptr, propname, root_ptr, name); +} + static int rna_ui_get_rnaptr_icon(bContext *C, PointerRNA *ptr_icon) { return UI_rnaptr_icon_get(C, ptr_icon, RNA_struct_ui_icon(ptr_icon->type), FALSE); @@ -192,11 +352,18 @@ static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propna #else +static void api_ui_item_common_text(FunctionRNA *func) +{ + RNA_def_string(func, "text", "", 0, "", "Override automatic text of the item"); + RNA_def_string(func, "text_ctxt", "", 0, "", "Override automatic translation context of the given text"); + RNA_def_boolean(func, "translate", true, "", "Translate the given text, when UI translation is enabled"); +} + static void api_ui_item_common(FunctionRNA *func) { PropertyRNA *prop; - RNA_def_string_py_translate(func, "text", "", 0, "", "Override automatic text of the item"); + api_ui_item_common_text(func); prop = RNA_def_property(func, "icon", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, icon_items); @@ -333,17 +500,17 @@ void RNA_api_ui_layout(StructRNA *srna) func = RNA_def_function(srna, "props_enum", "uiItemsEnumR"); api_ui_item_rna_common(func); - func = RNA_def_function(srna, "prop_menu_enum", "uiItemMenuEnumR"); + func = RNA_def_function(srna, "prop_menu_enum", "rna_uiItemMenuEnumR"); api_ui_item_rna_common(func); api_ui_item_common(func); - func = RNA_def_function(srna, "prop_enum", "uiItemEnumR_string"); + func = RNA_def_function(srna, "prop_enum", "rna_uiItemEnumR_string"); api_ui_item_rna_common(func); parm = RNA_def_string(func, "value", "", 0, "", "Enum property value"); RNA_def_property_flag(parm, PROP_REQUIRED); api_ui_item_common(func); - func = RNA_def_function(srna, "prop_search", "uiItemPointerR"); + func = RNA_def_function(srna, "prop_search", "rna_uiItemPointerR"); api_ui_item_rna_common(func); parm = RNA_def_pointer(func, "search_data", "AnyType", "", "Data from which to take collection to search in"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL); @@ -366,7 +533,7 @@ void RNA_api_ui_layout(StructRNA *srna) parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator"); RNA_def_property_flag(parm, PROP_REQUIRED); - func = RNA_def_function(srna, "operator_menu_enum", "uiItemMenuEnumO"); + func = RNA_def_function(srna, "operator_menu_enum", "rna_uiItemMenuEnumO"); api_ui_item_op(func); /* cant use api_ui_item_op_common because property must come right after */ parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in operator"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -415,13 +582,13 @@ void RNA_api_ui_layout(StructRNA *srna) func = RNA_def_function(srna, "label", "rna_uiItemL"); RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout"); - api_ui_item_common(func); + api_ui_item_common(func); parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item " "(use it e.g. with custom material icons returned by icon()...)"); - func = RNA_def_function(srna, "menu", "uiItemM"); + func = RNA_def_function(srna, "menu", "rna_uiItemM"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); parm = RNA_def_string(func, "menu", "", 0, "", "Identifier of the menu"); api_ui_item_common(func); @@ -458,7 +625,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX); RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX); - func = RNA_def_function(srna, "template_any_ID", "uiTemplateAnyID"); + func = RNA_def_function(srna, "template_any_ID", "rna_uiTemplateAnyID"); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL); parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data"); @@ -466,16 +633,16 @@ void RNA_api_ui_layout(StructRNA *srna) parm = RNA_def_string(func, "type_property", "", 0, "", "Identifier of property in data giving the type of the ID-blocks to use"); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_string_py_translate(func, "text", "", 0, "", "Custom label to display in UI"); + api_ui_item_common_text(func); - func = RNA_def_function(srna, "template_path_builder", "uiTemplatePathBuilder"); + func = RNA_def_function(srna, "template_path_builder", "rna_uiTemplatePathBuilder"); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL); parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "root", "ID", "", "ID-block from which path is evaluated from"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR); - RNA_def_string_py_translate(func, "text", "", 0, "", "Custom label to display in UI"); + api_ui_item_common_text(func); func = RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); -- cgit v1.2.3