summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2001-03-23 00:35:19 +0000
committerJonathan Blandford <jrb@src.gnome.org>2001-03-23 00:35:19 +0000
commit21fd434c5f528546a35036b4cfce6a708a4c2762 (patch)
tree86ff9f050f2a04d6154d608e211c32b561f8ebfd /gtk
parent18b5348b4838c99b85f14e4f0e351facef26b261 (diff)
downloadgdk-pixbuf-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.am1
-rw-r--r--gtk/gtkcellrenderertoggle.c8
-rw-r--r--gtk/gtkliststore.c132
-rw-r--r--gtk/gtkliststore.h6
-rw-r--r--gtk/gtkmarshal.list1
-rw-r--r--gtk/gtkmarshalers.list1
-rw-r--r--gtk/gtktreedatalist.c108
-rw-r--r--gtk/gtktreedatalist.h12
-rw-r--r--gtk/gtktreemodel.c29
-rw-r--r--gtk/gtktreemodel.h3
-rw-r--r--gtk/gtktreeprivate.h3
-rw-r--r--gtk/gtktreesortable.c127
-rw-r--r--gtk/gtktreesortable.h53
-rw-r--r--gtk/gtktreestore.c205
-rw-r--r--gtk/gtktreestore.h1
-rw-r--r--gtk/gtktreeview.c108
16 files changed, 647 insertions, 151 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index a33192e88..8ed2d8d1a 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 c257db44f..6207968f3 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 480a9217e..92de43a1a 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 4406bd74b..5ab9a8d14 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 f193de669..26e90358f 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 f193de669..26e90358f 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 0c44dc708..0bf615266 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 3150b97bc..929439534 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 4848ad07c..f30fe8f60 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 9d3c5422f..4aaac7d83 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 8d519c38c..cc2f89dd3 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 000000000..b2833af60
--- /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 8c7ed59b9..85369b9bd 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 5b58ac3d4..a4cba08a8 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,
&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)
{
diff --git a/gtk/gtktreestore.h b/gtk/gtktreestore.h
index 87a9413f5..d38ca5a55 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 3c24a4c51..761ab3b64 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);