diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2012-10-22 18:04:40 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2012-10-22 18:04:40 +0400 |
commit | b5e85cae705f47ae5a32c97564e1942a95e75bb4 (patch) | |
tree | 67f6cc66a0f4b6052fb53270b6b2db2f30401e52 /source/blender/blenfont | |
parent | c727f8cbde9b27433fa378d9a53ca9b8cefcc7d4 (diff) |
New "dynamic" i18n menu.
Now both UI translation menu (in userprefs) and isocodes are defined in a text file (release/datafiles/locale/languages), parsed at lunchtime. This way:
* No more need to edit Blender code each time we want to add an new language or reorganize the existing menu;
* Translators can easily add a new language for testing, by just editing the text file, so no more need to ask to change Blender code and wait for a new build to see your new translation work in Blender!
Remaining todo:
* Commit i18n py tools
* Update wiki doc!
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r-- | source/blender/blenfont/BLF_translation.h | 7 | ||||
-rw-r--r-- | source/blender/blenfont/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/blenfont/SConscript | 3 | ||||
-rw-r--r-- | source/blender/blenfont/intern/blf_lang.c | 194 |
4 files changed, 151 insertions, 55 deletions
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 278c45dac52..b01ce93cb65 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -49,9 +49,13 @@ const char *BLF_pgettext(const char *context, const char *message); /* Search the path directory to the locale files, this try all * the case for Linux, Win and Mac. + * Also dynamically builds locales and locales' menu from "languages" text file. */ void BLF_lang_init(void); +/* Free languages and locales_menu arrays created by BLF_lang_init. */ +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). */ @@ -60,6 +64,9 @@ const char *BLF_lang_get(void); /* Set the current encoding name. */ void BLF_lang_encoding(const char *str); +/* Get EnumPropertyItem's for translations menu. */ +struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void); + /* translation */ int BLF_translate_iface(void); int BLF_translate_tooltips(void); diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index da60710a137..022dfd282b0 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -25,8 +25,10 @@ set(INC . ../blenkernel ../blenlib + ../blenloader ../editors/include ../makesdna + ../makesrna ../imbuf ../../../intern/guardedalloc ) diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index d3c7b1c2fcc..075da58b116 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -4,7 +4,8 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. intern #/intern/guardedalloc ../blenkernel ../blenlib ../makesdna ../imbuf ../editors/include' +incs = '. intern #/intern/guardedalloc ../blenkernel ../blenlib ../blenloader' +incs += ' ../makesdna ../makesrna ../imbuf ../editors/include' incs += ' #/extern/glew/include' incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_GETTEXT_INC'] diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index e46e6be399e..5b9ec60fc11 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -35,7 +35,6 @@ #include "BKE_global.h" #include "BLF_api.h" - #include "BLF_translation.h" /* own include */ #ifdef WITH_INTERNATIONAL @@ -46,15 +45,16 @@ #include "DNA_userdef_types.h" -#include "DNA_listBase.h" -#include "DNA_vec_types.h" +#include "RNA_types.h" #include "MEM_guardedalloc.h" -#include "BLI_linklist.h" /* linknode */ #include "BLI_string.h" #include "BLI_utildefines.h" #include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_linklist.h" +#include "BLI_string.h" #define SYSTEM_ENCODING_DEFAULT "UTF-8" #define FONT_SIZE_DEFAULT 12 @@ -64,50 +64,120 @@ static char global_messagepath[1024]; static char global_language[32]; static char global_encoding_name[32]; -/* Map from the rna_userdef.c:rna_def_userdef_system(BlenderRNA *brna):language_items */ -static const char *locales[] = { - "", "", - "english", "en_US", - "japanese", "ja_JP", - "dutch", "nl_NL", - "italian", "it_IT", - "german", "de_DE", - "finnish", "fi_FI", - "swedish", "sv_SE", - "french", "fr_FR", - "spanish", "es", - "catalan", "ca_AD", - "czech", "cs_CZ", - "portuguese", "pt_PT", -#if defined(_WIN32) && !defined(FREE_WINDOWS) - "Chinese (Simplified)_China.1252", "zh_CN", - "Chinese (Traditional)_China.1252", "zh_TW", -#else - "chs", "zh_CN", - "cht", "zh_TW", -#endif - "russian", "ru_RU", - "croatian", "hr_HR", - "serbian", "sr_RS", - "ukrainian", "uk_UA", - "polish", "pl_PL", - "romanian", "ro_RO", - "arabic", "ar_EG", - "bulgarian", "bg_BG", - "greek", "el_GR", - "korean", "ko_KR", - "nepali", "ne_NP", - "persian", "fa_IR", - "indonesian", "id_ID", - "serbian (latin)", "sr_RS@latin", - "kyrgyz", "ky_KG", - "turkish", "tr_TR", - "hungarian", "hu_HU", - "portuguese-brazilian", "pt_BR", - "hebrew", "he_IL", - "estonian", "et_EE", - "esperanto", "eo", /* No country code for esperanto! ;) */ -}; +static const char **locales = NULL; +static int num_locales = 0; +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] : "") + +static void free_locales(void) +{ + if (locales) { + int idx = num_locales_menu - 1; /* Last item does not need to be freed! */ + while (idx--) { + printf("freeing %s\n", locales_menu[idx].identifier); + MEM_freeN((void*)locales_menu[idx].identifier); + printf("freeing %s\n", locales_menu[idx].name); + MEM_freeN((void*)locales_menu[idx].name); + printf("freeing %s\n", locales_menu[idx].description); + MEM_freeN((void*)locales_menu[idx].description); /* Also frees locales's relevant value! */ + } + MEM_freeN(locales); + MEM_freeN(locales_menu); + } + num_locales = num_locales_menu = 0; +} + +static void fill_locales(void) +{ + char *languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale"); + LinkNode *lines = NULL, *line; + char *str; + int idx = 0; + + free_locales(); + + BLI_join_dirfile(languages_path, FILE_MAX, languages_path, "languages"); + line = lines = BLI_file_read_as_lines(languages_path); + + /* This whole "parsing" code is a bit weak, in that it expects strictly formated input file... + * Should not be a problem, though, as this file is script-generated! */ + + /* First loop to find highest locale ID */ + while (line) { + int t; + str = (char*) line->link; + if (str[0] == '#' || str[0] == '\0') { + line = line->next; + continue; /* Comment or void... */ + } + printf("%s\n", str); + t = atoi(str); + if (t >= num_locales) + num_locales = t + 1; + num_locales_menu++; + line = line->next; + } + num_locales_menu++; /* The "closing" void item... */ + printf("num_locales_menu: %d\n", num_locales_menu); + + /* And now, buil locales and locale_menu! */ + locales = MEM_callocN(num_locales * sizeof(char*), __func__); + locales_menu = MEM_callocN(num_locales_menu * sizeof(EnumPropertyItem), __func__); + line = lines; + while (line) { + int id; + char *loc, *sep1, *sep2; + + str = (char*) line->link; + if (str[0] == '#' || str[0] == '\0') { + line = line->next; + continue; + } + + id = atoi(str); + printf("%s\n", str); + sep1 = strchr(str, ':'); + if (sep1) { + sep1++; + sep2 = strchr(sep1, ':'); + if (sep2) { + + locales_menu[idx].value = id; + locales_menu[idx].icon = 0; + locales_menu[idx].name = BLI_strdupn(sep1, sep2 - sep1); + locales_menu[idx].identifier = loc = BLI_strdup(sep2 + 1); + if (id == 0) { + /* The DEFAULT item... */ + if (BLI_strnlen(loc, 2)) + locales[id] = locales_menu[idx].description = BLI_strdup(""); + /* Menu "label", not to be stored in locales! */ + else + locales_menu[idx].description = BLI_strdup(""); + } + else + locales[id] = locales_menu[idx].description = BLI_strdup(loc); + idx++; + + } + } + + line = line->next; + } + + /* Add closing item to menu! */ + locales_menu[idx].value = locales_menu[idx].icon = 0; + locales_menu[idx].identifier = locales_menu[idx].name = locales_menu[idx].description = ""; + + BLI_file_free_lines(lines); +} + +EnumPropertyItem *BLF_RNA_lang_enum_properties(void) +{ + return locales_menu; +} void BLF_lang_init(void) { @@ -117,6 +187,7 @@ void BLF_lang_init(void) if (messagepath) { BLI_strncpy(global_messagepath, messagepath, sizeof(global_messagepath)); + fill_locales(); } else { printf("%s: 'locale' data path for translations not found, continuing\n", __func__); @@ -124,6 +195,11 @@ void BLF_lang_init(void) } } +void BLF_lang_free(void) +{ + free_locales(); +} + /* Get LANG/LANGUAGE environment variable. */ static void get_language_variable(const char *varname, char *var, const size_t maxlen) { @@ -166,7 +242,8 @@ void BLF_lang_set(const char *str) { char *locreturn; const char *short_locale; - int ok = 1; + int ok = TRUE; + int ulang = ULANGUAGE; if ((U.transopts & USER_DOTRANSLATE) == 0) return; @@ -174,14 +251,14 @@ void BLF_lang_set(const char *str) if (str) short_locale = str; else - short_locale = locales[2 * U.language + 1]; + short_locale = LOCALE(ulang); #if defined(_WIN32) && !defined(FREE_WINDOWS) { if (short_locale) { char *envStr; - if (U.language == 0) /* Use system setting. */ + if (ulang) /* Use system setting. */ envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); else envStr = BLI_sprintfN("LANG=%s", short_locale); @@ -196,7 +273,7 @@ void BLF_lang_set(const char *str) if (G.debug & G_DEBUG) printf("Could not change locale to %s\n", short_locale); - ok = 0; + ok = FALSE; } } #else @@ -265,7 +342,7 @@ void BLF_lang_set(const char *str) locreturn = setlocale(LC_ALL, ""); - ok = 0; + ok = FALSE; } } #endif @@ -284,7 +361,8 @@ void BLF_lang_set(const char *str) const char *BLF_lang_get(void) { - return locales[2 * U.language + 1]; + int uilang = ULANGUAGE; + return LOCALE(uilang); } void BLF_lang_encoding(const char *str) @@ -293,6 +371,9 @@ void BLF_lang_encoding(const char *str) /* bind_textdomain_codeset(TEXT_DOMAIN_NAME, encoding_name); */ } +#undef LOCALE +#undef ULANGUAGE + #else /* ! WITH_INTERNATIONAL */ void BLF_lang_init(void) @@ -300,6 +381,11 @@ void BLF_lang_init(void) return; } +void BLF_lang_free(void) +{ + return; +} + void BLF_lang_encoding(const char *str) { (void)str; |