Translation context for RNA properties

This commit implements a way to define context of property which is used by
localization stuff and which is needed to resolve translation context when
some word wit the same english spelling is used in different meanings
(like Manual in meaning of tutorial, and Manual in meaning of something is
setting up by hand).

To define property's context there's a function RNA_def_property_translation_context.
If property doesn't have context, regular BLF_gettext function is used to get
translation of property name, otherwise BLF_pgettext is used for this.

Hence, for correct translation, messages in .po files should be marked
by "msgctxt" context, otherwise property with context declared wouldn't
be translated at all. Toolchain scripts from bf-translation project
would be updated soon.

If context for some values of enumerator property, property itself should
be moved to other context and all items from this enum would be moved to
this context automatically (it's impossible to move one few items to
another context).

P.S. Think context like "BRUSH" or "MODIFIER" are preferable than "NOUN" and "VERB"
     because in some cases the same english noun used in different areas better be
	 translated differently to make translation more native.
This commit is contained in:
Sergey Sharybin 2011-12-22 18:25:59 +00:00
parent e06a0ba2bb
commit 39fd8fa400
9 changed files with 93 additions and 11 deletions

@ -33,6 +33,8 @@
#ifndef BLF_TRANSLATION_H
#define BLF_TRANSLATION_H
#define TEXT_DOMAIN_NAME "blender"
/* blf_translation.c */
#ifdef WITH_INTERNATIONAL
@ -40,7 +42,8 @@ unsigned char *BLF_get_unifont(int *unifont_size);
void BLF_free_unifont(void);
#endif
const char* BLF_gettext(const char *msgid);
const char *BLF_gettext(const char *msgid);
const char *BLF_pgettext(const char *context, const char *message);
/* blf_lang.c */

@ -58,7 +58,6 @@
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#define DOMAIN_NAME "blender"
#define SYSTEM_ENCODING_DEFAULT "UTF-8"
#define FONT_SIZE_DEFAULT 12
@ -205,15 +204,15 @@ void BLF_lang_set(const char *str)
setlocale(LC_NUMERIC, "C");
textdomain(DOMAIN_NAME);
bindtextdomain(DOMAIN_NAME, global_messagepath);
bind_textdomain_codeset(DOMAIN_NAME, global_encoding_name);
textdomain(TEXT_DOMAIN_NAME);
bindtextdomain(TEXT_DOMAIN_NAME, global_messagepath);
bind_textdomain_codeset(TEXT_DOMAIN_NAME, global_encoding_name);
}
void BLF_lang_encoding(const char *str)
{
BLI_strncpy(global_encoding_name, str, sizeof(global_encoding_name));
/* bind_textdomain_codeset(DOMAIN_NAME, encoding_name); */
/* bind_textdomain_codeset(TEXT_DOMAIN_NAME, encoding_name); */
}
#else /* ! WITH_INTERNATIONAL */

@ -29,9 +29,19 @@
*/
#include <stdlib.h>
#include <string.h>
#ifdef WITH_INTERNATIONAL
#include <libintl.h>
#include <locale.h>
#define GETTEXT_CONTEXT_GLUE "\004"
/* needed for windows version of gettext */
#ifndef LC_MESSAGES
# define LC_MESSAGES 1729
#endif
#endif
#include "MEM_guardedalloc.h"
@ -91,6 +101,40 @@ const char* BLF_gettext(const char *msgid)
#endif
}
const char *BLF_pgettext(const char *context, const char *message)
{
#ifdef WITH_INTERNATIONAL
char static_msg_ctxt_id[1024];
char *dynamic_msg_ctxt_id = NULL;
char *msg_ctxt_id;
const char *translation;
size_t overall_length = strlen(context) + strlen(message) + sizeof(GETTEXT_CONTEXT_GLUE) + 1;
if (overall_length > sizeof(static_msg_ctxt_id)) {
dynamic_msg_ctxt_id = malloc(overall_length);
msg_ctxt_id = dynamic_msg_ctxt_id;
}
else {
msg_ctxt_id = static_msg_ctxt_id;
}
sprintf(msg_ctxt_id, "%s%s%s", context, GETTEXT_CONTEXT_GLUE, message);
translation = (char*)dcgettext(TEXT_DOMAIN_NAME, msg_ctxt_id, LC_MESSAGES);
if (dynamic_msg_ctxt_id)
free(dynamic_msg_ctxt_id);
if (translation == msg_ctxt_id)
translation = message;
return translation;
#else
return message;
#endif
}
int BLF_translate_iface(void)
{
#ifdef WITH_INTERNATIONAL
@ -132,4 +176,3 @@ const char *BLF_translate_do_tooltip(const char *msgid)
return msgid;
#endif
}

@ -175,6 +175,8 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
void RNA_def_py_data(PropertyRNA *prop, void *py_data);
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context);
/* Function */
FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call);

@ -2229,6 +2229,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
fprintf(f, "%d,\n", prop->icon);
rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n\t");
fprintf(f, "\t%s, %s|%s, %s, %u, {%u, %u, %u}, %u,\n", RNA_property_typename(prop->type), rna_property_subtypename(prop->subtype), rna_property_subtype_unit(prop->subtype), rna_function_string(prop->getlength), prop->arraydimension, prop->arraylength[0], prop->arraylength[1], prop->arraylength[2], prop->totarraylength);
fprintf(f, "\t%s%s, %d, %s, %s,\n", (prop->flag & PROP_CONTEXT_UPDATE)? "(UpdateFunc)": "", rna_function_string(prop->update), prop->noteflag, rna_function_string(prop->editable), rna_function_string(prop->itemeditable));

@ -486,8 +486,12 @@ static const char *rna_ensure_property_name(PropertyRNA *prop)
name= ((IDProperty*)prop)->name;
#ifdef WITH_INTERNATIONAL
if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE))
name= BLF_gettext(name);
if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) {
if(prop->translation_context)
name = BLF_pgettext(prop->translation_context, name);
else
name = BLF_gettext(name);
}
#endif
return name;
@ -1194,8 +1198,12 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
}
for(i=0; nitem[i].identifier; i++) {
if( nitem[i].name )
nitem[i].name = BLF_gettext(nitem[i].name);
if( nitem[i].name ) {
if(prop->translation_context)
nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
else
nitem[i].name = BLF_gettext(nitem[i].name);
}
if( nitem[i].description )
nitem[i].description = BLF_gettext(nitem[i].description);
}

@ -1824,6 +1824,11 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname,
}
}
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
{
prop->translation_context= context;
}
/* Functions */
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)

@ -147,6 +147,8 @@ struct PropertyRNA {
const char *description;
/* icon ID */
int icon;
/* context for translation */
const char *translation_context;
/* property type as it appears to the outside */
PropertyType type;

@ -465,6 +465,20 @@ static int rna_Property_description_length(PointerRNA *ptr)
return prop->description ? strlen(prop->description) : 0;
}
static void rna_Property_translation_context_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
rna_idproperty_check(&prop, ptr);
strcpy(value, prop->translation_context ? prop->translation_context:"");
}
static int rna_Property_translation_context_length(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
rna_idproperty_check(&prop, ptr);
return prop->translation_context ? strlen(prop->translation_context) : 0;
}
static int rna_Property_type_get(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
@ -1047,6 +1061,11 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL);
RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips");
prop= RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Property_translation_context_get", "rna_Property_translation_context_length", NULL);
RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the property");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, property_type_items);