I18n users request: add the ability to use a translated name for newly added/created...
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 20 Mar 2013 18:42:09 +0000 (18:42 +0000)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 20 Mar 2013 18:42:09 +0000 (18:42 +0000)
This simply adds a third "translation type" (in addition to iface and tip), "new data", with relevant user settings flag and helper funcs/macros (and py api).

Currently implemented name translation when adding new objects, as well as modifiers and constraints, will add the others (cd layers, scenes, perhaps nodes [though I think they do not need this], etc.) later.

13 files changed:
release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenfont/BLF_translation.h
source/blender/blenfont/intern/blf_translation.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/editors/curve/editcurve.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/object/object_add.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c
source/blender/python/intern/bpy_app_translations.c

index f33b8516ae62c4071cbd36da4fce35523caf5c22..2742e6d8155701b046a1ed9d9393c2d5c3e63cbd 100644 (file)
@@ -528,9 +528,11 @@ class USERPREF_PT_system(Panel):
             if system.use_international_fonts:
                 column.prop(system, "language")
                 row = column.row()
-                row.label(text="Translate:")
-                row.prop(system, "use_translate_interface", text="Interface")
-                row.prop(system, "use_translate_tooltips", text="Tooltips")
+                row.label(text="Translate:", text_ctxt=bpy.app.translations.contexts.id_windowmanager)
+                row = column.row(True)
+                row.prop(system, "use_translate_interface", text="Interface", toggle=True)
+                row.prop(system, "use_translate_tooltips", text="Tooltips", toggle=True)
+                row.prop(system, "use_translate_new_dataname", text="New Data", toggle=True)
 
 
 class USERPREF_MT_interface_theme_presets(Menu):
index 379978feca38d205f29665aea88644c82fce979b..f59d3409b6520da2f48577456fd94a71b3404486 100644 (file)
@@ -77,8 +77,10 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid);
 /* translation */
 bool BLF_translate_iface(void);
 bool BLF_translate_tooltips(void);
+bool BLF_translate_new_dataname(void);
 const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid);
 const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
+const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid);
 
 
 /* The "translation-marker" macro. */
@@ -90,14 +92,18 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
 /*#  define _(msgid) BLF_gettext(msgid) */
 #  define IFACE_(msgid) BLF_translate_do_iface(NULL, msgid)
 #  define TIP_(msgid) BLF_translate_do_tooltip(NULL, msgid)
+#  define DATA_(msgid) BLF_translate_do_new_dataname(NULL, msgid)
 #  define CTX_IFACE_(context, msgid) BLF_translate_do_iface(context, msgid)
 #  define CTX_TIP_(context, msgid) BLF_translate_do_tooltip(context, msgid)
+#  define CTX_DATA_(context, msgid) BLF_translate_do_new_dataname(context, msgid)
 #else
 /*#  define _(msgid) msgid */
 #  define IFACE_(msgid) msgid
 #  define TIP_(msgid)   msgid
+#  define DATA_(msgid)  msgid
 #  define CTX_IFACE_(context, msgid) msgid
 #  define CTX_TIP_(context, msgid)   msgid
+#  define CTX_DATA_(context, msgid)  msgid
 #endif
 
 /* Helper macro, when we want to define a same msgid for multiple msgctxt...
index 0cd6bf56c2f794c9914f57c8ad54d899f62db7cd..57f442f8bfcf76e29f7c6ee62c6057ba7773d7c7 100644 (file)
@@ -177,6 +177,15 @@ bool BLF_translate_tooltips(void)
 #endif
 }
 
+bool BLF_translate_new_dataname(void)
+{
+#ifdef WITH_INTERNATIONAL
+       return (U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_NEWDATANAME);
+#else
+       return false;
+#endif
+}
+
 const char *BLF_translate_do_iface(const char *msgctxt, const char *msgid)
 {
 #ifdef WITH_INTERNATIONAL
@@ -206,3 +215,18 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid)
        return msgid;
 #endif
 }
+
+const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid)
+{
+#ifdef WITH_INTERNATIONAL
+       if (BLF_translate_new_dataname()) {
+               return BLF_pgettext(msgctxt, msgid);
+       }
+       else {
+               return msgid;
+       }
+#else
+       (void)msgctxt;
+       return msgid;
+#endif
+}
index 3430c2ea7a199dbc700c58279292aaaba36c43fe..dc47ff4086348b87ac4b2dd2afb5fc1f84d0e55a 100644 (file)
@@ -43,6 +43,8 @@
 #include "BLI_kdopbvh.h"
 #include "BLI_utildefines.h"
 
+#include "BLF_translation.h"
+
 #include "DNA_armature_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
@@ -4353,12 +4355,12 @@ static bConstraint *add_new_constraint_internal(const char *name, short type)
                        cti->new_data(con->data);
                
                /* if no name is provided, use the type of the constraint as the name */
-               newName = (name && name[0]) ? name : cti->name;
+               newName = (name && name[0]) ? name : DATA_(cti->name);
        }
        else {
                /* if no name is provided, use the generic "Const" name */
                /* NOTE: any constraint type that gets here really shouldn't get added... */
-               newName = (name && name[0]) ? name : "Const";
+               newName = (name && name[0]) ? name : DATA_("Const");
        }
        
        /* copy the name */
index b0566a6495fd818b955ff9221cc9b3f688a69a47..9b8101cdad4a9e43021c406e2520a80261216ad6 100644 (file)
@@ -95,7 +95,7 @@ ModifierData *modifier_new(int type)
        ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
        
        /* note, this name must be made unique later */
-       BLI_strncpy(md->name, mti->name, sizeof(md->name));
+       BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
 
        md->type = type;
        md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded;
index c93da151463c54055ded864f73f42965a1712439..55ec5db419db0243e96c6775e9c7f09b2180b638 100644 (file)
@@ -65,6 +65,8 @@
 #include "BLI_utildefines.h"
 #include "BLI_linklist.h"
 
+#include "BLF_translation.h"
+
 #include "BKE_pbvh.h"
 #include "BKE_main.h"
 #include "BKE_global.h"
@@ -855,20 +857,20 @@ void *BKE_object_obdata_add_from_type(int type)
 static const char *get_obdata_defname(int type)
 {
        switch (type) {
-               case OB_MESH: return "Mesh";
-               case OB_CURVE: return "Curve";
-               case OB_SURF: return "Surf";
-               case OB_FONT: return "Text";
-               case OB_MBALL: return "Mball";
-               case OB_CAMERA: return "Camera";
-               case OB_LAMP: return "Lamp";
-               case OB_LATTICE: return "Lattice";
-               case OB_ARMATURE: return "Armature";
-               case OB_SPEAKER: return "Speaker";
-               case OB_EMPTY: return "Empty";
+               case OB_MESH: return DATA_("Mesh");
+               case OB_CURVE: return DATA_("Curve");
+               case OB_SURF: return DATA_("Surf");
+               case OB_FONT: return DATA_("Text");
+               case OB_MBALL: return DATA_("Mball");
+               case OB_CAMERA: return DATA_("Camera");
+               case OB_LAMP: return DATA_("Lamp");
+               case OB_LATTICE: return DATA_("Lattice");
+               case OB_ARMATURE: return DATA_("Armature");
+               case OB_SPEAKER: return DATA_("Speaker");
+               case OB_EMPTY: return DATA_("Empty");
                default:
                        printf("get_obdata_defname: Internal error, bad type: %d\n", type);
-                       return "Empty";
+                       return DATA_("Empty");
        }
 }
 
index f90fde983aaa6f66958e53941746cf97550e69df..d9dabf24ba03456b7fe352bb935859f277afe102 100644 (file)
@@ -56,6 +56,8 @@
 #include "BLI_threads.h"
 #include "BLI_linklist.h"
 
+#include "BLF_translation.h"
+
 #include "BKE_anim.h"
 #include "BKE_animsys.h"
 
@@ -3488,17 +3490,19 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
        psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
        BLI_addtail(&ob->particlesystem, psys);
 
-       psys->part = psys_new_settings("ParticleSettings", NULL);
+       psys->part = psys_new_settings(DATA_("ParticleSettings"), NULL);
 
        if (BLI_countlist(&ob->particlesystem) > 1)
-               BLI_snprintf(psys->name, sizeof(psys->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+               BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
        else
-               strcpy(psys->name, "ParticleSystem");
+               strcpy(psys->name, DATA_("ParticleSystem"));
 
        md = modifier_new(eModifierType_ParticleSystem);
 
-       if (name) BLI_strncpy_utf8(md->name, name, sizeof(md->name));
-       else BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+       if (name)
+               BLI_strncpy_utf8(md->name, name, sizeof(md->name));
+       else
+               BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
        modifier_unique_name(&ob->modifiers, md);
 
        psmd = (ParticleSystemModifierData *) md;
index 5c8a755b391a18bf08f3b790bcdad0c06c0c97f4..8bd1830a289073d7b47b42b4bbef1691d4fd6247 100644 (file)
@@ -6150,20 +6150,20 @@ static const char *get_curve_defname(int type)
 
        if ((type & CU_TYPE) == CU_BEZIER) {
                switch (stype) {
-                       case CU_PRIM_CURVE: return "BezierCurve";
-                       case CU_PRIM_CIRCLE: return "BezierCircle";
-                       case CU_PRIM_PATH: return "CurvePath";
+                       case CU_PRIM_CURVE: return DATA_("BezierCurve");
+                       case CU_PRIM_CIRCLE: return DATA_("BezierCircle");
+                       case CU_PRIM_PATH: return DATA_("CurvePath");
                        default:
-                               return "Curve";
+                               return DATA_("Curve");
                }
        }
        else {
                switch (stype) {
-                       case CU_PRIM_CURVE: return "NurbsCurve";
-                       case CU_PRIM_CIRCLE: return "NurbsCircle";
-                       case CU_PRIM_PATH: return "NurbsPath";
+                       case CU_PRIM_CURVE: return DATA_("NurbsCurve");
+                       case CU_PRIM_CIRCLE: return DATA_("NurbsCircle");
+                       case CU_PRIM_PATH: return DATA_("NurbsPath");
                        default:
-                               return "Curve";
+                               return DATA_("Curve");
                }
        }
 }
@@ -6173,13 +6173,13 @@ static const char *get_surf_defname(int type)
        int stype = type & CU_PRIMITIVE;
 
        switch (stype) {
-               case CU_PRIM_CURVE: return "SurfCurve";
-               case CU_PRIM_CIRCLE: return "SurfCircle";
-               case CU_PRIM_PATCH: return "SurfPatch";
-               case CU_PRIM_SPHERE: return "SurfSphere";
-               case CU_PRIM_DONUT: return "SurfTorus";
+               case CU_PRIM_CURVE: return DATA_("SurfCurve");
+               case CU_PRIM_CIRCLE: return DATA_("SurfCircle");
+               case CU_PRIM_PATCH: return DATA_("SurfPatch");
+               case CU_PRIM_SPHERE: return DATA_("SurfSphere");
+               case CU_PRIM_DONUT: return DATA_("SurfTorus");
                default:
-                       return "Surface";
+                       return DATA_("Surface");
        }
 }
 
index bcff5adb345c951fc46603be495c484b61cc6ed8..29a7b59998378864a1717cb36011c5663eb6c7fc 100644 (file)
@@ -34,6 +34,8 @@
 
 #include "BLI_math.h"
 
+#include "BLF_translation.h"
+
 #include "BKE_context.h"
 #include "BKE_library.h"
 #include "BKE_tessmesh.h"
@@ -106,7 +108,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
        unsigned int layer;
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Plane"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(em, op, "verts.out",
@@ -147,7 +149,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op)
        unsigned int layer;
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Cube"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f", mat, dia * 2.0f)) {
@@ -196,7 +198,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
        cap_tri = (cap_end == 2);
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Circle"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(em, op, "verts.out",
@@ -251,7 +253,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
        cap_tri = (cap_end == 2);
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Cylinder"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(
@@ -312,7 +314,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
        cap_tri = (cap_end == 2);
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Cone"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(
@@ -369,7 +371,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
        unsigned int layer;
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Grid"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(em, op, "verts.out",
@@ -425,7 +427,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
        if (!view_aligned)
                rot[0] += (float)M_PI / 2.0f;
 
-       obedit = make_prim_init(C, "Suzanne", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Suzanne"), &dia, mat, &state, loc, rot, layer);
        mat[0][0] *= dia;
        mat[1][1] *= dia;
        mat[2][2] *= dia;
@@ -468,7 +470,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
        unsigned int layer;
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Sphere"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(em, op, "verts.out",
@@ -520,7 +522,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
        unsigned int layer;
 
        ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
-       obedit = make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer);
+       obedit = make_prim_init(C, DATA_("Icosphere"), &dia, mat, &state, loc, rot, layer);
        em = BMEdit_FromObject(obedit);
 
        if (!EDBM_op_call_and_selectf(
index 312cceac77d5aedafcda82a1d42530a5a6c21091..1cc428b3debb570beffffc13b5569cfa4aff3d8b 100644 (file)
@@ -452,7 +452,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
                if (!ob)
                        return OPERATOR_CANCELLED;
 
-               rename_id(&ob->id, "CurveGuide");
+               rename_id(&ob->id, DATA_("CurveGuide"));
                ((Curve *)ob->data)->flag |= CU_PATH | CU_3D;
                ED_object_enter_editmode(C, 0);
                ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE);
@@ -465,7 +465,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
                if (!ob)
                        return OPERATOR_CANCELLED;
 
-               rename_id(&ob->id, "Field");
+               rename_id(&ob->id, DATA_("Field"));
                if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX))
                        ob->empty_drawtype = OB_SINGLE_ARROW;
        }
@@ -822,13 +822,13 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot)
 static const char *get_lamp_defname(int type)
 {
        switch (type) {
-               case LA_LOCAL: return "Point";
-               case LA_SUN: return "Sun";
-               case LA_SPOT: return "Spot";
-               case LA_HEMI: return "Hemi";
-               case LA_AREA: return "Area";
+               case LA_LOCAL: return DATA_("Point");
+               case LA_SUN: return DATA_("Sun");
+               case LA_SPOT: return DATA_("Spot");
+               case LA_HEMI: return DATA_("Hemi");
+               case LA_AREA: return DATA_("Area");
                default:
-                       return "Lamp";
+                       return DATA_("Lamp");
        }
 }
 
@@ -980,7 +980,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
                BKE_nlatrack_add_strip(nlt, strip);
 
                /* auto-name the strip, and give the track an interesting name  */
-               strcpy(nlt->name, "SoundTrack");
+               strcpy(nlt->name, DATA_("SoundTrack"));
                BKE_nlastrip_validate_name(adt, strip);
 
                WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
index 5a16ff39e68f49dd3417d8e5198ff444d48086df..e459347c4e3f30fa5658631385f38c3dc8a6964a 100644 (file)
@@ -606,12 +606,13 @@ typedef enum eAutokey_Flag {
 typedef enum eUserpref_Translation_Flags {
        USER_TR_TOOLTIPS                = (1 << 0),
        USER_TR_IFACE                   = (1 << 1),
-/*     USER_TR_MENUS                   = (1 << 2)      deprecated */
-/*     USER_TR_FILESELECT      = (1 << 3)      deprecated */
-/*     USER_TR_TEXTEDIT                = (1 << 4)      deprecated */
+/*     USER_TR_MENUS                   = (1 << 2),  deprecated */
+/*     USER_TR_FILESELECT              = (1 << 3),  deprecated */
+/*     USER_TR_TEXTEDIT                = (1 << 4),  deprecated */
        USER_DOTRANSLATE                = (1 << 5),
        USER_USETEXTUREFONT             = (1 << 6),
-/*     CONVERT_TO_UTF8                 = (1 << 7)      deprecated */
+/*     CONVERT_TO_UTF8                 = (1 << 7),  deprecated */
+       USER_TR_NEWDATANAME             = (1 << 8),
 } eUserpref_Translation_Flags;
 
 /* dupflag */
index 58685229b44979d54a9f1afc311319179b40b533..847c9021ec6c6597d69d4c7807921216060463d2 100644 (file)
@@ -3366,12 +3366,17 @@ static void rna_def_userdef_system(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "use_translate_tooltips", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_TOOLTIPS);
-       RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate Tooltips");
+       RNA_def_property_ui_text(prop, "Translate Tooltips", "Translate tooltips");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
 
        prop = RNA_def_property(srna, "use_translate_interface", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_IFACE);
-       RNA_def_property_ui_text(prop, "Translate Interface", "Translate Interface");
+       RNA_def_property_ui_text(prop, "Translate Interface", "Translate interface");
+       RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+       prop = RNA_def_property(srna, "use_translate_new_dataname", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_TR_NEWDATANAME);
+       RNA_def_property_ui_text(prop, "Translate New Names", "Translate new data names (when adding/creating some)");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
 
        prop = RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE);
index 83e9d850ba03bff345343391b67fb164ab42f3d9..a1751d9717c9749566a55a489ab51775f872d395 100644 (file)
@@ -570,7 +570,7 @@ static PyObject *app_translations_pgettext_iface(BlenderAppTranslations *UNUSED(
 }
 
 PyDoc_STRVAR(app_translations_pgettext_tip_doc,
-".. method:: pgettext(msgid, msgctxt)\n"
+".. method:: pgettext_tip(msgid, msgctxt)\n"
 "\n"
 "   Try to translate the given msgid (with optional msgctxt), if tooltips' translation is enabled.\n"
 "   NOTE: See pgettext notes.\n"
@@ -588,6 +588,25 @@ static PyObject *app_translations_pgettext_tip(BlenderAppTranslations *UNUSED(se
        return _py_pgettext(args, kw, BLF_translate_do_tooltip);
 }
 
+PyDoc_STRVAR(app_translations_pgettext_data_doc,
+".. method:: pgettext_data(msgid, msgctxt)\n"
+"\n"
+"   Try to translate the given msgid (with optional msgctxt), if new data name's translation is enabled.\n"
+"   NOTE: See pgettext notes.\n"
+"\n"
+"   :arg msgid: The string to translate.\n"
+"   :type msgid: string\n"
+"   :arg msgctxt: The translation context.\n"
+"   :type msgctxt: string or None\n"
+"   :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+"   :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext_data(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+       return _py_pgettext(args, kw, BLF_translate_do_new_dataname);
+}
+
 PyDoc_STRVAR(app_translations_locale_explode_doc,
 ".. method:: locale_explode(locale)\n"
 "\n"
@@ -620,18 +639,20 @@ static PyObject *app_translations_locale_explode(BlenderAppTranslations *UNUSED(
 
 PyMethodDef app_translations_methods[] = {
        /* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */
-       {(char *)"register", (PyCFunction)app_translations_py_messages_register, METH_VARARGS | METH_KEYWORDS,
-                            app_translations_py_messages_register_doc},
-       {(char *)"unregister", (PyCFunction)app_translations_py_messages_unregister, METH_VARARGS | METH_KEYWORDS,
-                              app_translations_py_messages_unregister_doc},
-       {(char *)"pgettext", (PyCFunction)app_translations_pgettext, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
-                            app_translations_pgettext_doc},
-       {(char *)"pgettext_iface", (PyCFunction)app_translations_pgettext_iface, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
-                                  app_translations_pgettext_iface_doc},
-       {(char *)"pgettext_tip", (PyCFunction)app_translations_pgettext_tip, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
-                                app_translations_pgettext_tip_doc},
-       {(char *)"locale_explode", (PyCFunction)app_translations_locale_explode, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
-                                  app_translations_locale_explode_doc},
+       {"register", (PyCFunction)app_translations_py_messages_register, METH_VARARGS | METH_KEYWORDS,
+                     app_translations_py_messages_register_doc},
+       {"unregister", (PyCFunction)app_translations_py_messages_unregister, METH_VARARGS | METH_KEYWORDS,
+                       app_translations_py_messages_unregister_doc},
+       {"pgettext", (PyCFunction)app_translations_pgettext, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+                     app_translations_pgettext_doc},
+       {"pgettext_iface", (PyCFunction)app_translations_pgettext_iface, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+                           app_translations_pgettext_iface_doc},
+       {"pgettext_tip", (PyCFunction)app_translations_pgettext_tip, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+                         app_translations_pgettext_tip_doc},
+       {"pgettext_data", (PyCFunction)app_translations_pgettext_data, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+                          app_translations_pgettext_data_doc},
+       {"locale_explode", (PyCFunction)app_translations_locale_explode, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+                           app_translations_locale_explode_doc},
        {NULL}
 };
 
@@ -697,7 +718,7 @@ PyDoc_STRVAR(app_translations_doc,
 static PyTypeObject BlenderAppTranslationsType = {
        PyVarObject_HEAD_INIT(NULL, 0)
                                    /* tp_name */
-       (char *)"bpy.app._translations_type",
+       "bpy.app._translations_type",
                                    /* tp_basicsize */
        sizeof(BlenderAppTranslations),
        0,                          /* tp_itemsize */