[Xfce4-commits] <xfce4-settings:master> Make filtering work.
Nick Schermer
noreply at xfce.org
Thu Jan 26 23:02:09 CET 2012
Updating branch refs/heads/master
to eda1f1fd5b6d733cc41c9817350b87f745e3280e (commit)
from 5eaa8c9ecc3abd22b618bb39b5b301e6880a8864 (commit)
commit eda1f1fd5b6d733cc41c9817350b87f745e3280e
Author: Nick Schermer <nick at xfce.org>
Date: Thu Jan 26 19:24:21 2012 +0100
Make filtering work.
.../xfce-settings-manager-dialog.c | 301 +++++++++++++++++---
1 files changed, 255 insertions(+), 46 deletions(-)
diff --git a/xfce4-settings-manager/xfce-settings-manager-dialog.c b/xfce4-settings-manager/xfce-settings-manager-dialog.c
index 70ee927..0f34ad8 100644
--- a/xfce4-settings-manager/xfce-settings-manager-dialog.c
+++ b/xfce4-settings-manager/xfce-settings-manager-dialog.c
@@ -31,6 +31,7 @@
#endif
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
@@ -45,6 +46,11 @@
+struct _XfceSettingsManagerDialogClass
+{
+ XfceTitledDialogClass __parent__;
+};
+
struct _XfceSettingsManagerDialog
{
XfceTitledDialog __parent__;
@@ -53,12 +59,14 @@ struct _XfceSettingsManagerDialog
GtkListStore *store;
- GtkWidget *search_entry;
+ GtkWidget *filter_entry;
+ gchar *filter_text;
GtkWidget *category_viewport;
GtkWidget *category_scroll;
GtkWidget *category_box;
- GList *category_iconviews;
+
+ GList *categories;
GtkWidget *socket_scroll;
GtkWidget *socket_viewport;
@@ -71,10 +79,16 @@ struct _XfceSettingsManagerDialog
gchar *help_component;
};
-struct _XfceSettingsManagerDialogClass
+typedef struct
{
- XfceTitledDialogClass __parent__;
-};
+ GarconMenuDirectory *directory;
+ XfceSettingsManagerDialog *dialog;
+ GtkWidget *iconview;
+ GtkWidget *box;
+}
+DialogCategory;
+
+
enum
{
@@ -83,25 +97,34 @@ enum
COLUMN_TOOLTIP,
COLUMN_MENU_ITEM,
COLUMN_MENU_DIRECTORY,
+ COLUMN_FILTER_TEXT,
N_COLUMNS
};
-static void xfce_settings_manager_dialog_finalize (GObject *object);
-static void xfce_settings_manager_dialog_style_set (GtkWidget *widget,
- GtkStyle *old_style);
-static void xfce_settings_manager_dialog_response (GtkDialog *widget,
- gint response_id);
-static void xfce_settings_manager_dialog_header_style (GtkWidget *header,
- GtkStyle *old_style,
- GtkWidget *ebox);
-static void xfce_settings_manager_dialog_set_title (XfceSettingsManagerDialog *dialog,
- const gchar *title,
- const gchar *icon_name,
- const gchar *subtitle);
-static void xfce_settings_manager_dialog_go_back (XfceSettingsManagerDialog *dialog);
-static void xfce_settings_manager_dialog_menu_reload (XfceSettingsManagerDialog *dialog);
+static void xfce_settings_manager_dialog_finalize (GObject *object);
+static void xfce_settings_manager_dialog_style_set (GtkWidget *widget,
+ GtkStyle *old_style);
+static void xfce_settings_manager_dialog_response (GtkDialog *widget,
+ gint response_id);
+static void xfce_settings_manager_dialog_header_style (GtkWidget *header,
+ GtkStyle *old_style,
+ GtkWidget *ebox);
+static void xfce_settings_manager_dialog_set_title (XfceSettingsManagerDialog *dialog,
+ const gchar *title,
+ const gchar *icon_name,
+ const gchar *subtitle);
+static void xfce_settings_manager_dialog_go_back (XfceSettingsManagerDialog *dialog);
+static void xfce_settings_manager_dialog_entry_changed (GtkWidget *entry,
+ XfceSettingsManagerDialog *dialog);
+static gboolean xfce_settings_manager_dialog_entry_key_press (GtkWidget *entry,
+ GdkEventKey *event,
+ XfceSettingsManagerDialog *dialog);
+static void xfce_settings_manager_dialog_entry_clear (GtkWidget *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event);
+static void xfce_settings_manager_dialog_menu_reload (XfceSettingsManagerDialog *dialog);
@@ -148,7 +171,8 @@ xfce_settings_manager_dialog_init (XfceSettingsManagerDialog *dialog)
G_TYPE_STRING,
G_TYPE_STRING,
GARCON_TYPE_MENU_ITEM,
- GARCON_TYPE_MENU_DIRECTORY);
+ GARCON_TYPE_MENU_DIRECTORY,
+ G_TYPE_STRING);
path = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, "menus/xfce-settings-manager.menu");
dialog->menu = garcon_menu_new_for_path (path);
@@ -196,10 +220,16 @@ xfce_settings_manager_dialog_init (XfceSettingsManagerDialog *dialog)
gtk_container_set_border_width (GTK_CONTAINER (align), 6);
gtk_widget_show (align);
- dialog->search_entry = entry = gtk_entry_new ();
+ dialog->filter_entry = entry = gtk_entry_new ();
gtk_container_add (GTK_CONTAINER (align), entry);
gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_FIND);
- gtk_entry_set_icon_sensitive (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, FALSE);
+ gtk_entry_set_icon_activatable (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, FALSE);
+ g_signal_connect (G_OBJECT (entry), "changed",
+ G_CALLBACK (xfce_settings_manager_dialog_entry_changed), dialog);
+ g_signal_connect (G_OBJECT (entry), "icon-release",
+ G_CALLBACK (xfce_settings_manager_dialog_entry_clear), NULL);
+ g_signal_connect (G_OBJECT (entry), "key-press-event",
+ G_CALLBACK (xfce_settings_manager_dialog_entry_key_press), dialog);
gtk_widget_show (entry);
dialog_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
@@ -253,6 +283,8 @@ xfce_settings_manager_dialog_finalize (GObject *object)
g_free (dialog->help_page);
g_free (dialog->help_component);
+ g_free (dialog->filter_text);
+
if (dialog->socket_item != NULL)
g_object_unref (G_OBJECT (dialog->socket_item));
@@ -339,24 +371,37 @@ xfce_settings_manager_dialog_set_title (XfceSettingsManagerDialog *dialog,
+static gint
+xfce_settings_manager_dialog_iconview_find (gconstpointer a,
+ gconstpointer b)
+{
+ const DialogCategory *category = a;
+
+ return category->iconview == b ? 0 : 1;
+}
+
+
+
static gboolean
xfce_settings_manager_dialog_iconview_keynav_failed (ExoIconView *current_view,
GtkDirectionType direction,
XfceSettingsManagerDialog *dialog)
{
- GList *li;
- GtkTreePath *path;
- ExoIconView *new_view;
- gboolean result = FALSE;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gint col_old, col_new;
- gint dist_prev, dist_new;
- GtkTreePath *sel_path;
+ GList *li;
+ GtkTreePath *path;
+ ExoIconView *new_view;
+ gboolean result = FALSE;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint col_old, col_new;
+ gint dist_prev, dist_new;
+ GtkTreePath *sel_path;
+ DialogCategory *category;
if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
{
- li = g_list_find (dialog->category_iconviews, current_view);
+ li = g_list_find_custom (dialog->categories, current_view,
+ xfce_settings_manager_dialog_iconview_find);
if (direction == GTK_DIR_DOWN)
li = g_list_next (li);
else
@@ -366,7 +411,8 @@ xfce_settings_manager_dialog_iconview_keynav_failed (ExoIconView *
if (li == NULL)
return FALSE;
- new_view = EXO_ICON_VIEW (li->data);
+ category = li->data;
+ new_view = EXO_ICON_VIEW (category->iconview);
if (exo_icon_view_get_cursor (current_view, &path, NULL))
{
@@ -518,7 +564,7 @@ xfce_settings_manager_dialog_go_back (XfceSettingsManagerDialog *dialog)
gtk_widget_set_sensitive (dialog->button_back, FALSE);
gtk_widget_set_sensitive (dialog->button_help, TRUE);
- gtk_widget_set_sensitive (dialog->search_entry, TRUE);
+ gtk_widget_set_sensitive (dialog->filter_entry, TRUE);
socket = gtk_bin_get_child (GTK_BIN (dialog->socket_viewport));
if (G_LIKELY (socket != NULL))
@@ -534,6 +580,125 @@ xfce_settings_manager_dialog_go_back (XfceSettingsManagerDialog *dialog)
static void
+xfce_settings_manager_dialog_entry_changed (GtkWidget *entry,
+ XfceSettingsManagerDialog *dialog)
+{
+ const gchar *text;
+ gchar *normalized;
+ gchar *filter_text;
+ GList *li;
+ GtkTreeModel *model;
+ gint n_children;
+ DialogCategory *category;
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (text == NULL || *text == '\0')
+ {
+ filter_text = NULL;
+ }
+ else
+ {
+ /* create independent search string */
+ normalized = g_utf8_normalize (text, -1, G_NORMALIZE_DEFAULT);
+ filter_text = g_utf8_casefold (normalized, -1);
+ g_free (normalized);
+ }
+
+ /* check if we need to update */
+ if (g_strcmp0 (dialog->filter_text, filter_text) != 0)
+ {
+ /* update entry */
+ if (dialog->filter_text == NULL || filter_text == NULL)
+ {
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (dialog->filter_entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ filter_text == NULL ? GTK_STOCK_FIND : GTK_STOCK_CLEAR);
+ gtk_entry_set_icon_activatable (GTK_ENTRY (dialog->filter_entry),
+ GTK_ENTRY_ICON_SECONDARY, filter_text != NULL);
+ }
+
+ /* set new filter */
+ g_free (dialog->filter_text);
+ dialog->filter_text = filter_text;
+
+ /* update the category models */
+ for (li = dialog->categories; li != NULL; li = li->next)
+ {
+ category = li->data;
+
+ /* update model filters */
+ model = exo_icon_view_get_model (EXO_ICON_VIEW (category->iconview));
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
+
+ /* set visibility of the category */
+ n_children = gtk_tree_model_iter_n_children (model, NULL);
+ gtk_widget_set_visible (category->box, n_children > 0);
+ }
+ }
+ else
+ {
+ g_free (dialog->filter_text);
+ dialog->filter_text = NULL;
+ g_free (filter_text);
+ }
+}
+
+
+
+static gboolean
+xfce_settings_manager_dialog_entry_key_press (GtkWidget *entry,
+ GdkEventKey *event,
+ XfceSettingsManagerDialog *dialog)
+{
+ GList *li;
+ DialogCategory *category;
+ GtkTreePath *path;
+
+ if (event->keyval == GDK_Escape)
+ {
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+
+ return TRUE;
+ }
+ else if (event->keyval == GDK_Return)
+ {
+ for (li = dialog->categories; li != NULL; li = li->next)
+ {
+ category = li->data;
+
+ /* find the first visible category */
+ if (!gtk_widget_get_visible (category->box))
+ continue;
+
+ /* select first item */
+ path = gtk_tree_path_new_first ();
+ exo_icon_view_set_cursor (EXO_ICON_VIEW (category->iconview), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+
+ gtk_widget_grab_focus (category->iconview);
+ break;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+xfce_settings_manager_dialog_entry_clear (GtkWidget *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event)
+{
+ if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
+}
+
+
+
+static void
xfce_settings_manager_dialog_plug_added (GtkWidget *socket,
XfceSettingsManagerDialog *dialog)
{
@@ -550,7 +715,7 @@ xfce_settings_manager_dialog_plug_added (GtkWidget *socket,
/* button sensitivity */
gtk_widget_set_sensitive (dialog->button_back, TRUE);
gtk_widget_set_sensitive (dialog->button_help, dialog->help_page != NULL);
- gtk_widget_set_sensitive (dialog->search_entry, FALSE);
+ gtk_widget_set_sensitive (dialog->filter_entry, FALSE);
/* plug startup complete */
gdk_window_set_cursor (GTK_WIDGET (dialog)->window, NULL);
@@ -686,12 +851,25 @@ xfce_settings_manager_dialog_filter_category (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
- GValue value = { 0, };
- gboolean visible;
-
- gtk_tree_model_get_value (model, iter, COLUMN_MENU_DIRECTORY, &value);
- visible = g_value_get_object (&value) == data;
- g_value_unset (&value);
+ GValue cat_val = { 0, };
+ GValue filter_val = { 0, };
+ gboolean visible;
+ DialogCategory *category = data;
+ const gchar *filter_text;
+
+ /* filter only the active category */
+ gtk_tree_model_get_value (model, iter, COLUMN_MENU_DIRECTORY, &cat_val);
+ visible = g_value_get_object (&cat_val) == G_OBJECT (category->directory);
+ g_value_unset (&cat_val);
+
+ /* filter search string */
+ if (visible && category->dialog->filter_text != NULL)
+ {
+ gtk_tree_model_get_value (model, iter, COLUMN_FILTER_TEXT, &filter_val);
+ filter_text = g_value_get_string (&filter_val);
+ visible = strstr (filter_text, category->dialog->filter_text) != NULL;
+ g_value_unset (&filter_val);
+ }
return visible;
}
@@ -733,6 +911,17 @@ xfce_settings_manager_dialog_selection_changed (ExoIconView *iconv
static void
+xfce_settings_manager_dialog_category_free (gpointer data)
+{
+ DialogCategory *category = data;
+
+ g_object_unref (G_OBJECT (category->directory));
+ g_slice_free (DialogCategory, category);
+}
+
+
+
+static void
xfce_settings_manager_dialog_add_category (XfceSettingsManagerDialog *dialog,
GarconMenuDirectory *directory)
{
@@ -744,14 +933,19 @@ xfce_settings_manager_dialog_add_category (XfceSettingsManagerDialog *dialog,
GtkWidget *vbox;
PangoAttrList *attrs;
GtkCellRenderer *render;
+ DialogCategory *category;
+
+ category = g_slice_new0 (DialogCategory);
+ category->directory = g_object_ref (G_OBJECT (directory));
+ category->dialog = dialog;
/* filter category from main store */
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (dialog->store), NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
xfce_settings_manager_dialog_filter_category,
- g_object_ref (directory), g_object_unref);
+ category, xfce_settings_manager_dialog_category_free);
- vbox = gtk_vbox_new (FALSE, 0);
+ category->box = vbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (dialog->category_box), vbox, FALSE, TRUE, 0);
gtk_widget_show (vbox);
@@ -776,7 +970,7 @@ xfce_settings_manager_dialog_add_category (XfceSettingsManagerDialog *dialog,
gtk_container_add (GTK_CONTAINER (vbox), alignment);
gtk_widget_show (alignment);
- iconview = exo_icon_view_new_with_model (GTK_TREE_MODEL (filter));
+ category->iconview = iconview = exo_icon_view_new_with_model (GTK_TREE_MODEL (filter));
gtk_container_add (GTK_CONTAINER (alignment), iconview);
exo_icon_view_set_orientation (EXO_ICON_VIEW (iconview), GTK_ORIENTATION_HORIZONTAL);
exo_icon_view_set_margin (EXO_ICON_VIEW (iconview), 0);
@@ -786,7 +980,7 @@ xfce_settings_manager_dialog_add_category (XfceSettingsManagerDialog *dialog,
gtk_widget_show (iconview);
/* list used for unselecting */
- dialog->category_iconviews = g_list_append (dialog->category_iconviews, iconview);
+ dialog->categories = g_list_append (dialog->categories, category);
gtk_widget_set_has_tooltip (iconview, TRUE);
g_signal_connect (G_OBJECT (iconview), "query-tooltip",
@@ -874,6 +1068,9 @@ xfce_settings_manager_dialog_menu_reload (XfceSettingsManagerDialog *dialog)
GarconMenuDirectory *directory;
GList *items, *lp;
gint i = 0;
+ gchar *item_text;
+ gchar *normalized;
+ gchar *filter_text;
g_return_if_fail (XFCE_IS_SETTINGS_MANAGER_DIALOG (dialog));
g_return_if_fail (GARCON_IS_MENU (dialog->menu));
@@ -903,12 +1100,24 @@ xfce_settings_manager_dialog_menu_reload (XfceSettingsManagerDialog *dialog)
items = g_list_sort (items, xfce_settings_manager_dialog_menu_sort);
for (lp = items; lp != NULL; lp = lp->next)
{
+ /* create independent search string */
+ item_text = g_strdup_printf ("%s\n%s",
+ garcon_menu_item_get_name (lp->data),
+ garcon_menu_item_get_comment (lp->data));
+ normalized = g_utf8_normalize (item_text, -1, G_NORMALIZE_DEFAULT);
+ g_free (item_text);
+ filter_text = g_utf8_casefold (normalized, -1);
+ g_free (normalized);
+
gtk_list_store_insert_with_values (dialog->store, NULL, i++,
COLUMN_NAME, garcon_menu_item_get_name (lp->data),
COLUMN_ICON_NAME, garcon_menu_item_get_icon_name (lp->data),
COLUMN_TOOLTIP, garcon_menu_item_get_comment (lp->data),
COLUMN_MENU_ITEM, lp->data,
- COLUMN_MENU_DIRECTORY, directory, -1);
+ COLUMN_MENU_DIRECTORY, directory,
+ COLUMN_FILTER_TEXT, filter_text, -1);
+
+ g_free (filter_text);
}
g_list_free (items);
More information about the Xfce4-commits
mailing list