[gimp] Bug 704592 - only load language lists once at gui startup.



commit a129f84c68568cc96c3f06a40e8bab6fba035a01
Author: Jehan <jehan girinstud io>
Date:   Sat Jul 20 14:51:13 2013 +0900

    Bug 704592 - only load language lists once at gui startup.
    
    Improvements:
    - setenv/getenv() are not thread-safe, hence they should be run only at
    startup before any threading occurs.
    - it is counter-productive to load the huge ISO-639 XML file each time
    the user opens the Preferences dialog or the text tool options.

 app/gui/gui.c                          |    4 +
 app/widgets/gimplanguagestore-parser.c |  396 ++++++++++++++++++++++----------
 app/widgets/gimplanguagestore-parser.h |    7 +-
 app/widgets/gimplanguagestore.c        |   28 ++--
 app/widgets/gimplanguagestore.h        |    6 -
 app/widgets/gimptranslationstore.c     |  140 +----------
 6 files changed, 315 insertions(+), 266 deletions(-)
---
diff --git a/app/gui/gui.c b/app/gui/gui.c
index f3ad117..b6825f5 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -60,6 +60,7 @@
 #include "widgets/gimpsessioninfo.h"
 #include "widgets/gimpuimanager.h"
 #include "widgets/gimpwidgets-utils.h"
+#include "widgets/gimplanguagestore-parser.h"
 
 #include "actions/actions.h"
 #include "actions/windows-commands.h"
@@ -199,6 +200,7 @@ gui_init (Gimp     *gimp,
   the_gui_gimp = gimp;
 
   gui_unique_init (gimp);
+  gimp_language_store_parser_init ();
 
   gimp_widgets_init (gui_help_func,
                      gui_get_foreground_func,
@@ -601,6 +603,8 @@ gui_exit_callback (Gimp     *gimp,
   gimp_tools_save (gimp, gui_config->save_tool_options, FALSE);
   gimp_tools_exit (gimp);
 
+  gimp_language_store_parser_clean ();
+
   return FALSE; /* continue exiting */
 }
 
diff --git a/app/widgets/gimplanguagestore-parser.c b/app/widgets/gimplanguagestore-parser.c
index 1d6c1c9..c1382fc 100644
--- a/app/widgets/gimplanguagestore-parser.c
+++ b/app/widgets/gimplanguagestore-parser.c
@@ -3,6 +3,7 @@
  *
  * gimplanguagestore-parser.c
  * Copyright (C) 2008, 2009  Sven Neumann <sven gimp org>
+ * Copyright (C) 2013  Jehan <jehan at girinstud.io>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,53 +51,259 @@ typedef struct
   IsoCodesParserState  state;
   IsoCodesParserState  last_known_state;
   gint                 unknown_depth;
-  GimpLanguageStore   *store;
+  GHashTable          *base_lang_list;
 } IsoCodesParser;
 
 
-static void  iso_codes_parser_start_element (GMarkupParseContext  *context,
-                                             const gchar          *element_name,
-                                             const gchar         **attribute_names,
-                                             const gchar         **attribute_values,
-                                             gpointer              user_data,
-                                             GError              **error);
-static void  iso_codes_parser_end_element   (GMarkupParseContext  *context,
-                                             const gchar          *element_name,
-                                             gpointer              user_data,
-                                             GError              **error);
+static gboolean parse_iso_codes                 (GHashTable  *base_lang_list,
+                                                 GError     **error);
+static void     iso_codes_parser_init           (void);
+static void     iso_codes_parser_start_element  (GMarkupParseContext  *context,
+                                                 const gchar          *element_name,
+                                                 const gchar         **attribute_names,
+                                                 const gchar         **attribute_values,
+                                                 gpointer              user_data,
+                                                 GError              **error);
+static void     iso_codes_parser_end_element    (GMarkupParseContext  *context,
+                                                 const gchar          *element_name,
+                                                 gpointer              user_data,
+                                                 GError              **error);
+
+static void     iso_codes_parser_start_unknown  (IsoCodesParser       *parser);
+static void     iso_codes_parser_end_unknown    (IsoCodesParser       *parser);
+
+/*
+ * Language lists that we want to generate only once at program startup:
+ * @l10n_lang_list: all available localizations self-localized;
+ * @all_lang_list: all known languages, in the user-selected language.
+ */
+static GHashTable *l10n_lang_list = NULL;
+static GHashTable *all_lang_list = NULL;
 
-static void  iso_codes_parser_start_unknown (IsoCodesParser       *parser);
-static void  iso_codes_parser_end_unknown   (IsoCodesParser       *parser);
+/********************\
+ * Public Functions *
+\********************/
 
-static void  gimp_language_store_self_l10n  (GimpLanguageStore *store,
-                                             const gchar       *lang,
-                                             const gchar       *code);
+/*
+ * Initialize and run the language listing parser. This call must be
+ * made only once, at program initialization, but after language_init().
+ */
+void
+gimp_language_store_parser_init (void)
+{
+  GHashTable     *base_lang_list;
+  gchar          *current_env    = g_strdup (g_getenv ("LANGUAGE"));
+  GDir           *locales_dir;
+  GHashTableIter  lang_iter;
+  gpointer        key;
 
+  if (l10n_lang_list != NULL)
+    {
+      g_warning ("gimp_language_store_parser_init() must be run only once.");
+      return;
+    }
 
-static void
-iso_codes_parser_init (void)
-{
-  static gboolean initialized = FALSE;
+  l10n_lang_list = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                          (GDestroyNotify) g_free,
+                                          (GDestroyNotify) g_free);
+  all_lang_list = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                         (GDestroyNotify) g_free,
+                                         (GDestroyNotify) g_free);
+  base_lang_list = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                          (GDestroyNotify) g_free,
+                                          (GDestroyNotify) g_free);
+
+  /* Check all locales we have translations for. */
+  locales_dir = g_dir_open (gimp_locale_directory (), 0, NULL);
+  if (locales_dir)
+    {
+      const gchar *locale;
 
-  if (initialized)
-    return;
+      while ((locale = g_dir_read_name (locales_dir)) != NULL)
+        {
+          gchar *filename = g_build_filename (gimp_locale_directory (),
+                                              locale,
+                                              "LC_MESSAGES",
+                                              GETTEXT_PACKAGE ".mo",
+                                              NULL);
+          if (g_file_test (filename, G_FILE_TEST_EXISTS))
+            {
+              gchar *delimiter = strchr (locale, '_');
+              gchar *base_code = NULL;
+
+              if (delimiter)
+                base_code = g_strndup (locale, delimiter - locale);
+              else
+                base_code = g_strdup (locale);
+
+              delimiter = strchr (base_code, '@');
+
+              if (delimiter)
+                {
+                  gchar *temp = base_code;
+                  base_code = g_strndup (base_code, delimiter - base_code);
+                  g_free (temp);
+                }
+
+              /* Save the full language code. */
+              g_hash_table_insert (l10n_lang_list, g_strdup (locale), NULL);
+              /* Save the base language code. */
+              g_hash_table_insert (base_lang_list, base_code, NULL);
+            }
+
+          g_free (filename);
+        }
 
-#ifdef G_OS_WIN32
-  /*  on Win32, assume iso-codes is installed in the same location as GIMP  */
-  bindtextdomain ("iso_639", gimp_locale_directory ());
-#else
-  bindtextdomain ("iso_639", ISO_CODES_LOCALEDIR);
-#endif
+      g_dir_close (locales_dir);
+    }
 
-  bind_textdomain_codeset ("iso_639", "UTF-8");
+  /* Parse ISO-639 file to get full list of language and their names. */
+  parse_iso_codes (base_lang_list, NULL);
 
-  initialized = TRUE;
+  /* Generate the localized language names. */
+  g_hash_table_iter_init (&lang_iter, l10n_lang_list);
+  while (g_hash_table_iter_next (&lang_iter, &key, NULL))
+    {
+      gchar *code = GINT_TO_POINTER (key);
+      gchar *english_name;
+      gchar *delimiter = strchr (code, '_');
+      gchar *base_code;
+
+      if (delimiter)
+        base_code = g_strndup (code, delimiter - code);
+      else
+        base_code = g_strdup (code);
+
+      delimiter = strchr (base_code, '@');
+
+      if (delimiter)
+        {
+          gchar *temp = base_code;
+          base_code = g_strndup (base_code, delimiter - base_code);
+          g_free (temp);
+        }
+
+      english_name = GINT_TO_POINTER (g_hash_table_lookup (base_lang_list, base_code));
+
+      if (english_name)
+        {
+          gchar *localized_name;
+          gchar *semicolon;
+
+          /* If possible, we want to localize a language in itself.
+           * If it fails, gettext fallbacks to C (en_US) itself.
+           */
+          g_setenv ("LANGUAGE", code, TRUE);
+          setlocale (LC_ALL, "");
+
+          localized_name = g_strdup (dgettext ("iso_639", english_name));
+
+          /* If original and localized names are the same for other than English,
+           * maybe localization failed. Try now in the main dialect. */
+          if (g_strcmp0 (english_name, localized_name) == 0 &&
+              g_strcmp0 (base_code, "en") != 0 &&
+              g_strcmp0 (code, base_code) != 0)
+            {
+              g_free (localized_name);
+
+              g_setenv ("LANGUAGE", base_code, TRUE);
+              setlocale (LC_ALL, "");
+
+              localized_name = g_strdup (dgettext ("iso_639", english_name));
+            }
+
+          /*  there might be several language names; use the first one  */
+          semicolon = strchr (localized_name, ';');
+
+          if (semicolon)
+            {
+              gchar *temp = localized_name;
+              localized_name = g_strndup (localized_name, semicolon - localized_name);
+              g_free (temp);
+            }
+
+          g_hash_table_replace (l10n_lang_list, g_strdup(code),
+                                g_strdup_printf ("%s [%s]",
+                                                 localized_name ?
+                                                 localized_name : "???",
+                                                 code));
+          g_free (localized_name);
+        }
+
+      g_free (base_code);
+    }
+
+  /*  Add special entries for system locale.
+   *  We want the system locale to be localized in itself. */
+  g_setenv ("LANGUAGE", setlocale (LC_ALL, NULL), TRUE);
+  setlocale (LC_ALL, "");
+
+  /* g_str_hash() does not accept NULL. I give an empty code instead.
+   * Other solution would to create a custom hash. */
+  g_hash_table_insert (l10n_lang_list, g_strdup(""),
+                       g_strdup (_("System Language")));
+
+  /* Go back to original localization. */
+  if (current_env)
+    {
+      g_setenv ("LANGUAGE", current_env, TRUE);
+      g_free (current_env);
+    }
+  else
+    g_unsetenv ("LANGUAGE");
+  setlocale (LC_ALL, "");
+
+  /* Add special entry for C (en_US). */
+  g_hash_table_insert (l10n_lang_list, g_strdup ("en_US"),
+                       g_strdup ("English [en_US]"));
+
+  g_hash_table_destroy (base_lang_list);
 }
 
-gboolean
-gimp_language_store_parse_iso_codes (GimpLanguageStore  *store,
-                                     GError            **error)
+void
+gimp_language_store_parser_clean (void)
 {
+  g_hash_table_destroy (l10n_lang_list);
+  g_hash_table_destroy (all_lang_list);
+}
+
+/*
+ * Returns a Hash table of languages.
+ * Keys and values are respectively language codes and names from the
+ * ISO-639 standard code.
+ *
+ * If @localization_only is TRUE, it returns only the list of available
+ * GIMP localizations, and language names are translated in their own
+ * locale.
+ * If @localization_only is FALSE, the full list of ISO-639 languages
+ * is returned, and language names are in the user-set locale.
+ *
+ * Do not free the list or elements of the list.
+ */
+GHashTable *
+gimp_language_store_parser_get_languages (gboolean localization_only)
+{
+  if (localization_only)
+    return l10n_lang_list;
+  else
+    return all_lang_list;
+}
+
+/*****************************\
+ * Private Parsing Functions *
+\*****************************/
+
+/*
+ * Parse the ISO-639 code list if available on this system, and fill
+ * @base_lang_list with English names of all needed base codes.
+ *
+ * It will also fill the static @all_lang_list.
+ */
+static gboolean
+parse_iso_codes (GHashTable  *base_lang_list,
+                 GError     **error)
+{
+  gboolean         success = TRUE;
 #ifdef HAVE_ISO_CODES
   static const GMarkupParser markup_parser =
     {
@@ -109,15 +316,13 @@ gimp_language_store_parse_iso_codes (GimpLanguageStore  *store,
 
   GimpXmlParser   *xml_parser;
   gchar           *filename;
-  gboolean         success;
   IsoCodesParser   parser = { 0, };
 
-  g_return_val_if_fail (GIMP_IS_LANGUAGE_STORE (store), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   iso_codes_parser_init ();
 
-  parser.store = g_object_ref (store);
+  parser.base_lang_list = g_hash_table_ref (base_lang_list);
 
   xml_parser = gimp_xml_parser_new (&markup_parser, &parser);
 
@@ -134,12 +339,31 @@ gimp_language_store_parse_iso_codes (GimpLanguageStore  *store,
   g_free (filename);
 
   gimp_xml_parser_free (xml_parser);
-  g_object_unref (parser.store);
+  g_hash_table_unref (parser.base_lang_list);
+
+#endif
 
   return success;
+}
+
+static void
+iso_codes_parser_init (void)
+{
+  static gboolean initialized = FALSE;
+
+  if (initialized)
+    return;
+
+#ifdef G_OS_WIN32
+  /*  on Win32, assume iso-codes is installed in the same location as GIMP  */
+  bindtextdomain ("iso_639", gimp_locale_directory ());
+#else
+  bindtextdomain ("iso_639", ISO_CODES_LOCALEDIR);
 #endif
 
-  return TRUE;
+  bind_textdomain_codeset ("iso_639", "UTF-8");
+
+  initialized = TRUE;
 }
 
 static void
@@ -153,101 +377,41 @@ iso_codes_parser_entry (IsoCodesParser  *parser,
   while (*names && *values)
     {
       if (strcmp (*names, "name") == 0)
-        {
-          lang = *values;
-        }
+        lang = *values;
       else if (strcmp (*names, "iso_639_2B_code") == 0 && code == NULL)
-        {
-          /* 2-letter ISO 639-1 codes have priority.
-           * But some languages have no 2-letter code.
-           * Ex: Asturian (ast).
-           */
-          code = *values;
-        }
+        /* 2-letter ISO 639-1 codes have priority.
+         * But some languages have no 2-letter code. Ex: Asturian (ast).
+         */
+        code = *values;
       else if (strcmp (*names, "iso_639_2T_code") == 0 && code == NULL)
-        {
-          code = *values;
-        }
+        code = *values;
       else if (strcmp (*names, "iso_639_1_code") == 0)
-        {
-          code = *values;
-        }
+        code = *values;
 
       names++;
       values++;
     }
 
-  /* This is a hack for some special exception.
-   * It seems localization won't work for the base language "zh". Probably because
-   * written locale dialect are too different. So we have to be accurate and localize
-   * separately each Chinese dialect we support.
-   *
-   * There was unfortunately no cleaner way to achieve this since there is no standardized
-   * link between regions in iso-3166 and base languages in iso-639, which would allow
-   * automatization for generating locale dialects codes.
-   */
-  if (g_strcmp0 (code, "zh") == 0)
-    {
-      gimp_language_store_self_l10n (parser->store, "Chinese", "zh_CN");
-      gimp_language_store_self_l10n (parser->store, "Chinese", "zh_TW");
-      gimp_language_store_self_l10n (parser->store, "Chinese", "zh_HK");
-    }
-  else
-    gimp_language_store_self_l10n (parser->store, lang, code);
-}
-
-/* If possible, we want to localize a language in itself.
- * If it fails, fallback to the currently selected language, then to system lang.
- * Only fallback to C (en_US) as a last resort.
- */
-static void
-gimp_language_store_self_l10n (GimpLanguageStore *store,
-                               const gchar       *lang,
-                               const gchar       *code)
-{
   if (lang && *lang && code && *code)
     {
-      const gchar *semicolon;
-
-      /* English does not need localization. */
-      if (g_strcmp0 (code, "en") != 0)
-        {
-          gchar *current_lang = g_strdup (g_getenv ("LANGUAGE"));
-          gchar *temp_lang;
+      gchar *semicolon;
+      gchar *localized_name = g_strdup (dgettext ("iso_639", lang));
 
-          if (current_lang)
-            temp_lang = g_strdup_printf ("%s:%s:%s", code, current_lang, setlocale (LC_ALL, NULL));
-          else
-            temp_lang = g_strdup (code);
-
-          /* Temporarily change the localization language. */
-          g_setenv ("LANGUAGE", temp_lang, TRUE);
-          setlocale (LC_ALL, "");
-          lang = dgettext ("iso_639", lang);
-          if (current_lang)
-            g_setenv ("LANGUAGE", current_lang, TRUE);
-          else
-            g_unsetenv("LANGUAGE");
-          setlocale (LC_ALL, "");
-
-          g_free (current_lang);
-          g_free (temp_lang);
-        }
+      /* If the language is in our base table, we save its standard English name. */
+      if (g_hash_table_contains (parser->base_lang_list, code))
+        g_hash_table_replace (parser->base_lang_list, g_strdup (code), g_strdup (lang));
 
       /*  there might be several language names; use the first one  */
-      semicolon = strchr (lang, ';');
+      semicolon = strchr (localized_name, ';');
 
       if (semicolon)
         {
-          gchar *first = g_strndup (lang, semicolon - lang);
-
-          gimp_language_store_add (store, first, code);
-          g_free (first);
-        }
-      else
-        {
-          gimp_language_store_add (store, lang, code);
+          gchar *temp = localized_name;
+          localized_name = g_strndup (localized_name, semicolon - localized_name);
+          g_free (temp);
         }
+      /* In any case, we save the name in user-set language for all lang. */
+      g_hash_table_insert (all_lang_list, g_strdup (code), localized_name);
     }
 }
 
diff --git a/app/widgets/gimplanguagestore-parser.h b/app/widgets/gimplanguagestore-parser.h
index d84edd1..b5a79b5 100644
--- a/app/widgets/gimplanguagestore-parser.h
+++ b/app/widgets/gimplanguagestore-parser.h
@@ -3,6 +3,7 @@
  *
  * gimplanguagestore-parser.h
  * Copyright (C) 2008, 2009  Sven Neumann <sven gimp org>
+ * Copyright (C) 2013  Jehan <jehan at girinstud.io>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,8 +23,10 @@
 #define __GIMP_LANGUAGE_STORE_PARSER_H__
 
 
-gboolean  gimp_language_store_parse_iso_codes (GimpLanguageStore  *store,
-                                               GError            **error);
+void        gimp_language_store_parser_init          (void);
 
+void        gimp_language_store_parser_clean         (void);
+
+GHashTable* gimp_language_store_parser_get_languages (gboolean localization_only);
 
 #endif  /* __GIMP_LANGUAGE_STORE_PARSER_H__ */
diff --git a/app/widgets/gimplanguagestore.c b/app/widgets/gimplanguagestore.c
index ff584c6..8477ba2 100644
--- a/app/widgets/gimplanguagestore.c
+++ b/app/widgets/gimplanguagestore.c
@@ -76,9 +76,20 @@ gimp_language_store_init (GimpLanguageStore *store)
 static void
 gimp_language_store_constructed (GObject *object)
 {
+  GHashTable     *lang_list;
+  GHashTableIter  lang_iter;
+  gpointer        code;
+  gpointer        name;
+
   G_OBJECT_CLASS (parent_class)->constructed (object);
 
-  gimp_language_store_parse_iso_codes (GIMP_LANGUAGE_STORE (object), NULL);
+  lang_list = gimp_language_store_parser_get_languages (FALSE);
+  g_hash_table_iter_init (&lang_iter, lang_list);
+
+  while (g_hash_table_iter_next (&lang_iter, &code, &name))
+    GIMP_LANGUAGE_STORE_GET_CLASS (object)->add (GIMP_LANGUAGE_STORE (object),
+                                                 GINT_TO_POINTER (name),
+                                                 GINT_TO_POINTER (code));
 }
 
 static void
@@ -109,10 +120,10 @@ gimp_language_store_sort (GtkTreeModel *model,
   gtk_tree_model_get_value (model, a, GIMP_LANGUAGE_STORE_CODE, &avalue);
   gtk_tree_model_get_value (model, b, GIMP_LANGUAGE_STORE_CODE, &bvalue);
 
-  if (! g_value_get_string (&avalue))
+  if (g_strcmp0 ("", g_value_get_string (&avalue)) == 0)
     cmp = -1;
 
-  if (! g_value_get_string (&bvalue))
+  if (g_strcmp0 ("", g_value_get_string (&bvalue)) == 0)
     cmp = 1;
 
   g_value_unset (&avalue);
@@ -140,17 +151,6 @@ gimp_language_store_new (void)
   return g_object_new (GIMP_TYPE_LANGUAGE_STORE, NULL);
 }
 
-void
-gimp_language_store_add (GimpLanguageStore *store,
-                         const gchar       *label,
-                         const gchar       *code)
-{
-  g_return_if_fail (GIMP_IS_LANGUAGE_STORE (store));
-  g_return_if_fail (label != NULL);
-
-  GIMP_LANGUAGE_STORE_GET_CLASS (store)->add (store, label, code);
-}
-
 gboolean
 gimp_language_store_lookup (GimpLanguageStore *store,
                             const gchar       *code,
diff --git a/app/widgets/gimplanguagestore.h b/app/widgets/gimplanguagestore.h
index 88200a6..c041eae 100644
--- a/app/widgets/gimplanguagestore.h
+++ b/app/widgets/gimplanguagestore.h
@@ -62,10 +62,4 @@ gboolean       gimp_language_store_lookup   (GimpLanguageStore *store,
                                              const gchar       *code,
                                              GtkTreeIter       *iter);
 
-/*  used from gimplanguagestore-parser.c  */
-void           gimp_language_store_add      (GimpLanguageStore *store,
-                                             const gchar       *label,
-                                             const gchar       *code);
-
-
 #endif  /* __GIMP_LANGUAGE_STORE_H__ */
diff --git a/app/widgets/gimptranslationstore.c b/app/widgets/gimptranslationstore.c
index 1304fcb..15b7113 100644
--- a/app/widgets/gimptranslationstore.c
+++ b/app/widgets/gimptranslationstore.c
@@ -18,8 +18,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
-
 #include <locale.h>
 #include <string.h>
 
@@ -31,8 +29,6 @@
 
 #include "gimptranslationstore.h"
 
-#include "gimp-intl.h"
-
 
 struct _GimpTranslationStoreClass
 {
@@ -42,19 +38,11 @@ struct _GimpTranslationStoreClass
 struct _GimpTranslationStore
 {
   GimpLanguageStore  parent_instance;
-
-  GHashTable        *map;
 };
 
 
 static void   gimp_translation_store_constructed (GObject              *object);
 
-static void   gimp_translation_store_add         (GimpLanguageStore    *store,
-                                                  const gchar          *lang,
-                                                  const gchar          *code);
-
-static void   gimp_translation_store_populate    (GimpTranslationStore *store);
-
 
 G_DEFINE_TYPE (GimpTranslationStore, gimp_translation_store,
                GIMP_TYPE_LANGUAGE_STORE)
@@ -66,134 +54,30 @@ static void
 gimp_translation_store_class_init (GimpTranslationStoreClass *klass)
 {
   GObjectClass           *object_class = G_OBJECT_CLASS (klass);
-  GimpLanguageStoreClass *store_class  = GIMP_LANGUAGE_STORE_CLASS (klass);
 
   object_class->constructed = gimp_translation_store_constructed;
-
-  store_class->add          = gimp_translation_store_add;
 }
 
 static void
 gimp_translation_store_init (GimpTranslationStore *store)
 {
-  store->map = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                      (GDestroyNotify) g_free,
-                                      (GDestroyNotify) g_free);
 }
 
 static void
 gimp_translation_store_constructed (GObject *object)
 {
-  GimpTranslationStore *store        = GIMP_TRANSLATION_STORE (object);
-  gchar                *current_lang = g_strdup (g_getenv ("LANGUAGE"));
-  gchar                *label;
-
-  G_OBJECT_CLASS (parent_class)->constructed (object);
-
-  gimp_translation_store_populate (store);
-
-  /*  we don't need the map any longer  */
-  g_hash_table_unref (store->map);
-  store->map = NULL;
-
-  /*  add special entries for system locale and for "C".
-   *  We want the system locale to be localized in itself. */
-  g_setenv ("LANGUAGE", setlocale (LC_ALL, NULL), TRUE);
-  setlocale (LC_ALL, "");
-  label = g_strdup_printf ("%s", _("System Language"));
-  if (current_lang)
-    g_setenv ("LANGUAGE", current_lang, TRUE);
-  else
-    g_unsetenv ("LANGUAGE");
-  setlocale (LC_ALL, "");
-  g_free (current_lang);
-
-  GIMP_LANGUAGE_STORE_CLASS (parent_class)->add (GIMP_LANGUAGE_STORE (store),
-                                                 label,
-                                                 NULL);
-  g_free (label);
-
-  label = g_strdup_printf ("%s [%s]", "English", "en_US");
-  GIMP_LANGUAGE_STORE_CLASS (parent_class)->add (GIMP_LANGUAGE_STORE (store),
-                                                 label, "en_US");
-  g_free (label);
-}
-
-static const gchar *
-gimp_translation_store_map (GimpTranslationStore *store,
-                            const gchar          *locale)
-{
-  const gchar *lang;
-
-  /*  A locale directory name is typically of the form language[_territory]  */
-  lang = g_hash_table_lookup (store->map, locale);
-
-  if (! lang)
-    {
-      /*  strip off the territory suffix  */
-      const gchar *delimiter = strchr (locale, '_');
-
-      if (delimiter)
-        {
-          gchar *copy;
-
-          copy = g_strndup (locale, delimiter - locale);
-          lang = g_hash_table_lookup (store->map, copy);
-          g_free (copy);
-        }
-    }
-
-  return lang;
-}
-
-static void
-gimp_translation_store_populate (GimpTranslationStore *store)
-{
-  /*  FIXME: this should better be done asynchronously  */
-  GDir        *dir = g_dir_open (gimp_locale_directory (), 0, NULL);
-  const gchar *dirname;
-
-  if (! dir)
-    return;
-
-  while ((dirname = g_dir_read_name (dir)) != NULL)
-    {
-      gchar *filename = g_build_filename (gimp_locale_directory (),
-                                          dirname,
-                                          "LC_MESSAGES",
-                                          GETTEXT_PACKAGE ".mo",
-                                          NULL);
-      if (g_file_test (filename, G_FILE_TEST_EXISTS))
-        {
-          const gchar *lang = gimp_translation_store_map (store, dirname);
-
-          if (lang)
-            {
-              GimpLanguageStore *language_store = GIMP_LANGUAGE_STORE (store);
-              gchar             *label;
-
-              label = g_strdup_printf ("%s [%s]", lang, dirname);
-
-              GIMP_LANGUAGE_STORE_CLASS (parent_class)->add (language_store,
-                                                             label, dirname);
-              g_free (label);
-            }
-        }
-
-      g_free (filename);
-    }
-
-  g_dir_close (dir);
-}
-
-static void
-gimp_translation_store_add (GimpLanguageStore *store,
-                            const gchar       *lang,
-                            const gchar       *code)
-{
-  g_hash_table_replace (GIMP_TRANSLATION_STORE (store)->map,
-                        g_strdup (code),
-                        g_strdup (lang));
+  GHashTable     *lang_list;
+  GHashTableIter  lang_iter;
+  gpointer        code;
+  gpointer        name;
+
+  lang_list = gimp_language_store_parser_get_languages (TRUE);
+  g_hash_table_iter_init (&lang_iter, lang_list);
+
+  while (g_hash_table_iter_next (&lang_iter, &code, &name))
+    GIMP_LANGUAGE_STORE_GET_CLASS (object)->add (GIMP_LANGUAGE_STORE (object),
+                                                 GINT_TO_POINTER (name),
+                                                 GINT_TO_POINTER (code));
 }
 
 GtkListStore *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]