I18n fix: "" context is not the same as NULL context!

This bug did not appear earlier because the "" default context was actually never used, always NULL context was passed instead. But bpy.app.translations uses "" as default context in its keys (simplifies the hash/comp functions of internal py messages cache)...

So now, Blender prefers NULL (None in python) as default context value, but understands also "" as such.
This commit is contained in:
Bastien Montagne 2013-01-21 10:52:34 +00:00
parent 22b5f097d2
commit 3aa499f3f7
3 changed files with 37 additions and 15 deletions

@ -50,7 +50,7 @@ void BLF_lang_free(void);
/* Set the current locale. */
void BLF_lang_set(const char *);
/* Get the current locale (short code, e.g. es_ES). */
/* Get the current locale ([partial] ISO code, e.g. es_ES). */
const char *BLF_lang_get(void);
/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant,
@ -110,8 +110,11 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
* things, and limit the number of existing contexts!
*/
/* Default, void context. Just in case... */
#define BLF_I18NCONTEXT_DEFAULT ""
/* Default, void context.
* WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level!
*/
#define BLF_I18NCONTEXT_DEFAULT NULL /* Translated as None in Python. */
#define BLF_I18NCONTEXT_DEFAULT_BPY_INTERN "" /* Only used in code, never exposed to user! */
/* Default context for operator names/labels. */
#define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator"

@ -91,7 +91,14 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (msgid && msgid[0]) {
const char *ret = bl_locale_pgettext(msgctxt, msgid);
const char *ret;
/*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */
if (msgctxt && !msgctxt[0]) {
/* BLF_I18NCONTEXT_DEFAULT_BPY_INTERN context is reserved and considered the same as default NULL one. */
msgctxt = NULL;
}
ret = bl_locale_pgettext(msgctxt, msgid);
/* We assume if the returned string is the same (memory level) as the msgid, no translation was found,
* and we can try py scripts' ones!
*/

@ -76,7 +76,7 @@ typedef struct GHashKey {
static GHashKey *_ghashutil_keyalloc(const void *msgctxt, const void *msgid)
{
GHashKey *key = MEM_mallocN(sizeof(GHashKey), "GHashPair");
key->msgctxt = BLI_strdup(msgctxt);
key->msgctxt = BLI_strdup(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT_BPY_INTERN);
key->msgid = BLI_strdup(msgid);
return key;
}
@ -186,7 +186,10 @@ static void _build_translations_cache(PyObject *py_messages, const char *locale)
}
tmp = PyTuple_GET_ITEM(pykey, 0);
if (PyUnicode_Check(tmp)) {
if (tmp == Py_None) {
msgctxt = BLF_I18NCONTEXT_DEFAULT;
}
else if (PyUnicode_Check(tmp)) {
msgctxt = _PyUnicode_AsString(tmp);
}
tmp = PyTuple_GET_ITEM(pykey, 1);
@ -194,7 +197,7 @@ static void _build_translations_cache(PyObject *py_messages, const char *locale)
msgid = _PyUnicode_AsString(tmp);
}
if (!(msgctxt && msgid)) {
if (!msgid) {
continue;
}
@ -247,7 +250,7 @@ const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *ms
}
/* And now, simply create the key (context, messageid) and find it in the cached dict! */
key = _ghashutil_keyalloc(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT, msgid);
key = _ghashutil_keyalloc(msgctxt, msgid);
tmp = BLI_ghash_lookup(_translations_cache, key);
@ -359,12 +362,19 @@ static PyObject *app_translations_contexts_make(void)
}
#define SetObjString(item) PyStructSequence_SET_ITEM(translations_contexts, pos++, PyUnicode_FromString((item)))
#define SetObjNone() Py_INCREF(Py_None); PyStructSequence_SET_ITEM(translations_contexts, pos++, Py_None)
for (ctxt = _contexts; ctxt->c_id; ctxt++) {
SetObjString(ctxt->value);
if (ctxt->value) {
SetObjString(ctxt->value);
}
else {
SetObjNone();
}
}
#undef SetObjString
#undef SetObjNone
return translations_contexts;
}
@ -372,7 +382,9 @@ static PyObject *app_translations_contexts_make(void)
/***** Main BlenderAppTranslations Py object definition *****/
PyDoc_STRVAR(app_translations_contexts_doc,
"A named tuple containing all pre-defined translation contexts."
"A named tuple containing all pre-defined translation contexts.\n"
"WARNING: do not use the \"" BLF_I18NCONTEXT_DEFAULT_BPY_INTERN "\" context, it is internally assimilated as the "
"default one!\n"
);
PyDoc_STRVAR(app_translations_contexts_C_to_py_doc,
@ -433,14 +445,14 @@ PyDoc_STRVAR(app_translations_pgettext_doc,
"\n"
" Try to translate the given msgid (with optional msgctxt).\n"
" NOTE: The (msgid, msgctxt) parameter orders has been switched compared to gettext function, to allow\n"
" single-parameter calls (context then defaults to BLF_I18NCONTEXT_DEFAULT)."
" single-parameter calls (context then defaults to BLF_I18NCONTEXT_DEFAULT).\n"
" NOTE: You should really rarely need to use this function in regular addon code, as all translation should be\n"
" handled by Blender internal code."
" handled by Blender internal code.\n"
"\n"
" :arg msgid: The string to translate.\n"
" :type msgid: string\n"
" :arg msgctxt: The translation context.\n"
" :type msgctxt: string\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"
@ -450,7 +462,7 @@ static PyObject *app_translations_pgettext(BlenderAppTranslations *UNUSED(self),
static const char *kwlist[] = {"msgid", "msgctxt", NULL};
char *msgid, *msgctxt = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:bpy.app.translations.pgettext()", (char **)kwlist,
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|z:bpy.app.translations.pgettext", (char **)kwlist,
&msgid, &msgctxt))
{
return NULL;
@ -466,7 +478,7 @@ PyMethodDef app_translations_methods[] = {
{(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},
app_translations_pgettext_doc},
{NULL}
};