[gnome-control-center/wip/input-sources: 14/14] region: Use a hand-crafted input sources list
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/input-sources: 14/14] region: Use a hand-crafted input sources list
- Date: Wed, 18 Apr 2012 15:29:48 +0000 (UTC)
commit f9bf4d2d92a314eff3465684f9b251cb233dfc61
Author: Rui Matos <tiagomatos gmail com>
Date: Wed Apr 18 17:15:32 2012 +0200
region: Use a hand-crafted input sources list
Instead of asking IBus, we want to use an hand-crafted list of input
sources that we are sure that a) is intelligible for the user and b)
lists both an XKB layout and an IBus engine that work together.
For now we just hard-code this list but we might want to move it into
its own file and maybe even to some other module.
configure.ac | 3 +-
panels/region/gnome-region-panel-input-chooser.ui | 7 -
panels/region/gnome-region-panel-input.c | 389 +++++++++++----------
3 files changed, 212 insertions(+), 187 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3f6bdd6..b2a27b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,8 +113,7 @@ PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES colord >= 0.1.8)
PKG_CHECK_MODULES(PRINTERS_PANEL, $COMMON_MODULES
polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
PKG_CHECK_MODULES(REGION_PANEL, $COMMON_MODULES
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION
- ibus-1.0)
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
PKG_CHECK_MODULES(SCREEN_PANEL, $COMMON_MODULES)
PKG_CHECK_MODULES(SOUND_PANEL, $COMMON_MODULES libxml-2.0
libcanberra-gtk3 >= $CANBERRA_REQUIRED_VERSION
diff --git a/panels/region/gnome-region-panel-input-chooser.ui b/panels/region/gnome-region-panel-input-chooser.ui
index 8fc2b74..809e7e6 100644
--- a/panels/region/gnome-region-panel-input-chooser.ui
+++ b/panels/region/gnome-region-panel-input-chooser.ui
@@ -3,16 +3,9 @@
<requires lib="gtk+" version="2.16"/>
<object class="GtkListStore" id="input_source_model">
<columns>
- <!-- column-name id -->
<column type="gchararray"/>
- <!-- column-name name -->
<column type="gchararray"/>
- <!-- column-name lang -->
<column type="gchararray"/>
- <!-- column-name layout -->
- <column type="gchararray"/>
- <!-- column-name xkb -->
- <column type="gboolean"/>
</columns>
</object>
<object class="GtkTreeModelFilter" id="filtered_input_source_model">
diff --git a/panels/region/gnome-region-panel-input.c b/panels/region/gnome-region-panel-input.c
index 7dfbae7..d715715 100644
--- a/panels/region/gnome-region-panel-input.c
+++ b/panels/region/gnome-region-panel-input.c
@@ -26,8 +26,6 @@
#include <glib.h>
#include <glib/gi18n.h>
-#include <ibus.h>
-
#include "gnome-region-panel-input.h"
#define WID(s) GTK_WIDGET(gtk_builder_get_object (builder, s))
@@ -52,6 +50,115 @@
* - Allow changing shortcuts ?
*/
+struct _InputSource
+{
+ const gchar *layout;
+ const gchar *engine;
+ const gchar *name;
+};
+
+static const struct _InputSource input_sources[] =
+ {
+ { "us", NULL, "English (US)" },
+ { "ad", NULL, "Catalan" },
+ { "af", NULL, "Afghani" },
+ { "ara", NULL, "Arabic" },
+ { "al", NULL, "Albanian" },
+ { "am", NULL, "Armenian" },
+ { "at", NULL, "German (Austria)" },
+ { "az", NULL, "Azerbaijani" },
+ { "by", NULL, "Belarusian" },
+ { "be", NULL, "Belgian" },
+ { "bd", NULL, "Bengali" },
+ { "in", NULL, "Indian" },
+ { "ba", NULL, "Bosnian" },
+ { "br", NULL, "Portuguese (Brazil)" },
+ { "bg", NULL, "Bulgarian" },
+ { "ma", NULL, "Arabic (Morocco)" },
+ { "cm", NULL, "English (Cameroon)" },
+ { "mm", NULL, "Burmese" },
+ { "ca", NULL, "French (Canada)" },
+ { "cd", NULL, "French (Democratic Republic of the Congo)" },
+ { "cn", NULL, "Chinese" },
+ { "hr", NULL, "Croatian" },
+ { "cz", NULL, "Czech" },
+ { "dk", NULL, "Danish" },
+ { "nl", NULL, "Dutch" },
+ { "bt", NULL, "Dzongkha" },
+ { "ee", NULL, "Estonian" },
+ { "ir", NULL, "Persian" },
+ { "iq", NULL, "Iraqi" },
+ { "fo", NULL, "Faroese" },
+ { "fi", NULL, "Finnish" },
+ { "fr", NULL, "French" },
+ { "gh", NULL, "English (Ghana)" },
+ { "gn", NULL, "French (Guinea)" },
+ { "ge", NULL, "Georgian" },
+ { "de", NULL, "German" },
+ { "gr", NULL, "Greek" },
+ { "hu", NULL, "Hungarian" },
+ { "is", NULL, "Icelandic" },
+ { "il", NULL, "Hebrew" },
+ { "it", NULL, "Italian" },
+ { "jp", "anthy", "Japanese" },
+ { "kg", NULL, "Kyrgyz" },
+ { "kh", NULL, "Khmer (Cambodia)" },
+ { "kz", NULL, "Kazakh" },
+ { "la", NULL, "Lao" },
+ { "latam", NULL, "Spanish (Latin American)" },
+ { "lt", NULL, "Lithuanian" },
+ { "lv", NULL, "Latvian" },
+ { "mao", NULL, "Maori" },
+ { "me", NULL, "Montenegrin" },
+ { "mk", NULL, "Macedonian" },
+ { "mt", NULL, "Maltese" },
+ { "mn", NULL, "Mongolian" },
+ { "no", NULL, "Norwegian" },
+ { "pl", NULL, "Polish" },
+ { "pt", NULL, "Portuguese" },
+ { "ro", NULL, "Romanian" },
+ { "ru", NULL, "Russian" },
+ { "rs", NULL, "Serbian" },
+ { "si", NULL, "Slovenian" },
+ { "sk", NULL, "Slovak" },
+ { "es", NULL, "Spanish" },
+ { "se", NULL, "Swedish" },
+ { "ch", NULL, "German (Switzerland)" },
+ { "sy", NULL, "Arabic (Syria)" },
+ { "tj", NULL, "Tajik" },
+ { "lk", NULL, "Sinhala" },
+ { "th", NULL, "Thai" },
+ { "tr", NULL, "Turkish" },
+ { "tw", NULL, "Taiwanese" },
+ { "ua", NULL, "Ukrainian" },
+ { "gb", NULL, "English (UK)" },
+ { "uz", NULL, "Uzbek" },
+ { "vn", NULL, "Vietnamese" },
+ { "kr", "hangul", "Korean" },
+ { "ie", NULL, "Irish" },
+ { "pk", NULL, "Urdu (Pakistan)" },
+ { "mv", NULL, "Dhivehi" },
+ { "za", NULL, "English (South Africa)" },
+ { "epo", NULL, "Esperanto" },
+ { "np", NULL, "Nepali" },
+ { "ng", NULL, "English (Nigeria)" },
+ { "et", NULL, "Amharic" },
+ { "sn", NULL, "Wolof" },
+ { "brai", NULL, "Braille" },
+ { "tm", NULL, "Turkmen" },
+ { "ml", NULL, "Bambara" },
+ { "tz", NULL, "Swahili (Tanzania)" },
+ { "ke", NULL, "Swahili (Kenya)" },
+ { "bw", NULL, "Tswana" },
+ { "ph", NULL, "Filipino" }
+ };
+
+#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
+
+#define KEY_CURRENT_IS "current"
+#define KEY_INPUT_SOURCES "sources"
+
+static GSettings *is_settings = NULL;
static GtkWidget *input_chooser_new (GtkBuilder *builder);
static gboolean input_chooser_get_selected (GtkWidget *chooser,
@@ -60,193 +167,124 @@ static gboolean input_chooser_get_selected (GtkWidget *chooser,
enum
{
- COL_NAME,
- COL_DESC,
- COL_LANG,
COL_LAYOUT,
- COL_XKB
+ COL_ENGINE,
+ COL_NAME
};
-/* IBus interaction {{{1 */
-
-static gchar *
-engine_description (IBusEngineDesc *description, gboolean unique_lang)
+static gboolean
+add_source_to_hash (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
{
- const gchar *lang;
- gchar *longname;
- gchar *desc;
-
- lang = ibus_get_language_name (ibus_engine_desc_get_language (description));
-
- if (g_getenv ("DEBUG_IBUS"))
- return g_strdup_printf ("%s %s/%s/%s/%s", lang,
- ibus_engine_desc_get_name (description),
- ibus_engine_desc_get_longname (description),
- ibus_engine_desc_get_language (description),
- ibus_engine_desc_get_layout (description));
-
- if (unique_lang)
- return g_strdup (lang);
-
- if (g_str_has_prefix (ibus_engine_desc_get_name (description), "xkb:layout:"))
- {
- if (strcmp (ibus_engine_desc_get_longname (description), lang) == 0)
- return g_strdup_printf ("%s (xkb)", lang);
- else
- return g_strdup (ibus_engine_desc_get_longname (description));
- }
-
- longname = g_strdup (ibus_engine_desc_get_longname (description));
- if (g_str_has_suffix (longname, " (m17n)"))
- {
- longname[strlen (longname) - strlen (" (m17n)")] = '\0';
- }
-
- desc = g_strdup_printf ("%s (%s)", lang, longname);
+ GHashTable *hash = data;
+ gchar *layout;
- g_free (longname);
+ gtk_tree_model_get (model, iter, COL_LAYOUT, &layout, -1);
+ g_hash_table_insert (hash, layout, GINT_TO_POINTER (1));
- return desc;
+ return FALSE;
}
static void
populate_model (GtkListStore *store,
- gboolean only_active)
+ GtkListStore *active_sources)
{
- IBusBus *bus;
- GList *list, *l;
- GList *active_list;
- IBusEngineDesc *description;
- const gchar *name;
- const gchar *lang;
- gchar *desc;
- gint count;
- GtkTreeIter iter;
- GHashTable *lang_hash;
GHashTable *active_hash;
+ GtkTreeIter iter;
+ gint i;
- bus = ibus_bus_new ();
-
- list = ibus_bus_list_engines (bus);
- active_list = ibus_bus_list_active_engines (bus);
+ active_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- lang_hash = g_hash_table_new (g_str_hash, g_str_equal);
- active_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ gtk_tree_model_foreach (GTK_TREE_MODEL (active_sources),
+ add_source_to_hash,
+ active_hash);
- /* Figure out which languages occur more than once
- * for these, showing only the language is not sufficient
- */
- for (l = list; l; l = l->next)
+ for (i = 0; i < G_N_ELEMENTS (input_sources); ++i)
{
- description = (IBusEngineDesc *)l->data;
-
- name = ibus_engine_desc_get_name (description);
- if (g_str_has_prefix (name, "xkb:layout:default:#"))
+ if (g_hash_table_lookup (active_hash, input_sources[i].layout))
continue;
- lang = ibus_engine_desc_get_language (description);
- lang = ibus_get_language_name (lang);
- if (lang == NULL)
- continue;
-
- count = GPOINTER_TO_INT (g_hash_table_lookup (lang_hash, lang));
- count++;
- g_hash_table_insert (lang_hash, (gpointer)lang, GINT_TO_POINTER (count));
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_LAYOUT, input_sources[i].layout,
+ COL_ENGINE, input_sources[i].engine,
+ COL_NAME, input_sources[i].name,
+ -1);
}
- if (only_active)
- {
- g_list_free (list);
- list = active_list;
- active_list = NULL;
- }
- else
+ g_hash_table_destroy (active_hash);
+}
+
+static const gchar *
+get_source_name (const gchar *layout,
+ const gchar *engine)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (input_sources); ++i)
{
- /* We want to skip active engines when
- * making a list of inactive engines
- */
- for (l = active_list; l; l = l->next)
- {
- description = (IBusEngineDesc *)l->data;
- name = ibus_engine_desc_get_name (description);
- g_hash_table_insert (active_hash, (gpointer)name, (gpointer)name);
- }
- g_list_free (active_list);
- active_list = NULL;
+ if (!g_strcmp0 (layout, input_sources[i].layout) &&
+ !g_strcmp0 (engine, input_sources[i].engine))
+ return input_sources[i].name;
}
- for (l = list; l; l = l->next)
- {
- description = (IBusEngineDesc *)l->data;
+ return NULL;
+}
- name = ibus_engine_desc_get_name (description);
- if (g_str_has_prefix (name, "xkb:layout:default:#"))
- continue;
+static void
+populate_with_active_sources (GtkListStore *store)
+{
+ GVariant *sources;
+ GVariantIter iter;
+ const gchar *layout;
+ const gchar *engine;
+ const gchar *name;
+ GtkTreeIter tree_iter;
- if (g_hash_table_lookup (active_hash, name))
- continue;
+ sources = g_settings_get_value (is_settings, KEY_INPUT_SOURCES);
- lang = ibus_engine_desc_get_language (description);
- lang = ibus_get_language_name (lang);
- if (lang == NULL)
+ g_variant_iter_init (&iter, sources);
+ while (g_variant_iter_loop (&iter, "(&sm&s)", &layout, &engine))
+ {
+ name = get_source_name (layout, engine);
+ if (!name)
continue;
- count = GPOINTER_TO_INT (g_hash_table_lookup (lang_hash, lang));
- desc = engine_description (description, count <= 1);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
+ gtk_list_store_append (store, &tree_iter);
+ gtk_list_store_set (store, &tree_iter,
+ COL_LAYOUT, layout,
+ COL_ENGINE, engine,
COL_NAME, name,
- COL_DESC, desc,
- COL_LANG, lang,
- COL_LAYOUT, ibus_engine_desc_get_layout (description),
- COL_XKB, g_str_has_prefix (name, "xkb:layout:"),
-1);
- g_free (desc);
}
- g_hash_table_unref (lang_hash);
- g_hash_table_unref (active_hash);
-
- g_list_free (list);
-
- g_object_unref (bus);
+ g_variant_unref (sources);
}
static void
-update_ibus_configuration (GtkTreeModel *model)
+update_configuration (GtkTreeModel *model)
{
GtkTreeIter iter;
- IBusBus *bus;
- IBusConfig *config;
- gchar **active;
- gsize n_active;
- gchar *name;
- gint i;
+ gchar *layout;
+ gchar *engine;
+ GVariantBuilder builder;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sms)"));
- n_active = gtk_tree_model_iter_n_children (model, NULL);
- active = g_new0 (gchar *, n_active + 1);
gtk_tree_model_get_iter_first (model, &iter);
- i = 0;
do {
- gtk_tree_model_get (model, &iter, COL_NAME, &name, -1);
- active[i++] = name;
+ gtk_tree_model_get (model, &iter,
+ COL_LAYOUT, &layout,
+ COL_ENGINE, &engine,
+ -1);
+ g_variant_builder_add (&builder, "(sms)", layout, engine);
+ g_free (layout);
+ g_free (engine);
} while (gtk_tree_model_iter_next (model, &iter));
- active[n_active] = NULL;
-
- bus = ibus_bus_new ();
- config = ibus_bus_get_config (bus);
-
- if (!ibus_config_set_value (config,
- "general", "preload_engines",
- g_variant_new_strv ((const gchar * const *)active, -1)))
- {
- g_warning ("Failed to update IBus configuration");
- }
-
- g_strfreev (active);
- g_object_unref (bus);
+ g_settings_set_value (is_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder));
}
/* List handling {{{1 */
@@ -337,18 +375,14 @@ chooser_response (GtkWidget *chooser, gint response_id, gpointer data)
GtkTreeView *my_tv;
GtkListStore *my_model;
GtkTreeIter my_iter;
- gchar *name;
- gchar *desc;
- gchar *lang;
gchar *layout;
- gboolean xkb;
+ gchar *engine;
+ gchar *name;
gtk_tree_model_get (model, &iter,
- COL_NAME, &name,
- COL_DESC, &desc,
- COL_LANG, &lang,
COL_LAYOUT, &layout,
- COL_XKB, &xkb,
+ COL_ENGINE, &engine,
+ COL_NAME, &name,
-1);
my_tv = GTK_TREE_VIEW (WID ("active_input_sources"));
@@ -357,22 +391,19 @@ chooser_response (GtkWidget *chooser, gint response_id, gpointer data)
gtk_list_store_append (my_model, &my_iter);
gtk_list_store_set (my_model, &my_iter,
- COL_NAME, name,
- COL_DESC, desc,
- COL_LANG, lang,
COL_LAYOUT, layout,
- COL_XKB, xkb,
+ COL_ENGINE, engine,
+ COL_NAME, name,
-1);
g_free (name);
- g_free (desc);
- g_free (lang);
+ g_free (engine);
g_free (layout);
gtk_tree_selection_select_iter (gtk_tree_view_get_selection (my_tv), &my_iter);
update_button_sensitivity (builder);
- update_ibus_configuration (GTK_TREE_MODEL (my_model));
+ update_configuration (GTK_TREE_MODEL (my_model));
}
else
{
@@ -420,7 +451,7 @@ remove_selected_input (GtkButton *button, gpointer data)
gtk_tree_path_free (path);
update_button_sensitivity (builder);
- update_ibus_configuration (model);
+ update_configuration (model);
}
static void
@@ -447,7 +478,7 @@ move_selected_input_up (GtkButton *button, gpointer data)
gtk_tree_path_free (path);
update_button_sensitivity (builder);
- update_ibus_configuration (model);
+ update_configuration (model);
}
static void
@@ -473,7 +504,7 @@ move_selected_input_down (GtkButton *button, gpointer data)
gtk_tree_path_free (path);
update_button_sensitivity (builder);
- update_ibus_configuration (model);
+ update_configuration (model);
}
static void
@@ -535,20 +566,20 @@ setup_input_tabs (GtkBuilder *builder,
gchar *next = NULL;
GtkWidget *label;
- ibus_init ();
+ is_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
/* set up the list of active inputs */
treeview = WID("active_input_sources");
column = gtk_tree_view_column_new ();
cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, TRUE);
- gtk_tree_view_column_add_attribute (column, cell, "text", COL_DESC);
+ gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
- /* id, name, language, layout, xkb? */
- store = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
+ /* layout, engine, name */
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
- populate_model (store, TRUE);
+ populate_with_active_sources (store);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
g_signal_connect_swapped (selection, "changed",
@@ -688,7 +719,7 @@ filter_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
- gchar *desc = NULL;
+ gchar *name = NULL;
gchar **pattern;
gboolean rv = TRUE;
@@ -696,13 +727,13 @@ filter_func (GtkTreeModel *model,
return TRUE;
gtk_tree_model_get (model, iter,
- COL_DESC, &desc,
+ COL_NAME, &name,
-1);
pattern = search_pattern_list;
do {
gboolean is_pattern_found = FALSE;
- gchar *udesc = g_utf8_strup (desc, -1);
+ gchar *udesc = g_utf8_strup (name, -1);
if (udesc != NULL && g_strstr_len (udesc, -1, *pattern))
{
is_pattern_found = TRUE;
@@ -717,7 +748,7 @@ filter_func (GtkTreeModel *model,
} while (*++pattern != NULL);
- g_free (desc);
+ g_free (name);
return rv;
}
@@ -748,9 +779,9 @@ input_chooser_new (GtkBuilder *main_builder)
g_object_set_data (G_OBJECT (chooser),
"filtered_input_source_list", filtered_list);
visible_column =
- gtk_tree_view_column_new_with_attributes ("Layout",
+ gtk_tree_view_column_new_with_attributes ("Input Sources",
gtk_cell_renderer_text_new (),
- "text", COL_DESC,
+ "text", COL_NAME,
NULL);
gtk_window_set_transient_for (GTK_WINDOW (chooser),
@@ -774,10 +805,12 @@ input_chooser_new (GtkBuilder *main_builder)
model =
GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model"));
- populate_model (model, FALSE);
+ populate_model (model,
+ GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (main_builder,
+ "active_input_sources")))));
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
- COL_DESC, GTK_SORT_ASCENDING);
+ COL_NAME, GTK_SORT_ASCENDING);
gtk_tree_model_filter_set_visible_func (filtered_model,
filter_func,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]