From 426ac9c6fea9e3786f3d17ec6500984fd43792d3 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Thu, 14 Jun 2001 23:25:52 +0000 Subject: [PATCH] Whoops. Forgot this a couple months ago. Now GtkTreeStore sort of sorts. Thu Jun 14 19:21:27 2001 Jonathan Blandford * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot this a couple months ago. Now GtkTreeStore sort of sorts. I'll finish it off tonight, though it basically works now when it's a list. Also, I have a sinking feeling neither GtkTreeStore or GtkListStore actually resort when adding a new item. I'll look into it. --- ChangeLog | 9 ++ ChangeLog.pre-2-0 | 9 ++ ChangeLog.pre-2-10 | 9 ++ ChangeLog.pre-2-2 | 9 ++ ChangeLog.pre-2-4 | 9 ++ ChangeLog.pre-2-6 | 9 ++ ChangeLog.pre-2-8 | 9 ++ gtk/gtkliststore.c | 16 +-- gtk/gtktreemodel.c | 4 +- gtk/gtktreemodelsort.c | 284 +++++++++++++++++++++++++---------------- gtk/gtktreemodelsort.h | 13 +- gtk/gtktreestore.c | 118 ++++++++++++++++- gtk/gtktreeview.c | 1 - tests/testtreesort.c | 6 +- tests/testtreeview.c | 4 +- tests/treestoretest.c | 20 ++- 16 files changed, 386 insertions(+), 143 deletions(-) diff --git a/ChangeLog b/ChangeLog index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f79fcbca8a..2d4e12ceb9 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,12 @@ +Thu Jun 14 19:21:27 2001 Jonathan Blandford + + * gtk/gtktreestore.c (gtk_tree_store_sort_helper): Whoops. Forgot + this a couple months ago. Now GtkTreeStore sort of sorts. I'll + finish it off tonight, though it basically works now when it's a + list. Also, I have a sinking feeling neither GtkTreeStore or + GtkListStore actually resort when adding a new item. I'll look + into it. + 2001-06-14 Havoc Pennington * demos/gtk-demo/main.c (load_file): fix bug identified by diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index 38d5afd667..bfaf22a558 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -1347,9 +1347,9 @@ typedef struct _SortTuple } SortTuple; static gint -_gtk_list_store_compare_func (gconstpointer a, - gconstpointer b, - gpointer user_data) +gtk_list_store_compare_func (gconstpointer a, + gconstpointer b, + gpointer user_data) { GtkListStore *list_store = user_data; GtkTreeDataSortHeader *header = NULL; @@ -1394,7 +1394,6 @@ gtk_list_store_sort (GtkListStore *list_store) GtkTreeIter iter; GArray *sort_array; gint i; - GList *header_list; gint *new_order; GSList *list; GtkTreePath *path; @@ -1404,12 +1403,7 @@ gtk_list_store_sort (GtkListStore *list_store) g_assert (GTK_LIST_STORE_IS_SORTED (list_store)); - for (header_list = list_store->sort_list; header_list; header_list = header_list->next) - { - header = (GtkTreeDataSortHeader*) header_list->data; - if (header->sort_column_id == list_store->sort_column_id) - break; - } + header = _gtk_tree_data_list_get_header (list_store->sort_list, list_store->sort_column_id); /* We want to make sure that we have a function */ g_return_if_fail (header != NULL); @@ -1435,7 +1429,7 @@ gtk_list_store_sort (GtkListStore *list_store) list = list->next; } - g_array_sort_with_data (sort_array, _gtk_list_store_compare_func, list_store); + g_array_sort_with_data (sort_array, gtk_list_store_compare_func, list_store); for (i = 0; i < list_store->length - 1; i++) g_array_index (sort_array, SortTuple, i).el->next = diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c index 244fca757d..f71d88c1e3 100644 --- a/gtk/gtktreemodel.c +++ b/gtk/gtktreemodel.c @@ -576,8 +576,8 @@ gtk_tree_iter_free (GtkTreeIter *iter) * @tree_model: A #GtkTreeModel. * * Returns a set of flags supported by this interface. The flags are a bitwise - * combination of #GtkTreeModelFlags. It is expected that the flags supported - * do not change for an interface. + * combination of #GtkTreeModelFlags. The flags supported should not change + * during the lifecycle of the tree_model. * * Return value: The flags supported by this interface. **/ diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c index 91ea606d9c..657e4afdea 100644 --- a/gtk/gtktreemodelsort.c +++ b/gtk/gtktreemodelsort.c @@ -25,9 +25,13 @@ */ #include "gtktreemodelsort.h" +#include "gtktreesortable.h" #include "gtksignal.h" +#include "gtktreedatalist.h" #include + + typedef struct _SortElt SortElt; struct _SortElt { @@ -53,6 +57,7 @@ struct _SortData static void gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort); static void gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class); static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface); +static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface); static void gtk_tree_model_sort_finalize (GObject *object); static void gtk_tree_model_sort_range_changed (GtkTreeModel *model, GtkTreePath *start_path, @@ -104,6 +109,19 @@ static void gtk_tree_model_sort_ref_node (GtkTreeModel * static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model, GtkTreeIter *iter); +/* sortable */ +static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order); +static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order); +static void gtk_tree_model_sort_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); + /* Internal functions */ static gint gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort, GArray *array, @@ -115,14 +133,6 @@ static GtkTreePath *gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tre static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortElt *place); static void gtk_tree_model_sort_free_level (GArray *array); -static GFunc gtk_tree_model_sort_get_func (GtkTreeModelSort *tree_model_sort); -static gint gtk_tree_model_sort_func (gconstpointer a, - gconstpointer b, - gpointer user_data); -static gint g_value_string_compare_func (const GValue *a, - const GValue *b); -static gint g_value_int_compare_func (const GValue *a, - const GValue *b); @@ -153,10 +163,21 @@ gtk_tree_model_sort_get_type (void) NULL }; + static const GInterfaceInfo sortable_info = + { + (GInterfaceInitFunc) gtk_tree_model_sort_tree_sortable_init, + NULL, + NULL + }; + tree_model_sort_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeModelSort", &tree_model_sort_info, 0); g_type_add_interface_static (tree_model_sort_type, GTK_TYPE_TREE_MODEL, &tree_model_info); + + g_type_add_interface_static (tree_model_sort_type, + GTK_TYPE_TREE_SORTABLE, + &sortable_info); } return tree_model_sort_type; @@ -190,9 +211,18 @@ gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface) iface->unref_node = gtk_tree_model_sort_unref_node; } +static void +gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface) +{ + iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id; + iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id; + iface->sort_column_id_set_func = gtk_tree_model_sort_sort_column_id_set_func; +} + static void gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort) { + tree_model_sort->sort_column_id = -1; tree_model_sort->stamp = g_random_int (); } @@ -203,17 +233,13 @@ gtk_tree_model_sort_new (void) } GtkTreeModel * -gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model, - GValueCompareFunc func, - gint sort_col) +gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model) { GtkTreeModel *retval; retval = gtk_tree_model_sort_new (); gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model); - GTK_TREE_MODEL_SORT (retval)->func = func; - GTK_TREE_MODEL_SORT (retval)->sort_col = sort_col; return retval; } @@ -249,35 +275,56 @@ gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort, g_object_unref (G_OBJECT (tree_model_sort->child_model)); } - tree_model_sort->child_model = child_model; + if (tree_model_sort->root) + { + gtk_tree_model_sort_free_level (tree_model_sort->root); + tree_model_sort->root; + } + if (tree_model_sort->sort_list) + { + _gtk_tree_data_list_header_free (tree_model_sort->sort_list); + tree_model_sort->sort_list = NULL; + } + + tree_model_sort->child_model = child_model; if (child_model) { + GType *types; + gint i, n_columns; + tree_model_sort->changed_id = g_signal_connectc (child_model, "range_changed", - gtk_tree_model_sort_range_changed, + G_CALLBACK (gtk_tree_model_sort_range_changed), tree_model_sort, FALSE); tree_model_sort->inserted_id = g_signal_connectc (child_model, - "inserted", - gtk_tree_model_sort_inserted, + "inserted", + G_CALLBACK (gtk_tree_model_sort_inserted), tree_model_sort, FALSE); tree_model_sort->has_child_toggled_id = g_signal_connectc (child_model, "has_child_toggled", - gtk_tree_model_sort_has_child_toggled, + G_CALLBACK (gtk_tree_model_sort_has_child_toggled), tree_model_sort, FALSE); tree_model_sort->deleted_id = g_signal_connectc (child_model, "deleted", - gtk_tree_model_sort_deleted, + G_CALLBACK (gtk_tree_model_sort_deleted), tree_model_sort, FALSE); + tree_model_sort->flags = gtk_tree_model_get_flags (child_model); + n_columns = gtk_tree_model_get_n_columns (child_model); + types = g_new (GType, n_columns); + for (i = 0; i < n_columns; i++) + types[i] = gtk_tree_model_get_column_type (child_model, i); + tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns, types); + g_free (types); } } @@ -333,6 +380,11 @@ gtk_tree_model_sort_finalize (GObject *object) g_object_unref (G_OBJECT (tree_model_sort->child_model)); tree_model_sort->child_model = NULL; } + if (tree_model_sort->sort_list) + { + _gtk_tree_data_list_header_free (tree_model_sort->sort_list); + tree_model_sort->sort_list = NULL; + } } static void @@ -594,8 +646,12 @@ gtk_tree_model_sort_deleted (GtkTreeModel *s_model, static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model) { + GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; + g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0); - g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0); + + if (tree_model_sort->child_model == 0) + return 0; return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->child_model); } @@ -857,6 +913,98 @@ gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model, GtkTreeIter *iter) { + +} + +static gboolean +gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order) +{ + GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable; + + g_return_val_if_fail (sortable != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE); + + if (tree_model_sort->sort_column_id == -1) + return FALSE; + + if (sort_column_id) + *sort_column_id = tree_model_sort->sort_column_id; + if (order) + *order = tree_model_sort->order; + + return TRUE; +} + +static void +gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order) +{ + GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable; + GList *list; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable)); + + for (list = tree_model_sort->sort_list; list; list = list->next) + { + GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader*) list->data; + if (header->sort_column_id == sort_column_id) + break; + } + g_return_if_fail (list != NULL); + + if ((tree_model_sort->sort_column_id == sort_column_id) && + (tree_model_sort->order == order)) + return; + + tree_model_sort->sort_column_id = sort_column_id; + tree_model_sort->order = order; + + /* if (tree_model_sort->sort_column_id >= 0) + gtk_list_store_sort (tree_model_sort);*/ + + gtk_tree_sortable_sort_column_changed (sortable); + +} + +static void +gtk_tree_model_sort_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy) +{ + GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable; + GtkTreeDataSortHeader *header = NULL; + GList *list; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable)); + g_return_if_fail (func != NULL); + + for (list = tree_model_sort->sort_list; list; list = list->next) + { + header = (GtkTreeDataSortHeader*) list->data; + if (header->sort_column_id == sort_column_id) + break; + } + + if (header == NULL) + { + header = g_new0 (GtkTreeDataSortHeader, 1); + header->sort_column_id = sort_column_id; + tree_model_sort->sort_list = g_list_append (tree_model_sort->sort_list, header); + } + + if (header->destroy) + (* header->destroy) (header->data); + + header->func = func; + header->data = data; + header->destroy = destroy; } /* Internal functions */ @@ -874,11 +1022,11 @@ gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort, GValue tmp_value = {0, }; SortElt *tmp_elt; - func = (GValueCompareFunc) gtk_tree_model_sort_get_func (tree_model_sort); + func = NULL; //(GValueCompareFunc) gtk_tree_model_sort_get_func (tree_model_sort); g_return_val_if_fail (func != NULL, 0); - gtk_tree_model_get_value (tree_model_sort->child_model, iter, tree_model_sort->sort_col, &value); + gtk_tree_model_get_value (tree_model_sort->child_model, iter, tree_model_sort->sort_column_id, &value); for (middle = 0; middle < array->len; middle++) { @@ -888,7 +1036,7 @@ gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort, continue; gtk_tree_model_get_value (tree_model_sort->child_model, (GtkTreeIter *) tmp_elt, - tree_model_sort->sort_col, + tree_model_sort->sort_column_id, &tmp_value); cmp = ((func) (&value, &tmp_value)); @@ -1019,12 +1167,6 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, i++; } while (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter)); - - sort_data.func = (GValueCompareFunc) gtk_tree_model_sort_get_func (tree_model_sort); - sort_data.model = tree_model_sort->child_model; - sort_data.sort_col = tree_model_sort->sort_col; - - g_array_sort_with_data (children, gtk_tree_model_sort_func, &sort_data); } static void @@ -1047,88 +1189,6 @@ gtk_tree_model_sort_free_level (GArray *array) g_array_free (array, TRUE); } -static GFunc -gtk_tree_model_sort_get_func (GtkTreeModelSort *tree_model_sort) -{ - GValueCompareFunc func; - if (tree_model_sort->func) - func = tree_model_sort->func; - else - { - switch (gtk_tree_model_get_column_type (tree_model_sort->child_model, - tree_model_sort->sort_col)) - { - case G_TYPE_STRING: - func = &g_value_string_compare_func; - break; - case G_TYPE_INT: - func = &g_value_int_compare_func; - break; - default: - g_warning ("No comparison function for row %d (Type %s)\n", - tree_model_sort->sort_col, - g_type_name (gtk_tree_model_get_column_type (tree_model_sort->child_model, - tree_model_sort->sort_col))); - return NULL; - } - - } - return (GFunc) func; -} - -static gint -gtk_tree_model_sort_func (gconstpointer a, - gconstpointer b, - gpointer user_data) -{ - GValue value_a = {0, }; - GValue value_b = {0, }; - SortData *sort_data = user_data; - gboolean retval; - - gtk_tree_model_get_value (sort_data->model, (GtkTreeIter *) a, sort_data->sort_col, &value_a); - gtk_tree_model_get_value (sort_data->model, (GtkTreeIter *) b, sort_data->sort_col, &value_b); - - retval = (sort_data->func) (&value_a, &value_b); - - g_value_unset (&value_a); - g_value_unset (&value_b); - - return retval; -} - - -static gint -g_value_string_compare_func (const GValue *a, - const GValue *b) -{ - gchar *a_str = g_value_get_string (a); - gchar *b_str = g_value_get_string (b); - - if (b_str == NULL) - return a_str == NULL; - if (a_str == NULL) - return -1; - - return strcmp (a_str, b_str); -} - -static gint -g_value_int_compare_func (const GValue *a, - const GValue *b) -{ - gint a_int = g_value_get_int (a); - gint b_int = g_value_get_int (b); - - if (a_int < b_int) - return -1; - else if (a_int > b_int) - return 1; - else - return 0; -} - - /* DEAD CODE */ #if 0 @@ -1147,7 +1207,7 @@ g_value_int_compare_func (const GValue *a, tmp_elt = &(g_array_index (array, SortElt, middle)); gtk_tree_model_get_value (sort->child_model, (GtkTreeIter *) tmp_elt, - sort->sort_col, + sort->sort_column_id, &tmp_value); cmp = ((func) (&tmp_value, &s_value)); diff --git a/gtk/gtktreemodelsort.h b/gtk/gtktreemodelsort.h index 192e030d30..c780693117 100644 --- a/gtk/gtktreemodelsort.h +++ b/gtk/gtktreemodelsort.h @@ -21,6 +21,7 @@ #define __GTK_TREE_MODEL_SORT_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -48,9 +49,13 @@ struct _GtkTreeModelSort gint stamp; guint flags; GtkTreeModel *child_model; - gint sort_col; - GValueCompareFunc func; + /* sort information */ + GList *sort_list; + gint sort_column_id; + GtkTreeSortOrder order; + + /* signal ids */ guint changed_id; guint inserted_id; guint has_child_toggled_id; @@ -65,9 +70,7 @@ struct _GtkTreeModelSortClass GtkType gtk_tree_model_sort_get_type (void); GtkTreeModel *gtk_tree_model_sort_new (void); -GtkTreeModel *gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model, - GValueCompareFunc func, - gint sort_col); +GtkTreeModel *gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model); void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort, GtkTreeModel *child_model); GtkTreeModel *gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model); diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c index e7753b1277..b6e8f0ea98 100644 --- a/gtk/gtktreestore.c +++ b/gtk/gtktreestore.c @@ -1330,11 +1330,127 @@ gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, return TRUE; } +/* Sorting */ +typedef struct _SortTuple +{ + gint offset; + GNode *node; +} SortTuple; + +static gint +gtk_tree_store_compare_func (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + GtkTreeStore *tree_store = user_data; + GtkTreeDataSortHeader *header = NULL; + GNode *node_a; + GNode *node_b; + GtkTreeIter iter_a; + GtkTreeIter iter_b; + gint retval; + + header = _gtk_tree_data_list_get_header (tree_store->sort_list, + tree_store->sort_column_id); + + g_return_val_if_fail (header != NULL, 0); + g_return_val_if_fail (header->func != NULL, 0); + + node_a = ((SortTuple *) a)->node; + node_b = ((SortTuple *) b)->node; + + iter_a.stamp = tree_store->stamp; + iter_a.user_data = node_a; + iter_b.stamp = tree_store->stamp; + iter_b.user_data = node_b; + + retval = (* header->func) (GTK_TREE_MODEL (user_data), + &iter_a, &iter_b, + header->data); + + if (tree_store->order == GTK_TREE_SORT_DESCENDING) + { + if (retval > 0) + retval = -1; + else if (retval < 0) + retval = 1; + } + return retval; +} + +static void +gtk_tree_store_sort_helper (GtkTreeStore *tree_store, + GNode *node) +{ + GtkTreeDataSortHeader *header = NULL; + GtkTreeIter iter; + GArray *sort_array; + GNode *tmp_node; + gint list_length; + gint i; + gint *new_order; + GtkTreePath *path; + + if (node->next == NULL) + return; + + g_assert (GTK_TREE_STORE_IS_SORTED (tree_store)); + + header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id); + + /* We want to make sure that we have a function */ + g_return_if_fail (header != NULL); + g_return_if_fail (header->func != NULL); + + list_length = 0; + for (tmp_node = node; tmp_node; tmp_node = tmp_node->next) + list_length++; + + sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length); + + i = 0; + for (tmp_node = node; tmp_node; tmp_node = tmp_node->next) + { + SortTuple tuple; + + tuple.offset = i; + tuple.node = tmp_node; + g_array_append_val (sort_array, tuple); + i++; + } + + g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store); + + for (i = 0; i < list_length - 1; i++) + { + g_array_index (sort_array, SortTuple, i).node->next = + g_array_index (sort_array, SortTuple, i + 1).node; + g_array_index (sort_array, SortTuple, i + 1).node->prev = + g_array_index (sort_array, SortTuple, i).node; + } + g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL; + g_array_index (sort_array, SortTuple, 0).node->prev = NULL; + G_NODE (tree_store->root)->children = g_array_index (sort_array, SortTuple, 0).node; + + /* Let the world know about our new order */ + new_order = g_new (gint, list_length); + for (i = 0; i < list_length; i++) + new_order[i] = g_array_index (sort_array, SortTuple, i).offset; + path = gtk_tree_path_new (); + iter.stamp = tree_store->stamp; + iter.user_data = NULL; + + gtk_tree_model_reordered (GTK_TREE_MODEL (tree_store), + path, &iter, new_order); + gtk_tree_path_free (path); + g_free (new_order); + g_array_free (sort_array, TRUE); +} static void gtk_tree_store_sort (GtkTreeStore *tree_store) { - + gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root)->children); } static void diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index e89ec3fa06..a5432b930b 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -1571,7 +1571,6 @@ gtk_tree_view_button_press (GtkWidget *widget, tree_view->priv->press_start_y = event->y; } - g_print ("%d\n", event->state); gtk_tree_view_real_set_cursor (tree_view, path, TRUE, event->state); if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) diff --git a/tests/testtreesort.c b/tests/testtreesort.c index f8d8be52aa..54ff205dfb 100644 --- a/tests/testtreesort.c +++ b/tests/testtreesort.c @@ -65,15 +65,15 @@ main (int argc, char *argv[]) gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); - model = gtk_list_store_new_with_types (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + model = gtk_tree_store_new_with_types (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); // gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, GTK_TREE_SORT_ASCENDING); g_print ("start model\n"); tree_view = gtk_tree_view_new_with_model (model); for (j = 0; j < 2; j++) for (i = 0; data[i].word_1 != NULL; i++) { - gtk_list_store_prepend (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, + gtk_tree_store_prepend (GTK_TREE_STORE (model), &iter, NULL); + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, WORD_COLUMN_1, data[i].word_1, WORD_COLUMN_2, data[i].word_2, WORD_COLUMN_3, data[i].word_3, diff --git a/tests/testtreeview.c b/tests/testtreeview.c index 7bf2c0636c..a8bfed3dd1 100644 --- a/tests/testtreeview.c +++ b/tests/testtreeview.c @@ -673,11 +673,11 @@ main (int argc, models[MODEL_TREE] = create_tree_model (); model = create_list_model (); - models[MODEL_SORTED_LIST] = gtk_tree_model_sort_new_with_model (model, NULL, 0); + models[MODEL_SORTED_LIST] = gtk_tree_model_sort_new_with_model (model); g_object_unref (G_OBJECT (model)); model = create_tree_model (); - models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model, NULL, 0); + models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model); g_object_unref (G_OBJECT (model)); models[MODEL_EMPTY_LIST] = GTK_TREE_MODEL (gtk_list_store_new ()); diff --git a/tests/treestoretest.c b/tests/treestoretest.c index 9ede2222b5..c32e8842a9 100644 --- a/tests/treestoretest.c +++ b/tests/treestoretest.c @@ -224,7 +224,7 @@ make_window (gint view_type) GtkWidget *tree_view; GtkTreeViewColumn *column; GtkCellRenderer *cell; - GtkObject *selection; + GObject *selection; /* Make the Widgets/Objects */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -251,14 +251,16 @@ make_window (gint view_type) { GtkTreeModel *sort_model; - sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model), - NULL, 1); + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (base_model)); tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model)); } break; + default: + g_assert_not_reached (); + break; } - selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view))); + selection = G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view))); gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE); /* Put them together */ @@ -319,11 +321,17 @@ make_window (gint view_type) /* The selected column */ cell = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Node ID", cell, "markup", 0, NULL); + gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + g_object_unref (G_OBJECT (cell)); + g_object_unref (G_OBJECT (column)); cell = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Random Number", cell, "text", 1, NULL); + gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + g_object_unref (G_OBJECT (cell)); + g_object_unref (G_OBJECT (column)); /* A few to start */ if (view_type == 0) @@ -334,9 +342,9 @@ make_window (gint view_type) iter_append (NULL, GTK_TREE_VIEW (tree_view)); iter_append (NULL, GTK_TREE_VIEW (tree_view)); iter_append (NULL, GTK_TREE_VIEW (tree_view)); + gtk_widget_show_all (window); } /* Show it all */ - gtk_widget_show_all (window); } int @@ -348,7 +356,7 @@ main (int argc, char *argv[]) /* FIXME: reverse this */ make_window (0); - make_window (1); + // make_window (1); gtk_main ();