From c8df83a2fee148d871b36ca5ac742dc566c64612 Mon Sep 17 00:00:00 2001 From: Stefan Jeske Date: Wed, 5 Aug 1998 20:02:32 +0000 Subject: new enum GtkSortType. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wed Aug 5 21:12:37 1998 Stefan Jeske * gtk/gtkenums.h: new enum GtkSortType. * gtk/gtkclist.h: * gtk/gtkclist.c: Added sorting capabilities to GtkCList. New APIs : gtk_clist_set_compare_func, gtk_clist_set_sort_column, gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. New internal functions : default_compare, merge, mergesort. (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. (gtk_clist_insert): Modified to handle gtk_clist_append and the auto sort flag. Changed the return value from void to gint to return the row number where the element was actually inserted. (gtk_clist_swap_rows): Return immediately if auto sort flag is set. * gtk/gtkctree.h: * gtk/gtkctree.c: Removed the auto_sort flag, replaced ctree->node_compare with clist->compare all over the place, modified default_compare to match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. * gtk/testgtk.c: Modified clist/ctree samples to demonstrate sorting. The lists can be sorted by a column by clicking the corresponding title button. --- ChangeLog | 30 +++++ ChangeLog.pre-2-0 | 30 +++++ ChangeLog.pre-2-10 | 30 +++++ ChangeLog.pre-2-2 | 30 +++++ ChangeLog.pre-2-4 | 30 +++++ ChangeLog.pre-2-6 | 30 +++++ ChangeLog.pre-2-8 | 30 +++++ gtk/gtkclist.c | 346 ++++++++++++++++++++++++++++++++++++++++++----------- gtk/gtkclist.h | 119 ++++++++++-------- gtk/gtkctree.c | 109 +++++++---------- gtk/gtkctree.h | 13 +- gtk/gtkenums.h | 7 ++ gtk/testgtk.c | 54 ++++++++- tests/testgtk.c | 54 ++++++++- 14 files changed, 713 insertions(+), 199 deletions(-) diff --git a/ChangeLog b/ChangeLog index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index b47db2be7..2fd2cdc64 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,33 @@ +Wed Aug 5 21:12:37 1998 Stefan Jeske + + * gtk/gtkenums.h: new enum GtkSortType. + + * gtk/gtkclist.h: + * gtk/gtkclist.c: + Added sorting capabilities to GtkCList. New APIs : + gtk_clist_set_compare_func, gtk_clist_set_sort_column, + gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. + New internal functions : default_compare, merge, mergesort. + + (gtk_clist_append): This is just a wrapper for gtk_clist_insert now. + + (gtk_clist_insert): Modified to handle gtk_clist_append and the + auto sort flag. Changed the return value from void to gint to + return the row number where the element was actually inserted. + + (gtk_clist_swap_rows): Return immediately if auto sort flag is set. + + * gtk/gtkctree.h: + * gtk/gtkctree.c: + Removed the auto_sort flag, replaced ctree->node_compare with + clist->compare all over the place, modified default_compare to + match clist's needs. Removed API´s : gtk_ctree_set_auto_sort, + gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef. + + * gtk/testgtk.c: Modified clist/ctree samples to demonstrate + sorting. The lists can be sorted by a column by clicking the + corresponding title button. + Tue Aug 4 22:02:49 PDT 1998 Shawn T. Amundson * Released GTK+ 1.1.1 diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index ae7d89144..bf05c86d9 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -350,6 +350,17 @@ static void extend_selection (GtkCList *clist, gfloat position, gboolean auto_start_selection); +/* Sorting */ +static gint default_compare (GtkCList *clist, + gconstpointer row1, + gconstpointer row2); +static GList * merge (GtkCList *clist, + GList *a, + GList *b); +static GList * mergesort (GtkCList *clist, + GList *list, + gint num); + /* Fill in data after widget is realized and has style */ static void add_style_data (GtkCList * clist); @@ -809,6 +820,10 @@ gtk_clist_init (GtkCList * clist) clist->drag_pos = -1; clist->htimer = 0; clist->vtimer = 0; + + clist->compare = default_compare; + clist->sort_type = GTK_SORT_ASCENDING; + clist->sort_column = 0; } /* Constructors */ @@ -1613,57 +1628,14 @@ gint gtk_clist_append (GtkCList * clist, gchar * text[]) { - gint i; - GtkCListRow *clist_row; - g_return_val_if_fail (clist != NULL, -1); g_return_val_if_fail (GTK_IS_CLIST (clist), -1); + g_return_val_if_fail (text != NULL, -1); - clist_row = row_new (clist); - clist->rows++; - - /* set the text in the row's columns */ - if (text) - for (i = 0; i < clist->columns; i++) - if (text[i]) - cell_set_text (clist, clist_row, i, text[i]); - - /* keeps track of the end of the list so the list - * doesn't have to be traversed every time a item is added */ - if (!clist->row_list) - { - clist->row_list = g_list_append (clist->row_list, clist_row); - clist->row_list_end = clist->row_list; - - /* check the selection mode to see if we should select - * the first row automaticly */ - switch (clist->selection_mode) - { - case GTK_SELECTION_BROWSE: - select_row (clist, 0, -1, NULL); - break; - - default: - break; - } - } - else - clist->row_list_end = (g_list_append (clist->row_list_end, clist_row))->next; - - /* redraw the list if it's not frozen */ - if (!GTK_CLIST_FROZEN (clist)) - { - adjust_scrollbars (clist); - - if (gtk_clist_row_is_visible (clist, clist->rows - 1) != GTK_VISIBILITY_NONE) - draw_rows (clist, NULL); - } - - /* return index of the row */ - return clist->rows - 1; + return gtk_clist_insert (clist, clist->rows, text); } -void +gint gtk_clist_insert (GtkCList * clist, gint row, gchar * text[]) @@ -1671,42 +1643,72 @@ gtk_clist_insert (GtkCList * clist, gint i; GtkCListRow *clist_row; - g_return_if_fail (clist != NULL); - g_return_if_fail (GTK_IS_CLIST (clist)); - g_return_if_fail (text != NULL); + g_return_val_if_fail (clist != NULL, -1); + g_return_val_if_fail (GTK_IS_CLIST (clist), -1); + g_return_val_if_fail (text != NULL, -1); /* return if out of bounds */ if (row < 0 || row > clist->rows) - return; + return -1; + + /* create the row */ + clist_row = row_new (clist); + + /* set the text in the row's columns */ + for (i = 0; i < clist->columns; i++) + if (text[i]) + cell_set_text (clist, clist_row, i, text[i]); - if (clist->rows == 0) - gtk_clist_append (clist, text); + if (!clist->rows) + { + clist->row_list = g_list_append (clist->row_list, clist_row); + clist->row_list_end = clist->row_list; + } else { - /* create the row */ - clist_row = row_new (clist); - - /* set the text in the row's columns */ - if (text) - for (i = 0; i < clist->columns; i++) - if (text[i]) - cell_set_text (clist, clist_row, i, text[i]); + if (GTK_CLIST_AUTO_SORT (clist)) /* override insertion pos */ + { + GList *work; + + row = 0; + work = clist->row_list; + + if (clist->sort_type == GTK_SORT_ASCENDING) + { + while (row < clist->rows && + clist->compare (clist, clist_row, + GTK_CLIST_ROW (work)) > 0) + { + row++; + work = work->next; + } + } + else + { + while (row < clist->rows && + clist->compare (clist, clist_row, + GTK_CLIST_ROW (work)) < 0) + { + row++; + work = work->next; + } + } + } - /* reset the row end pointer if we're inserting at the - * end of the list */ + /* reset the row end pointer if we're inserting at the end of the list */ if (row == clist->rows) clist->row_list_end = (g_list_append (clist->row_list_end, clist_row))->next; else clist->row_list = g_list_insert (clist->row_list, clist_row, row); + } + + clist->rows++; - clist->rows++; - - if (row < ROW_FROM_YPIXEL (clist, 0)) - clist->voffset -= (clist->row_height + CELL_SPACING); + if (row < ROW_FROM_YPIXEL (clist, 0)) + clist->voffset -= (clist->row_height + CELL_SPACING); - /* syncronize the selection list */ - sync_selection (clist, row, SYNC_INSERT); - } + /* syncronize the selection list */ + sync_selection (clist, row, SYNC_INSERT); /* redraw the list if it isn't frozen */ if (!GTK_CLIST_FROZEN (clist)) @@ -1716,6 +1718,8 @@ gtk_clist_insert (GtkCList * clist, if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) draw_rows (clist, NULL); } + + return row; } void @@ -1894,6 +1898,9 @@ gtk_clist_swap_rows (GtkCList * clist, g_return_if_fail (clist != NULL); g_return_if_fail (GTK_IS_CLIST (clist)); + if (GTK_CLIST_AUTO_SORT (clist)) + return; + if (row1 < 0 || row1 > (clist->rows - 1)) return; @@ -5989,3 +5996,204 @@ selection_find (GtkCList *clist, { return g_list_find (clist->selection, GINT_TO_POINTER (row_number)); } + +static gint +default_compare (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2) +{ + GtkCListRow *row1 = (GtkCListRow *) ptr1; + GtkCListRow *row2 = (GtkCListRow *) ptr2; + char *text1; + char *text2; + + text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; + text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; + + return strcmp (text1, text2); +} + +void +gtk_clist_set_compare_func (GtkCList *clist, + GtkCListCompareFunc cmp_func) +{ + g_return_if_fail (clist != NULL); + g_return_if_fail (GTK_IS_CLIST (clist)); + + clist->compare = (cmp_func) ? cmp_func : default_compare; +} + +void +gtk_clist_set_auto_sort (GtkCList *clist, + gboolean auto_sort) +{ + g_return_if_fail (clist != NULL); + g_return_if_fail (GTK_IS_CLIST (clist)); + + if (GTK_CLIST_AUTO_SORT (clist) && !auto_sort) + GTK_CLIST_UNSET_FLAG (clist, CLIST_AUTO_SORT); + else if (!GTK_CLIST_AUTO_SORT (clist) && auto_sort) + { + GTK_CLIST_SET_FLAG (clist, CLIST_AUTO_SORT); + gtk_clist_sort (clist); + } +} + +void +gtk_clist_set_sort_type (GtkCList *clist, + GtkSortType sort_type) +{ + g_return_if_fail (clist != NULL); + g_return_if_fail (GTK_IS_CLIST (clist)); + + clist->sort_type = sort_type; +} + +void +gtk_clist_set_sort_column (GtkCList *clist, + gint column) +{ + g_return_if_fail (clist != NULL); + g_return_if_fail (GTK_IS_CLIST (clist)); + + if (column < 0 || column >= clist->columns) + return; + + clist->sort_column = column; +} + +static GList * +merge (GtkCList *clist, + GList *a, /* first list to merge */ + GList *b) /* second list to merge */ +{ + GList z = { 0 }; /* auxiliary node */ + GList *c; + gint cmp; + + c = &z; + + while (a || b) + { + if (a && !b) + { + c->next = a; + a->prev = c; + c = a; + a = a->next; + break; + } + else if (!a && b) + { + c->next = b; + b->prev = c; + c = b; + b = b->next; + break; + } + else /* a && b */ + { + cmp = clist->compare (clist, GTK_CLIST_ROW (a), GTK_CLIST_ROW (b)); + if ((cmp >= 0 && clist->sort_type == GTK_SORT_DESCENDING) || + (cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING) || + (a && !b)) + { + c->next = a; + a->prev = c; + c = a; + a = a->next; + } + else + { + c->next = b; + b->prev = c; + c = b; + b = b->next; + } + } + } + + return z.next; +} + +static GList * +mergesort (GtkCList *clist, + GList *list, /* the list to sort */ + gint num) /* the list's length */ +{ + GList *half; + gint i; + + if (num == 1) + { + return list; + } + else + { + /* move "half" to the middle */ + half = list; + for (i = 0; i < num / 2; i++) + half = half->next; + + /* cut the list in two */ + half->prev->next = NULL; + half->prev = NULL; + + /* recursively sort both lists */ + return merge (clist, + mergesort (clist, list, num / 2), + mergesort (clist, half, num - num / 2)); + } +} + +void +gtk_clist_sort (GtkCList *clist) +{ + GList *list; + GList *work; + gint i; + gboolean thaw = FALSE; + + g_return_if_fail (clist != NULL); + g_return_if_fail (GTK_IS_CLIST (clist)); + + if (clist->rows <= 1) + return; + + if (GTK_WIDGET_HAS_GRAB (GTK_WIDGET (clist))) + return; + + if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED) + { + GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); + g_list_free (clist->undo_selection); + g_list_free (clist->undo_unselection); + clist->undo_selection = NULL; + clist->undo_unselection = NULL; + } + + if (!GTK_CLIST_FROZEN (clist)) + { + gtk_clist_freeze (clist); + thaw = TRUE; + } + + clist->row_list = mergesort (clist, clist->row_list, clist->rows); + + work = clist->selection; + + for (i = 0, list = clist->row_list; i < clist->rows; i++, list = list->next) + { + if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED) + { + work->data = GINT_TO_POINTER (i); + work = work->next; + } + + if (i == clist->rows - 1) + clist->row_list_end = list; + } + + if (thaw) + gtk_clist_thaw (clist); +} diff --git a/gtk/gtkclist.h b/gtk/gtkclist.h index 25f99d559..2dbe14bcf 100644 --- a/gtk/gtkclist.h +++ b/gtk/gtkclist.h @@ -44,7 +44,8 @@ enum GTK_CLIST_SHOW_TITLES = 1 << 4, GTK_CLIST_CONSTRUCTED = 1 << 5, GTK_CLIST_CHILD_HAS_FOCUS = 1 << 6, - GTK_CLIST_ADD_MODE = 1 << 7 + GTK_CLIST_ADD_MODE = 1 << 7, + GTK_CLIST_AUTO_SORT = 1 << 8 }; /* cell types */ @@ -75,6 +76,7 @@ typedef enum #define GTK_CLIST_CHILD_HAS_FOCUS(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CHILD_HAS_FOCUS) #define GTK_CLIST_DRAG_SELECTION(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_DRAG_SELECTION) #define GTK_CLIST_ADD_MODE(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ADD_MODE) +#define GTK_CLIST_AUTO_SORT(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_SORT) #define GTK_CLIST_ROW(_glist_) ((GtkCListRow *)((_glist_)->data)) @@ -95,6 +97,10 @@ typedef struct _GtkCellPixmap GtkCellPixmap; typedef struct _GtkCellPixText GtkCellPixText; typedef struct _GtkCellWidget GtkCellWidget; +typedef gint (*GtkCListCompareFunc) (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2); + struct _GtkCList { GtkContainer container; @@ -176,56 +182,56 @@ struct _GtkCList gint drag_pos; gint htimer; gint vtimer; + + GtkSortType sort_type; + GtkCListCompareFunc compare; + gint sort_column; }; struct _GtkCListClass { GtkContainerClass parent_class; - void (*select_row) (GtkCList * clist, - gint row, - gint column, - GdkEvent * event); - void (*unselect_row) (GtkCList * clist, - gint row, - gint column, - GdkEvent * event); - void (*click_column) (GtkCList * clist, - gint column); - - void (*toggle_focus_row) (GtkCList * clist); - void (*select_all) (GtkCList * clist); - void (*unselect_all) (GtkCList * clist); - void (*undo_selection) (GtkCList * clist); - void (*start_selection) (GtkCList * clist); - void (*end_selection) (GtkCList * clist); - void (*extend_selection) (GtkCList * clist, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection); - void (*scroll_horizontal) (GtkCList * clist, - GtkScrollType scroll_type, - gfloat position); - void (*scroll_vertical) (GtkCList * clist, - GtkScrollType scroll_type, - gfloat position); - void (*toggle_add_mode) (GtkCList * clist); + void (*select_row) (GtkCList * clist, + gint row, + gint column, + GdkEvent * event); + void (*unselect_row) (GtkCList * clist, + gint row, + gint column, + GdkEvent * event); + void (*click_column) (GtkCList * clist, + gint column); + void (*toggle_focus_row) (GtkCList * clist); + void (*select_all) (GtkCList * clist); + void (*unselect_all) (GtkCList * clist); + void (*undo_selection) (GtkCList * clist); + void (*start_selection) (GtkCList * clist); + void (*end_selection) (GtkCList * clist); + void (*extend_selection) (GtkCList * clist, + GtkScrollType scroll_type, + gfloat position, + gboolean auto_start_selection); + void (*scroll_horizontal) (GtkCList * clist, + GtkScrollType scroll_type, + gfloat position); + void (*scroll_vertical) (GtkCList * clist, + GtkScrollType scroll_type, + gfloat position); + void (*toggle_add_mode) (GtkCList * clist); void (*abort_column_resize) (GtkCList * clist); - - void (*resync_selection) (GtkCList * clist, - GdkEvent * event); - GList * (*selection_find) (GtkCList *clist, - gint row_number, - GList *row_list_element); - void (*draw_row) (GtkCList * clist, - GdkRectangle * area, - gint row, - GtkCListRow * clist_row); - void (*clear) (GtkCList * clist); - void (*fake_unselect_all) (GtkCList * clist, - gint row); - - + void (*resync_selection) (GtkCList * clist, + GdkEvent * event); + GList * (*selection_find) (GtkCList *clist, + gint row_number, + GList *row_list_element); + void (*draw_row) (GtkCList * clist, + GdkRectangle * area, + gint row, + GtkCListRow * clist_row); + void (*clear) (GtkCList * clist); + void (*fake_unselect_all) (GtkCList * clist, + gint row); gint scrollbar_spacing; }; @@ -493,8 +499,9 @@ void gtk_clist_set_shift (GtkCList * clist, gint gtk_clist_append (GtkCList * clist, gchar * text[]); -/* inserts a row at index row */ -void gtk_clist_insert (GtkCList * clist, +/* inserts a row at index row and returns the row where it was actually +inserted (may be different from "row" in auto_sort mode) */ +gint gtk_clist_insert (GtkCList * clist, gint row, gchar * text[]); @@ -555,9 +562,27 @@ void gtk_clist_unselect_all (GtkCList *clist); /* swap the position of two rows */ void gtk_clist_swap_rows (GtkCList * clist, gint row1, gint row2); +/* sets a compare function different to the default */ +void gtk_clist_set_compare_func (GtkCList *clist, + GtkCListCompareFunc cmp_func); + +/* the column to sort by */ +void gtk_clist_set_sort_column (GtkCList *clist, + gint column); + +/* how to sort : ascending or descending */ +void gtk_clist_set_sort_type (GtkCList *clist, + GtkSortType sort_type); + +/* sort the list with the current compare function */ +void gtk_clist_sort (GtkCList *clist); + +/* Automatically sort upon insertion */ +void gtk_clist_set_auto_sort (GtkCList *clist, + gboolean auto_sort); + #ifdef __cplusplus } #endif /* __cplusplus */ - #endif /* __GTK_CLIST_H__ */ diff --git a/gtk/gtkctree.c b/gtk/gtkctree.c index 1b4ea3ecc..e69dfac88 100644 --- a/gtk/gtkctree.c +++ b/gtk/gtkctree.c @@ -177,12 +177,9 @@ static gboolean ctree_is_hot_spot (GtkCTree *ctree, static void tree_sort (GtkCTree *ctree, GtkCTreeNode *node, gpointer data); -static gint default_compare (GtkCTree *ctree, - const GtkCTreeNode *node1, - const GtkCTreeNode *node2); - - - +static gint default_compare (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2); static void fake_unselect_all (GtkCList *clist, gint row); static GList * selection_find (GtkCList *clist, @@ -406,8 +403,7 @@ gtk_ctree_init (GtkCTree *ctree) ctree->drag_source = NULL; ctree->drag_target = NULL; ctree->insert_pos = GTK_CTREE_POS_AS_CHILD; - ctree->node_compare = default_compare; - ctree->auto_sort = FALSE; + GTK_CLIST (ctree)->compare = default_compare; ctree->reorderable = FALSE; ctree->use_icons = TRUE; ctree->in_drag = FALSE; @@ -2741,7 +2737,7 @@ real_tree_move (GtkCTree *ctree, clist->undo_unselection = NULL; } - if (ctree->auto_sort) + if (GTK_CLIST_AUTO_SORT (clist)) { if (new_parent == GTK_CTREE_ROW (node)->parent) return; @@ -2751,7 +2747,7 @@ real_tree_move (GtkCTree *ctree, else new_sibling = GTK_CTREE_NODE (clist->row_list); - while (new_sibling && ctree->node_compare (ctree, node, new_sibling) > 0) + while (new_sibling && clist->compare (clist, node, new_sibling) > 0) new_sibling = GTK_CTREE_ROW (new_sibling)->sibling; } @@ -3624,21 +3620,23 @@ ctree_is_hot_spot (GtkCTree *ctree, } static gint -default_compare (GtkCTree *ctree, - const GtkCTreeNode *node1, - const GtkCTreeNode *node2) +default_compare (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2) { + GtkCTreeNode *node1 = (GtkCTreeNode *) ptr1; + GtkCTreeNode *node2 = (GtkCTreeNode *) ptr2; char *text1; char *text2; text1 = GTK_CELL_PIXTEXT (GTK_CTREE_ROW - (node1)->row.cell[ctree->tree_column])->text; + (node1)->row.cell[clist->sort_column])->text; text2 = GTK_CELL_PIXTEXT (GTK_CTREE_ROW - (node2)->row.cell[ctree->tree_column])->text; + (node2)->row.cell[clist->sort_column])->text; + return strcmp (text1, text2); } - /*********************************************************** *********************************************************** *** Public interface *** @@ -3744,14 +3742,14 @@ gtk_ctree_insert (GtkCTree *ctree, mask_closed, pixmap_opened, mask_opened, is_leaf, expanded); /* sorted insertion */ - if (ctree->auto_sort) + if (GTK_CLIST_AUTO_SORT (clist)) { if (parent) sibling = GTK_CTREE_ROW (parent)->children; else sibling = GTK_CTREE_NODE (clist->row_list); - while (sibling && ctree->node_compare (ctree, node, sibling) > 0) + while (sibling && clist->compare (clist, node, sibling) > 0) sibling = GTK_CTREE_ROW (sibling)->sibling; } @@ -3771,6 +3769,7 @@ gtk_ctree_insert_gnode (GtkCTree *ctree, GtkCTreeGNodeFunc func, gpointer data) { + GtkCList *clist; GtkCTreeNode *cnode = NULL; GtkCTreeNode *child = NULL; GtkCTreeNode *new_child; @@ -3785,6 +3784,8 @@ gtk_ctree_insert_gnode (GtkCTree *ctree, if (sibling) g_return_val_if_fail (GTK_CTREE_ROW (sibling)->parent == parent, NULL); + clist = GTK_CLIST (ctree); + if (parent) depth = GTK_CTREE_ROW (parent)->level + 1; @@ -3802,17 +3803,17 @@ gtk_ctree_insert_gnode (GtkCTree *ctree, return NULL; } - if ((thaw = !GTK_CLIST_FROZEN (GTK_CLIST (ctree)))) - gtk_clist_freeze (GTK_CLIST (ctree)); + if ((thaw = !GTK_CLIST_FROZEN (clist))) + gtk_clist_freeze (clist); - if (ctree->auto_sort) + if (GTK_CLIST_AUTO_SORT (clist)) { if (parent) sibling = GTK_CTREE_ROW (parent)->children; else - sibling = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list); + sibling = GTK_CTREE_NODE (clist->row_list); - while (sibling && ctree->node_compare (ctree, cnode, sibling) > 0) + while (sibling && clist->compare (clist, cnode, sibling) > 0) sibling = GTK_CTREE_ROW (sibling)->sibling; } @@ -3827,7 +3828,7 @@ gtk_ctree_insert_gnode (GtkCTree *ctree, } if (thaw) - gtk_clist_thaw (GTK_CLIST (ctree)); + gtk_clist_thaw (clist); return cnode; } @@ -4981,65 +4982,47 @@ gtk_ctree_set_line_style (GtkCTree *ctree, ***********************************************************/ -void -gtk_ctree_set_auto_sort (GtkCTree *ctree, - gboolean auto_sort) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (GTK_IS_CTREE (ctree)); - - if (ctree->auto_sort == (auto_sort != 0)) - return; - - ctree->auto_sort = (auto_sort != 0); - - if (auto_sort) - gtk_ctree_sort_recursive (ctree, NULL); -} - -void -gtk_ctree_set_compare_func (GtkCTree *ctree, - GtkCTreeCompareFunc cmp_func) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (GTK_IS_CTREE (ctree)); - - if (cmp_func == NULL) - ctree->node_compare = default_compare; - else - ctree->node_compare = cmp_func; -} - static void tree_sort (GtkCTree *ctree, GtkCTreeNode *node, gpointer data) { GtkCTreeNode *list_start; - GtkCTreeNode *max; + GtkCTreeNode *cmp; GtkCTreeNode *work; + GtkCList *clist; + + clist = GTK_CLIST (ctree); if (node) list_start = GTK_CTREE_ROW (node)->children; else - list_start = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list); + list_start = GTK_CTREE_NODE (clist->row_list); while (list_start) { - max = list_start; - work = GTK_CTREE_ROW (max)->sibling; + cmp = list_start; + work = GTK_CTREE_ROW (cmp)->sibling; while (work) { - if (ctree->node_compare (ctree, work, max) < 0) - max = work; + if (clist->sort_type == GTK_SORT_ASCENDING) + { + if (clist->compare (clist, work, cmp) < 0) + cmp = work; + } + else + { + if (clist->compare (clist, work, cmp) > 0) + cmp = work; + } work = GTK_CTREE_ROW (work)->sibling; } - if (max == list_start) - list_start = GTK_CTREE_ROW (max)->sibling; + if (cmp == list_start) + list_start = GTK_CTREE_ROW (cmp)->sibling; else { - gtk_ctree_unlink (ctree, max, FALSE); - gtk_ctree_link (ctree, max, node, list_start, FALSE); + gtk_ctree_unlink (ctree, cmp, FALSE); + gtk_ctree_link (ctree, cmp, node, list_start, FALSE); } } } diff --git a/gtk/gtkctree.h b/gtk/gtkctree.h index 77f5fb7bd..c9d9b5e1b 100644 --- a/gtk/gtkctree.h +++ b/gtk/gtkctree.h @@ -81,17 +81,12 @@ typedef void (*GtkCTreeFunc) (GtkCTree *ctree, GtkCTreeNode *node, gpointer data); -typedef gint (*GtkCTreeCompareFunc) (GtkCTree *ctree, - const GtkCTreeNode *node1, - const GtkCTreeNode *node2); - typedef gboolean (*GtkCTreeGNodeFunc) (GtkCTree *ctree, guint depth, GNode *gnode, GtkCTreeNode *cnode, gpointer data); - struct _GtkCTree { GtkCList clist; @@ -108,9 +103,7 @@ struct _GtkCTree GtkCTreeNode *drag_source; GtkCTreeNode *drag_target; gint insert_pos; - GtkCTreeCompareFunc node_compare; - - guint auto_sort : 1; + guint reorderable : 1; guint use_icons : 1; guint in_drag : 1; @@ -384,10 +377,6 @@ void gtk_ctree_set_line_style (GtkCTree *ctree, * Tree sorting functions * ***********************************************************/ -void gtk_ctree_set_auto_sort (GtkCTree *ctree, - gboolean auto_sort); -void gtk_ctree_set_compare_func (GtkCTree *ctree, - GtkCTreeCompareFunc cmp_func); void gtk_ctree_sort (GtkCTree *ctree, GtkCTreeNode *node); void gtk_ctree_sort_recursive (GtkCTree *ctree, diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index ecfe5ca95..86504ea75 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -305,6 +305,13 @@ typedef enum GTK_WINDOW_POPUP } GtkWindowType; +/* How to sort */ +typedef enum +{ + GTK_SORT_ASCENDING, + GTK_SORT_DESCENDING +} GtkSortType; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 28aac144c..6658a342e 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -3150,10 +3150,11 @@ add1000_clist (GtkWidget *widget, gpointer data) gtk_clist_freeze (GTK_CLIST (data)); for (i = 0; i < 1000; i++) { - sprintf (text[0], "Row %d", clist_rows++); + sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/); row = gtk_clist_append (GTK_CLIST (data), texts); gtk_clist_set_pixtext (GTK_CLIST (data), row, 3, "Hello World", 5, pixmap, mask); } + gtk_clist_thaw (GTK_CLIST (data)); gdk_pixmap_unref (pixmap); @@ -3179,7 +3180,7 @@ add10000_clist (GtkWidget *widget, gpointer data) gtk_clist_freeze (GTK_CLIST (data)); for (i = 0; i < 10000; i++) { - sprintf (text[0], "Row %d", clist_rows++); + sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/); gtk_clist_append (GTK_CLIST (data), texts); } gtk_clist_thaw (GTK_CLIST (data)); @@ -3342,7 +3343,10 @@ insert_row_clist (GtkWidget *widget, gpointer data) "This", "is", "a", "inserted", "row." }; - gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text); + if (GTK_CLIST (data)->focus_row >= 0) + gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text); + else + gtk_clist_insert (GTK_CLIST (data), 0, text); clist_rows++; } @@ -3393,6 +3397,22 @@ clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist) gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i)); } +static void +clist_click_column (GtkCList *clist, gint column, gpointer data) +{ + if (column == clist->sort_column) + { + if (clist->sort_type == GTK_SORT_ASCENDING) + clist->sort_type = GTK_SORT_DESCENDING; + else + clist->sort_type = GTK_SORT_ASCENDING; + } + else + gtk_clist_set_sort_column (clist, column); + + gtk_clist_sort (clist); +} + static void create_clist (void) { @@ -3451,6 +3471,10 @@ create_clist (void) clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles); /*clist = gtk_clist_new (TESTGTK_CLIST_COLUMNS);*/ + gtk_signal_connect (GTK_OBJECT (clist), "click_column", + (GtkSignalFunc) clist_click_column, + NULL); + /* control buttons */ button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps"); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); @@ -4032,6 +4056,26 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree) after_press (ctree, NULL); } +static void +ctree_click_column (GtkCTree *ctree, gint column, gpointer data) +{ + GtkCList *clist; + + clist = GTK_CLIST (ctree); + + if (column == clist->sort_column) + { + if (clist->sort_type == GTK_SORT_ASCENDING) + clist->sort_type = GTK_SORT_DESCENDING; + else + clist->sort_type = GTK_SORT_ASCENDING; + } + else + gtk_clist_set_sort_column (clist, column); + + gtk_ctree_sort_recursive (ctree, NULL); +} + void create_ctree (void) { static GtkWidget *window = NULL; @@ -4132,6 +4176,9 @@ void create_ctree (void) ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title)); gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED); gtk_ctree_set_reorderable (ctree, TRUE); + gtk_signal_connect (GTK_OBJECT (ctree), "click_column", + (GtkSignalFunc) ctree_click_column, + NULL); gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event", GTK_SIGNAL_FUNC (button_press), NULL); gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event", @@ -4154,7 +4201,6 @@ void create_ctree (void) GTK_SIGNAL_FUNC (after_press), NULL); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0); - gtk_clist_column_titles_passive (GTK_CLIST (ctree)); gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED); gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, GTK_POLICY_AUTOMATIC); diff --git a/tests/testgtk.c b/tests/testgtk.c index 28aac144c..6658a342e 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -3150,10 +3150,11 @@ add1000_clist (GtkWidget *widget, gpointer data) gtk_clist_freeze (GTK_CLIST (data)); for (i = 0; i < 1000; i++) { - sprintf (text[0], "Row %d", clist_rows++); + sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/); row = gtk_clist_append (GTK_CLIST (data), texts); gtk_clist_set_pixtext (GTK_CLIST (data), row, 3, "Hello World", 5, pixmap, mask); } + gtk_clist_thaw (GTK_CLIST (data)); gdk_pixmap_unref (pixmap); @@ -3179,7 +3180,7 @@ add10000_clist (GtkWidget *widget, gpointer data) gtk_clist_freeze (GTK_CLIST (data)); for (i = 0; i < 10000; i++) { - sprintf (text[0], "Row %d", clist_rows++); + sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/); gtk_clist_append (GTK_CLIST (data), texts); } gtk_clist_thaw (GTK_CLIST (data)); @@ -3342,7 +3343,10 @@ insert_row_clist (GtkWidget *widget, gpointer data) "This", "is", "a", "inserted", "row." }; - gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text); + if (GTK_CLIST (data)->focus_row >= 0) + gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text); + else + gtk_clist_insert (GTK_CLIST (data), 0, text); clist_rows++; } @@ -3393,6 +3397,22 @@ clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist) gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i)); } +static void +clist_click_column (GtkCList *clist, gint column, gpointer data) +{ + if (column == clist->sort_column) + { + if (clist->sort_type == GTK_SORT_ASCENDING) + clist->sort_type = GTK_SORT_DESCENDING; + else + clist->sort_type = GTK_SORT_ASCENDING; + } + else + gtk_clist_set_sort_column (clist, column); + + gtk_clist_sort (clist); +} + static void create_clist (void) { @@ -3451,6 +3471,10 @@ create_clist (void) clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles); /*clist = gtk_clist_new (TESTGTK_CLIST_COLUMNS);*/ + gtk_signal_connect (GTK_OBJECT (clist), "click_column", + (GtkSignalFunc) clist_click_column, + NULL); + /* control buttons */ button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps"); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); @@ -4032,6 +4056,26 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree) after_press (ctree, NULL); } +static void +ctree_click_column (GtkCTree *ctree, gint column, gpointer data) +{ + GtkCList *clist; + + clist = GTK_CLIST (ctree); + + if (column == clist->sort_column) + { + if (clist->sort_type == GTK_SORT_ASCENDING) + clist->sort_type = GTK_SORT_DESCENDING; + else + clist->sort_type = GTK_SORT_ASCENDING; + } + else + gtk_clist_set_sort_column (clist, column); + + gtk_ctree_sort_recursive (ctree, NULL); +} + void create_ctree (void) { static GtkWidget *window = NULL; @@ -4132,6 +4176,9 @@ void create_ctree (void) ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title)); gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED); gtk_ctree_set_reorderable (ctree, TRUE); + gtk_signal_connect (GTK_OBJECT (ctree), "click_column", + (GtkSignalFunc) ctree_click_column, + NULL); gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event", GTK_SIGNAL_FUNC (button_press), NULL); gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event", @@ -4154,7 +4201,6 @@ void create_ctree (void) GTK_SIGNAL_FUNC (after_press), NULL); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0); - gtk_clist_column_titles_passive (GTK_CLIST (ctree)); gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED); gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, GTK_POLICY_AUTOMATIC); -- cgit v1.2.1