Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2013-01-20 21:29:07 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2013-01-20 21:29:07 +0400
commitcef730d969b35d7cc25006acded05c361602b319 (patch)
tree7b2b5f2412aac91cb9247866992cc8ae935cd241 /source/blender/blenfont
parent08bcbafe36e28330f98d9143fe4743e69f6d6289 (diff)
Python i18n API. Many thanks to Campbell and Brecht for the reviews and suggestions!
This commit adds: * A new bpy.app.translations module giving some info about locales/translation stuff (current active locale, all locales currently known by blender, all translation contexts currently defined, etc.). * The ability for addons to feature translations, using the (un)register functions of above module. * Also cleans up "translate py string when storing into RNA prop" by removing "PROP_TRANSLATE" string's subtype, and adding a PROP_STRING_PY_TRANSLATE flag instead (this way it is no more exposed to python...). Addon translations work with py dictionaries: each addon features a dict {lang: {(context, message): translation, ...}, ...}, which is registered when the addon is enabled (and unregistered when disabled). Then, when a key (context, message) is not found in regular mo catalog, a cache dict for current locale is built from all registered addon translations, and key is searched in it. Note: currently addons writers have to do all the work by hand, will add something (probably extend "edit translation" addon) to automate messages extraction from addons soon(ish)! To get a look to expected behavior from addons, have a look at render_copy_settings/__init__.py and render_copy_settings/translations.py (rather stupid example currently, but...). Once we have a complete process, I'll also update relevant wiki pages.
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r--source/blender/blenfont/BLF_translation.h59
-rw-r--r--source/blender/blenfont/CMakeLists.txt1
-rw-r--r--source/blender/blenfont/SConscript2
-rw-r--r--source/blender/blenfont/intern/blf_lang.c71
-rw-r--r--source/blender/blenfont/intern/blf_translation.c12
5 files changed, 138 insertions, 7 deletions
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index 0832907d1d9..59f66cae727 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -51,6 +51,13 @@ void BLF_lang_set(const char *);
/* Get the current locale (short 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,
+ * *variant and *language_variant will always be NULL).
+ * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them.
+ */
+void BLF_locale_explode(const char *locale, char **language, char **country, char **variant,
+ char **language_country, char **language_variant);
+
/* Get EnumPropertyItem's for translations menu. */
struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void);
@@ -143,4 +150,54 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
#define BLF_I18NCONTEXT_ID_MOVIECLIP "MovieClip"
#define BLF_I18NCONTEXT_ID_MASK "Mask"
-#endif /* __BLF_TRANSLATION_H__ */
+/* Helper for bpy.app.i18n object... */
+typedef struct
+{
+ const char *c_id;
+ const char *py_id;
+ const char *value;
+} BLF_i18n_contexts_descriptor;
+
+#define BLF_I18NCONTEXTS_ITEM(ctxt_id, py_id) {#ctxt_id, py_id, ctxt_id}
+
+#define BLF_I18NCONTEXTS_DESC { \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_BRUSH, "id_brush"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CAMERA, "id_camera"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_CURVE, "id_curve"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GPENCIL, "id_gpencil"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_GROUP, "id_group"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ID, "id_id"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IMAGE, "id_image"), \
+ /*BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_IPO, "id_ipo"),*/ \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SHAPEKEY, "id_shapekey"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LAMP, "id_lamp"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LIBRARY, "id_library"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LATTICE, "id_lattice"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MATERIAL, "id_material"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_METABALL, "id_metaball"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MESH, "id_mesh"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_NODETREE, "id_nodetree"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_OBJECT, "id_object"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PARTICLESETTINGS, "id_particlesettings"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCENE, "id_scene"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCREEN, "id_screen"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SEQUENCE, "id_sequence"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SPEAKER, "id_speaker"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SOUND, "id_sound"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXTURE, "id_texture"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_TEXT, "id_text"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_VFONT, "id_vfont"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WORLD, "id_world"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \
+ {NULL, NULL, NULL} \
+}
+
+//#undef _BLF_I18NCONTEXTS_ITEM
+
+#endif /* __BLF_TRANSLATION_H__ */ \ No newline at end of file
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index 90baef14a74..7bb80c34323 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../editors/include
../makesdna
../makesrna
+ ../python
../imbuf
../../../intern/guardedalloc
../../../intern/locale
diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript
index a6ea724a51f..d1ef181f75c 100644
--- a/source/blender/blenfont/SConscript
+++ b/source/blender/blenfont/SConscript
@@ -31,7 +31,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
incs = '. intern #/intern/guardedalloc #/intern/locale ../blenkernel ../blenlib ../blenloader'
-incs += ' ../makesdna ../makesrna ../imbuf ../editors/include'
+incs += ' ../makesdna ../makesrna ../python ../imbuf ../editors/include'
incs += ' #/extern/glew/include'
incs += ' ' + env['BF_FREETYPE_INC']
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 9086799f984..ab29fae1a58 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -60,7 +60,7 @@ static EnumPropertyItem *locales_menu = NULL;
static int num_locales_menu = 0;
#define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0)
-#define LOCALE(_id) (locales ? locales[_id] : "")
+#define LOCALE(_id) (locales ? locales[(_id)] : "")
static void free_locales(void)
{
@@ -113,7 +113,7 @@ static void fill_locales(void)
}
num_locales_menu++; /* The "closing" void item... */
- /* And now, buil locales and locale_menu! */
+ /* And now, build locales and locale_menu! */
locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__);
line = lines;
/* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
@@ -234,10 +234,15 @@ void BLF_lang_set(const char *str)
}
}
+/* Get the current locale (short code, e.g. es_ES). */
const char *BLF_lang_get(void)
{
- int uilang = ULANGUAGE;
- return LOCALE(uilang);
+ const char *locale = LOCALE(ULANGUAGE);
+ if (locale[0] == '\0') {
+ /* Default locale, we have to find which one we are actually using! */
+ locale = bl_locale_get();
+ }
+ return locale;
}
#undef LOCALE
@@ -245,6 +250,11 @@ const char *BLF_lang_get(void)
#else /* ! WITH_INTERNATIONAL */
+EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
+{
+ return NULL;
+}
+
void BLF_lang_init(void)
{
return;
@@ -266,3 +276,56 @@ const char *BLF_lang_get(void)
}
#endif /* WITH_INTERNATIONAL */
+
+
+/* Get locale's elements (if relevant pointer is not NULL and element actually exists, e.g. if there is no variant,
+ * *variant and *language_variant will always be NULL).
+ * Non-null elements are always MEM_mallocN'ed, it's the caller's responsibility to free them.
+ * NOTE: Keep that one always available, you never know, may become useful even in no-WITH_INTERNATIONAL context...
+ */
+void BLF_locale_explode(const char *locale, char **language, char **country, char **variant,
+ char **language_country, char **language_variant)
+{
+ char *m1, *m2, *_t = NULL;
+
+ m1 = strchr(locale, '_');
+ m2 = strchr(locale, '@');
+
+ if (language || language_variant) {
+ if (m1 || m2) {
+ _t = m1 ? BLI_strdupn(locale, m1 - locale) : BLI_strdupn(locale, m2 - locale);
+ if (language)
+ *language = _t;
+ }
+ else if (language) {
+ *language = NULL;
+ }
+ }
+ if (country) {
+ if (m1)
+ *country = m2 ? BLI_strdupn(m1 + 1, m2 - (m1 + 1)) : BLI_strdup(m1 + 1);
+ else
+ *country = NULL;
+ }
+ if (variant) {
+ if (m2)
+ *variant = BLI_strdup(m2 + 1);
+ else
+ *variant = NULL;
+ }
+ if (language_country) {
+ if (m2)
+ *language_country = BLI_strdupn(locale, m2 - locale);
+ else
+ *language_country = NULL;
+ }
+ if (language_variant) {
+ if (m2)
+ *language_variant = m1 ? BLI_strdupcat(_t, m2 + 1) : BLI_strdup(locale);
+ else
+ *language_variant = NULL;
+ }
+ if (_t && !language) {
+ MEM_freeN(_t);
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index 5d4b631688a..3aaa61d55f2 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -47,6 +47,8 @@
#include "DNA_userdef_types.h" /* For user settings. */
+#include "BPY_extern.h"
+
static const char unifont_filename[] = "droidsans.ttf.gz";
static unsigned char *unifont_ttf = NULL;
static int unifont_size = 0;
@@ -84,7 +86,15 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
if (msgid && msgid[0]) {
- return bl_locale_pgettext(msgctxt, msgid);
+ const char *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!
+ */
+ if (ret == msgid) {
+ ret = BPY_app_translations_py_pgettext(msgctxt, msgid);
+ }
+
+ return ret;
}
return "";
#else