Fix for [#32992] Switching language does nothing under Windows.
authorBastien Montagne <montagne29@wanadoo.fr>
Fri, 2 Nov 2012 20:03:15 +0000 (20:03 +0000)
committerBastien Montagne <montagne29@wanadoo.fr>
Fri, 2 Nov 2012 20:03:15 +0000 (20:03 +0000)
Our current intl build for windows is quite old (don't know the exact version), and does not have the new setlocale overwrite. Problem is, new windows dll have no more the gettext_putenv helper, which is currently mandatory to make it work for this OS.

So back for now to the ugly long_locales for win. Best fix is probably to build our own static version of libl, but this is not trivial and will require some time. :/

PS: I had a look over i18n/translation in wxWidget, Qt and boost: all implement their own system, even though wxWidget and boost use po/mo files...

release/scripts/modules/bl_i18n_utils/settings.py
release/scripts/modules/bl_i18n_utils/update_languages_menu.py
source/blender/blenfont/intern/blf_lang.c
source/blender/blenkernel/intern/cdderivedmesh.c

index 4bfcee9c583a8ad131cee7a670edda206fa0b4e6..0db3f85f1ff38c539bab0228f9d4830705f091ae 100644 (file)
@@ -40,46 +40,46 @@ LANGUAGES_CATEGORIES = (
 )
 LANGUAGES = (
     # ID, UI english label, ISO code.
-    ( 0, "Default (Default)", "DEFAULT"),
-    ( 1, "English (English)", "en_US"),
-    ( 2, "Japanese (日本語)", "ja_JP"),
-    ( 3, "Dutch (Nederlandse taal)", "nl_NL"),
-    ( 4, "Italian (Italiano)", "it_IT"),
-    ( 5, "German (Deutsch)", "de_DE"),
-    ( 6, "Finnish (Suomi)", "fi_FI"),
-    ( 7, "Swedish (Svenska)", "sv_SE"),
-    ( 8, "French (Français)", "fr_FR"),
-    ( 9, "Spanish (Español)", "es"),
-    (10, "Catalan (Català)", "ca_AD"),
-    (11, "Czech (Český)", "cs_CZ"),
-    (12, "Portuguese (Português)", "pt_PT"),
-    (13, "Simplified Chinese (简体中文)", "zh_CN"),
-    (14, "Traditional Chinese (繁體中文)", "zh_TW"),
-    (15, "Russian (Русский)", "ru_RU"),
-    (16, "Croatian (Hrvatski)", "hr_HR"),
-    (17, "Serbian (Српски)", "sr_RS"),
-    (18, "Ukrainian (Український)", "uk_UA"),
-    (19, "Polish (Polski)", "pl_PL"),
-    (20, "Romanian (Român)", "ro_RO"), # XXX No po's yet.
+    ( 0, "Default (Default)", "DEFAULT", ""),
+    ( 1, "English (English)", "en_US", "english"),
+    ( 2, "Japanese (日本語)", "ja_JP", "japanese"),
+    ( 3, "Dutch (Nederlandse taal)", "nl_NL", "dutch"),
+    ( 4, "Italian (Italiano)", "it_IT", "italian"),
+    ( 5, "German (Deutsch)", "de_DE", "german"),
+    ( 6, "Finnish (Suomi)", "fi_FI", "finnish"),
+    ( 7, "Swedish (Svenska)", "sv_SE", "swedish"),
+    ( 8, "French (Français)", "fr_FR", "french"),
+    ( 9, "Spanish (Español)", "es", "spanish"),
+    (10, "Catalan (Català)", "ca_AD", "catalan"),
+    (11, "Czech (Český)", "cs_CZ", "czech"),
+    (12, "Portuguese (Português)", "pt_PT", "portuguese_portugal"),
+    (13, "Simplified Chinese (简体中文)", "zh_CN", "Chinese (Simplified)_China.1252"),
+    (14, "Traditional Chinese (繁體中文)", "zh_TW", "Chinese (Traditional)_China.1252"),
+    (15, "Russian (Русский)", "ru_RU", "russian"),
+    (16, "Croatian (Hrvatski)", "hr_HR", "croatian"),
+    (17, "Serbian (Српски)", "sr_RS", "serbian"),
+    (18, "Ukrainian (Український)", "uk_UA", "ukrainian"),
+    (19, "Polish (Polski)", "pl_PL", "polish"),
+    (20, "Romanian (Român)", "ro_RO", "romanian"),
     # Using the utf8 flipped form of Arabic (العربية).
-    (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"),
-    (22, "Bulgarian (Български)", "bg_BG"),
-    (23, "Greek (Ελληνικά)", "el_GR"),
-    (24, "Korean (한국 언어)", "ko_KR"), # XXX No po's yet.
-    (25, "Nepali (नेपाली)", "ne_NP"),
+    (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG", "arabic"),
+    (22, "Bulgarian (Български)", "bg_BG", "bulgarian"),
+    (23, "Greek (Ελληνικά)", "el_GR", "greek"),
+    (24, "Korean (한국 언어)", "ko_KR", "korean"),
+    (25, "Nepali (नेपाली)", "ne_NP", "nepali"),
     # Using the utf8 flipped form of Persian (فارسی).
-    (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"),
-    (27, "Indonesian (Bahasa indonesia)", "id_ID"),
-    (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin"),
-    (29, "Kyrgyz (Кыргыз тили)", "ky_KG"),
-    (30, "Turkish (Türkçe)", "tr_TR"),
-    (31, "Hungarian (Magyar)", "hu_HU"),
-    (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR"),
+    (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR", "farsi"),
+    (27, "Indonesian (Bahasa indonesia)", "id_ID", "indonesian"),
+    (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin", "serbian (latin)"),
+    (29, "Kyrgyz (Кыргыз тили)", "ky_KG", "kyrgyz"),
+    (30, "Turkish (Türkçe)", "tr_TR", "turkish"),
+    (31, "Hungarian (Magyar)", "hu_HU", "hungarian"),
+    (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR", "protuguese_brazil"),
     # Using the utf8 flipped form of Hebrew (עִבְרִית)).
-    (33, "Hebrew (תירִבְעִ)", "he_IL"),
-    (34, "Estonian (Eestlane)", "et_EE"),
-    (35, "Esperanto (Esperanto)", "eo"),
-    (36, "Spanish from Spain (Español de España)", "es_ES"),
+    (33, "Hebrew (תירִבְעִ)", "he_IL", "hebrew"),
+    (34, "Estonian (Eestlane)", "et_EE", "estonian"),
+    (35, "Esperanto (Esperanto)", "eo", "esperanto"),
+    (36, "Spanish from Spain (Español de España)", "es_ES", "spanish_spain"),
 )
 
 # Name of language file used by Blender to generate translations' menu.
index 5eeeb152af7665429ccc7527dc9f95ef9a14437c..d45a55432207fdc141b46643bca1410fb9858ce9 100755 (executable)
@@ -53,7 +53,7 @@ FLAG_MESSAGES = {
 def find_matching_po(languages, stats, forbidden):
     """Match languages defined in LANGUAGES setting to relevant po, if possible!"""
     ret = []
-    for uid, label, org_key in languages:
+    for uid, label, org_key, long_loc in languages:
         key = org_key
         if key not in stats:
             # Try to simplify the key (eg from es_ES to es).
@@ -64,11 +64,11 @@ def find_matching_po(languages, stats, forbidden):
                 key = key + org_key[org_key.index('@'):]
         if key in stats:
             if key in forbidden:
-                ret.append((stats[key], uid, label, org_key, FORBIDDEN))
+                ret.append((stats[key], uid, label, org_key, long_loc, FORBIDDEN))
             else:
-                ret.append((stats[key], uid, label, org_key, OK))
+                ret.append((stats[key], uid, label, org_key, long_loc, OK))
         else:
-            ret.append((0.0, uid, label, org_key, MISSING))
+            ret.append((0.0, uid, label, org_key, long_loc, MISSING))
     return ret
 
 def main():
@@ -103,14 +103,14 @@ def main():
     stats = sorted(stats, key=lambda it: it[0], reverse=True)
     langs_cats = [[] for i in range(len(limits))]
     highest_uid = 0
-    for prop, uid, label, key, flag in stats:
+    for prop, uid, label, key, long_loc, flag in stats:
         if prop < limits[idx][0]:
             # Sub-sort languages by iso-codes.
             langs_cats[idx].sort(key=lambda it: it[2])
             idx += 1
         if prop < min_trans and flag == OK:
             flag = TOOLOW
-        langs_cats[idx].append((uid, label, key, flag))
+        langs_cats[idx].append((uid, label, key, long_loc, flag))
         if abs(uid) > highest_uid:
             highest_uid = abs(uid)
     # Sub-sort last group of languages by iso-codes!
@@ -120,7 +120,7 @@ def main():
         f.write("# and to generate translation menu.\n")
         f.write("#\n")
         f.write("# File format:\n")
-        f.write("# ID:MENULABEL:ISOCODE\n")
+        f.write("# ID:MENULABEL:ISOCODE:WINCODE\n")
         f.write("# ID must be unique, except for 0 value (marks categories for menu).\n")
         f.write("# Line starting with a # are comments!\n")
         f.write("#\n")
@@ -130,17 +130,17 @@ def main():
             f.write("#\n")
             # Write "category menu label"...
             if langs_cat:
-                f.write("0:{}:\n".format(cat[1]))
+                f.write("0:{}::\n".format(cat[1]))
             else:
                 # Do not write the category if it has no language!
                 f.write("# Void category! #0:{}:\n".format(cat[1]))
             # ...and all matching language entries!
-            for uid, label, key, flag in langs_cat:
+            for uid, label, key, long_loc, flag in langs_cat:
                 if flag == OK:
-                    f.write("{}:{}:{}\n".format(uid, label, key))
+                    f.write("{}:{}:{}:{}\n".format(uid, label, key, long_loc))
                 else:
                     # Non-existing, commented entry!
-                    f.write("# {} #{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key))
+                    f.write("# {} #{}:{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key, long_loc))
 
 
 if __name__ == "__main__":
index 9f4cf72d1207a72b7c06a67df9ac9261195bdc32..501f8cd2958c696e740d3231fb9784b0fc0d329f 100644 (file)
@@ -65,12 +65,14 @@ static char global_language[32];
 static char global_encoding_name[32];
 
 static const char **locales = NULL;
+static char **long_locales = NULL; /* XXX Temp fix until we get a final solution with modern intl lib under windows! */
 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] : "")
+#define LONG_LOCALE(_id) (long_locales ? long_locales[_id] : "")
 
 static void free_locales(void)
 {
@@ -81,8 +83,18 @@ static void free_locales(void)
                        MEM_freeN((void*)locales_menu[idx].name);
                        MEM_freeN((void*)locales_menu[idx].description); /* Also frees locales's relevant value! */
                }
+
+               idx = num_locales;
+               while (idx--) {
+                       if (long_locales[idx]) {
+                               MEM_freeN(long_locales[idx]);
+                       }
+               }
+
                MEM_freeN(locales);
                locales = NULL;
+               MEM_freeN(long_locales);
+               long_locales = NULL;
        }
        if (locales_menu) {
                MEM_freeN(locales_menu);
@@ -128,9 +140,10 @@ static void fill_locales(void)
        /* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */
        if (num_locales > 0) {
                locales = MEM_callocN(num_locales * sizeof(char*), __func__);
+               long_locales = MEM_callocN(num_locales * sizeof(char*), __func__);
                while (line) {
                        int id;
-                       char *loc, *sep1, *sep2;
+                       char *loc, *sep1, *sep2, *sep3;
 
                        str = (char*) line->link;
                        if (str[0] == '#' || str[0] == '\0') {
@@ -144,23 +157,32 @@ static void fill_locales(void)
                                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);
+
+                                       sep2++;
+                                       sep3 = strchr(sep2, ':');
+                                       if (sep3) {
+                                               locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - 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))
+                                                       if (BLI_strnlen(loc, 2)) {
                                                                locales[id] = locales_menu[idx].description = BLI_strdup("");
+                                                               long_locales[id] = BLI_strdup("");
+                                                       }
                                                        /* Menu "label", not to be stored in locales! */
-                                                       else
+                                                       else {
                                                                locales_menu[idx].description = BLI_strdup("");
+                                                       }
                                                }
-                                               else
+                                               else {
                                                        locales[id] = locales_menu[idx].description = BLI_strdup(loc);
+                                                       long_locales[id] = BLI_strdup(sep3 + 1);
+                                               }
                                                idx++;
-                               
+                                       }
                                }
                        }
 
@@ -243,43 +265,39 @@ static void get_language(const char *locale, const char *lang, char *language, c
 void BLF_lang_set(const char *str)
 {
        char *locreturn;
-       const char *short_locale;
        int ok = TRUE;
        int ulang = ULANGUAGE;
 
        if ((U.transopts & USER_DOTRANSLATE) == 0)
                return;
 
-       if (str)
-               short_locale = str;
-       else
-               short_locale = LOCALE(ulang);
-
 #if defined(_WIN32) && !defined(FREE_WINDOWS)
        {
-               if (short_locale) {
+               const char *long_locale = str ? str : LONG_LOCALE(ulang);
+               if (long_locale) {
                        char *envStr;
 
-                       if (ulang) /* Use system setting. */
+                       if (ulang)
+                               envStr = BLI_sprintfN("LANG=%s", long_locale);
+                       else /* Use system setting. */
                                envStr = BLI_sprintfN("LANG=%s", getenv("LANG"));
-                       else
-                               envStr = BLI_sprintfN("LANG=%s", short_locale);
 
                        gettext_putenv(envStr);
                        MEM_freeN(envStr);
                }
 
-               locreturn = setlocale(LC_ALL, short_locale);
+               locreturn = setlocale(LC_ALL, long_locale);
 
                if (locreturn == NULL) {
                        if (G.debug & G_DEBUG)
-                               printf("Could not change locale to %s\n", short_locale);
+                               printf("Could not change locale to %s\n", long_locale);
 
                        ok = FALSE;
                }
        }
 #else
        {
+               const char *short_locale = str ? str : LOCALE(ulang);
                static char default_lang[64] = "\0";
                static char default_language[64] = "\0";
 
index e5aa152f68c856eb9622ec615baedb3434ca293c..2e0b3a3c64a5cd77bc4b91f48993758414f293f1 100644 (file)
@@ -828,6 +828,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
                mcol = DM_get_tessface_data_layer(dm, colType);
        }
 
+       printf("%s: %p(%d/%d)\n", __func__, mcol, CD_ID_MCOL, colType);
+
        cdDM_update_normals_from_pbvh(dm);
 
        /* back-buffer always uses legacy since VBO's would need the