[gnome-system-tools] Implement sorting and search in users and groups lists



commit 2c9725a0019f0ab1eabe29eebcc3f58ba21c4a2f
Author: Milan Bouchet-Valat <nalimilan club fr>
Date:   Sat Jan 30 13:17:46 2010 +0100

    Implement sorting and search in users and groups lists
    
    Sort by user login/group name, and set search column to this too, since this feature is mostly useful for large user bases, where logins are primary identifiers.
    
    Replace table_get_row_references() with its groups_table_() and users_table() equivalents, since they don't use the same model (users have a GtkTreeModelFilter). Remove get_table(), which is now unused. Add users_table_get_model() and groups_table_get_model() convenience functions to make the code clearer.

 src/users/callbacks.c     |    3 +-
 src/users/groups-table.c  |   75 +++++++++++++++++++++++++++---
 src/users/groups-table.h  |   19 +++++---
 src/users/table.c         |   55 ----------------------
 src/users/user-settings.c |    3 +-
 src/users/users-table.c   |  111 +++++++++++++++++++++++++++++++++++++++------
 src/users/users-table.h   |   16 ++++---
 7 files changed, 190 insertions(+), 92 deletions(-)
---
diff --git a/src/users/callbacks.c b/src/users/callbacks.c
index cba26e4..4f22c07 100644
--- a/src/users/callbacks.c
+++ b/src/users/callbacks.c
@@ -268,7 +268,8 @@ on_group_delete_clicked (GtkButton *button, gpointer user_data)
 	GtkTreePath *path;
 	GList *list, *elem;
 
-	list = elem = table_get_row_references (TABLE_GROUPS, &model);
+	list = elem = groups_table_get_row_references ();
+	model = groups_table_get_model ();
 
 	/* Before going further, check for authorizations, authenticating if needed */
 	if (!gst_tool_authenticate (tool, GST_USERS_TOOL (tool)->groups_config))
diff --git a/src/users/groups-table.c b/src/users/groups-table.c
index ca8b800..efb6542 100644
--- a/src/users/groups-table.c
+++ b/src/users/groups-table.c
@@ -54,6 +54,7 @@ add_group_columns (GtkTreeView *treeview)
 static GtkTreeModel*
 create_groups_model (void)
 {
+	GtkTreeModel *sort_model;
 	GtkListStore *store;
 
 	store = gtk_list_store_new (COL_GROUP_LAST,
@@ -61,7 +62,12 @@ create_groups_model (void)
 	                            G_TYPE_INT,
 				    G_TYPE_OBJECT);
 
-	return GTK_TREE_MODEL (store);
+	/* Sort model */
+	sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+	                                      COL_GROUP_NAME, GTK_SORT_ASCENDING);
+
+	return sort_model;
 }
 
 void
@@ -98,11 +104,24 @@ create_groups_table (void)
 			  G_CALLBACK (on_table_popup_menu), NULL);
 }
 
+GtkTreeModel *
+groups_table_get_model ()
+{
+	GtkWidget *groups_table;
+	GtkTreeModel *sort_model;
+
+	groups_table = gst_dialog_get_widget (tool->main_dialog, "groups_table");
+	sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (groups_table));
+
+	return gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
+}
+
 void
 groups_table_set_group (OobsGroup *group, GtkTreeIter *iter)
 {
-	GtkWidget *groups_table = gst_dialog_get_widget (tool->main_dialog, "groups_table");
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (groups_table));
+	GtkTreeModel *model;
+
+	model = groups_table_get_model ();
 
 	gtk_list_store_set (GTK_LIST_STORE (model), iter,
 			    COL_GROUP_NAME, oobs_group_get_name (group),
@@ -114,10 +133,11 @@ groups_table_set_group (OobsGroup *group, GtkTreeIter *iter)
 void
 groups_table_add_group (OobsGroup *group)
 {
-	GtkWidget *groups_table = gst_dialog_get_widget (tool->main_dialog, "groups_table");
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (groups_table));
+	GtkTreeModel *model;
 	GtkTreeIter iter;
 
+	model = groups_table_get_model ();
+
 	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 	groups_table_set_group (group, &iter);
 }
@@ -125,8 +145,49 @@ groups_table_add_group (OobsGroup *group)
 void
 groups_table_clear (void)
 {
-	GtkWidget *groups_table = gst_dialog_get_widget (tool->main_dialog, "groups_table");
-	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (groups_table));
+	GtkTreeModel *model;
+
+	model = groups_table_get_model ();
 
 	gtk_list_store_clear (GTK_LIST_STORE (model));
 }
+
+/*
+ * Get selected items, translating them to child GtkListStore references.
+ */
+GList*
+groups_table_get_row_references ()
+{
+	GtkWidget *groups_table;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeModel *sort_model;
+	GtkTreePath *path;
+	GList *paths, *elem, *list = NULL;
+
+	groups_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "groups_table");
+	sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (groups_table));
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (groups_table));
+	paths = elem = gtk_tree_selection_get_selected_rows (selection, &model);
+
+	if (!paths)
+		return NULL;
+
+	while (elem) {
+		path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (sort_model),
+		                                                       elem->data);
+
+		list = g_list_prepend (list, gtk_tree_row_reference_new (model, path));
+
+		gtk_tree_path_free (path);
+		elem = elem->next;
+	}
+
+	list = g_list_reverse (list);
+	g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (paths);
+
+	return list;
+}
+
diff --git a/src/users/groups-table.h b/src/users/groups-table.h
index ef8841a..d4c89cb 100644
--- a/src/users/groups-table.h
+++ b/src/users/groups-table.h
@@ -48,13 +48,16 @@ struct GroupTreeItem_
 	GroupTreeItem *children;
 };
 
-void    groups_table_clear              (void);
-void	create_groups_table		(void);
-void	populate_groups_table		(void);
-void	group_table_update_content	(void);
-
-void    groups_table_set_group          (OobsGroup    *group,
-                                         GtkTreeIter  *iter);
-void    groups_table_add_group          (OobsGroup    *group);
+void          groups_table_clear               (void);
+void	      create_groups_table              (void);
+void          populate_groups_table            (void);
+void	      group_table_update_content       (void);
+
+GtkTreeModel *groups_table_get_model           ();
+void          groups_table_set_group           (OobsGroup    *group,
+                                                GtkTreeIter  *iter);
+void          groups_table_add_group           (OobsGroup    *group);
+
+GList        *groups_table_get_row_references  ();
 
 #endif /* _GROUPS_TABLE_H */
diff --git a/src/users/table.c b/src/users/table.c
index 000660e..ae9912a 100644
--- a/src/users/table.c
+++ b/src/users/table.c
@@ -209,58 +209,3 @@ create_tables (GstUsersTool *tool)
 	setup_groups_combo ();
 	setup_shells_combo (tool);
 }
-
-static GtkWidget*
-get_table (gint table)
-{
-	switch (table) {
-	case TABLE_USERS:
-		return gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
-	case TABLE_GROUPS:
-		return gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "groups_table");
-	default:
-		g_assert_not_reached ();
-	}
-}
-
-GList*
-table_get_row_references (gint table, GtkTreeModel **model)
-{
-	GtkTreeSelection *selection;
-	GtkTreeModel *table_model;
-	GtkTreePath *child_path;
-	GList *paths, *elem, *list = NULL;
-
-	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (get_table (table)));
-	paths = elem = gtk_tree_selection_get_selected_rows (selection, &table_model);
-	if (table == TABLE_USERS)
-		*model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (table_model));
-	else
-		*model = table_model;
-
-	if (!paths)
-		return NULL;
-
-	if (table == TABLE_USERS) {
-		while (elem) {
-			child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (table_model),
-			                                                               (GtkTreePath *) elem->data);
-
-			list = g_list_prepend (list, gtk_tree_row_reference_new (*model, child_path));
-			gtk_tree_path_free (child_path);
-			elem = elem->next;
-		}
-	}
-	else {
-		while (elem) {
-			list = g_list_prepend (list, gtk_tree_row_reference_new (*model, (GtkTreePath *) elem->data));
-			elem = elem->next;
-		}
-	}
-
-	list = g_list_reverse (list);
-	g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
-	g_list_free (paths);
-
-	return list;
-}
diff --git a/src/users/user-settings.c b/src/users/user-settings.c
index f4ab547..7c01282 100644
--- a/src/users/user-settings.c
+++ b/src/users/user-settings.c
@@ -187,7 +187,8 @@ on_user_delete_clicked (GtkButton *button, gpointer user_data)
 	if (!gst_tool_authenticate (tool, GST_USERS_TOOL (tool)->users_config))
 		return;
 
-	list = elem = table_get_row_references (TABLE_USERS, &model);
+	list = elem = users_table_get_row_references ();
+	model = users_table_get_model ();
 
 	while (elem) {
 		path = gtk_tree_row_reference_get_path (elem->data);
diff --git a/src/users/users-table.c b/src/users/users-table.c
index c067fc8..240288e 100644
--- a/src/users/users-table.c
+++ b/src/users/users-table.c
@@ -94,6 +94,7 @@ create_users_model (GstUsersTool *tool)
 {
 	GtkListStore *store;
 	GtkTreeModel *filter_model;
+	GtkTreeModel *sort_model;
 	
 	store = gtk_list_store_new (COL_USER_LAST,
 				    GDK_TYPE_PIXBUF,
@@ -105,11 +106,18 @@ create_users_model (GstUsersTool *tool)
 	                            G_TYPE_BOOLEAN,
 				    G_TYPE_OBJECT,
 				    OOBS_TYPE_LIST_ITER);
-	filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
 
+	/* Filter model */
+	filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
 	gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model),
 						users_model_filter, tool, NULL);
-	return filter_model;
+
+	/* Sort model */
+	sort_model = gtk_tree_model_sort_new_with_model (filter_model);
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+	                                      COL_USER_LOGIN, GTK_SORT_ASCENDING);
+
+	return sort_model;
 }
 
 void
@@ -131,6 +139,8 @@ create_users_table (GstUsersTool *tool)
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (users_table));
 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
 
+	gtk_tree_view_set_search_column (GTK_TREE_VIEW (users_table), COL_USER_LOGIN);
+
 	popup = popup_menu_create (users_table, TABLE_USERS);
 	g_object_set_data_full (G_OBJECT (users_table),
 				"popup", popup,
@@ -146,17 +156,32 @@ create_users_table (GstUsersTool *tool)
 			  G_CALLBACK (on_table_popup_menu), NULL);
 }
 
+GtkTreeModel *
+users_table_get_model ()
+{
+	GtkWidget *users_table;
+	GtkTreeModel *sort_model;
+	GtkTreeModel *filter_model;
+
+	users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
+
+	sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
+	filter_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
+
+	return gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+}
+
 void
 users_table_set_user (OobsUser *user, GtkTreeIter *iter)
 {
-	GtkWidget *users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
-	GtkTreeModel *filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
-	GtkTreeModel *model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+	GtkTreeModel *model;
 	GdkPixbuf *face;
 	const char *name;
 	const char *login;
 	char *label;
 
+	model = users_table_get_model ();
+
 	face = user_settings_get_user_face (user, 48);
 	name = oobs_user_get_full_name (user);
 	login = oobs_user_get_login_name (user);
@@ -185,11 +210,11 @@ users_table_set_user (OobsUser *user, GtkTreeIter *iter)
 GtkTreePath *
 users_table_add_user (OobsUser *user)
 {
-	GtkWidget *users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
-	GtkTreeModel *filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
-	GtkTreeModel *model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+	GtkTreeModel *model;
 	GtkTreeIter iter;
 
+	model = users_table_get_model ();
+
 	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 	users_table_set_user (user, &iter);
 
@@ -199,14 +224,59 @@ users_table_add_user (OobsUser *user)
 void
 users_table_clear (void)
 {
-        GtkWidget *users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
-        GtkTreeModel *filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
-        GtkTreeModel *model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+        GtkTreeModel *model;
+
+	model = users_table_get_model ();
 
         gtk_list_store_clear (GTK_LIST_STORE (model));
 }
 
 /*
+ * Get selected items, translating them to child GtkListStore references.
+ */
+GList*
+users_table_get_row_references ()
+{
+	GtkWidget *users_table;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeModel *sort_model;
+	GtkTreeModel *filter_model;
+	GtkTreePath *path, *filter_path;
+	GList *paths, *elem, *list = NULL;
+
+	users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
+	sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
+	filter_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (users_table));
+	paths = elem = gtk_tree_selection_get_selected_rows (selection, &model);
+
+	if (!paths)
+		return NULL;
+
+	while (elem) {
+		filter_path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (sort_model),
+		                                                              elem->data);
+
+		path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (filter_model),
+		                                                         filter_path);
+
+		list = g_list_prepend (list, gtk_tree_row_reference_new (model, path));
+
+		gtk_tree_path_free (path);
+		gtk_tree_path_free (filter_path);
+		elem = elem->next;
+	}
+
+	list = g_list_reverse (list);
+	g_list_foreach (paths, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (paths);
+
+	return list;
+}
+
+/*
  * Select the given path, translating it to a row in the filter model. Useful when
  * we only want to select a newly added item.
  */
@@ -214,12 +284,19 @@ void
 users_table_select_path (GtkTreePath *path)
 {
 	GtkWidget *users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
-	GtkTreeModel *filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
+	GtkTreeModel *filter_model;
+	GtkTreeModel *sort_model;
 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (users_table));
 	GtkTreePath *filter_path;
+	GtkTreePath *sort_path;
+
+	sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (users_table));
+	filter_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
 
 	filter_path = gtk_tree_model_filter_convert_child_path_to_path
 		(GTK_TREE_MODEL_FILTER (filter_model), path);
+	sort_path = gtk_tree_model_sort_convert_child_path_to_path
+		(GTK_TREE_MODEL_SORT (sort_model), filter_path);
 
 	gtk_tree_selection_unselect_all (selection);
 	gtk_tree_selection_select_path (selection, filter_path);
@@ -242,23 +319,29 @@ users_table_update_current ()
 {
 	GtkWidget *users_table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "users_table");
 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (users_table));
+	GtkTreeModel *sort_model;
 	GtkTreeModel *filter_model;
 	GList *selected;
 	GtkTreePath *path;
 	GtkTreeIter iter;
+	GtkTreeIter sort_iter;
 	GtkTreeIter filter_iter;
 	OobsUser *user;
 
-	selected = gtk_tree_selection_get_selected_rows (selection, &filter_model);
+	selected = gtk_tree_selection_get_selected_rows (selection, &sort_model);
 	g_assert (selected != NULL);
 
 	/* Only choose the first selected user */
 	path = (GtkTreePath *) selected->data;
 
-	gtk_tree_model_get_iter (filter_model, &filter_iter, path);
+	gtk_tree_model_get_iter (sort_model, &sort_iter, path);
 	g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free (selected);
 
+	gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (sort_model),
+	                                                &filter_iter, &sort_iter);
+
+	filter_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
 	gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (filter_model),
 	                                                  &iter, &filter_iter);
 
diff --git a/src/users/users-table.h b/src/users/users-table.h
index b49884d..12627b7 100644
--- a/src/users/users-table.h
+++ b/src/users/users-table.h
@@ -38,18 +38,22 @@ enum {
 	COL_USER_LAST
 };
 
-void         create_users_table	               (GstUsersTool *tool);
+void          create_users_table                (GstUsersTool *tool);
 
-void         users_table_clear                 (void);
+GtkTreeModel *users_table_get_model             ();
 
-void         users_table_set_user              (OobsUser     *user,
+void          users_table_clear                 (void);
+
+void          users_table_set_user              (OobsUser     *user,
                                                 GtkTreeIter  *iter);
 
-GtkTreePath *users_table_add_user              (OobsUser     *user);
+GtkTreePath  *users_table_add_user              (OobsUser     *user);
+
+GList        *users_table_get_row_references    ();
 
-void         users_table_select_path           (GtkTreePath *path);
+void          users_table_select_path           (GtkTreePath *path);
 
-void         users_table_select_first          (void);
+void          users_table_select_first          (void);
 
 OobsUser    *users_table_get_current           (void);
 



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