[gnome-control-center] region: make layout filtering much faster
- From: Sergey V. Udaltsov <svu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] region: make layout filtering much faster
- Date: Tue, 8 Feb 2011 22:23:49 +0000 (UTC)
commit 963f992452dda54ff344a924470d8bf5f7950efb
Author: Sergey V. Udaltsov <svu gnome org>
Date: Tue Feb 8 22:21:09 2011 +0000
region: make layout filtering much faster
Using app-level filter instead of libxklavier filter
panels/region/gnome-region-panel-layout-chooser.ui | 9 +-
panels/region/gnome-region-panel-xkbltadd.c | 209 +++++++++++++++++---
2 files changed, 185 insertions(+), 33 deletions(-)
---
diff --git a/panels/region/gnome-region-panel-layout-chooser.ui b/panels/region/gnome-region-panel-layout-chooser.ui
index e020f3d..82b8e74 100644
--- a/panels/region/gnome-region-panel-layout-chooser.ui
+++ b/panels/region/gnome-region-panel-layout-chooser.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.16"/>
- <object class="GtkListStore" id="filtered_layout_list_model">
+ <object class="GtkListStore" id="layout_list_model">
<columns>
<!-- column-name sort_order -->
<column type="gchararray"/>
@@ -9,10 +9,15 @@
<column type="gchararray"/>
<!-- column-name xkb_id -->
<column type="gchararray"/>
- <!-- column-name real_id -->
+ <!-- column-name country_desc -->
+ <column type="gchararray"/>
+ <!-- column-name language_desc -->
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkTreeModelFilter" id="filtered_layout_list_model">
+ <property name="child_model">layout_list_model</property>
+ </object>
<object class="GtkDialog" id="xkb_layout_chooser">
<property name="visible">True</property>
<property name="can_focus">False</property>
diff --git a/panels/region/gnome-region-panel-xkbltadd.c b/panels/region/gnome-region-panel-xkbltadd.c
index 3196fad..26889cc 100644
--- a/panels/region/gnome-region-panel-xkbltadd.c
+++ b/panels/region/gnome-region-panel-xkbltadd.c
@@ -33,9 +33,13 @@
enum {
COMBO_BOX_MODEL_COL_SORT,
COMBO_BOX_MODEL_COL_VISIBLE,
- COMBO_BOX_MODEL_COL_XKB_ID
+ COMBO_BOX_MODEL_COL_XKB_ID,
+ COMBO_BOX_MODEL_COL_COUNTRY_DESC,
+ COMBO_BOX_MODEL_COL_LANGUAGE_DESC
};
+static gchar **search_pattern_list = NULL;
+
#define RESPONSE_PREVIEW 1
static void
@@ -106,15 +110,70 @@ xkb_layout_chooser_response (GtkDialog * dialog,
gtk_widget_destroy (GTK_WIDGET (dialog));
}
+static gchar *
+xkl_create_description_from_list (const XklConfigItem * item,
+ const XklConfigItem * subitem,
+ const gchar * prop_name,
+ const gchar *
+ (*desc_getter) (const gchar * code))
+{
+ gchar *rv = NULL, *code = NULL;
+ gchar **list = NULL;
+ const gchar *desc;
+
+ if (subitem != NULL)
+ list =
+ (gchar
+ **) (g_object_get_data (G_OBJECT (subitem),
+ prop_name));
+ if (list == NULL || *list == 0)
+ list =
+ (gchar
+ **) (g_object_get_data (G_OBJECT (item), prop_name));
+
+ /* First try the parent id as such */
+ desc = desc_getter (item->name);
+ if (desc != NULL) {
+ rv = g_utf8_strup (desc, -1);
+ } else {
+ code = g_utf8_strup (item->name, -1);
+ desc = desc_getter (code);
+ if (desc != NULL) {
+ rv = g_utf8_strup (desc, -1);
+ }
+ g_free (code);
+ }
+
+ if (list == NULL || *list == 0)
+ return rv;
+
+ while (*list != 0) {
+ code = *list++;
+ desc = desc_getter (code);
+ if (desc != NULL) {
+ gchar *udesc = g_utf8_strup (desc, -1);
+ if (rv == NULL) {
+ rv = udesc;
+ } else {
+ gchar *orv = rv;
+ rv = g_strdup_printf ("%s %s", rv, udesc);
+ g_free (orv);
+ g_free (udesc);
+ }
+ }
+ }
+ return rv;
+}
+
static void
-xkl_layout_add_to_filtered_list (XklConfigRegistry * config,
- const XklConfigItem * item,
- const XklConfigItem * subitem,
- GtkBuilder * chooser_dialog)
+xkl_layout_add_to_list (XklConfigRegistry * config,
+ const XklConfigItem * item,
+ const XklConfigItem * subitem,
+ GtkBuilder * chooser_dialog)
{
GtkListStore *list_store =
GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog,
- "filtered_layout_list_model"));
+ "layout_list_model"));
GtkTreeIter iter;
gchar *utf_variant_name =
subitem ?
@@ -127,6 +186,15 @@ xkl_layout_add_to_filtered_list (XklConfigRegistry * config,
subitem->name) :
item->name;
+ gchar *country_desc =
+ xkl_create_description_from_list (item, subitem,
+ XCI_PROP_COUNTRY_LIST,
+ xkl_get_country_name);
+ gchar *language_desc =
+ xkl_create_description_from_list (item, subitem,
+ XCI_PROP_LANGUAGE_LIST,
+ xkl_get_language_name);
+
if (subitem
&& g_object_get_data (G_OBJECT (subitem),
XCI_PROP_EXTRA_ITEM)) {
@@ -138,7 +206,11 @@ xkl_layout_add_to_filtered_list (XklConfigRegistry * config,
COMBO_BOX_MODEL_COL_VISIBLE,
buf,
COMBO_BOX_MODEL_COL_XKB_ID,
- xkb_id, -1);
+ xkb_id,
+ COMBO_BOX_MODEL_COL_COUNTRY_DESC,
+ country_desc,
+ COMBO_BOX_MODEL_COL_LANGUAGE_DESC,
+ language_desc, -1);
g_free (buf);
} else
gtk_list_store_insert_with_values (list_store, &iter,
@@ -148,27 +220,34 @@ xkl_layout_add_to_filtered_list (XklConfigRegistry * config,
COMBO_BOX_MODEL_COL_VISIBLE,
utf_variant_name,
COMBO_BOX_MODEL_COL_XKB_ID,
- xkb_id, -1);
+ xkb_id,
+ COMBO_BOX_MODEL_COL_COUNTRY_DESC,
+ country_desc,
+ COMBO_BOX_MODEL_COL_LANGUAGE_DESC,
+ language_desc, -1);
g_free (utf_variant_name);
+ g_free (country_desc);
+ g_free (language_desc);
}
static void
xkb_layout_filter_changed (GtkBuilder * chooser_dialog)
{
+ GtkTreeModelFilter *filtered_model =
+ GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog,
+ "filtered_layout_list_model"));
GtkWidget *xkb_layout_filter = CWID ("xkb_layout_filter");
const gchar *pattern =
gtk_entry_get_text (GTK_ENTRY (xkb_layout_filter));
- GtkListStore *model =
- GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog,
- "filtered_layout_list_model"));
+ gchar *upattern = g_utf8_strup (pattern, -1);
- gtk_list_store_clear (model);
- xkl_config_registry_search_by_pattern (config_registry, pattern,
- (TwoConfigItemsProcessFunc)
- (xkl_layout_add_to_filtered_list), chooser_dialog);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
- COMBO_BOX_MODEL_COL_SORT,
- GTK_SORT_ASCENDING);
+ if (search_pattern_list != NULL)
+ g_strfreev (search_pattern_list);
+
+ search_pattern_list = g_strsplit (upattern, " ", -1);
+ g_free (upattern);
+
+ gtk_tree_model_filter_refilter (filtered_model);
}
static void
@@ -184,6 +263,52 @@ xkb_layout_chooser_selection_changed (GtkTreeSelection * selection,
gtk_widget_set_sensitive (preview_button, anything_selected);
}
+static gboolean
+xkb_filter_layouts (GtkTreeModel * model,
+ GtkTreeIter * iter, gpointer data)
+{
+ gchar *desc = NULL, *country_desc = NULL, *language_desc =
+ NULL, **pattern;
+ gboolean rv = TRUE;
+
+ if (search_pattern_list == NULL || search_pattern_list[0] == NULL)
+ return TRUE;
+
+ gtk_tree_model_get (model, iter,
+ COMBO_BOX_MODEL_COL_SORT, &desc,
+ COMBO_BOX_MODEL_COL_COUNTRY_DESC,
+ &country_desc,
+ COMBO_BOX_MODEL_COL_LANGUAGE_DESC,
+ &language_desc, -1);
+
+ pattern = search_pattern_list;
+ do {
+ gboolean is_pattern_found = FALSE;
+ gchar *udesc = g_utf8_strup (desc, -1);
+ if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) {
+ is_pattern_found = TRUE;
+ } else if (country_desc != NULL
+ && g_strstr_len (country_desc, -1, *pattern)) {
+ is_pattern_found = TRUE;
+ } else if (language_desc != NULL
+ && g_strstr_len (language_desc, -1, *pattern)) {
+ is_pattern_found = TRUE;
+ }
+ g_free (udesc);
+
+ if (!is_pattern_found) {
+ rv = FALSE;
+ break;
+ }
+
+ } while (*++pattern != NULL);
+
+ g_free (desc);
+ g_free (country_desc);
+ g_free (language_desc);
+ return rv;
+}
+
void
xkb_layout_choose (GtkBuilder * dialog)
{
@@ -191,6 +316,8 @@ xkb_layout_choose (GtkBuilder * dialog)
GtkWidget *chooser, *xkb_filtered_layouts_list, *xkb_layout_filter;
GtkTreeViewColumn *visible_column;
GtkTreeSelection *selection;
+ GtkListStore *model;
+ GtkTreeModelFilter *filtered_model;
gtk_builder_add_from_file (chooser_dialog, GNOMECC_UI_DIR
"/gnome-region-panel-layout-chooser.ui",
@@ -207,16 +334,17 @@ xkb_layout_choose (GtkBuilder * dialog)
NULL);
gtk_window_set_transient_for (GTK_WINDOW (chooser),
- GTK_WINDOW (gtk_widget_get_toplevel
- (WID
- ("region_notebook"))));
+ GTK_WINDOW
+ (gtk_widget_get_toplevel
+ (WID ("region_notebook"))));
gtk_tree_view_append_column (GTK_TREE_VIEW
(xkb_filtered_layouts_list),
visible_column);
g_signal_connect_swapped (G_OBJECT (xkb_layout_filter),
"notify::text",
- G_CALLBACK (xkb_layout_filter_changed),
+ G_CALLBACK
+ (xkb_layout_filter_changed),
chooser_dialog);
g_signal_connect (G_OBJECT (chooser),
@@ -236,7 +364,26 @@ xkb_layout_choose (GtkBuilder * dialog)
xkb_layout_chooser_selection_changed (selection, chooser_dialog);
- xkb_layout_filter_changed (chooser_dialog);
+ filtered_model =
+ GTK_TREE_MODEL_FILTER (gtk_builder_get_object
+ (chooser_dialog,
+ "filtered_layout_list_model"));
+ model =
+ GTK_LIST_STORE (gtk_builder_get_object
+ (chooser_dialog, "layout_list_model"));
+
+ xkl_config_registry_search_by_pattern (config_registry,
+ NULL,
+ (TwoConfigItemsProcessFunc)
+ (xkl_layout_add_to_list),
+ chooser_dialog);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+ COMBO_BOX_MODEL_COL_SORT,
+ GTK_SORT_ASCENDING);
+
+ gtk_tree_model_filter_set_visible_func (filtered_model,
+ xkb_filter_layouts,
+ NULL, NULL);
gtk_widget_grab_focus (xkb_layout_filter);
@@ -246,9 +393,7 @@ xkb_layout_choose (GtkBuilder * dialog)
gchar *
xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog)
{
- GtkListStore *list_store =
- GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog,
- "filtered_layout_list_model"));
+ GtkTreeModel *filtered_list_model;
GtkWidget *xkb_filtered_layouts_list =
CWID ("xkb_filtered_layouts_list");
GtkTreeIter viter;
@@ -257,18 +402,20 @@ xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog)
gtk_tree_view_get_selection (GTK_TREE_VIEW
(xkb_filtered_layouts_list));
GList *selected_layouts =
- gtk_tree_selection_get_selected_rows (selection, NULL);
+ gtk_tree_selection_get_selected_rows (selection,
+ &filtered_list_model);
if (g_list_length (selected_layouts) != 1)
return NULL;
- gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &viter,
+ gtk_tree_model_get_iter (filtered_list_model,
+ &viter,
(GtkTreePath *) (selected_layouts->data));
- g_list_foreach (selected_layouts, (GFunc) gtk_tree_path_free,
- NULL);
+ g_list_foreach (selected_layouts,
+ (GFunc) gtk_tree_path_free, NULL);
g_list_free (selected_layouts);
- gtk_tree_model_get (GTK_TREE_MODEL (list_store), &viter,
+ gtk_tree_model_get (filtered_list_model, &viter,
COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1);
return v_id;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]