[gtranslator] Provide a way to automatize the profile filling. Fixes bug #547610.
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtranslator] Provide a way to automatize the profile filling. Fixes bug #547610.
- Date: Mon, 4 Apr 2011 12:42:38 +0000 (UTC)
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]