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.
This commit is contained in:
Jonathan Blandford 2001-03-23 00:35:19 +00:00 committed by Jonathan Blandford
parent 18b5348b48
commit 21fd434c5f
23 changed files with 772 additions and 150 deletions

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -1,3 +1,21 @@
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.
2001-03-22 Havoc Pennington <hp@redhat.com>
* gtk/gtkcontainer.c (gtk_container_set_focus_chain):

View File

@ -344,6 +344,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtktreemodel.c \
gtktreemodelsort.c \
gtktreeselection.c \
gtktreesortable.c \
gtktreestore.c \
gtktreeview.c \
gtktreeviewcolumn.c \

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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

View File

@ -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);

View File

@ -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;

127
gtk/gtktreesortable.c Normal file
View File

@ -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);
}

View File

@ -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);
/* signals */
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);
/* 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
}

View File

@ -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,
&copy,
dest_iter);
recursive_node_copy (tree_store, &child, &copy);
}
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)
{

View File

@ -40,6 +40,7 @@ struct _GtkTreeStore
{
GObject parent;
GList *sort_list;
gint stamp;
gpointer root;
gpointer last;

View File

@ -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);