[gtranslator] Provide a way to automatize the profile filling. Fixes bug #547610.



commit bd45c4f729dbf1c3ea604fa4cb2b1041bece6526
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Sun Apr 3 23:18:30 2011 +0200

    Provide a way to automatize the profile filling. Fixes bug #547610.

 configure.ac                      |   26 +++
 data/Makefile.am                  |    1 +
 data/gtr-plural-forms.ini         |    4 +
 src/Makefile.am                   |    2 +
 src/dialogs/gtr-profile-dialog.c  |  339 +++++++++++++++++++++++++++++++------
 src/dialogs/gtr-profile-dialog.ui |  282 +++++++++++++++++++++----------
 src/gtr-language.c                |  278 ++++++++++++++++++++++++++++++
 src/gtr-language.h                |   51 ++++++
 8 files changed, 835 insertions(+), 148 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8330094..bbde000 100644
--- a/configure.ac
+++ b/configure.ac
@@ -144,6 +144,32 @@ else
 fi
 AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
 
+dnl ================================================================
+dnl iso-codes
+dnl ================================================================
+
+ISO_CODES_REQUIRED=0.35
+
+PKG_CHECK_EXISTS([iso-codes >= $ISO_CODES_REQUIRED],
+		 [have_iso_codes=yes],[have_iso_codes=no])
+
+if test "x$have_iso_codes" = "xyes"; then
+	AC_MSG_CHECKING([whether iso-codes has iso-639 domain])
+	if $PKG_CONFIG --variable=domains iso-codes | grep 639 > /dev/null; then
+		result=yes
+	else
+		result=no
+		have_iso_codes=no
+	fi
+	AC_MSG_RESULT([$result])
+fi
+
+if test "x$have_iso_codes" = "xyes"; then
+	AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX],["`$PKG_CONFIG --variable=prefix iso-codes`"],[ISO codes prefix])
+else
+	AC_MSG_ERROR([iso-codes is required to build gtranslator.])
+fi
+
 dnl -------------------------------------------------------------------
 dnl Check for gtkspell >= 2.0 and use it if found
 dnl -------------------------------------------------------------------
diff --git a/data/Makefile.am b/data/Makefile.am
index e6806c5..7b63b10 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -11,6 +11,7 @@ uidir = $(pkgdatadir)
 ui_DATA =			\
 	gtranslator-ui.xml	\
 	gtr-toolbar.xml		\
+	gtr-plural-forms.ini	\
 	po.lang			\
 	layout.xml
 
diff --git a/data/gtr-plural-forms.ini b/data/gtr-plural-forms.ini
new file mode 100644
index 0000000..8d51a14
--- /dev/null
+++ b/data/gtr-plural-forms.ini
@@ -0,0 +1,4 @@
+[Plural Forms]
+
+es=nplurals=2; plural=(n!=1);
+gl=nplurals=2; plural=(n!=1);
diff --git a/src/Makefile.am b/src/Makefile.am
index 7b0765f..11d7fe6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,6 +81,7 @@ NOINST_H_FILES = \
 	gtr-history-entry.h \
 	gtr-io-error-info-bar.h \
 	gtr-message-table-model.h \
+	gtr-language.h \
 	gtr-plugins-engine.h \
 	gtr-profile-manager.h \
 	gtr-settings.h \
@@ -115,6 +116,7 @@ libgtranslator_c_files = \
 	gtr-message-table-model.c \
 	gtr-msg.c \
 	gtr-notebook.c \
+	gtr-language.c \
 	gtr-plugins-engine.c \
 	gtr-po.c \
 	gtr-profile.c \
diff --git a/src/dialogs/gtr-profile-dialog.c b/src/dialogs/gtr-profile-dialog.c
index 0f0099b..f4f63c0 100644
--- a/src/dialogs/gtr-profile-dialog.c
+++ b/src/dialogs/gtr-profile-dialog.c
@@ -28,13 +28,13 @@
 #include "gtr-profile-dialog.h"
 #include "gtr-profile.h"
 #include "gtr-utils.h"
+#include "gtr-language.h"
 
 #include <string.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-
 #define GTR_PROFILE_DIALOG_GET_PRIVATE(object)	(G_TYPE_INSTANCE_GET_PRIVATE ( \
                                                  (object), \
                                                  GTR_TYPE_PROFILE_DIALOG, \
@@ -46,17 +46,20 @@ struct _GtrProfileDialogPrivate
 {
   GtkWidget *main_box;
 
-  GtkWidget *profile_name_entry;
+  GtkWidget *profile_name;
+
+  GtkWidget *author_name;
+  GtkWidget *author_email;
 
-  GtkWidget *author_name_entry;
-  GtkWidget *author_email_entry;
+  GtkWidget *language;
+  GtkWidget *language_code;
+  GtkWidget *charset;
+  GtkWidget *encoding;
+  GtkWidget *team_email;
+  GtkWidget *plural_forms;
 
-  GtkWidget *language_name_entry;
-  GtkWidget *language_code_entry;
-  GtkWidget *charset_entry;
-  GtkWidget *encoding_entry;
-  GtkWidget *language_email_entry;
-  GtkWidget *plural_forms_entry;
+  GtkListStore *language_store;
+  GtkListStore *code_store;
 };
 
 static void
@@ -66,6 +69,213 @@ gtr_profile_dialog_class_init (GtrProfileDialogClass *klass)
 }
 
 static void
+append_from_languages (GtrProfileDialog *dlg)
+{
+  const GSList *languages, *l;
+  GHashTable *plurals;
+
+  plurals = g_hash_table_new (g_str_hash, g_int_equal);
+
+  languages = gtr_language_get_languages ();
+
+  for (l = languages; l != NULL; l = (const GSList *)g_list_next (l))
+    {
+      GtrLanguage *lang = (GtrLanguage *)l->data;
+      GtkTreeIter iter1, iter2;
+      const gchar *plural_form;
+
+      gtk_list_store_append (dlg->priv->language_store, &iter1);
+      gtk_list_store_set (dlg->priv->language_store, &iter1,
+                          0, gtr_language_get_name (lang),
+                          1, lang,
+                          -1);
+
+      gtk_list_store_append (dlg->priv->code_store, &iter2);
+      gtk_list_store_set (dlg->priv->code_store, &iter2,
+                          0, gtr_language_get_code (lang),
+                          1, lang,
+                          -1);
+
+      plural_form = gtr_language_get_plural_form (lang);
+      if (plural_form != NULL && *plural_form != '\0')
+        {
+          gint *value;
+
+          value = g_hash_table_lookup (plurals, plural_form);
+          if (value == NULL)
+            {
+              g_hash_table_insert (plurals, (gchar *)plural_form, GINT_TO_POINTER (1));
+              gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dlg->priv->plural_forms),
+                                              plural_form);
+            }
+        }
+    }
+
+    g_hash_table_unref (plurals);
+}
+
+static void
+fill_encoding_and_charset (GtrProfileDialog *dlg)
+{
+  const gchar *text;
+
+  text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->charset))));
+
+  if (text == NULL || *text == '\0')
+    gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->priv->charset), 0);
+
+  text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->encoding))));
+
+  if (text == NULL || *text == '\0')
+    gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->priv->encoding), 0);
+}
+
+static void
+fill_from_language_entry (GtrProfileDialog *dlg,
+                          GtrLanguage      *lang)
+{
+  const gchar *entry_text;
+
+  fill_encoding_and_charset (dlg);
+
+  entry_text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code))));
+
+  if (*entry_text == '\0')
+    {
+      const gchar *code;
+
+      code = gtr_language_get_code (lang);
+
+      if (code != NULL && *code != '\0')
+        gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code))), code);
+    }
+
+  entry_text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->plural_forms))));
+
+  if (*entry_text == '\0')
+    {
+      const gchar *plural_form;
+
+      plural_form = gtr_language_get_plural_form (lang);
+
+      if (plural_form != NULL && *plural_form != '\0')
+        gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->plural_forms))), plural_form);
+    }
+}
+
+static void
+fill_from_language_code_entry (GtrProfileDialog *dlg,
+                               GtrLanguage      *lang)
+{
+  const gchar *entry_text;
+
+  fill_encoding_and_charset (dlg);
+
+  entry_text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language))));
+
+  if (*entry_text == '\0')
+    {
+      const gchar *name;
+
+      name = gtr_language_get_name (lang);
+
+      if (name != NULL && *name != '\0')
+        gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language))), name);
+    }
+
+  entry_text = gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->plural_forms))));
+
+  if (*entry_text == '\0')
+    {
+      const gchar *plural_form;
+
+      plural_form = gtr_language_get_plural_form (lang);
+
+      if (plural_form != NULL && *plural_form != '\0')
+        gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->plural_forms))), plural_form);
+    }
+}
+
+typedef void (* fill_method) (GtrProfileDialog *dlg, GtrLanguage *lang);
+
+static void
+fill_boxes (GtrProfileDialog *dlg,
+            GtkEntry         *entry,
+            GtkTreeModel     *store,
+            fill_method       fill)
+{
+  const gchar *text;
+  gchar *entry_row;
+  GtkTreeIter iter;
+  GtrLanguage *lang;
+  gboolean found = FALSE;
+
+  text = gtk_entry_get_text (entry);
+
+  if (text == NULL || *text == '\0' ||
+      !gtk_tree_model_get_iter_first (store, &iter))
+    return;
+
+  do
+    {
+      gtk_tree_model_get (store, &iter,
+                          0, &entry_row,
+                          -1);
+
+      if (entry_row != NULL && strcmp (entry_row, text) == 0)
+        {
+          found = TRUE;
+          g_free (entry_row);
+          break;
+        }
+
+      g_free (entry_row);
+    }
+  while (gtk_tree_model_iter_next (store, &iter));
+
+  if (found)
+    {
+      gtk_tree_model_get (store, &iter,
+                          1, &lang,
+                          -1);
+
+      fill (dlg, lang);
+    }
+}
+
+static void
+on_language_activate (GtkEntry         *entry,
+                      GtrProfileDialog *dlg)
+{
+  fill_boxes (dlg, entry, GTK_TREE_MODEL (dlg->priv->language_store),
+              fill_from_language_entry);
+}
+
+static void
+on_language_focus_out_event (GtkEntry         *entry,
+                             GdkEvent         *event,
+                             GtrProfileDialog *dlg)
+{
+  on_language_activate (entry, dlg);
+}
+
+static void
+on_language_code_activate (GtkEntry         *entry,
+                           GtrProfileDialog *dlg)
+{
+  fill_boxes (dlg, entry, GTK_TREE_MODEL (dlg->priv->code_store),
+              fill_from_language_code_entry);
+}
+
+static void
+on_language_code_focus_out_event (GtkEntry         *entry,
+                                  GdkEvent         *event,
+                                  GtrProfileDialog *dlg)
+{
+  on_language_code_activate (entry, dlg);
+}
+
+static void
 gtr_profile_dialog_init (GtrProfileDialog *dlg)
 {
   gboolean ret;
@@ -73,15 +283,16 @@ gtr_profile_dialog_init (GtrProfileDialog *dlg)
   GtkBox *content_area;
   gchar *path;
   gchar *root_objects[] = {
-    "profiles_dialog",
+    "main_box",
+    "language_store",
+    "code_store",
     NULL
   };
 
   dlg->priv = GTR_PROFILE_DIALOG_GET_PRIVATE (dlg);
 
-  gtk_dialog_add_buttons (GTK_DIALOG (dlg),
-                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                          NULL);
+  gtk_dialog_add_button (GTK_DIALOG (dlg),
+                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
 
   gtk_window_set_title (GTK_WINDOW (dlg), _("Gtranslator Profile"));
   gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
@@ -101,26 +312,20 @@ gtr_profile_dialog_init (GtrProfileDialog *dlg)
   ret = gtr_utils_get_ui_objects (path,
                                   root_objects,
                                   &error_widget,
-                                  "profiles_dialog",
-                                  &dlg->priv->main_box,
-                                  "profile_entry",
-                                  &dlg->priv->profile_name_entry,
-                                  "name_entry",
-                                  &dlg->priv->author_name_entry,
-                                  "email_entry",
-                                  &dlg->priv->author_email_entry,
-                                  "language_entry",
-                                  &dlg->priv->language_name_entry,
-                                  "langcode_entry",
-                                  &dlg->priv->language_code_entry,
-                                  "charset_entry",
-                                  &dlg->priv->charset_entry,
-                                  "encoding_entry",
-                                  &dlg->priv->encoding_entry,
-                                  "team_email_entry",
-                                  &dlg->priv->language_email_entry,
-                                  "plurals_entry",
-                                  &dlg->priv->plural_forms_entry, NULL);
+                                  "main_box", &dlg->priv->main_box,
+                                  "profile_name", &dlg->priv->profile_name,
+                                  "name", &dlg->priv->author_name,
+                                  "email", &dlg->priv->author_email,
+                                  "language", &dlg->priv->language,
+                                  "language_code", &dlg->priv->language_code,
+                                  "charset", &dlg->priv->charset,
+                                  "encoding", &dlg->priv->encoding,
+                                  "team_email", &dlg->priv->team_email,
+                                  "plural_forms", &dlg->priv->plural_forms,
+
+                                  "language_store", &dlg->priv->language_store,
+                                  "code_store", &dlg->priv->code_store,
+                                  NULL);
   g_free (path);
 
   if (!ret)
@@ -132,45 +337,65 @@ gtr_profile_dialog_init (GtrProfileDialog *dlg)
     }
 
   gtk_box_pack_start (content_area, dlg->priv->main_box, FALSE, FALSE, 0);
+
+  /* add items to comboboxes */
+  append_from_languages (dlg);
+
+  g_signal_connect (gtk_bin_get_child (GTK_BIN (dlg->priv->language)),
+                    "activate",
+                    G_CALLBACK (on_language_activate),
+                    dlg);
+  g_signal_connect (gtk_bin_get_child (GTK_BIN (dlg->priv->language)),
+                    "focus-out-event",
+                    G_CALLBACK (on_language_focus_out_event),
+                    dlg);
+  g_signal_connect (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code)),
+                    "activate",
+                    G_CALLBACK (on_language_code_activate),
+                    dlg);
+  g_signal_connect (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code)),
+                    "focus-out-event",
+                    G_CALLBACK (on_language_code_focus_out_event),
+                    dlg);
 }
 
 static void
 fill_entries (GtrProfileDialog *dlg, GtrProfile *profile)
 {
   if (gtr_profile_get_name (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->profile_name_entry),
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->profile_name),
                         gtr_profile_get_name (profile));
 
   if (gtr_profile_get_author_name (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->author_name_entry),
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->author_name),
                         gtr_profile_get_author_name (profile));
 
   if (gtr_profile_get_author_email (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->author_email_entry),
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->author_email),
                         gtr_profile_get_author_email (profile));
 
   if (gtr_profile_get_language_name (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->language_name_entry),
+    gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language))),
                         gtr_profile_get_language_name (profile));
 
   if (gtr_profile_get_language_code (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->language_code_entry),
+    gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code))),
                         gtr_profile_get_language_code (profile));
 
   if (gtr_profile_get_charset (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->charset_entry),
+    gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->charset))),
                         gtr_profile_get_charset (profile));
 
   if (gtr_profile_get_encoding (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->encoding_entry),
+    gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->encoding))),
                         gtr_profile_get_encoding (profile));
 
   if (gtr_profile_get_group_email (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->language_email_entry),
+    gtk_entry_set_text (GTK_ENTRY (dlg->priv->team_email),
                         gtr_profile_get_group_email (profile));
 
   if (gtr_profile_get_plural_forms (profile) != NULL)
-    gtk_entry_set_text (GTK_ENTRY (dlg->priv->plural_forms_entry),
+    gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->plural_forms))),
                         gtr_profile_get_plural_forms (profile));
 }
 
@@ -209,37 +434,41 @@ GtrProfile *
 gtr_profile_dialog_get_profile (GtrProfileDialog *dlg)
 {
   GtrProfile *profile;
+  gchar *text;
 
   g_return_val_if_fail (GTR_IS_PROFILE_DIALOG (dlg), NULL);
 
   profile = gtr_profile_new ();
 
   gtr_profile_set_name (profile,
-                        gtk_entry_get_text (GTK_ENTRY (dlg->priv->profile_name_entry)));
+                        gtk_entry_get_text (GTK_ENTRY (dlg->priv->profile_name)));
 
   gtr_profile_set_author_name (profile,
-                               gtk_entry_get_text (GTK_ENTRY (dlg->priv->author_name_entry)));
+                               gtk_entry_get_text (GTK_ENTRY (dlg->priv->author_name)));
 
   gtr_profile_set_author_email (profile,
-                                gtk_entry_get_text (GTK_ENTRY (dlg->priv->author_email_entry)));
+                                gtk_entry_get_text (GTK_ENTRY (dlg->priv->author_email)));
 
   gtr_profile_set_language_name (profile,
-                                 gtk_entry_get_text (GTK_ENTRY (dlg->priv->language_name_entry)));
+                                 gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language)))));
 
   gtr_profile_set_language_code (profile,
-                                 gtk_entry_get_text (GTK_ENTRY (dlg->priv->language_code_entry)));
+                                 gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (dlg->priv->language_code)))));
 
-  gtr_profile_set_charset (profile,
-                           gtk_entry_get_text (GTK_ENTRY (dlg->priv->charset_entry)));
+  text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dlg->priv->charset));
+  gtr_profile_set_charset (profile, text);
+  g_free (text);
 
-  gtr_profile_set_encoding (profile,
-                            gtk_entry_get_text (GTK_ENTRY (dlg->priv->encoding_entry)));
+  text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dlg->priv->encoding));
+  gtr_profile_set_encoding (profile, text);
+  g_free (text);
 
   gtr_profile_set_group_email (profile,
-                               gtk_entry_get_text (GTK_ENTRY (dlg->priv->language_email_entry)));
+                               gtk_entry_get_text (GTK_ENTRY (dlg->priv->team_email)));
 
-  gtr_profile_set_plural_forms (profile,
-                                gtk_entry_get_text (GTK_ENTRY (dlg->priv->plural_forms_entry)));
+  text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dlg->priv->plural_forms));
+  gtr_profile_set_plural_forms (profile, text);
+  g_free (text);
 
   return profile;
 }
diff --git a/src/dialogs/gtr-profile-dialog.ui b/src/dialogs/gtr-profile-dialog.ui
index 77f5826..b50f3d4 100644
--- a/src/dialogs/gtr-profile-dialog.ui
+++ b/src/dialogs/gtr-profile-dialog.ui
@@ -1,34 +1,57 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkListStore" id="code_store">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name language -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="dialog1">
+    <property name="can_focus">False</property>
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <property name="border_width">5</property>
     <property name="window_position">center-on-parent</property>
     <property name="type_hint">dialog</property>
-    <property name="has_separator">False</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="vbox1">
+      <object class="GtkBox" id="vbox1">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+        </child>
         <child>
-          <object class="GtkVBox" id="profiles_dialog">
+          <object class="GtkVBox" id="main_box">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">18</property>
             <child>
               <object class="GtkVBox" id="vbox2">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label1">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Profile Information</property>
@@ -45,10 +68,12 @@
                 <child>
                   <object class="GtkHBox" id="hbox1">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <child>
                       <object class="GtkLabel" id="label2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                       </object>
                       <packing>
@@ -61,12 +86,13 @@
                     <child>
                       <object class="GtkTable" id="table1">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="n_columns">2</property>
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <object class="GtkEntry" id="profile_entry">
+                          <object class="GtkEntry" id="profile_name">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -79,11 +105,12 @@
                         <child>
                           <object class="GtkLabel" id="label3">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">_Name:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">profile_entry</property>
+                            <property name="mnemonic_widget">profile_name</property>
                           </object>
                           <packing>
                             <property name="x_options">GTK_FILL</property>
@@ -91,11 +118,15 @@
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -109,12 +140,13 @@
             <child>
               <object class="GtkVBox" id="vbox3">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label4">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Translator Information</property>
@@ -131,10 +163,12 @@
                 <child>
                   <object class="GtkHBox" id="hbox2">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <child>
                       <object class="GtkLabel" id="label5">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                       </object>
                       <packing>
@@ -147,13 +181,14 @@
                     <child>
                       <object class="GtkTable" id="table2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="n_rows">2</property>
                         <property name="n_columns">2</property>
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <object class="GtkEntry" id="email_entry">
+                          <object class="GtkEntry" id="email">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -168,11 +203,12 @@
                         <child>
                           <object class="GtkLabel" id="label7">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">_Email:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">email_entry</property>
+                            <property name="mnemonic_widget">email</property>
                           </object>
                           <packing>
                             <property name="top_attach">1</property>
@@ -183,18 +219,19 @@
                         <child>
                           <object class="GtkLabel" id="label6">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">N_ame:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">name_entry</property>
+                            <property name="mnemonic_widget">name</property>
                           </object>
                           <packing>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="name_entry">
+                          <object class="GtkEntry" id="name">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -206,11 +243,15 @@
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -224,12 +265,13 @@
             <child>
               <object class="GtkVBox" id="vbox4">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label8">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes">Language Settings</property>
@@ -246,10 +288,12 @@
                 <child>
                   <object class="GtkHBox" id="hbox3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <child>
                       <object class="GtkLabel" id="label9">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                       </object>
                       <packing>
@@ -262,161 +306,206 @@
                     <child>
                       <object class="GtkVBox" id="vbox5">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="orientation">vertical</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkTable" id="table4">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="n_rows">5</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">6</property>
                             <property name="row_spacing">6</property>
                             <child>
-                              <object class="GtkEntry" id="team_email_entry">
+                              <object class="GtkLabel" id="label15">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Team email:</property>
+                                <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">4</property>
                                 <property name="bottom_attach">5</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkEntry" id="encoding_entry">
+                              <object class="GtkLabel" id="label14">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Transfer en_coding:</property>
+                                <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">3</property>
                                 <property name="bottom_attach">4</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkEntry" id="charset_entry">
+                              <object class="GtkLabel" id="label13">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Character _set</property>
+                                <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">2</property>
                                 <property name="bottom_attach">3</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkEntry" id="langcode_entry">
+                              <object class="GtkLabel" id="label12">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Language _code:</property>
+                                <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
                                 <property name="top_attach">1</property>
                                 <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkEntry" id="language_entry">
+                              <object class="GtkLabel" id="label11">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Language:</property>
+                                <property name="use_underline">True</property>
                               </object>
                               <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="label15">
+                              <object class="GtkEntry" id="team_email">
                                 <property name="visible">True</property>
+                                <property name="can_focus">True</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Team email:</property>
-                                <property name="use_underline">True</property>
                               </object>
                               <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                                 <property name="top_attach">4</property>
                                 <property name="bottom_attach">5</property>
-                                <property name="x_options">GTK_FILL</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="label14">
+                              <object class="GtkComboBoxText" id="charset">
                                 <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Transfer en_coding:</property>
-                                <property name="use_underline">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="has_entry">True</property>
+                                <property name="entry_text_column">0</property>
+                                <property name="id_column">1</property>
+                                <items>
+                                  <item>UTF-8</item>
+                                </items>
+                                <child internal-child="entry">
+                                  <object class="GtkEntry" id="comboboxentry-entry2">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </object>
+                                </child>
                               </object>
                               <packing>
-                                <property name="top_attach">3</property>
-                                <property name="bottom_attach">4</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="label13">
+                              <object class="GtkComboBoxText" id="encoding">
                                 <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Character _set</property>
-                                <property name="use_underline">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="has_entry">True</property>
+                                <property name="entry_text_column">0</property>
+                                <items>
+                                  <item>8bits</item>
+                                </items>
+                                <child internal-child="entry">
+                                  <object class="GtkEntry" id="comboboxentry-entry3">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </object>
+                                </child>
                               </object>
                               <packing>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="label12">
+                              <object class="GtkComboBox" id="language">
                                 <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Language _code:</property>
-                                <property name="use_underline">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="model">language_store</property>
+                                <property name="has_entry">True</property>
+                                <property name="entry_text_column">0</property>
+                                <child internal-child="entry">
+                                  <object class="GtkEntry" id="comboboxentry-entry1">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </object>
+                                </child>
                               </object>
                               <packing>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkLabel" id="label11">
+                              <object class="GtkComboBox" id="language_code">
                                 <property name="visible">True</property>
-                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">_Language:</property>
-                                <property name="use_underline">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="model">code_store</property>
+                                <property name="has_entry">True</property>
+                                <property name="entry_text_column">0</property>
+                                <child internal-child="entry">
+                                  <object class="GtkEntry" id="comboboxentry-entry">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                  </object>
+                                </child>
                               </object>
                               <packing>
-                                <property name="x_options">GTK_FILL</property>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkLabel" id="label10">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">_Plural forms:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">plurals_entry</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -425,22 +514,37 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="plurals_entry">
+                          <object class="GtkComboBoxText" id="plural_forms">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="can_focus">False</property>
+                            <property name="has_entry">True</property>
+                            <property name="entry_text_column">0</property>
+                            <property name="id_column">1</property>
+                            <property name="active_id">text</property>
+                            <child internal-child="entry">
+                              <object class="GtkEntry" id="comboboxentry-entry4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                              </object>
+                            </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -453,28 +557,20 @@
             </child>
           </object>
           <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="layout_style">end</property>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-          </object>
-          <packing>
             <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
     </child>
   </object>
+  <object class="GtkListStore" id="language_store">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name language -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
 </interface>
diff --git a/src/gtr-language.c b/src/gtr-language.c
new file mode 100644
index 0000000..63f1186
--- /dev/null
+++ b/src/gtr-language.c
@@ -0,0 +1,278 @@
+/*
+ * gtr-language.c
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2003, 2004 - Christian Persch
+ * Copyright (C) 2006 - Paolo Maggi
+ * Copyright (C) 2011 - Ignacio Casal Quinteiro
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <libxml/xmlreader.h>
+
+#include "gtr-language.h"
+#include "gtr-dirs.h"
+
+#define ISO_639_DOMAIN	"iso_639"
+
+#define ISOCODESLOCALEDIR		ISO_CODES_PREFIX "/share/locale"
+#define GTR_PLURAL_FORMS_FILENAME	"gtr-plural-forms.ini"
+
+struct _GtrLanguage
+{
+  gchar *code;
+  gchar *name;
+  gchar *plural_form;
+};
+
+static gboolean initialized = FALSE;
+static GKeyFile *plurals_file = NULL;
+static GSList *languages = NULL;
+
+G_DEFINE_BOXED_TYPE (GtrLanguage, gtr_language,
+                     gtr_language_copy,
+                     gtr_language_free)
+
+/* These are to make language bindings happy. Since Languages are
+ * const, copy() just returns the same pointer and frees() doesn't
+ * do nothing */
+
+GtrLanguage *
+gtr_language_copy (const GtrLanguage *lang)
+{
+	g_return_val_if_fail (lang != NULL, NULL);
+
+	return (GtrLanguage *) lang;
+}
+
+void 
+gtr_language_free (GtrLanguage *lang)
+{
+	g_return_if_fail (lang != NULL);
+}
+
+static void
+bind_iso_domains (void)
+{
+  static gboolean bound = FALSE;
+
+  if (bound == FALSE)
+    {
+      bindtextdomain (ISO_639_DOMAIN, ISOCODESLOCALEDIR);
+      bind_textdomain_codeset (ISO_639_DOMAIN, "UTF-8");
+
+      bound = TRUE;
+    }
+}
+
+static void
+load_plural_form (GtrLanguage *lang)
+{
+  gchar *plural_form;
+
+  plural_form = g_key_file_get_string (plurals_file, "Plural Forms", lang->code, NULL);
+
+  if (plural_form != NULL && *plural_form != '\0')
+    {
+      lang->plural_form = plural_form;
+    }
+  else
+    {
+      lang->plural_form = NULL;
+    }
+}
+
+static void
+read_iso_639_entry (xmlTextReaderPtr reader,
+                    GSList **langs)
+{
+  xmlChar *code, *name;
+
+  code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "iso_639_1_code");
+  name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name");
+
+  if (code != NULL && code[0] != '\0' && name != NULL && name[0] != '\0')
+    {
+      GtrLanguage *lang = g_slice_new (GtrLanguage);
+      lang->code = (gchar *)code;
+      lang->name = g_strdup (dgettext (ISO_639_DOMAIN, (gchar *)name));
+      xmlFree (name);
+
+      /* set the plural form */
+      load_plural_form (lang);
+
+      *langs = g_slist_prepend (*langs, lang);
+    }
+  else
+    {
+      xmlFree (code);
+      xmlFree (name);
+    }
+}
+
+typedef enum
+{
+  STATE_START,
+  STATE_STOP,
+  STATE_ENTRIES
+} ParserState;
+
+static void
+load_iso_entries (int iso,
+                  GFunc read_entry_func,
+                  gpointer user_data)
+{
+  xmlTextReaderPtr reader;
+  ParserState state = STATE_START;
+  xmlChar iso_entries[32], iso_entry[32];
+  char *filename;
+  int ret = -1;
+
+  filename = g_strdup_printf (ISO_CODES_PREFIX "/share/xml/iso-codes/iso_%d.xml", iso);
+  reader = xmlNewTextReaderFilename (filename);
+  if (reader == NULL)
+    goto out;
+
+  xmlStrPrintf (iso_entries, sizeof (iso_entries), (const xmlChar *)"iso_%d_entries", iso);
+  xmlStrPrintf (iso_entry, sizeof (iso_entry), (const xmlChar *)"iso_%d_entry", iso);
+
+  ret = xmlTextReaderRead (reader);
+
+  while (ret == 1)
+    {
+      const xmlChar *tag;
+      xmlReaderTypes type;
+
+      tag = xmlTextReaderConstName (reader);
+      type = xmlTextReaderNodeType (reader);
+
+      if (state == STATE_ENTRIES &&
+          type == XML_READER_TYPE_ELEMENT &&
+          xmlStrEqual (tag, iso_entry))
+        {
+          read_entry_func (reader, user_data);
+        }
+      else if (state == STATE_START &&
+               type == XML_READER_TYPE_ELEMENT &&
+               xmlStrEqual (tag, iso_entries))
+        {
+          state = STATE_ENTRIES;
+        }
+      else if (state == STATE_ENTRIES &&
+               type == XML_READER_TYPE_END_ELEMENT &&
+               xmlStrEqual (tag, iso_entries))
+        {
+          state = STATE_STOP;
+        }
+      else if (type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE ||
+               type == XML_READER_TYPE_WHITESPACE ||
+               type == XML_READER_TYPE_TEXT ||
+               type == XML_READER_TYPE_COMMENT)
+        {
+          /* eat it */
+        }
+      else
+        {
+          /* ignore it */
+        }
+
+      ret = xmlTextReaderRead (reader);
+    }
+
+  xmlFreeTextReader (reader);
+
+out:
+  if (ret < 0 || state != STATE_STOP)
+    {
+      g_warning ("Failed to load ISO-%d codes from %s!\n",
+                 iso, filename);
+    }
+
+  g_free (filename);
+}
+
+static void
+gtr_language_lazy_init (void)
+{
+  gchar *filename;
+
+  if (initialized)
+    return;
+
+  plurals_file = g_key_file_new ();
+  filename = g_build_filename (gtr_dirs_get_gtr_data_dir (),
+                               GTR_PLURAL_FORMS_FILENAME,
+                               NULL);
+  if (!g_key_file_load_from_file (plurals_file, filename, G_KEY_FILE_NONE, NULL))
+    {
+      g_warning ("Bad plugin file: '%s'", filename);
+      g_free (filename);
+      return;
+    }
+
+  g_free (filename);
+
+  bind_iso_domains ();
+  load_iso_entries (639, (GFunc) read_iso_639_entry, &languages);
+  languages = g_slist_reverse (languages);
+
+  /* free the file, not needed anymore */
+  g_key_file_free (plurals_file);
+
+  initialized = TRUE;
+}
+
+const GSList *
+gtr_language_get_languages ()
+{
+  gtr_language_lazy_init ();
+
+  return languages;
+}
+
+const gchar *
+gtr_language_get_code (const GtrLanguage *lang)
+{
+  g_return_val_if_fail (lang != NULL, NULL);
+
+  gtr_language_lazy_init ();
+
+  return lang->code;
+}
+
+const gchar *
+gtr_language_get_name (const GtrLanguage *lang)
+{
+  g_return_val_if_fail (lang != NULL, NULL);
+
+  gtr_language_lazy_init ();
+
+  return lang->name;
+}
+
+const gchar *
+gtr_language_get_plural_form (const GtrLanguage *lang)
+{
+  g_return_val_if_fail (lang != NULL, NULL);
+
+  gtr_language_lazy_init ();
+
+  return lang->plural_form;
+}
diff --git a/src/gtr-language.h b/src/gtr-language.h
new file mode 100644
index 0000000..82050c2
--- /dev/null
+++ b/src/gtr-language.h
@@ -0,0 +1,51 @@
+/*
+ * gtr-language.h
+ * This file is part of gtranslator
+ *
+ * Copyright (C) 2003, 2004 - Christian Persch
+ * Copyright (C) 2006 - Paolo Maggi
+ * Copyright (C) 2011 - Ignacio Casal Quinteiro
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTR_LANGUAGE_H__
+#define __GTR_LANGUAGE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GtrLanguage GtrLanguage;
+
+#define GTR_TYPE_LANGUAGE (gtr_language_get_type ())
+
+GType                    gtr_language_get_type           (void) G_GNUC_CONST;
+
+/* These should not be used, they are just to make python bindings happy */
+GtrLanguage             *gtr_language_copy               (const GtrLanguage *lang);
+void                     gtr_language_free               (GtrLanguage       *lang);
+
+const GSList            *gtr_language_get_languages      (void);
+
+const gchar             *gtr_language_get_code           (const GtrLanguage *lang);
+
+const gchar             *gtr_language_get_name           (const GtrLanguage *lang);
+
+const gchar             *gtr_language_get_plural_form    (const GtrLanguage *lang);
+
+G_END_DECLS
+
+#endif  /* __GTR_LANGUAGE_H__ */



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