diff options
author | Jonathan Blandford <jrb@redhat.com> | 2001-03-23 00:35:19 +0000 |
---|---|---|
committer | Jonathan Blandford <jrb@src.gnome.org> | 2001-03-23 00:35:19 +0000 |
commit | 21fd434c5f528546a35036b4cfce6a708a4c2762 (patch) | |
tree | 86ff9f050f2a04d6154d608e211c32b561f8ebfd /gtk | |
parent | 18b5348b4838c99b85f14e4f0e351facef26b261 (diff) | |
download | gtk+-21fd434c5f528546a35036b4cfce6a708a4c2762.tar.gz |
fix braino. New interface to add cleanup sortable support.
Thu Mar 22 19:27:34 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
fix braino.
* gtk/gtktreesortable.[ch]: New interface to add cleanup sortable
support.
* gtk/gtktreeview.c: Addition of initial sortable support.
* gtk/gtktreestore.c: Addition of initial sortable support.
* gtk/gtkliststore.c: Addition of initial sortable support.
* gtk/gtkmarshal.list: yet another marshaller.
* gtk/gtktreedatallist.[ch]: shared code between the store models
for handling sorting headers.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.am | 1 | ||||
-rw-r--r-- | gtk/gtkcellrenderertoggle.c | 8 | ||||
-rw-r--r-- | gtk/gtkliststore.c | 132 | ||||
-rw-r--r-- | gtk/gtkliststore.h | 6 | ||||
-rw-r--r-- | gtk/gtkmarshal.list | 1 | ||||
-rw-r--r-- | gtk/gtkmarshalers.list | 1 | ||||
-rw-r--r-- | gtk/gtktreedatalist.c | 108 | ||||
-rw-r--r-- | gtk/gtktreedatalist.h | 12 | ||||
-rw-r--r-- | gtk/gtktreemodel.c | 29 | ||||
-rw-r--r-- | gtk/gtktreemodel.h | 3 | ||||
-rw-r--r-- | gtk/gtktreeprivate.h | 3 | ||||
-rw-r--r-- | gtk/gtktreesortable.c | 127 | ||||
-rw-r--r-- | gtk/gtktreesortable.h | 53 | ||||
-rw-r--r-- | gtk/gtktreestore.c | 205 | ||||
-rw-r--r-- | gtk/gtktreestore.h | 1 | ||||
-rw-r--r-- | gtk/gtktreeview.c | 108 |
16 files changed, 647 insertions, 151 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index a33192e884..8ed2d8d1a1 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -344,6 +344,7 @@ gtk_c_sources = @STRIP_BEGIN@ \ gtktreemodel.c \ gtktreemodelsort.c \ gtktreeselection.c \ + gtktreesortable.c \ gtktreestore.c \ gtktreeview.c \ gtktreeviewcolumn.c \ diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c index c257db44fb..6207968f39 100644 --- a/gtk/gtkcellrenderertoggle.c +++ b/gtk/gtkcellrenderertoggle.c @@ -291,8 +291,8 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, window, state, shadow, cell_area, widget, "cellradio", - cell_area->x + x_offset, - cell_area->y + y_offset, + cell_area->x + x_offset + cell->xpad, + cell_area->y + y_offset + cell->ypad, width, height); } else @@ -301,8 +301,8 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, window, state, shadow, cell_area, widget, "cellcheck", - cell_area->x + x_offset, - cell_area->y + y_offset, + cell_area->x + x_offset + cell->xpad, + cell_area->y + y_offset + cell->ypad, width, height); } } diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index 480a9217e8..92de43a1ad 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -32,6 +32,7 @@ static void gtk_list_store_class_init (GtkListStoreClass *class); static void gtk_list_store_tree_model_init (GtkTreeModelIface *iface); static void gtk_list_store_drag_source_init(GtkTreeDragSourceIface *iface); static void gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface); +static void gtk_list_store_sortable_init (GtkTreeSortableIface *iface); static guint gtk_list_store_get_flags (GtkTreeModel *tree_model); static gint gtk_list_store_get_n_columns (GtkTreeModel *tree_model); static GType gtk_list_store_get_column_type (GtkTreeModel *tree_model, @@ -62,6 +63,8 @@ static gboolean gtk_list_store_iter_parent (GtkTreeModel *tree_mode GtkTreeIter *iter, GtkTreeIter *child); + +/* Drag and Drop */ static gboolean gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path); static gboolean gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source, @@ -74,6 +77,22 @@ static gboolean gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest, GtkTreeModel *src_model, GtkTreePath *src_path, GtkTreePath *dest_path); + +/* sortable */ +static gboolean gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order); +static void gtk_list_store_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order); +static void gtk_list_store_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); + + + static void validate_list_store (GtkListStore *list_store) { @@ -125,7 +144,14 @@ gtk_list_store_get_type (void) NULL, NULL }; - + + static const GInterfaceInfo sortable_info = + { + (GInterfaceInitFunc) gtk_list_store_sortable_init, + NULL, + NULL + }; + list_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkListStore", &list_store_info, 0); g_type_add_interface_static (list_store_type, GTK_TYPE_TREE_MODEL, @@ -136,6 +162,9 @@ gtk_list_store_get_type (void) g_type_add_interface_static (list_store_type, GTK_TYPE_TREE_DRAG_DEST, &drag_dest_info); + g_type_add_interface_static (list_store_type, + GTK_TYPE_TREE_SORTABLE, + &sortable_info); } return list_store_type; @@ -174,17 +203,26 @@ gtk_list_store_drag_source_init (GtkTreeDragSourceIface *iface) } static void -gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface) +gtk_list_store_drag_dest_init (GtkTreeDragDestIface *iface) { iface->drag_data_received = gtk_list_store_drag_data_received; iface->row_drop_possible = gtk_list_store_row_drop_possible; } static void +gtk_list_store_sortable_init (GtkTreeSortableIface *iface) +{ + iface->get_sort_column_id = gtk_list_store_get_sort_column_id; + iface->set_sort_column_id = gtk_list_store_set_sort_column_id; + iface->sort_column_id_set_func = gtk_list_store_sort_column_id_set_func; +} + +static void gtk_list_store_init (GtkListStore *list_store) { list_store->root = NULL; list_store->tail = NULL; + list_store->sort_list = NULL; list_store->stamp = g_random_int (); list_store->length = 0; } @@ -286,6 +324,11 @@ gtk_list_store_set_n_columns (GtkListStore *list_store, g_free (list_store->column_headers); } + if (list_store->sort_list) + _gtk_tree_data_list_header_free (list_store->sort_list); + + list_store->sort_list = _gtk_tree_data_list_header_new (n_columns, list_store->column_headers); + list_store->column_headers = new_columns; list_store->n_columns = n_columns; } @@ -815,7 +858,7 @@ insert_after (GtkListStore *list_store, sibling->next = new_list; /* if list was the tail, the new node is the new tail */ - if (sibling == list_store->tail) + if (sibling == ((GSList *) list_store->tail)) list_store->tail = new_list; list_store->length += 1; @@ -1069,7 +1112,7 @@ gtk_list_store_append (GtkListStore *list_store, iter->user_data = g_slist_alloc (); if (list_store->tail) - list_store->tail->next = iter->user_data; + ((GSList *)list_store->tail)->next = iter->user_data; else list_store->root = iter->user_data; @@ -1271,3 +1314,84 @@ gtk_list_store_row_drop_possible (GtkTreeDragDest *drag_dest, else return FALSE; } + +/* Sorting */ +static gboolean +gtk_list_store_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order) +{ + GtkListStore *list_store = (GtkListStore *) sortable; + + g_return_val_if_fail (sortable != NULL, FALSE); + g_return_val_if_fail (GTK_IS_LIST_STORE (sortable), FALSE); + + if (list_store->sort_column_id == -1) + return FALSE; + + if (sort_column_id) + * sort_column_id = list_store->sort_column_id; + if (order) + * order = list_store->order; + return TRUE; +} + +static void +gtk_list_store_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order) +{ + GtkListStore *list_store = (GtkListStore *) sortable; + GList *list; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_LIST_STORE (sortable)); + + for (list = list_store->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); + + list_store->sort_column_id = sort_column_id; + list_store->order = order; +} + +static void +gtk_list_store_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy) +{ + GtkListStore *list_store = (GtkListStore *) sortable; + GtkTreeDataSortHeader *header = NULL; + GList *list; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_LIST_STORE (sortable)); + g_return_if_fail (func != NULL); + + for (list = list_store->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; + list_store->sort_list = g_list_append (list_store->sort_list, header); + } + + if (header->destroy) + (* header->destroy) (header->data); + + header->func = func; + header->data = data; + header->destroy = destroy; +} diff --git a/gtk/gtkliststore.h b/gtk/gtkliststore.h index 4406bd74bc..5ab9a8d144 100644 --- a/gtk/gtkliststore.h +++ b/gtk/gtkliststore.h @@ -21,6 +21,7 @@ #define __GTK_LIST_STORE_H__ #include <gtk/gtktreemodel.h> +#include <gtk/gtktreesortable.h> #ifdef __cplusplus extern "C" { @@ -42,8 +43,11 @@ struct _GtkListStore /*< private >*/ gint stamp; gpointer root; - GSList *tail; + gpointer tail; + GList *sort_list; gint n_columns; + gint sort_column_id; + GtkTreeSortOrder order; GType *column_headers; gint length; }; diff --git a/gtk/gtkmarshal.list b/gtk/gtkmarshal.list index f193de669e..26e90358ff 100644 --- a/gtk/gtkmarshal.list +++ b/gtk/gtkmarshal.list @@ -38,6 +38,7 @@ NONE:STRING,INT,POINTER VOID:BOOLEAN VOID:BOXED VOID:BOXED,BOXED +VOID:BOXED,POINTER VOID:BOXED,OBJECT VOID:BOXED,STRING,INT VOID:BOXED,UINT diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list index f193de669e..26e90358ff 100644 --- a/gtk/gtkmarshalers.list +++ b/gtk/gtkmarshalers.list @@ -38,6 +38,7 @@ NONE:STRING,INT,POINTER VOID:BOOLEAN VOID:BOXED VOID:BOXED,BOXED +VOID:BOXED,POINTER VOID:BOXED,OBJECT VOID:BOXED,STRING,INT VOID:BOXED,UINT diff --git a/gtk/gtktreedatalist.c b/gtk/gtktreedatalist.c index 0c44dc7080..0bf6152665 100644 --- a/gtk/gtktreedatalist.c +++ b/gtk/gtktreedatalist.c @@ -15,10 +15,13 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. + * + * This file contains code shared between GtkTreeStore and GtkListStore. Please + * do not use it. */ #include "gtktreedatalist.h" - +#include <string.h> static GMemChunk *tree_chunk = NULL; #define TREE_CHUNK_PREALLOCS 64 @@ -250,3 +253,106 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list, return new_list; } +static gint +gtk_tree_data_list_compare_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) +{ + gint column = GPOINTER_TO_INT (user_data); + GType type = gtk_tree_model_get_column_type (model, column); + GValue a_value = {0, }; + GValue b_value = {0, }; + gint retval; + + gtk_tree_model_get_value (model, a, column, &a_value); + gtk_tree_model_get_value (model, b, column, &b_value); + + switch (G_TYPE_FUNDAMENTAL (type)) + { + case G_TYPE_BOOLEAN: + retval = (g_value_get_int (&a_value) < g_value_get_int (&b_value)); + break; + case G_TYPE_CHAR: + retval = (g_value_get_char (&a_value) < g_value_get_char (&b_value)); + break; + case G_TYPE_UCHAR: + retval = (g_value_get_uchar (&a_value) < g_value_get_uchar (&b_value)); + break; + case G_TYPE_INT: + retval = (g_value_get_int (&a_value) < g_value_get_int (&b_value)); + break; + case G_TYPE_UINT: + retval = (g_value_get_uint (&a_value) < g_value_get_uint (&b_value)); + break; + case G_TYPE_ENUM: + /* this is somewhat bogus. */ + retval = (g_value_get_int (&a_value) < g_value_get_int (&b_value)); + break; + case G_TYPE_FLAGS: + retval = (g_value_get_uint (&a_value) < g_value_get_uint (&b_value)); + break; + case G_TYPE_FLOAT: + retval = (g_value_get_float (&a_value) < g_value_get_float (&b_value)); + break; + case G_TYPE_DOUBLE: + retval = (g_value_get_double (&a_value) < g_value_get_double (&b_value)); + break; + case G_TYPE_STRING: + retval = strcmp (g_value_get_string (&a_value), g_value_get_string (&b_value)); + break; + case G_TYPE_POINTER: + case G_TYPE_BOXED: + case G_TYPE_OBJECT: + default: + g_warning ("Attempting to sort on invalid type %s\n", g_type_name (type)); + retval = FALSE; + break; + } + + g_value_unset (&a_value); + g_value_unset (&b_value); + + return retval; +} + + +GList * +_gtk_tree_data_list_header_new (gint n_columns, + GType *types) +{ + GList *retval = NULL; + + gint i; + + for (i = 0; i < n_columns; i ++) + { + GtkTreeDataSortHeader *header; + + header = g_new (GtkTreeDataSortHeader, 1); + + retval = g_list_prepend (retval, header); + header->sort_column_id = i; + header->func = gtk_tree_data_list_compare_func; + header->destroy = NULL; + header->data = GINT_TO_POINTER (i); + } + return g_list_reverse (retval); +} + +void +_gtk_tree_data_list_header_free (GList *list) +{ + GList *tmp; + + for (tmp = list; tmp; tmp = tmp->next) + { + GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader *) tmp->data; + + if (header->destroy) + (* header->destroy) (header->data); + + g_free (header); + } + g_list_free (list); +} diff --git a/gtk/gtktreedatalist.h b/gtk/gtktreedatalist.h index 3150b97bc0..9294395347 100644 --- a/gtk/gtktreedatalist.h +++ b/gtk/gtktreedatalist.h @@ -23,6 +23,7 @@ #include <glib.h> #include <glib-object.h> +#include "gtktreesortable.h" typedef struct _GtkTreeDataList GtkTreeDataList; struct _GtkTreeDataList @@ -40,6 +41,13 @@ struct _GtkTreeDataList } data; }; +typedef struct _GtkTreeDataSortHeader +{ + gint sort_column_id; + GtkTreeIterCompareFunc func; + gpointer data; + GtkDestroyNotify destroy; +} GtkTreeDataSortHeader; GtkTreeDataList *_gtk_tree_data_list_alloc (void); void _gtk_tree_data_list_free (GtkTreeDataList *list, @@ -54,5 +62,9 @@ void _gtk_tree_data_list_value_to_node (GtkTreeDataList *list, GtkTreeDataList *_gtk_tree_data_list_node_copy (GtkTreeDataList *list, GType type); +/* Header code */ +GList *_gtk_tree_data_list_header_new (gint n_columns, + GType *types); +void _gtk_tree_data_list_header_free (GList *header_list); #endif /* __GTK_TREE_DATA_LIST_H__ */ diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c index 4848ad07c4..f30fe8f608 100644 --- a/gtk/gtktreemodel.c +++ b/gtk/gtktreemodel.c @@ -42,7 +42,7 @@ gtk_tree_model_get_type (void) { static GtkType tree_model_type = 0; - if (!tree_model_type) + if (! tree_model_type) { static const GTypeInfo tree_model_info = { @@ -68,9 +68,9 @@ gtk_tree_model_get_type (void) static void gtk_tree_model_base_init (gpointer g_class) { - static gboolean initted = FALSE; + static gboolean initialized = FALSE; - if (! initted) + if (! initialized) { g_signal_newc ("changed", GTK_TYPE_TREE_MODEL, @@ -107,7 +107,16 @@ gtk_tree_model_base_init (gpointer g_class) gtk_marshal_VOID__BOXED, G_TYPE_NONE, 1, GTK_TYPE_TREE_PATH); - initted = TRUE; + g_signal_newc ("reordered", + GTK_TYPE_TREE_MODEL, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkTreeModelIface, reordered), + NULL, NULL, + gtk_marshal_VOID__BOXED_POINTER, + G_TYPE_NONE, 2, + GTK_TYPE_TREE_PATH, + G_TYPE_POINTER); + initialized = TRUE; } } @@ -1057,6 +1066,18 @@ gtk_tree_model_deleted (GtkTreeModel *tree_model, g_signal_emit_by_name (tree_model, "deleted", path); } +void +gtk_tree_model_reordered (GtkTreeModel *tree_model, + GtkTreePath *path, + gint *new_order) +{ + g_return_if_fail (tree_model != NULL); + g_return_if_fail (GTK_IS_TREE_MODEL (tree_model)); + g_return_if_fail (new_order != NULL); + + g_signal_emit_by_name (tree_model, "reordered", path, new_order); +} + /** ** GtkTreeRowReference diff --git a/gtk/gtktreemodel.h b/gtk/gtktreemodel.h index 9d3c5422fa..4aaac7d834 100644 --- a/gtk/gtktreemodel.h +++ b/gtk/gtktreemodel.h @@ -217,6 +217,9 @@ void gtk_tree_model_has_child_toggled (GtkTreeModel *tree_model, GtkTreeIter *iter); void gtk_tree_model_deleted (GtkTreeModel *tree_model, GtkTreePath *path); +void gtk_tree_model_reordered (GtkTreeModel *tree_model, + GtkTreePath *path, + gint *new_order); diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h index 8d519c38cb..cc2f89dd35 100644 --- a/gtk/gtktreeprivate.h +++ b/gtk/gtktreeprivate.h @@ -92,7 +92,8 @@ struct _GtkTreeViewPrivate /* Focus code */ gboolean header_has_focus; - GList *focus_column; + GtkTreeViewColumn *focus_column; + GtkTreeViewColumn *scroll_column; /* Selection stuff */ GtkTreeRowReference *anchor; diff --git a/gtk/gtktreesortable.c b/gtk/gtktreesortable.c new file mode 100644 index 0000000000..b2833af60e --- /dev/null +++ b/gtk/gtktreesortable.c @@ -0,0 +1,127 @@ +/* gtktreesortable.c + * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include "gtktreesortable.h" +#include "gtksignal.h" + +static void gtk_tree_sortable_base_init (gpointer g_class); + +GtkType +gtk_tree_sortable_get_type (void) +{ + static GtkType tree_sortable_type = 0; + + if (! tree_sortable_type) + { + static const GTypeInfo tree_sortable_info = + { + sizeof (GtkTreeSortableIface), /* class_size */ + gtk_tree_sortable_base_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, + NULL + }; + tree_sortable_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeSortable", &tree_sortable_info, 0); + g_type_interface_add_prerequisite (tree_sortable_type, G_TYPE_OBJECT); + } + + return tree_sortable_type; +} + +static void +gtk_tree_sortable_base_init (gpointer g_class) +{ + static gboolean initialized = FALSE; + + if (! initialized) + { + g_signal_newc ("sort_column_changed", + GTK_TYPE_TREE_SORTABLE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkTreeSortableIface, sort_column_changed), + NULL, NULL, + gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); + initialized = TRUE; + } +} + +gboolean +gtk_tree_sortable_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order) +{ + GtkTreeSortableIface *iface; + + g_return_val_if_fail (sortable != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_SORTABLE (sortable), FALSE); + + iface = GTK_TREE_SORTABLE_GET_IFACE (sortable); + + g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (iface->get_sort_column_id != NULL, FALSE); + + return (* iface->get_sort_column_id) (sortable, sort_column_id, order); +} + +void +gtk_tree_sortable_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order) +{ + GtkTreeSortableIface *iface; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable)); + + iface = GTK_TREE_SORTABLE_GET_IFACE (sortable); + + g_return_if_fail (iface != NULL); + g_return_if_fail (iface->set_sort_column_id != NULL); + + (* iface->set_sort_column_id) (sortable, sort_column_id, order); + +} + +void +gtk_tree_sortable_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy) +{ + GtkTreeSortableIface *iface; + + g_return_if_fail (sortable != NULL); + g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable)); + + iface = GTK_TREE_SORTABLE_GET_IFACE (sortable); + + g_return_if_fail (iface != NULL); + g_return_if_fail (iface->sort_column_id_set_func != NULL); + + (* iface->sort_column_id_set_func) (sortable, sort_column_id, func, data, destroy); +} + + diff --git a/gtk/gtktreesortable.h b/gtk/gtktreesortable.h index 8c7ed59b9e..85369b9bd7 100644 --- a/gtk/gtktreesortable.h +++ b/gtk/gtktreesortable.h @@ -28,39 +28,64 @@ extern "C" { typedef enum { + GTK_TREE_SORT_NONE, GTK_TREE_SORT_ASCENDING, GTK_TREE_SORT_DESCENDING } GtkTreeSortOrder; #define GTK_TYPE_TREE_SORTABLE (gtk_tree_sortable_get_type ()) #define GTK_TREE_SORTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_SORTABLE, GtkTreeSortable)) +#define GTK_TREE_SORTABLE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_TREE_SORTABLE, GtkTreeSortableIface)) #define GTK_IS_TREE_SORTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_SORTABLE)) #define GTK_TREE_SORTABLE_GET_IFACE(obj) ((GtkTreeSortableIface *)g_type_interface_peek (((GTypeInstance *)GTK_TREE_SORTABLE (obj))->g_class, GTK_TYPE_TREE_SORTABLE)) + typedef struct _GtkTreeSortable GtkTreeSortable; /* Dummy typedef */ typedef struct _GtkTreeSortableIface GtkTreeSortableIface; +typedef gint (* GtkTreeIterCompareFunc) (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data); + + struct _GtkTreeSortableIface { GTypeInterface g_iface; - /* This one is a signal */ - void (* sort_column_changed) (GtkTreeSortable *sortable); - - /* virtual methods */ - gboolean (* column_sortable) (GtkTreeSortable *sortable, - gint column, - GtkTreeSortOrder order); - void (* get_sort_column) (GtkTreeSortable *sortable, - gint *column, - GtkTreeSortOrder *order); - void (* set_sort_column) (GtkTreeSortable *sortable, - gint column, - GtkTreeSortOrder order); + /* signals */ + void (* sort_column_changed) (GtkTreeSortable *sortable); + + /* virtual table */ + gboolean (* get_sort_column_id) (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order); + void (* set_sort_column_id) (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order); + void (* sort_column_id_set_func) (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); }; -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_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); + + #ifdef __cplusplus } diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c index 5b58ac3d42..a4cba08a83 100644 --- a/gtk/gtktreestore.c +++ b/gtk/gtktreestore.c @@ -31,6 +31,7 @@ static void gtk_tree_store_class_init (GtkTreeStoreClass *tree_stor static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface); static void gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface); static void gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface); +static void gtk_tree_store_sortable_init (GtkTreeSortableIface *iface); static guint gtk_tree_store_get_flags (GtkTreeModel *tree_model); static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model); static GType gtk_tree_store_get_column_type (GtkTreeModel *tree_model, @@ -59,18 +60,35 @@ static gboolean gtk_tree_store_iter_parent (GtkTreeModel *tree_mode GtkTreeIter *child); +/* DND interfaces */ static gboolean gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source, - GtkTreePath *path); + GtkTreePath *path); static gboolean gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source, - GtkTreePath *path, - GtkSelectionData *selection_data); + GtkTreePath *path, + GtkSelectionData *selection_data); static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, - GtkTreePath *dest, - GtkSelectionData *selection_data); + GtkTreePath *dest, + GtkSelectionData *selection_data); static gboolean gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, - GtkTreeModel *src_model, - GtkTreePath *src_path, - GtkTreePath *dest_path); + GtkTreeModel *src_model, + GtkTreePath *src_path, + GtkTreePath *dest_path); + +/* Sortable Interfaces */ + +static void gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order); +static void gtk_tree_store_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order); +static void gtk_tree_store_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); + + static void validate_gnode (GNode *node); @@ -80,7 +98,7 @@ validate_tree (GtkTreeStore *tree_store) if (gtk_debug_flags & GTK_DEBUG_TREE) { g_assert (G_NODE (tree_store->root)->parent == NULL); - + validate_gnode (G_NODE (tree_store->root)); } } @@ -125,21 +143,29 @@ gtk_tree_store_get_type (void) NULL, NULL }; - + + static const GInterfaceInfo sortable_info = + { + (GInterfaceInitFunc) gtk_tree_store_sortable_init, + NULL, + NULL + }; + tree_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0); g_type_add_interface_static (tree_store_type, GTK_TYPE_TREE_MODEL, &tree_model_info); - g_type_add_interface_static (tree_store_type, GTK_TYPE_TREE_DRAG_SOURCE, &drag_source_info); g_type_add_interface_static (tree_store_type, GTK_TYPE_TREE_DRAG_DEST, &drag_dest_info); + g_type_add_interface_static (tree_store_type, + GTK_TYPE_TREE_SORTABLE, + &sortable_info); - } return tree_store_type; @@ -178,17 +204,26 @@ gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface) } static void -gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface) +gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface) { iface->drag_data_received = gtk_tree_store_drag_data_received; iface->row_drop_possible = gtk_tree_store_row_drop_possible; } static void +gtk_tree_store_sortable_init (GtkTreeSortableIface *iface) +{ + iface->get_sort_column_id = NULL; + iface->set_sort_column_id = NULL; + iface->sort_column_id_set_func = NULL; +} + +static void gtk_tree_store_init (GtkTreeStore *tree_store) { tree_store->root = g_node_new (NULL); tree_store->stamp = g_random_int (); + tree_store->sort_list = NULL; } GtkTreeStore * @@ -228,6 +263,14 @@ gtk_tree_store_new_with_types (gint n_columns, return retval; } +/** + * gtk_tree_store_set_n_columns: + * @tree_store: + * @n_columns: + * + * As a side effect of calling this function, all sort columns that overlap with + * the current number of columns will be removed. + **/ void gtk_tree_store_set_n_columns (GtkTreeStore *tree_store, gint n_columns) @@ -252,6 +295,11 @@ gtk_tree_store_set_n_columns (GtkTreeStore *tree_store, g_free (tree_store->column_headers); } + if (tree_store->sort_list) + _gtk_tree_data_list_header_free (tree_store->sort_list); + + tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers); + tree_store->column_headers = new_columns; tree_store->n_columns = n_columns; } @@ -261,12 +309,12 @@ gtk_tree_store_set_n_columns (GtkTreeStore *tree_store, * @tree_store: a #GtkTreeStore * @column: column number * @type: type of the data to be stored in @column - * + * * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR, * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT, * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with * subclasses of those types such as %GDK_TYPE_PIXBUF. - * + * **/ void gtk_tree_store_set_column_type (GtkTreeStore *tree_store, @@ -325,7 +373,7 @@ gtk_tree_store_get_path (GtkTreeModel *tree_model, GtkTreePath *retval; GNode *tmp_node; gint i = 0; - + g_return_val_if_fail (tree_model != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL); g_return_val_if_fail (iter != NULL, NULL); @@ -334,7 +382,7 @@ gtk_tree_store_get_path (GtkTreeModel *tree_model, validate_tree ((GtkTreeStore*)tree_model); g_assert (G_NODE (iter->user_data)->parent != NULL); - + if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root)) { retval = gtk_tree_path_new (); @@ -343,7 +391,7 @@ gtk_tree_store_get_path (GtkTreeModel *tree_model, else { GtkTreeIter tmp_iter = *iter; - + tmp_iter.user_data = G_NODE (iter->user_data)->parent; retval = gtk_tree_store_get_path (tree_model, @@ -418,7 +466,7 @@ gtk_tree_store_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) { g_return_val_if_fail (iter->user_data != NULL, FALSE); - + if (G_NODE (iter->user_data)->next) { iter->user_data = G_NODE (iter->user_data)->next; @@ -436,7 +484,7 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model, GNode *children; g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE); - + if (parent) children = G_NODE (parent->user_data)->children; else @@ -475,7 +523,7 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model, g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0); g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (iter->user_data != NULL, FALSE); - + if (iter == NULL) node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children; else @@ -526,13 +574,13 @@ gtk_tree_store_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *child) { GNode *parent; - + g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (iter->user_data != NULL, FALSE); parent = G_NODE (child->user_data)->parent; - g_assert (parent != NULL); + g_assert (parent != NULL); if (parent != GTK_TREE_STORE (tree_model)->root) { @@ -648,7 +696,7 @@ gtk_tree_store_set_cell (GtkTreeStore *tree_store, * * See gtk_tree_store_set(); this version takes a va_list for * use by language bindings. - * + * **/ void gtk_tree_store_set_valist (GtkTreeStore *tree_store, @@ -701,7 +749,7 @@ gtk_tree_store_set_valist (GtkTreeStore *tree_store, * @tree_store: a #GtkTreeStore * @iter: row iterator * @Varargs: pairs of column number and value, terminated with -1 - * + * * Sets the value of one or more cells in the row referenced by @iter. * The variable argument list should contain integer column numbers, * each column number followed by the value to be set. For example, @@ -737,7 +785,7 @@ gtk_tree_store_remove (GtkTreeStore *model, parent = G_NODE (iter->user_data)->parent; g_assert (parent != NULL); - + if (G_NODE (iter->user_data)->data) _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data, model->column_headers); @@ -767,7 +815,7 @@ gtk_tree_store_insert (GtkTreeStore *model, { GtkTreePath *path; GNode *parent_node; - + g_return_if_fail (model != NULL); g_return_if_fail (GTK_IS_TREE_STORE (model)); @@ -779,7 +827,7 @@ gtk_tree_store_insert (GtkTreeStore *model, iter->stamp = model->stamp; iter->user_data = g_node_new (NULL); g_node_insert (parent_node, position, G_NODE (iter->user_data)); - + path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter); gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter); @@ -797,12 +845,12 @@ gtk_tree_store_insert_before (GtkTreeStore *model, GtkTreePath *path; GNode *parent_node = NULL; GNode *new_node; - + g_return_if_fail (model != NULL); g_return_if_fail (GTK_IS_TREE_STORE (model)); g_return_if_fail (iter != NULL); - new_node = g_node_new (NULL); + new_node = g_node_new (NULL); if (parent == NULL && sibling == NULL) parent_node = model->root; @@ -823,7 +871,7 @@ gtk_tree_store_insert_before (GtkTreeStore *model, iter->stamp = model->stamp; iter->user_data = new_node; - + path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter); gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter); @@ -841,7 +889,7 @@ gtk_tree_store_insert_after (GtkTreeStore *model, GtkTreePath *path; GNode *parent_node; GNode *new_node; - + g_return_if_fail (model != NULL); g_return_if_fail (GTK_IS_TREE_STORE (model)); g_return_if_fail (iter != NULL); @@ -861,14 +909,14 @@ gtk_tree_store_insert_after (GtkTreeStore *model, parent_node = G_NODE (parent->user_data); } - + g_node_insert_after (parent_node, sibling ? G_NODE (sibling->user_data) : NULL, new_node); - + iter->stamp = model->stamp; iter->user_data = new_node; - + path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter); gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter); @@ -883,7 +931,7 @@ gtk_tree_store_prepend (GtkTreeStore *model, GtkTreeIter *parent) { GNode *parent_node; - + g_return_if_fail (model != NULL); g_return_if_fail (GTK_IS_TREE_STORE (model)); g_return_if_fail (iter != NULL); @@ -892,16 +940,16 @@ gtk_tree_store_prepend (GtkTreeStore *model, parent_node = model->root; else parent_node = parent->user_data; - + if (parent_node->children == NULL) { GtkTreePath *path; - + iter->stamp = model->stamp; iter->user_data = g_node_new (NULL); - + g_node_prepend (parent_node, iter->user_data); - + if (parent_node != model->root) { path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent); @@ -933,7 +981,7 @@ gtk_tree_store_append (GtkTreeStore *model, g_return_if_fail (model != NULL); g_return_if_fail (GTK_IS_TREE_STORE (model)); g_return_if_fail (iter != NULL); - + if (parent == NULL) parent_node = model->root; else @@ -945,7 +993,7 @@ gtk_tree_store_append (GtkTreeStore *model, iter->stamp = model->stamp; iter->user_data = g_node_new (NULL); - + g_node_append (parent_node, G_NODE (iter->user_data)); if (parent_node != model->root) @@ -958,7 +1006,7 @@ gtk_tree_store_append (GtkTreeStore *model, { path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter); } - + gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter); gtk_tree_path_free (path); } @@ -1007,7 +1055,7 @@ gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreeIter iter; g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE); - + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path)) @@ -1060,7 +1108,7 @@ copy_node_data (GtkTreeStore *tree_store, GtkTreeDataList *copy_iter = NULL; GtkTreePath *path; gint col; - + col = 0; while (dl) { @@ -1094,7 +1142,7 @@ recursive_node_copy (GtkTreeStore *tree_store, GtkTreeModel *model; model = GTK_TREE_MODEL (tree_store); - + copy_node_data (tree_store, src_iter, dest_iter); if (gtk_tree_model_iter_children (model, @@ -1112,7 +1160,7 @@ recursive_node_copy (GtkTreeStore *tree_store, gtk_tree_store_append (tree_store, ©, dest_iter); - + recursive_node_copy (tree_store, &child, ©); } while (gtk_tree_model_iter_next (model, &child)); @@ -1129,14 +1177,14 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreeModel *src_model = NULL; GtkTreePath *src_path = NULL; gboolean retval = FALSE; - + g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE); tree_model = GTK_TREE_MODEL (drag_dest); tree_store = GTK_TREE_STORE (drag_dest); validate_tree (tree_store); - + if (gtk_selection_data_get_tree_row (selection_data, &src_model, &src_path) && @@ -1146,7 +1194,7 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreeIter src_iter; GtkTreeIter dest_iter; GtkTreePath *prev; - + if (!gtk_tree_model_get_iter (src_model, &src_iter, src_path)) @@ -1156,17 +1204,17 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, /* Get the path to insert _after_ (dest is the path to insert _before_) */ prev = gtk_tree_path_copy (dest); - + if (!gtk_tree_path_prev (prev)) { GtkTreeIter dest_parent; GtkTreePath *parent; GtkTreeIter *dest_parent_p; - + /* dest was the first spot at the current depth; which means * we are supposed to prepend. */ - + /* Get the parent, NULL if parent is the root */ dest_parent_p = NULL; parent = gtk_tree_path_copy (dest); @@ -1179,11 +1227,11 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, } gtk_tree_path_free (parent); parent = NULL; - + gtk_tree_store_prepend (GTK_TREE_STORE (tree_model), &dest_iter, dest_parent_p); - + retval = TRUE; } else @@ -1203,11 +1251,11 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, } gtk_tree_path_free (prev); - + /* If we succeeded in creating dest_iter, walk src_iter tree branch, * duplicating it below dest_iter. */ - + if (retval) { recursive_node_copy (tree_store, @@ -1224,11 +1272,11 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest, } out: - + if (src_path) gtk_tree_path_free (src_path); - - return retval; + + return retval; } static gboolean @@ -1240,7 +1288,7 @@ gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, /* can only drag to ourselves */ if (src_model != GTK_TREE_MODEL (drag_dest)) return FALSE; - + /* Can't drop into ourself. */ if (gtk_tree_path_is_ancestor (src_path, dest_path)) @@ -1264,20 +1312,47 @@ gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest, return FALSE; } } - + if (tmp) gtk_tree_path_free (tmp); } - + /* Can otherwise drop anywhere. */ return TRUE; } - + + +static void +gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkTreeSortOrder *order) +{ + +} + +static void +gtk_tree_store_set_sort_column_id (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeSortOrder order) +{ + +} + +static void +gtk_tree_store_sort_column_id_set_func (GtkTreeSortable *sortable, + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy) +{ + +} + static void validate_gnode (GNode* node) { GNode *iter; - + iter = node->children; while (iter != NULL) { diff --git a/gtk/gtktreestore.h b/gtk/gtktreestore.h index 87a9413f50..d38ca5a551 100644 --- a/gtk/gtktreestore.h +++ b/gtk/gtktreestore.h @@ -40,6 +40,7 @@ struct _GtkTreeStore { GObject parent; + GList *sort_list; gint stamp; gpointer root; gpointer last; diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 3c24a4c517..761ab3b641 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -186,7 +186,9 @@ static void gtk_tree_view_has_child_toggled (GtkTreeModel *model, static void gtk_tree_view_deleted (GtkTreeModel *model, GtkTreePath *path, gpointer data); - +static void gtk_tree_view_reordered (GtkTreeModel *model, + GtkTreePath *parent, + gint *new_order); /* Internal functions */ static void gtk_tree_view_unref_tree (GtkTreeView *tree_view, GtkRBTree *tree); @@ -244,9 +246,7 @@ static void gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view, static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view, GdkEventMotion *event); static void _gtk_tree_view_update_col_width (GtkTreeView *tree_view); -static void gtk_tree_view_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column); + static GtkContainerClass *parent_class = NULL; static guint tree_view_signals[LAST_SIGNAL] = { 0 }; @@ -325,6 +325,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class) container_class->forall = gtk_tree_view_forall; container_class->remove = gtk_tree_view_remove; + container_class->set_focus_child = gtk_tree_view_set_focus_child; container_class->focus = gtk_tree_view_focus; class->set_scroll_adjustments = gtk_tree_view_set_adjustments; @@ -720,7 +721,6 @@ gtk_tree_view_unrealize (GtkWidget *widget) GtkTreeView *tree_view; GList *list; - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (widget)); tree_view = GTK_TREE_VIEW (widget); @@ -798,7 +798,6 @@ gtk_tree_view_map (GtkWidget *widget) GList *tmp_list; GtkTreeView *tree_view; - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (widget)); tree_view = GTK_TREE_VIEW (widget); @@ -855,7 +854,6 @@ gtk_tree_view_size_request (GtkWidget *widget, GtkTreeView *tree_view; GList *tmp_list; - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (widget)); tree_view = GTK_TREE_VIEW (widget); @@ -920,7 +918,6 @@ gtk_tree_view_size_allocate (GtkWidget *widget, GList *tmp_list; GtkTreeView *tree_view; - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (widget)); widget->allocation = *allocation; @@ -1130,7 +1127,6 @@ gtk_tree_view_bin_expose (GtkWidget *widget, GtkTreePath *drag_dest_path; GList *last_column; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); tree_view = GTK_TREE_VIEW (widget); @@ -1494,7 +1490,6 @@ gtk_tree_view_expose (GtkWidget *widget, { GtkTreeView *tree_view; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); tree_view = GTK_TREE_VIEW (widget); @@ -1688,7 +1683,6 @@ gtk_tree_view_enter_notify (GtkWidget *widget, GtkRBNode *node; gint new_y; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); tree_view = GTK_TREE_VIEW (widget); @@ -1732,7 +1726,6 @@ gtk_tree_view_leave_notify (GtkWidget *widget, { GtkTreeView *tree_view; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); tree_view = GTK_TREE_VIEW (widget); @@ -1759,7 +1752,6 @@ gtk_tree_view_button_press (GtkWidget *widget, GdkRectangle background_area; GdkRectangle cell_area; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -1954,7 +1946,6 @@ gtk_tree_view_button_release (GtkWidget *widget, { GtkTreeView *tree_view; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -2052,7 +2043,19 @@ static void gtk_tree_view_set_focus_child (GtkContainer *container, GtkWidget *child) { + GtkTreeView *tree_view = GTK_TREE_VIEW (container); + GList *list; + + for (list = tree_view->priv->columns; list; list = list->next) + { + if (GTK_TREE_VIEW_COLUMN (list->data)->button == child) + { + tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (list->data); + break; + } + } + (* parent_class->set_focus_child) (container, child); } static void gtk_tree_view_draw_focus (GtkWidget *widget) @@ -2064,7 +2067,6 @@ gtk_tree_view_draw_focus (GtkWidget *widget) gint x, y; gint width, height; - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (widget)); tree_view = GTK_TREE_VIEW (widget); @@ -2099,11 +2101,10 @@ gtk_tree_view_draw_focus (GtkWidget *widget) height = BACKGROUND_HEIGHT (node) - 1; if (tree_view->priv->focus_column != NULL) { - GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data); gboolean visible; gboolean can_focus; - g_object_get (G_OBJECT (column->cell), + g_object_get (G_OBJECT (tree_view->priv->focus_column->cell), "can_activate", &can_focus, "visible", &visible, NULL); @@ -2114,15 +2115,15 @@ gtk_tree_view_draw_focus (GtkWidget *widget) gint x_offset; gint y_offset; - cell_area.x = column->button->allocation.x; + cell_area.x = tree_view->priv->focus_column->button->allocation.x; cell_area.y = y; - cell_area.width = column->displayed_width; + cell_area.width = tree_view->priv->focus_column->displayed_width; cell_area.height = CELL_HEIGHT (node); gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path); - gtk_tree_view_column_set_cell_data (column, tree_view->priv->model, &iter); + gtk_tree_view_column_set_cell_data (tree_view->priv->focus_column, tree_view->priv->model, &iter); - gtk_cell_renderer_get_size (column->cell, GTK_WIDGET (tree_view), &cell_area, &x_offset, &y_offset, &width, &height); + gtk_cell_renderer_get_size (tree_view->priv->focus_column->cell, GTK_WIDGET (tree_view), &cell_area, &x_offset, &y_offset, &width, &height); width += 2; height += 2; x = cell_area.x + x_offset - 1; @@ -2147,7 +2148,6 @@ gtk_tree_view_focus_in (GtkWidget *widget, { GtkTreeView *tree_view; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -2166,7 +2166,6 @@ static gint gtk_tree_view_focus_out (GtkWidget *widget, GdkEventFocus *event) { - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -2223,7 +2222,7 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, if (focus_child == NULL) { if (tree_view->priv->focus_column != NULL) - focus_child = GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data)->button; + focus_child = tree_view->priv->focus_column->button; else focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button; gtk_widget_grab_focus (focus_child); @@ -2236,7 +2235,7 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, if (focus_child == NULL) { if (tree_view->priv->focus_column != NULL) - focus_child = GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data)->button; + focus_child = tree_view->priv->focus_column->button; else if (dir == GTK_DIR_LEFT) focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button; else @@ -2308,7 +2307,7 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, if (GTK_TREE_VIEW_COLUMN (tmp_list->data)->button == focus_child) break; - tree_view->priv->focus_column = tmp_list; + tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (tmp_list->data); /* If the following isn't true, then the view is smaller then the scrollpane. */ @@ -2334,6 +2333,13 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view, /* We make the assumption that if container->focus_child != NULL, the focus must * be in the header. For now, this is accurate. It may not be in the future. */ + +/* The sordid relationship between focus_column and scroll_column: + * + * The focus_column represents the column that currently has keyboard focus, and + * is used when navigating columns by keyboard. scroll_column is used for + * handling scrolling by keyboard, such that in cases. + */ static gint gtk_tree_view_focus (GtkContainer *container, GtkDirectionType direction) @@ -2345,7 +2351,6 @@ gtk_tree_view_focus (GtkContainer *container, GtkRBNode *cursor_node; GtkTreePath *cursor_path; - g_return_val_if_fail (container != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (container), FALSE); g_return_val_if_fail (GTK_WIDGET_VISIBLE (container), FALSE); @@ -2614,7 +2619,6 @@ gtk_tree_view_remove (GtkContainer *container, GtkTreeViewChild *child = NULL; GList *tmp_list; - g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (container)); tree_view = GTK_TREE_VIEW (container); @@ -2663,7 +2667,6 @@ gtk_tree_view_forall (GtkContainer *container, GtkTreeViewColumn *column; GList *tmp_list; - g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (container)); g_return_if_fail (callback != NULL); @@ -3002,6 +3005,15 @@ gtk_tree_view_deleted (GtkTreeModel *model, _gtk_tree_view_update_size (GTK_TREE_VIEW (data)); } + +static void +gtk_tree_view_reordered (GtkTreeModel *model, + GtkTreePath *parent, + gint *new_order) +{ + +} + /* Internal tree functions */ static gint gtk_tree_view_insert_iter_height (GtkTreeView *tree_view, @@ -3832,7 +3844,6 @@ gtk_tree_view_new_with_model (GtkTreeModel *model) GtkTreeModel * gtk_tree_view_get_model (GtkTreeView *tree_view) { - g_return_val_if_fail (tree_view != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); return tree_view->priv->model; @@ -3866,6 +3877,11 @@ gtk_tree_view_setup_model (GtkTreeView *tree_view) gtk_tree_view_deleted, tree_view, FALSE); + g_signal_connectc (tree_view->priv->model, + "reordered", + gtk_tree_view_reordered, + tree_view, + FALSE); if (tree_view->priv->columns == NULL) return; @@ -3898,7 +3914,6 @@ void gtk_tree_view_set_model (GtkTreeView *tree_view, GtkTreeModel *model) { - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); if (model != NULL) @@ -3924,6 +3939,10 @@ gtk_tree_view_set_model (GtkTreeView *tree_view, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, gtk_tree_view_deleted, NULL); + g_signal_handlers_disconnect_matched (G_OBJECT (tree_view->priv->model), + G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, + gtk_tree_view_reordered, NULL); _gtk_rbtree_free (tree_view->priv->tree); } @@ -3963,7 +3982,6 @@ gtk_tree_view_set_model (GtkTreeView *tree_view, GtkTreeSelection * gtk_tree_view_get_selection (GtkTreeView *tree_view) { - g_return_val_if_fail (tree_view != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); if (tree_view->priv->selection == NULL) @@ -3985,7 +4003,6 @@ gtk_tree_view_get_selection (GtkTreeView *tree_view) GtkAdjustment * gtk_tree_view_get_hadjustment (GtkTreeView *tree_view) { - g_return_val_if_fail (tree_view != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); if (tree_view->priv->hadjustment == NULL) @@ -4005,7 +4022,6 @@ void gtk_tree_view_set_hadjustment (GtkTreeView *tree_view, GtkAdjustment *adjustment) { - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); gtk_tree_view_set_adjustments (tree_view, @@ -4027,7 +4043,6 @@ gtk_tree_view_set_hadjustment (GtkTreeView *tree_view, GtkAdjustment * gtk_tree_view_get_vadjustment (GtkTreeView *tree_view) { - g_return_val_if_fail (tree_view != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); if (tree_view->priv->vadjustment == NULL) @@ -4047,7 +4062,6 @@ void gtk_tree_view_set_vadjustment (GtkTreeView *tree_view, GtkAdjustment *adjustment) { - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); gtk_tree_view_set_adjustments (tree_view, @@ -4072,7 +4086,6 @@ gtk_tree_view_set_adjustments (GtkTreeView *tree_view, { gboolean need_adjust = FALSE; - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); if (hadj) @@ -4138,7 +4151,6 @@ gtk_tree_view_set_adjustments (GtkTreeView *tree_view, gboolean gtk_tree_view_get_headers_visible (GtkTreeView *tree_view) { - g_return_val_if_fail (tree_view != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE); return GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE); @@ -4159,7 +4171,6 @@ gtk_tree_view_set_headers_visible (GtkTreeView *tree_view, GList *list; GtkTreeViewColumn *column; - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); headers_visible = !! headers_visible; @@ -4220,7 +4231,6 @@ gtk_tree_view_columns_autosize (GtkTreeView *tree_view) GList *list; GtkTreeViewColumn *column; - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); for (list = tree_view->priv->columns; list; list = list->next) @@ -4249,7 +4259,6 @@ gtk_tree_view_set_headers_clickable (GtkTreeView *tree_view, { GList *list; - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); g_return_if_fail (tree_view->priv->model != NULL); @@ -4272,9 +4281,7 @@ gint gtk_tree_view_append_column (GtkTreeView *tree_view, GtkTreeViewColumn *column) { - g_return_val_if_fail (tree_view != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1); - g_return_val_if_fail (column != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), -1); g_return_val_if_fail (column->tree_view == NULL, -1); @@ -4295,16 +4302,13 @@ gint gtk_tree_view_remove_column (GtkTreeView *tree_view, GtkTreeViewColumn *column) { - g_return_val_if_fail (tree_view != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1); - g_return_val_if_fail (column != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), -1); g_return_val_if_fail (column->tree_view == GTK_WIDGET (tree_view), -1); _gtk_tree_view_column_unset_tree_view (column); - if (tree_view->priv->focus_column && - GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data) == column) + if (tree_view->priv->focus_column == column) tree_view->priv->focus_column = NULL; tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column); @@ -4351,9 +4355,7 @@ gtk_tree_view_insert_column (GtkTreeView *tree_view, GtkTreeViewColumn *column, gint position) { - g_return_val_if_fail (tree_view != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1); - g_return_val_if_fail (column != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), -1); g_return_val_if_fail (column->tree_view == NULL, -1); @@ -4416,7 +4418,6 @@ gtk_tree_view_insert_column_with_attributes (GtkTreeView *tree_view, va_list args; gint column_id; - g_return_val_if_fail (tree_view != NULL, -1); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1); column = gtk_tree_view_column_new (); @@ -4457,7 +4458,6 @@ GtkTreeViewColumn * gtk_tree_view_get_column (GtkTreeView *tree_view, gint n) { - g_return_val_if_fail (tree_view != NULL, NULL); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL); g_return_val_if_fail (tree_view->priv->model != NULL, NULL); @@ -4553,7 +4553,6 @@ gtk_tree_view_scroll_to_cell (GtkTreeView *tree_view, * we do incremental reflow for trees */ - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); g_return_if_fail (row_align >= 0.0); g_return_if_fail (row_align <= 1.0); @@ -5050,7 +5049,6 @@ gtk_tree_view_expand_all_helper (GtkRBTree *tree, void gtk_tree_view_expand_all (GtkTreeView *tree_view) { - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); g_return_if_fail (tree_view->priv->tree != NULL); @@ -5101,7 +5099,6 @@ gtk_tree_view_collapse_all_helper (GtkRBTree *tree, void gtk_tree_view_collapse_all (GtkTreeView *tree_view) { - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); g_return_if_fail (tree_view->priv->tree != NULL); @@ -5140,7 +5137,6 @@ gtk_tree_view_expand_row (GtkTreeView *tree_view, GtkRBTree *tree; GtkRBNode *node; - g_return_val_if_fail (tree_view != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE); g_return_val_if_fail (tree_view->priv->model != NULL, FALSE); g_return_val_if_fail (path != NULL, FALSE); @@ -5193,7 +5189,6 @@ gtk_tree_view_collapse_row (GtkTreeView *tree_view, GtkRBNode *node; GtkTreeIter iter; - g_return_val_if_fail (tree_view != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE); g_return_val_if_fail (tree_view->priv->tree != NULL, FALSE); g_return_val_if_fail (path != NULL, FALSE); @@ -5243,7 +5238,6 @@ gtk_tree_view_get_visible_rect (GtkTreeView *tree_view, { GtkWidget *widget; - g_return_if_fail (tree_view != NULL); g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); widget = GTK_WIDGET (tree_view); |