More work on implementing sortable interface.

Tue Mar 27 20:55:29 2001  Jonathan Blandford  <jrb@redhat.com>

	* gtk/gtkliststore.c: More work on implementing sortable
	interface.
This commit is contained in:
Jonathan Blandford
2001-03-28 01:54:14 +00:00
committed by Jonathan Blandford
parent 2c613ffd95
commit 88bbc2a534
21 changed files with 658 additions and 91 deletions

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -1,3 +1,8 @@
Tue Mar 27 20:55:29 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkliststore.c: More work on implementing sortable
interface.
Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com> Mon Mar 26 15:48:45 2001 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwindow.c (gtk_window_list_toplevels): Don't * gtk/gtkwindow.c (gtk_window_list_toplevels): Don't

View File

@ -34,7 +34,6 @@ GtkTreeViewColumn
@alignment: @alignment:
@window: @window:
@xalign: @xalign:
@id:
@width: @width:
@min_width: @min_width:
@max_width: @max_width:
@ -46,6 +45,8 @@ GtkTreeViewColumn
@cell: @cell:
@attributes: @attributes:
@column_type: @column_type:
@sort_signal:
@sort_column_id:
@sort_order: @sort_order:
@visible: @visible:
@button_active: @button_active:

View File

@ -26,6 +26,7 @@
#include <gobject/gvaluecollector.h> #include <gobject/gvaluecollector.h>
#define G_SLIST(x) ((GSList *) x) #define G_SLIST(x) ((GSList *) x)
#define GTK_LIST_STORE_IS_SORTED(list) (GTK_LIST_STORE (list)->sort_column_id != -1)
static void gtk_list_store_init (GtkListStore *list_store); static void gtk_list_store_init (GtkListStore *list_store);
static void gtk_list_store_class_init (GtkListStoreClass *class); static void gtk_list_store_class_init (GtkListStoreClass *class);
@ -79,6 +80,9 @@ static gboolean gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
GtkTreePath *dest_path); GtkTreePath *dest_path);
/* sortable */ /* sortable */
static void gtk_list_store_sort (GtkListStore *list_store);
static void gtk_list_store_sort_iter_changed (GtkListStore *list_store,
GtkTreeIter *iter);
static gboolean gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable, static gboolean gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable,
gint *sort_column_id, gint *sort_column_id,
GtkTreeSortOrder *order); GtkTreeSortOrder *order);
@ -93,6 +97,7 @@ static void gtk_list_store_sort_column_id_set_func (GtkTreeSortable *
static void static void
validate_list_store (GtkListStore *list_store) validate_list_store (GtkListStore *list_store)
{ {
@ -667,6 +672,9 @@ gtk_list_store_set_value (GtkListStore *list_store,
gtk_tree_path_free (path); gtk_tree_path_free (path);
if (converted) if (converted)
g_value_unset (&real_value); g_value_unset (&real_value);
if (GTK_LIST_STORE_IS_SORTED (list_store))
gtk_list_store_sort_iter_changed (list_store, iter);
} }
/** /**
@ -890,7 +898,8 @@ gtk_list_store_insert (GtkListStore *list_store,
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
g_return_if_fail (position >= 0); g_return_if_fail (position >= 0);
if (position == 0) if (position == 0 ||
GTK_LIST_STORE_IS_SORTED (list_store))
{ {
gtk_list_store_prepend (list_store, iter); gtk_list_store_prepend (list_store, iter);
return; return;
@ -943,6 +952,12 @@ gtk_list_store_insert_before (GtkListStore *list_store,
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
if (GTK_LIST_STORE_IS_SORTED (list_store))
{
gtk_list_store_prepend (list_store, iter);
return;
}
if (sibling == NULL) if (sibling == NULL)
{ {
gtk_list_store_append (list_store, iter); gtk_list_store_append (list_store, iter);
@ -1024,7 +1039,8 @@ gtk_list_store_insert_after (GtkListStore *list_store,
if (sibling) if (sibling)
g_return_if_fail (sibling->stamp == list_store->stamp); g_return_if_fail (sibling->stamp == list_store->stamp);
if (sibling == NULL) if (sibling == NULL ||
GTK_LIST_STORE_IS_SORTED (list_store))
{ {
gtk_list_store_prepend (list_store, iter); gtk_list_store_prepend (list_store, iter);
return; return;
@ -1109,6 +1125,12 @@ gtk_list_store_append (GtkListStore *list_store,
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
if (GTK_LIST_STORE_IS_SORTED (list_store))
{
gtk_list_store_prepend (list_store, iter);
return;
}
iter->stamp = list_store->stamp; iter->stamp = list_store->stamp;
iter->user_data = g_slist_alloc (); iter->user_data = g_slist_alloc ();
@ -1316,7 +1338,250 @@ gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest,
return FALSE; return FALSE;
} }
/* Sorting */ /* Sorting */
typedef struct _SortTuple
{
gint offset;
GSList *el;
} SortTuple;
static gint
_gtk_list_store_compare_func (gconstpointer a,
gconstpointer b,
gpointer user_data)
{
GtkListStore *list_store = user_data;
GtkTreeDataSortHeader *header = NULL;
GSList *el_a; /* Los Angeles? */
GSList *el_b;
GtkTreeIter iter_a;
GtkTreeIter iter_b;
gint retval;
header = _gtk_tree_data_list_get_header (list_store->sort_list,
list_store->sort_column_id);
g_return_val_if_fail (header != NULL, 0);
g_return_val_if_fail (header->func != NULL, 0);
el_a = ((SortTuple *) a)->el;
el_b = ((SortTuple *) b)->el;
iter_a.stamp = list_store->stamp;
iter_a.user_data = el_a;
iter_b.stamp = list_store->stamp;
iter_b.user_data = el_b;
retval = (* header->func) (GTK_TREE_MODEL (list_store),
&iter_a, &iter_b,
header->data);
if (list_store->order == GTK_TREE_SORT_DESCENDING)
{
if (retval > 0)
retval = -1;
else if (retval < 0)
retval = 1;
}
return retval;
}
static void
gtk_list_store_sort (GtkListStore *list_store)
{
GtkTreeDataSortHeader *header = NULL;
GArray *sort_array;
gint i;
GList *header_list;
gint *new_order;
GSList *list;
GtkTreePath *path;
if (list_store->length <= 1)
return;
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;
}
/* We want to make sure that we have a function */
g_return_if_fail (header != NULL);
g_return_if_fail (header->func != NULL);
list = G_SLIST (list_store->root);
sort_array = g_array_sized_new (FALSE, FALSE,
sizeof (SortTuple),
list_store->length);
for (i = 0; i < list_store->length; i++)
{
SortTuple tuple;
/* If this fails, we are in an inconsistent state. Bad */
g_return_if_fail (list != NULL);
tuple.offset = i;
tuple.el = list;
g_array_append_val (sort_array, tuple);
list = list->next;
}
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 =
g_array_index (sort_array, SortTuple, i + 1).el;
g_array_index (sort_array, SortTuple, list_store->length - 1).el->next = NULL;
list_store->root = g_array_index (sort_array, SortTuple, 0).el;
/* Let the world know about our new order */
new_order = g_new (gint, list_store->length);
for (i = 0; i < list_store->length; i++)
new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
path = gtk_tree_path_new ();
gtk_tree_model_reordered (GTK_TREE_MODEL (list_store),
path, new_order);
gtk_tree_path_free (path);
g_free (new_order);
g_array_free (sort_array, TRUE);
}
static void
gtk_list_store_sort_iter_changed (GtkListStore *list_store,
GtkTreeIter *iter)
{
GtkTreeDataSortHeader *header;
GSList *prev = NULL;
GSList *next = NULL;
GSList *list = G_SLIST (list_store->root);
GtkTreeIter tmp_iter;
gint cmp_a = 0;
gint cmp_b = 0;
if (list_store->length < 2)
return;
tmp_iter.stamp = list_store->stamp;
header = _gtk_tree_data_list_get_header (list_store->sort_list,
list_store->sort_column_id);
g_return_if_fail (header != NULL);
g_return_if_fail (header->func != NULL);
/* First we find the iter, its prev, and its next */
while (list)
{
if (list == G_SLIST (iter->user_data))
break;
prev = list;
list = list->next;
}
g_assert (list != NULL);
next = list->next;
/* Check the common case, where we don't need to sort it moved. */
if (prev != NULL)
{
tmp_iter.user_data = prev;
cmp_a = (* header->func) (GTK_TREE_MODEL (list_store),
&tmp_iter, iter,
header->data);
}
if (next != NULL)
{
tmp_iter.user_data = next;
cmp_b = (* header->func) (GTK_TREE_MODEL (list_store),
iter, &tmp_iter,
header->data);
}
if (list_store->order == GTK_TREE_SORT_DESCENDING)
{
if (cmp_a < 0)
cmp_a = 1;
else if (cmp_a > 0)
cmp_a = -1;
if (cmp_b < 0)
cmp_b = 1;
else if (cmp_b > 0)
cmp_b = -1;
}
if (prev == NULL && cmp_b <= 0)
return;
else if (next == NULL && cmp_a <= 0)
return;
else if (prev != NULL && next != NULL &&
cmp_a <= 0 && cmp_b <= 0)
return;
/* We actually need to sort it */
/* First, remove the old link. */
if (prev == NULL)
list_store->root = next;
else
prev->next = next;
if (next == NULL)
list_store->tail = prev;
list->next = NULL;
/* FIXME: as an optimization, we can potentially start at next */
prev = NULL;
list = G_SLIST (list_store->root);
tmp_iter.user_data = list;
if (list_store->order == GTK_TREE_SORT_DESCENDING)
cmp_a = (* header->func) (GTK_TREE_MODEL (list_store),
&tmp_iter, iter, header->data);
else
cmp_a = (* header->func) (GTK_TREE_MODEL (list_store),
iter, &tmp_iter, header->data);
while ((list->next) && (cmp_a > 0))
{
prev = list;
list = list->next;
tmp_iter.user_data = list;
if (list_store->order == GTK_TREE_SORT_DESCENDING)
cmp_a = (* header->func) (GTK_TREE_MODEL (list_store),
&tmp_iter, iter, header->data);
else
cmp_a = (* header->func) (GTK_TREE_MODEL (list_store),
iter, &tmp_iter, header->data);
}
if ((!list->next) && (cmp_a > 0))
{
list->next = G_SLIST (iter->user_data);
list_store->tail = list->next;
}
else if (prev)
{
prev->next = G_SLIST (iter->user_data);
G_SLIST (iter->user_data)->next = list;
}
else
{
G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
list_store->root = G_SLIST (iter->user_data);
}
}
static gboolean static gboolean
gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable, gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable,
gint *sort_column_id, gint *sort_column_id,
@ -1356,8 +1621,15 @@ gtk_list_store_set_sort_column_id (GtkTreeSortable *sortable,
} }
g_return_if_fail (list != NULL); g_return_if_fail (list != NULL);
if ((list_store->sort_column_id == sort_column_id) &&
(list_store->order == order))
return;
list_store->sort_column_id = sort_column_id; list_store->sort_column_id = sort_column_id;
list_store->order = order; list_store->order = order;
if (list_store->sort_column_id >= 0)
gtk_list_store_sort (list_store);
} }
static void static void

View File

@ -38,6 +38,7 @@ NONE:STRING,INT,POINTER
VOID:BOOLEAN VOID:BOOLEAN
VOID:BOXED VOID:BOXED
VOID:BOXED,BOXED VOID:BOXED,BOXED
VOID:BOXED,BOXED,POINTER
VOID:BOXED,POINTER VOID:BOXED,POINTER
VOID:BOXED,OBJECT VOID:BOXED,OBJECT
VOID:BOXED,STRING,INT VOID:BOXED,STRING,INT

View File

@ -38,6 +38,7 @@ NONE:STRING,INT,POINTER
VOID:BOOLEAN VOID:BOOLEAN
VOID:BOXED VOID:BOXED
VOID:BOXED,BOXED VOID:BOXED,BOXED
VOID:BOXED,BOXED,POINTER
VOID:BOXED,POINTER VOID:BOXED,POINTER
VOID:BOXED,OBJECT VOID:BOXED,OBJECT
VOID:BOXED,STRING,INT VOID:BOXED,STRING,INT

View File

@ -264,6 +264,7 @@ gtk_tree_data_list_compare_func (GtkTreeModel *model,
GValue a_value = {0, }; GValue a_value = {0, };
GValue b_value = {0, }; GValue b_value = {0, };
gint retval; gint retval;
gchar *stra, *strb;
gtk_tree_model_get_value (model, a, column, &a_value); gtk_tree_model_get_value (model, a, column, &a_value);
gtk_tree_model_get_value (model, b, column, &b_value); gtk_tree_model_get_value (model, b, column, &b_value);
@ -299,7 +300,13 @@ gtk_tree_data_list_compare_func (GtkTreeModel *model,
retval = (g_value_get_double (&a_value) < g_value_get_double (&b_value)); retval = (g_value_get_double (&a_value) < g_value_get_double (&b_value));
break; break;
case G_TYPE_STRING: case G_TYPE_STRING:
retval = strcmp (g_value_get_string (&a_value), g_value_get_string (&b_value)); stra = g_value_get_string (&a_value);
strb = g_value_get_string (&b_value);
if (stra == NULL)
stra = "";
if (strb == NULL)
strb = "";
retval = strcmp (stra, strb);
break; break;
case G_TYPE_POINTER: case G_TYPE_POINTER:
case G_TYPE_BOXED: case G_TYPE_BOXED:
@ -356,3 +363,18 @@ _gtk_tree_data_list_header_free (GList *list)
} }
g_list_free (list); g_list_free (list);
} }
GtkTreeDataSortHeader *
_gtk_tree_data_list_get_header (GList *header_list,
gint sort_column_id)
{
GtkTreeDataSortHeader *header = NULL;
for (; header_list; header_list = header_list->next)
{
header = (GtkTreeDataSortHeader*) header_list->data;
if (header->sort_column_id == sort_column_id)
return header;
}
return NULL;
}

View File

@ -63,8 +63,11 @@ GtkTreeDataList *_gtk_tree_data_list_node_copy (GtkTreeDataList *list,
GType type); GType type);
/* Header code */ /* Header code */
GList *_gtk_tree_data_list_header_new (gint n_columns, GList * _gtk_tree_data_list_header_new (gint n_columns,
GType *types); GType *types);
void _gtk_tree_data_list_header_free (GList *header_list); void _gtk_tree_data_list_header_free (GList *header_list);
GtkTreeDataSortHeader *_gtk_tree_data_list_get_header (GList *header_list,
gint sort_column_id);
#endif /* __GTK_TREE_DATA_LIST_H__ */ #endif /* __GTK_TREE_DATA_LIST_H__ */

View File

@ -112,9 +112,10 @@ gtk_tree_model_base_init (gpointer g_class)
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTreeModelIface, reordered), G_STRUCT_OFFSET (GtkTreeModelIface, reordered),
NULL, NULL, NULL, NULL,
gtk_marshal_VOID__BOXED_POINTER, gtk_marshal_VOID__BOXED_BOXED_POINTER,
G_TYPE_NONE, 2, G_TYPE_NONE, 3,
GTK_TYPE_TREE_PATH, GTK_TYPE_TREE_PATH,
GTK_TYPE_TREE_ITER,
G_TYPE_POINTER); G_TYPE_POINTER);
initialized = TRUE; initialized = TRUE;
} }

View File

@ -69,6 +69,7 @@ struct _GtkTreeModelIface
GtkTreePath *path); GtkTreePath *path);
void (* reordered) (GtkTreeModel *tree_model, void (* reordered) (GtkTreeModel *tree_model,
GtkTreePath *path, GtkTreePath *path,
GtkTreeIter *iter,
gint *new_order); gint *new_order);
/* Virtual Table */ /* Virtual Table */
@ -219,6 +220,7 @@ void gtk_tree_model_deleted (GtkTreeModel *tree_model,
GtkTreePath *path); GtkTreePath *path);
void gtk_tree_model_reordered (GtkTreeModel *tree_model, void gtk_tree_model_reordered (GtkTreeModel *tree_model,
GtkTreePath *path, GtkTreePath *path,
GtkTreeIter *iter,
gint *new_order); gint *new_order);

View File

@ -28,7 +28,6 @@ extern "C" {
typedef enum typedef enum
{ {
GTK_TREE_SORT_NONE,
GTK_TREE_SORT_ASCENDING, GTK_TREE_SORT_ASCENDING,
GTK_TREE_SORT_DESCENDING GTK_TREE_SORT_DESCENDING
} GtkTreeSortOrder; } GtkTreeSortOrder;
@ -71,19 +70,20 @@ struct _GtkTreeSortableIface
}; };
GType gtk_tree_sortable_get_type (void) G_GNUC_CONST; GType gtk_tree_sortable_get_type (void) G_GNUC_CONST;
gboolean gtk_tree_sortable_get_sort_column_id (GtkTreeSortable *sortable,
gint *sort_column_id,
GtkTreeSortOrder *order);
void gtk_tree_sortable_set_sort_column_id (GtkTreeSortable *sortable,
gint sort_column_id,
GtkTreeSortOrder order);
void gtk_tree_sortable_sort_column_id_set_func (GtkTreeSortable *sortable,
gint sort_column_id,
GtkTreeIterCompareFunc func,
gpointer data,
GtkDestroyNotify destroy);
gboolean gtk_tree_sortable_get_sort_id (GtkTreeSortable *sortable,
gint *sort_column_id,
GtkTreeSortOrder *order);
void gtk_tree_sortable_set_sort_id (GtkTreeSortable *sortable,
gint sort_column_id,
GtkTreeSortOrder order);
void gtk_tree_sortable_sort_id_set_func (GtkTreeSortable *sortable,
gint sort_column_id,
GtkTreeIterCompareFunc func,
gpointer data,
GtkDestroyNotify destroy);

View File

@ -3011,6 +3011,17 @@ gtk_tree_view_reordered (GtkTreeModel *model,
GtkTreePath *parent, GtkTreePath *parent,
gint *new_order) gint *new_order)
{ {
GtkTreeView *tree_view = GTK_TREE_VIEW (model);
GtkTreeIter iter;
GArray *array;
gint len;
gtk_tree_model_get_iter (model, parent, &iter);
len = gtk_tree_model_iter_n_children (model, &iter);
if (len < 2)
return;
} }

View File

@ -252,6 +252,8 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
tree_column->dirty = TRUE; tree_column->dirty = TRUE;
tree_column->sort_order = GTK_TREE_SORT_ASCENDING; tree_column->sort_order = GTK_TREE_SORT_ASCENDING;
tree_column->show_sort_indicator = FALSE; tree_column->show_sort_indicator = FALSE;
tree_column->sort_signal = 0;
tree_column->sort_column_id = -1;
} }
static void static void
@ -1478,6 +1480,79 @@ gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
return tree_column->xalign; return tree_column->xalign;
} }
static void
sort_clicked_func (GtkTreeViewColumn *tree_column,
gpointer data)
{
GList *list;
g_return_if_fail (tree_column->tree_view != NULL);
if (tree_column->show_sort_indicator)
{
if (tree_column->sort_order == GTK_TREE_SORT_ASCENDING)
gtk_tree_view_column_set_sort_order (tree_column, GTK_TREE_SORT_DESCENDING);
else
gtk_tree_view_column_set_sort_order (tree_column, GTK_TREE_SORT_ASCENDING);
}
else
{
gtk_tree_view_column_set_sort_order (tree_column, GTK_TREE_SORT_ASCENDING);
gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
}
list = (GTK_TREE_VIEW (tree_column->tree_view)->priv->columns);
g_assert (list);
while (list)
{
GtkTreeViewColumn *tmp_column;
tmp_column = GTK_TREE_VIEW_COLUMN (list->data);
if (tmp_column->visible && tmp_column != tree_column)
gtk_tree_view_column_set_sort_indicator (tmp_column, FALSE);
list = list->next;
}
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
tree_column->sort_column_id,
tree_column->sort_order);
}
/**
* gtk_tree_view_column_set_sort_column_id:
* @tree_column: a #GtkTreeViewColumn
* @sort_column_id: The sort_column_id of the model to sort on.
*
* Sets the sort_column_id that the column sorts on.
**/
void
gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
gint sort_column_id)
{
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
g_return_if_fail (sort_column_id >= 0);
if (tree_column->sort_column_id == sort_column_id)
return;
if (sort_column_id == -1)
{
if (tree_column->sort_signal)
g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_signal);
return;
}
if (! tree_column->sort_signal)
tree_column->sort_signal = g_signal_connectc (G_OBJECT (tree_column),
"clicked",
G_CALLBACK (sort_clicked_func),
NULL, FALSE);
tree_column->sort_column_id = sort_column_id;
gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
gtk_tree_view_column_set_sort_order (tree_column, GTK_TREE_SORT_ASCENDING);
}
/** /**
* gtk_tree_view_column_set_sort_indicator: * gtk_tree_view_column_set_sort_indicator:
* @tree_column: a #GtkTreeViewColumn * @tree_column: a #GtkTreeViewColumn
@ -1531,12 +1606,13 @@ gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column)
* @order: sort order that the sort indicator should indicate * @order: sort order that the sort indicator should indicate
* *
* Changes the appearance of the sort indicator. (This <emphasis>does * Changes the appearance of the sort indicator. (This <emphasis>does
* not</emphasis> actually sort the model - for the models shipped * not</emphasis> actually sort the model. Use
* with GTK+, use at gtk_tree_sortable_set_sort_column() to do * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting
* that. For custom models, the mechanism will vary.) The sort * support. This function is primarily for custom sorting behavior, and should
* indicator changes direction to indicate normal sort or reverse * be used in conjunction with #gtk_tree_sortable_set_sort_column() to do
* sort. Note that you must have the sort indicator enabled to see * that. For custom models, the mechanism will vary.) The sort indicator changes
* anything when calling this function; see * direction to indicate normal sort or reverse sort. Note that you must have
* the sort indicator enabled to see anything when calling this function; see
* gtk_tree_view_column_set_sort_indicator(). * gtk_tree_view_column_set_sort_indicator().
* *
**/ **/

View File

@ -64,8 +64,6 @@ struct _GtkTreeViewColumn
GdkWindow *window; GdkWindow *window;
gfloat xalign; gfloat xalign;
gint id;
gint width; gint width;
gint min_width; gint min_width;
gint max_width; gint max_width;
@ -78,7 +76,13 @@ struct _GtkTreeViewColumn
GtkCellRenderer *cell; GtkCellRenderer *cell;
GSList *attributes; GSList *attributes;
GtkTreeViewColumnSizing column_type; GtkTreeViewColumnSizing column_type;
/* Sorting */
guint sort_signal;
gint sort_column_id;
GtkTreeSortOrder sort_order; GtkTreeSortOrder sort_order;
guint visible : 1; guint visible : 1;
guint button_active : 1; guint button_active : 1;
guint dirty : 1; guint dirty : 1;
@ -147,6 +151,14 @@ GtkWidget *gtk_tree_view_column_get_widget (GtkTreeViewColumn
void gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column, void gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
gfloat xalign); gfloat xalign);
gfloat gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column); gfloat gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column);
/* You probably only want to use gtk_tree_view_column_set_sort_column_id. The
* other sorting functions exist primarily to let others do their own custom sorting.
*/
void gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
gint sort_column_id);
void gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column, void gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column,
gboolean setting); gboolean setting);
gboolean gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column); gboolean gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column);

View File

@ -31,21 +31,24 @@ LDADDS = @STRIP_BEGIN@ \
@STRIP_END@ @STRIP_END@
noinst_PROGRAMS = \ noinst_PROGRAMS = \
testsocket \ ## testsocket \
testsocket_child \ ## testsocket_child \
testtreeview \ testtreeview \
testtreefocus \ testtreefocus \
testtreecolumns testtreecolumns \
testtreesort
testsocket_DEPENDENCIES = $(DEPS) #testsocket_DEPENDENCIES = $(DEPS)
testsocket_child_DEPENDENCIES = $(DEPS) #testsocket_child_DEPENDENCIES = $(DEPS)
testtreeview_DEPENDENCIES = $(DEPS) testtreeview_DEPENDENCIES = $(DEPS)
testtreefocus_DEPENDENCIES = $(DEPS) testtreefocus_DEPENDENCIES = $(DEPS)
testtreecolumns_DEPENDENCIES = $(DEPS) testtreecolumns_DEPENDENCIES = $(DEPS)
testtreesort_DEPENDENCIES = $(DEPS)
testsocket_LDADD = $(LDADDS) #testsocket_LDADD = $(LDADDS)
testsocket_child_LDADD = $(LDADDS) #testsocket_child_LDADD = $(LDADDS)
testtreeview_LDADD = $(LDADDS) testtreeview_LDADD = $(LDADDS)
testtreefocus_LDADD = $(LDADDS) testtreefocus_LDADD = $(LDADDS)
testtreecolumns_LDADD = $(LDADDS) testtreecolumns_LDADD = $(LDADDS)
testtreesort_LDADD = $(LDADDS)

127
tests/testtreesort.c Normal file
View File

@ -0,0 +1,127 @@
#include <gtk/gtk.h>
typedef struct _ListSort ListSort;
struct _ListSort
{
const gchar *word_1;
const gchar *word_2;
const gchar *word_3;
const gchar *word_4;
};
static ListSort data[] =
{
{ "Apples", "Transmorgrify", "Exculpatory", "Gesundheit"},
{ "Oranges", "Wicker", "Adamantine", "Convivial" },
{ "Bovine Spongiform Encephilopathy", "Sleazebucket", "Mountaineer", "Pander" },
{ "Foot and Mouth", "Lampshade", "Skim Milk\nFull Milk", "Viewless" },
{ "Blood,\nsweat,\ntears", "The Man", "Horses", "Muckety-Muck" },
{ "Rare Steak", "Siam", "Watchdog", "Xantippe" },
{ "SIGINT", "Rabbit Breath", "Alligator", "Bloodstained" },
{ "Google", "Chrysanthemums", "Hobnob", "Leapfrog"},
{ "Technology fibre optic", "Turtle", "Academe", "Lonely" },
{ "Freon", "Harpes", "Quidditch", "Reagan" },
{ "Transposition", "Fruit Basket", "Monkey Wort", "Glogg" },
{ "Fern", "Glasnost and Perestroika", "Latitude", "Bomberman!!!" },
{NULL, }
};
enum
{
WORD_COLUMN = 0,
WORD_COLUMN_2,
WORD_COLUMN_3,
WORD_COLUMN_4,
NUM_COLUMNS
};
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *scrolled_window;
GtkWidget *tree_view;
GtkTreeModel *model;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeIter iter;
gint i;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy", gtk_main_quit, NULL);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("My List of cool words"), FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
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);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
0, GTK_TREE_SORT_ASCENDING);
for (i = 0; data[i].word_1 != NULL; i++)
{
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
WORD_COLUMN, data[i].word_1,
WORD_COLUMN_2, data[i].word_2,
WORD_COLUMN_3, data[i].word_3,
WORD_COLUMN_4, data[i].word_4,
-1);
}
tree_view = gtk_tree_view_new_with_model (model);
g_object_unref (G_OBJECT (model));
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("First Word", renderer,
"text", WORD_COLUMN,
NULL);
gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_unref (column);
g_object_unref (renderer);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Second Word", renderer,
"text", WORD_COLUMN_2,
NULL);
gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_2);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_unref (column);
g_object_unref (renderer);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Third Word", renderer,
"text", WORD_COLUMN_3,
NULL);
gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_3);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_unref (column);
g_object_unref (renderer);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Fourth Word", renderer,
"text", WORD_COLUMN_4,
NULL);
gtk_tree_view_column_set_sort_column_id (column, WORD_COLUMN_4);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
g_object_unref (column);
g_object_unref (renderer);
gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}