added more fields to allow more interesting iterators. Also, made the
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to allow more interesting iterators. Also, made the lifecycle of iterators more explicit. * gtk/gtktreemodelsort.[ch]: New model for sorting. * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed types.
This commit is contained in:

committed by
Jonathan Blandford

parent
8898529c12
commit
c97d57ebb8
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -1,3 +1,14 @@
|
||||
Thu Nov 9 11:23:22 2000 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
|
||||
allow more interesting iterators. Also, made the lifecycle of
|
||||
iterators more explicit.
|
||||
|
||||
* gtk/gtktreemodelsort.[ch]: New model for sorting.
|
||||
|
||||
* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
|
||||
types.
|
||||
|
||||
2000-11-09 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* demos/testgtk/menus.c:
|
||||
|
@ -242,7 +242,7 @@ selection_cb (GtkTreeSelection *selection,
|
||||
GtkTreeIter iter;
|
||||
GValue value = {0, };
|
||||
|
||||
if (! gtk_tree_selection_get_selected (selection, &iter))
|
||||
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get_value (model, &iter,
|
||||
|
@ -242,7 +242,7 @@ selection_cb (GtkTreeSelection *selection,
|
||||
GtkTreeIter iter;
|
||||
GValue value = {0, };
|
||||
|
||||
if (! gtk_tree_selection_get_selected (selection, &iter))
|
||||
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get_value (model, &iter,
|
||||
|
@ -171,6 +171,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
|
||||
gtktree.h \
|
||||
gtktreeitem.h \
|
||||
gtktreemodel.h \
|
||||
gtktreemodelsort.h \
|
||||
gtktreeselection.h \
|
||||
gtktreestore.h \
|
||||
gtktreeview.h \
|
||||
@ -329,6 +330,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
|
||||
gtktreeitem.c \
|
||||
gtktreedatalist.c \
|
||||
gtktreemodel.c \
|
||||
gtktreemodelsort.c \
|
||||
gtktreeselection.c \
|
||||
gtktreestore.c \
|
||||
gtktreeview.c \
|
||||
|
@ -1286,6 +1286,15 @@
|
||||
gtk_text_iter_copy
|
||||
gtk_text_iter_free)
|
||||
|
||||
;; TreeView
|
||||
(define-boxed GtkTreeIter
|
||||
gtk_tree_iter_copy
|
||||
gtk_tree_iter_free)
|
||||
|
||||
(define-boxed GtkTreePath
|
||||
gtk_tree_path_copy
|
||||
gtk_tree_path_free)
|
||||
|
||||
;; Alignment
|
||||
|
||||
(define-object GtkAlignment (GtkBin))
|
||||
|
@ -141,6 +141,7 @@
|
||||
#include <gtk/gtktree.h>
|
||||
#include <gtk/gtktreeitem.h>
|
||||
#include <gtk/gtktreemodel.h>
|
||||
#include <gtk/gtktreemodelsort.h>
|
||||
#include <gtk/gtktreeselection.h>
|
||||
#include <gtk/gtktreestore.h>
|
||||
#include <gtk/gtktreeview.h>
|
||||
|
@ -38,6 +38,7 @@ static guint list_store_signals[LAST_SIGNAL] = { 0 };
|
||||
static void gtk_list_store_init (GtkListStore *list_store);
|
||||
static void gtk_list_store_class_init (GtkListStoreClass *class);
|
||||
static void gtk_list_store_tree_model_init (GtkTreeModelIface *iface);
|
||||
static guint gtk_list_store_get_flags (GtkTreeModel *tree_model);
|
||||
static gint gtk_list_store_get_n_columns (GtkTreeModel *tree_model);
|
||||
static gboolean gtk_list_store_get_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
@ -152,6 +153,7 @@ gtk_list_store_class_init (GtkListStoreClass *class)
|
||||
static void
|
||||
gtk_list_store_tree_model_init (GtkTreeModelIface *iface)
|
||||
{
|
||||
iface->get_flags = gtk_list_store_get_flags;
|
||||
iface->get_n_columns = gtk_list_store_get_n_columns;
|
||||
iface->get_iter = gtk_list_store_get_iter;
|
||||
iface->get_path = gtk_list_store_get_path;
|
||||
@ -168,7 +170,7 @@ static void
|
||||
gtk_list_store_init (GtkListStore *list_store)
|
||||
{
|
||||
list_store->root = NULL;
|
||||
list_store->stamp = 1;
|
||||
list_store->stamp = g_random_int ();
|
||||
}
|
||||
|
||||
GtkListStore *
|
||||
@ -242,6 +244,14 @@ gtk_list_store_set_column_type (GtkListStore *list_store,
|
||||
}
|
||||
|
||||
/* Fulfill the GtkTreeModel requirements */
|
||||
static guint
|
||||
gtk_list_store_get_flags (GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), 0);
|
||||
|
||||
return GTK_TREE_MODEL_ITERS_PERSIST;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_list_store_get_n_columns (GtkTreeModel *tree_model)
|
||||
{
|
||||
@ -350,6 +360,9 @@ static gint
|
||||
gtk_list_store_iter_n_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
if (iter == NULL)
|
||||
return g_slist_length (G_SLIST (GTK_LIST_STORE (tree_model)->root));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ gtk_tree_path_free (GtkTreePath *path)
|
||||
* gtk_tree_path_copy:
|
||||
* @path: A #GtkTreePath.
|
||||
*
|
||||
* Creates a new #GtkTreePath based upon @path.
|
||||
* Creates a new #GtkTreePath as a copy of @path.
|
||||
*
|
||||
* Return value: A new #GtkTreePath.
|
||||
**/
|
||||
@ -381,6 +381,69 @@ gtk_tree_path_down (GtkTreePath *path)
|
||||
gtk_tree_path_append_index (path, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_tree_iter_copy:
|
||||
* @iter: A #GtkTreeIter.
|
||||
*
|
||||
* Creates a dynamically allocated tree iterator as a copy of @iter. This
|
||||
* function is not intended for use in applications, because you can just copy
|
||||
* the structs by value (<literal>GtkTreeIter new_iter = iter;</literal>). You
|
||||
* must free this iter with gtk_tree_iter_free ().
|
||||
*
|
||||
* Return value: a newly allocated copy of @iter.
|
||||
**/
|
||||
GtkTreeIter *
|
||||
gtk_tree_iter_copy (GtkTreeIter *iter)
|
||||
{
|
||||
GtkTreeIter *retval;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, NULL);
|
||||
|
||||
retval = g_new (GtkTreeIter, 1);
|
||||
*retval = *iter;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_iter_free:
|
||||
* @iter: A dynamically allocated tree iterator.
|
||||
*
|
||||
* Free an iterator that has been allocated on the heap. This function is
|
||||
* mainly used for language bindings.
|
||||
**/
|
||||
void
|
||||
gtk_tree_iter_free (GtkTreeIter *iter)
|
||||
{
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
g_free (iter);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_get_flags:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
*
|
||||
* Returns a list of flags supported by this interface. The flags are a bitwise
|
||||
* combination of #GtkTreeModelFlags. It is expected that the flags supported
|
||||
* do not change for an interface.
|
||||
*
|
||||
* Return value: The flags supported by this interface.
|
||||
**/
|
||||
guint
|
||||
gtk_tree_model_get_flags (GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail (tree_model != NULL, 0);
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
|
||||
|
||||
if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags)
|
||||
return (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags) (tree_model);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_get_n_columns:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
@ -399,6 +462,27 @@ gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
|
||||
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns) (tree_model);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_get_column_type:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
* @index: The column index.
|
||||
*
|
||||
* Returns the type of the column.
|
||||
*
|
||||
* Return value: The type of the column.
|
||||
**/
|
||||
GType
|
||||
gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
|
||||
gint index)
|
||||
{
|
||||
g_return_val_if_fail (tree_model != NULL, G_TYPE_INVALID);
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type != NULL, G_TYPE_INVALID);
|
||||
g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
|
||||
|
||||
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type) (tree_model, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_get_iter:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
@ -564,9 +648,10 @@ gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
|
||||
/**
|
||||
* gtk_tree_model_iter_n_children:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
* @iter: The #GtkTreeIter.
|
||||
* @iter: The #GtkTreeIter, or NULL.
|
||||
*
|
||||
* Returns the number of children that @iter has.
|
||||
* Returns the number of children that @iter has. If @iter is NULL, then the
|
||||
* number of toplevel nodes is returned.
|
||||
*
|
||||
* Return value: The number of children of @iter.
|
||||
**/
|
||||
@ -576,7 +661,6 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
|
||||
{
|
||||
g_return_val_if_fail (tree_model != NULL, 0);
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children != NULL, 0);
|
||||
|
||||
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children) (tree_model, iter);
|
||||
@ -589,10 +673,11 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
|
||||
* @parent: The #GtkTreeIter to get the child from, or NULL.
|
||||
* @n: Then index of the desired child.
|
||||
*
|
||||
* Sets @iter to be the child of @parent, using the given index. The first index
|
||||
* is 0. If the index is too big, or @parent has no children, @iter is set to an
|
||||
* invalid iterator and FALSE is returned. @parent will remain a valid node after
|
||||
* this function has been called. If @parent is NULL, then the root node is assumed.
|
||||
* Sets @iter to be the child of @parent, using the given index. The first
|
||||
* index is 0. If the index is too big, or @parent has no children, @iter is
|
||||
* set to an invalid iterator and FALSE is returned. @parent will remain a
|
||||
* valid node after this function has been called. If @parent is NULL, then the
|
||||
* root node is assumed.
|
||||
*
|
||||
* Return value: TRUE, if @parent has an nth child.
|
||||
**/
|
||||
@ -629,8 +714,51 @@ gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child)
|
||||
{
|
||||
g_return_val_if_fail (tree_model != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
g_return_val_if_fail (child != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent != NULL, FALSE);
|
||||
|
||||
return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent) (tree_model, iter, child);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_ref_iter:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
* @iter: The #GtkTreeIter.
|
||||
*
|
||||
* Ref's the iter. This is an optional method for models to implement. To be
|
||||
* more specific, models may ignore this call as it exists primarily for
|
||||
* performance reasons.
|
||||
**/
|
||||
void
|
||||
gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
g_return_if_fail (tree_model != NULL);
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
|
||||
|
||||
if (GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter)
|
||||
(* GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter) (tree_model, iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_unref_iter:
|
||||
* @tree_model: A #GtkTreeModel.
|
||||
* @iter: The #GtkTreeIter.
|
||||
*
|
||||
* Unref's the iter. This is an optional method for models to implement. To be
|
||||
* more specific, models may ignore this call as it exists primarily for
|
||||
* performance reasons.
|
||||
**/
|
||||
void
|
||||
gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
g_return_if_fail (tree_model != NULL);
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
|
||||
|
||||
if (GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter)
|
||||
(* GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter) (tree_model, iter);
|
||||
}
|
||||
|
@ -37,10 +37,18 @@ typedef struct _GtkTreePath GtkTreePath;
|
||||
typedef struct _GtkTreeModel GtkTreeModel; /* Dummy typedef */
|
||||
typedef struct _GtkTreeModelIface GtkTreeModelIface;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_TREE_MODEL_ITERS_PERSIST = 1 << 0
|
||||
} GtkTreeModelFlags;
|
||||
|
||||
struct _GtkTreeIter
|
||||
{
|
||||
gint stamp;
|
||||
gpointer tree_node;
|
||||
gpointer tree_node2;
|
||||
gpointer tree_node3;
|
||||
};
|
||||
|
||||
struct _GtkTreeModelIface
|
||||
@ -65,6 +73,7 @@ struct _GtkTreeModelIface
|
||||
GtkTreePath *path);
|
||||
|
||||
/* VTable - not signals */
|
||||
guint (* get_flags) (GtkTreeModel *tree_model);
|
||||
gint (* get_n_columns) (GtkTreeModel *tree_model);
|
||||
GType (* get_column_type) (GtkTreeModel *tree_model,
|
||||
gint index);
|
||||
@ -93,10 +102,14 @@ struct _GtkTreeModelIface
|
||||
gboolean (* iter_parent) (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child);
|
||||
void (* ref_iter) (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
void (* unref_iter) (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
};
|
||||
|
||||
|
||||
/* Path operations */
|
||||
/* GtkTreePath operations */
|
||||
GtkTreePath *gtk_tree_path_new (void);
|
||||
GtkTreePath *gtk_tree_path_new_from_string (gchar *path);
|
||||
gchar *gtk_tree_path_to_string (GtkTreePath *path);
|
||||
@ -117,9 +130,13 @@ gint gtk_tree_path_up (GtkTreePath *path);
|
||||
void gtk_tree_path_down (GtkTreePath *path);
|
||||
|
||||
|
||||
/* GtkTreeIter operations */
|
||||
GtkTreeIter *gtk_tree_iter_copy (GtkTreeIter *iter);
|
||||
void gtk_tree_iter_free (GtkTreeIter *iter);
|
||||
|
||||
/* GtkTreeModel stuff */
|
||||
GtkType gtk_tree_model_get_type (void) G_GNUC_CONST;
|
||||
|
||||
guint gtk_tree_model_get_flags (GtkTreeModel *tree_model);
|
||||
|
||||
/* Column information */
|
||||
gint gtk_tree_model_get_n_columns (GtkTreeModel *tree_model);
|
||||
@ -153,7 +170,10 @@ gboolean gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
|
||||
gboolean gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child);
|
||||
|
||||
void gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
void gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
897
gtk/gtktreemodelsort.c
Normal file
897
gtk/gtktreemodelsort.c
Normal file
@ -0,0 +1,897 @@
|
||||
/* gtktreemodelsort.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 "gtktreemodelsort.h"
|
||||
#include "gtksignal.h"
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
INSERTED,
|
||||
CHILD_TOGGLED,
|
||||
DELETED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
typedef struct _SortElt SortElt;
|
||||
struct _SortElt
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
SortElt *parent;
|
||||
GArray *children;
|
||||
gint ref;
|
||||
gint offset;
|
||||
};
|
||||
|
||||
static guint tree_model_sort_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
#define get_array(e,t) ((GArray *)((e)->parent?(e)->parent->children:GTK_TREE_MODEL_SORT(t)->root))
|
||||
|
||||
static void gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort);
|
||||
static void gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class);
|
||||
static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
|
||||
static void gtk_tree_model_sort_finalize (GObject *object);
|
||||
static void gtk_tree_model_sort_changed (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
static void gtk_tree_model_sort_inserted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
static void gtk_tree_model_sort_child_toggled (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
static void gtk_tree_model_sort_deleted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
gpointer data);
|
||||
static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
|
||||
static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
|
||||
gint index);
|
||||
static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *path);
|
||||
static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
gint column,
|
||||
GValue *value);
|
||||
static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent);
|
||||
static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent,
|
||||
gint n);
|
||||
static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child);
|
||||
static void gtk_tree_model_sort_ref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
static void gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
/* Internal functions */
|
||||
static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
|
||||
SortElt *place);
|
||||
static void gtk_tree_model_sort_free_level (GArray *array);
|
||||
gint g_value_string_compare_func (const GValue *a,
|
||||
const GValue *b);
|
||||
gint g_value_int_compare_func (const GValue *a,
|
||||
const GValue *b);
|
||||
|
||||
|
||||
GtkType
|
||||
gtk_tree_model_sort_get_type (void)
|
||||
{
|
||||
static GtkType tree_model_sort_type = 0;
|
||||
|
||||
if (!tree_model_sort_type)
|
||||
{
|
||||
static const GTypeInfo tree_model_sort_info =
|
||||
{
|
||||
sizeof (GtkTreeModelSortClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) gtk_tree_model_sort_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkTreeModelSort),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gtk_tree_model_sort_init
|
||||
};
|
||||
|
||||
static const GInterfaceInfo tree_model_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
tree_model_sort_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeModelSort", &tree_model_sort_info, 0);
|
||||
g_type_add_interface_static (tree_model_sort_type,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
&tree_model_info);
|
||||
}
|
||||
|
||||
return tree_model_sort_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = (GObjectClass *) tree_model_sort_class;
|
||||
|
||||
tree_model_sort_signals[CHANGED] =
|
||||
gtk_signal_new ("changed",
|
||||
GTK_RUN_FIRST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, changed),
|
||||
gtk_marshal_VOID__POINTER_POINTER,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_TYPE_POINTER);
|
||||
tree_model_sort_signals[INSERTED] =
|
||||
gtk_signal_new ("inserted",
|
||||
GTK_RUN_FIRST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, inserted),
|
||||
gtk_marshal_VOID__POINTER_POINTER,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_TYPE_POINTER);
|
||||
tree_model_sort_signals[CHILD_TOGGLED] =
|
||||
gtk_signal_new ("child_toggled",
|
||||
GTK_RUN_FIRST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, child_toggled),
|
||||
gtk_marshal_VOID__POINTER_POINTER,
|
||||
GTK_TYPE_NONE, 2,
|
||||
GTK_TYPE_POINTER,
|
||||
GTK_TYPE_POINTER);
|
||||
tree_model_sort_signals[DELETED] =
|
||||
gtk_signal_new ("deleted",
|
||||
GTK_RUN_FIRST,
|
||||
GTK_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, deleted),
|
||||
gtk_marshal_VOID__POINTER,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_POINTER);
|
||||
|
||||
object_class->finalize = gtk_tree_model_sort_finalize;
|
||||
|
||||
gtk_object_class_add_signals (GTK_OBJECT_CLASS (object_class), tree_model_sort_signals, LAST_SIGNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
|
||||
{
|
||||
iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
|
||||
iface->get_column_type = gtk_tree_model_sort_get_column_type;
|
||||
iface->get_iter = gtk_tree_model_sort_get_iter;
|
||||
iface->get_path = gtk_tree_model_sort_get_path;
|
||||
iface->get_value = gtk_tree_model_sort_get_value;
|
||||
iface->iter_next = gtk_tree_model_sort_iter_next;
|
||||
iface->iter_children = gtk_tree_model_sort_iter_children;
|
||||
iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
|
||||
iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
|
||||
iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
|
||||
iface->iter_parent = gtk_tree_model_sort_iter_parent;
|
||||
iface->ref_iter = gtk_tree_model_sort_ref_iter;
|
||||
iface->unref_iter = gtk_tree_model_sort_unref_iter;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
|
||||
{
|
||||
tree_model_sort->stamp = g_random_int ();
|
||||
}
|
||||
|
||||
GtkTreeModel *
|
||||
gtk_tree_model_sort_new (void)
|
||||
{
|
||||
return GTK_TREE_MODEL (gtk_type_new (gtk_tree_model_sort_get_type ()));
|
||||
}
|
||||
|
||||
GtkTreeModel *
|
||||
gtk_tree_model_sort_new_with_model (GtkTreeModel *model,
|
||||
GValueCompareFunc *func,
|
||||
gint sort_col)
|
||||
{
|
||||
GtkTreeModel *retval;
|
||||
|
||||
retval = gtk_tree_model_sort_new ();
|
||||
gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), model);
|
||||
|
||||
GTK_TREE_MODEL_SORT (retval)->func = func;
|
||||
GTK_TREE_MODEL_SORT (retval)->sort_col = sort_col;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_sort_set_model:
|
||||
* @tree_model_sort: The #GtkTreeModelSort.
|
||||
* @model: A #GtkTreeModel, or NULL.
|
||||
*
|
||||
* Sets the model of @tree_model_sort to be @model. If @model is NULL, then the
|
||||
* old model is unset.
|
||||
**/
|
||||
void
|
||||
gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
g_return_if_fail (tree_model_sort != NULL);
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
|
||||
|
||||
if (model)
|
||||
g_object_ref (G_OBJECT (model));
|
||||
|
||||
if (tree_model_sort->model)
|
||||
{
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
|
||||
gtk_tree_model_sort_changed,
|
||||
tree_model_sort);
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
|
||||
gtk_tree_model_sort_inserted,
|
||||
tree_model_sort);
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
|
||||
gtk_tree_model_sort_child_toggled,
|
||||
tree_model_sort);
|
||||
gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
|
||||
gtk_tree_model_sort_deleted,
|
||||
tree_model_sort);
|
||||
|
||||
g_object_unref (G_OBJECT (tree_model_sort->model));
|
||||
}
|
||||
|
||||
tree_model_sort->model = model;
|
||||
|
||||
if (model)
|
||||
{
|
||||
gtk_signal_connect (GTK_OBJECT (model),
|
||||
"changed",
|
||||
gtk_tree_model_sort_changed,
|
||||
tree_model_sort);
|
||||
gtk_signal_connect (GTK_OBJECT (model),
|
||||
"inserted",
|
||||
gtk_tree_model_sort_inserted,
|
||||
tree_model_sort);
|
||||
gtk_signal_connect (GTK_OBJECT (model),
|
||||
"child_toggled",
|
||||
gtk_tree_model_sort_child_toggled,
|
||||
tree_model_sort);
|
||||
gtk_signal_connect (GTK_OBJECT (model),
|
||||
"deleted",
|
||||
gtk_tree_model_sort_deleted,
|
||||
tree_model_sort);
|
||||
|
||||
tree_model_sort->flags = gtk_tree_model_get_flags (model);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_model_sort_convert_path:
|
||||
* @tree_model_sort: The #GtkTreeModelSort.
|
||||
* @path: A #GtkTreePath, relative to the @tree_model_sort 's model.
|
||||
*
|
||||
* Converts the @path to a new path, relative to the sorted position. In other
|
||||
* words, the value found in the @tree_model_sort ->model at the @path, is
|
||||
* identical to that found in the @tree_model_sort and the return value.
|
||||
*
|
||||
* Return value: A new path, or NULL if @path does not exist in @tree_model_sort
|
||||
* ->model.
|
||||
**/
|
||||
GtkTreePath *
|
||||
gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GtkTreePath *retval;
|
||||
GArray *array;
|
||||
gint *indices;
|
||||
gint i = 0;
|
||||
|
||||
if (tree_model_sort->root == NULL)
|
||||
gtk_tree_model_sort_build_level (tree_model_sort, NULL);
|
||||
|
||||
retval = gtk_tree_path_new ();
|
||||
array = (GArray *) tree_model_sort->root;
|
||||
indices = gtk_tree_path_get_indices (path);
|
||||
|
||||
do
|
||||
{
|
||||
SortElt *elt;
|
||||
gboolean found = FALSE;
|
||||
gint j;
|
||||
|
||||
if ((array->len < indices[i]) || (array == NULL))
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
elt = (SortElt *) array->data;
|
||||
for (j = 0; j < array->len; j++, elt++)
|
||||
{
|
||||
if (elt->offset == indices[i])
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! found)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_tree_path_prepend_index (retval, j);
|
||||
if (elt->children == NULL)
|
||||
gtk_tree_model_sort_build_level (tree_model_sort, elt);
|
||||
i++;
|
||||
}
|
||||
while (i < gtk_tree_path_get_depth (path));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_finalize (GObject *object)
|
||||
{
|
||||
GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
|
||||
|
||||
if (tree_model_sort->root)
|
||||
gtk_tree_model_sort_free_level (tree_model_sort->root);
|
||||
|
||||
g_object_unref (G_OBJECT (tree_model_sort->model));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_changed (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
|
||||
GtkTreePath *local_path;
|
||||
GtkTreeIter local_iter;
|
||||
|
||||
g_return_if_fail (path != NULL || iter != NULL);
|
||||
|
||||
if (path == NULL)
|
||||
path = gtk_tree_model_get_path (model, iter);
|
||||
|
||||
local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (data),
|
||||
"changed",
|
||||
local_path,
|
||||
&local_iter);
|
||||
gtk_tree_path_free (local_path);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
|
||||
GtkTreeIter *old_iter,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GtkTreePath *parent_path;
|
||||
GArray *array;
|
||||
GtkTreeIter iter;
|
||||
SortElt new_elt;
|
||||
SortElt *tmp_elt;
|
||||
gint high, low, middle;
|
||||
GValueCompareFunc *func;
|
||||
GValue tmp_value = {0, };
|
||||
GValue old_value = {0, };
|
||||
|
||||
parent_path = gtk_tree_path_copy (path);
|
||||
gtk_tree_path_up (parent_path);
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (sort),
|
||||
&iter,
|
||||
parent_path);
|
||||
gtk_tree_path_free (parent_path);
|
||||
array = ((SortElt *) iter.tree_node)->children;
|
||||
|
||||
if (sort->func)
|
||||
func = sort->func;
|
||||
else
|
||||
{
|
||||
switch (gtk_tree_model_get_column_type (sort->model, sort->sort_col))
|
||||
{
|
||||
case G_TYPE_STRING:
|
||||
func = &g_value_string_compare_func;
|
||||
break;
|
||||
case G_TYPE_INT:
|
||||
func = &g_value_int_compare_func;
|
||||
break;
|
||||
default:
|
||||
g_warning ("No comparison function for row %d\n", sort->sort_col);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
new_elt.iter = iter;
|
||||
new_elt.ref = 0;
|
||||
new_elt.parent = ((SortElt *) iter.tree_node);
|
||||
new_elt.children = NULL;
|
||||
|
||||
last = 0;
|
||||
j = array->len/2;
|
||||
while (1)
|
||||
{
|
||||
gint cmp;
|
||||
tmp_elt = &(g_array_index (array, SortElt, j));
|
||||
gtk_tree_model_get_value (sort->model, tmp_elt, sort->sort_col, &tmp_value);
|
||||
|
||||
cmp = ((func) (&tmp_value, value));
|
||||
if (retval < 0)
|
||||
;
|
||||
else if (retval == 0)
|
||||
g_array_insert_vals
|
||||
;
|
||||
else if (retval > 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_inserted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
|
||||
GtkTreePath *local_path;
|
||||
GtkTreeIter local_iter;
|
||||
GValue value;
|
||||
|
||||
g_return_if_fail (path != NULL || iter != NULL);
|
||||
|
||||
if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
|
||||
(tree_model_sort->root != NULL))
|
||||
{
|
||||
gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
|
||||
tree_model_sort->root = NULL;
|
||||
}
|
||||
|
||||
if (path == NULL)
|
||||
path = gtk_tree_model_get_path (model, iter);
|
||||
|
||||
local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (data),
|
||||
"inserted",
|
||||
local_path,
|
||||
&local_iter);
|
||||
gtk_tree_path_free (local_path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_child_toggled (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
|
||||
GtkTreePath *local_path;
|
||||
GtkTreeIter local_iter;
|
||||
|
||||
g_return_if_fail (path != NULL || iter != NULL);
|
||||
|
||||
if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
|
||||
(tree_model_sort->root != NULL))
|
||||
{
|
||||
gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
|
||||
tree_model_sort->root = NULL;
|
||||
}
|
||||
|
||||
if (path == NULL)
|
||||
path = gtk_tree_model_get_path (model, iter);
|
||||
|
||||
local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (data),
|
||||
"child_toggled",
|
||||
local_path,
|
||||
&local_iter);
|
||||
gtk_tree_path_free (local_path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_deleted (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
|
||||
GtkTreePath *local_path;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
|
||||
(tree_model_sort->root != NULL))
|
||||
{
|
||||
gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
|
||||
tree_model_sort->root = NULL;
|
||||
}
|
||||
local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
|
||||
tree_model_sort->stamp++;
|
||||
gtk_signal_emit_by_name (GTK_OBJECT (data),
|
||||
"deleted",
|
||||
local_path);
|
||||
|
||||
gtk_tree_path_free (local_path);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
|
||||
|
||||
return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->model);
|
||||
}
|
||||
|
||||
static GType
|
||||
gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
|
||||
gint index)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, G_TYPE_INVALID);
|
||||
|
||||
return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->model, index);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
|
||||
GArray *array,
|
||||
GtkTreeIter *iter,
|
||||
gint depth,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
if (array == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_tree_path_get_indices (path)[depth] > array->len)
|
||||
return FALSE;
|
||||
|
||||
elt = & (g_array_index (array, SortElt, gtk_tree_path_get_indices (path)[depth]));
|
||||
|
||||
if (depth == gtk_tree_path_get_depth (path) - 1)
|
||||
{
|
||||
iter->stamp = tree_model_sort->stamp;
|
||||
iter->tree_node = elt;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (elt->children != NULL)
|
||||
return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
|
||||
elt->children,
|
||||
iter,
|
||||
depth + 1,
|
||||
path);
|
||||
|
||||
if (gtk_tree_model_iter_has_child (tree_model_sort->model,
|
||||
&(elt->iter)))
|
||||
|
||||
gtk_tree_model_sort_build_level (tree_model_sort, elt);
|
||||
|
||||
return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
|
||||
elt->children,
|
||||
iter,
|
||||
depth + 1,
|
||||
path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
|
||||
if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
|
||||
gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
|
||||
|
||||
return gtk_tree_model_sort_get_iter_helper (GTK_TREE_MODEL_SORT (tree_model),
|
||||
GTK_TREE_MODEL_SORT (tree_model)->root,
|
||||
iter, 0, path);
|
||||
}
|
||||
|
||||
static GtkTreePath *
|
||||
gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, NULL);
|
||||
|
||||
return gtk_tree_model_get_path (GTK_TREE_MODEL_SORT (tree_model)->model, iter);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
gint column,
|
||||
GValue *value)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
|
||||
g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL);
|
||||
g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
|
||||
|
||||
elt = iter->tree_node;
|
||||
|
||||
gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt, column, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GArray *array;
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
|
||||
|
||||
elt = iter->tree_node;
|
||||
array = get_array (elt, tree_model);
|
||||
|
||||
if (elt - ((SortElt*) array->data) >= array->len - 1)
|
||||
{
|
||||
iter->stamp = 0;
|
||||
return FALSE;
|
||||
}
|
||||
iter->tree_node = elt+1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
if (parent)
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
|
||||
|
||||
if (parent)
|
||||
elt = parent->tree_node;
|
||||
else
|
||||
elt = (SortElt *) ((GArray *)GTK_TREE_MODEL_SORT (tree_model)->root)->data;
|
||||
|
||||
if (elt == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (elt->children == NULL &&
|
||||
gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
|
||||
gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
|
||||
|
||||
if (elt->children == NULL)
|
||||
return FALSE;
|
||||
|
||||
iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
|
||||
iter->tree_node = elt->children->data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
|
||||
|
||||
elt = iter->tree_node;
|
||||
if (elt->children)
|
||||
return TRUE;
|
||||
|
||||
return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
|
||||
|
||||
elt = iter->tree_node;
|
||||
if (elt->children)
|
||||
return elt->children->len;
|
||||
|
||||
return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent,
|
||||
gint n)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
if (parent)
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
|
||||
|
||||
elt = iter->tree_node;
|
||||
|
||||
|
||||
if (elt->children == NULL)
|
||||
{
|
||||
if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
|
||||
gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (elt->children == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (n >= elt->children->len)
|
||||
return FALSE;
|
||||
|
||||
iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
|
||||
iter->tree_node = &g_array_index (elt->children, SortElt, n);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
|
||||
|
||||
elt = iter->tree_node;
|
||||
if (elt->parent)
|
||||
{
|
||||
iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
|
||||
iter->tree_node = elt->parent;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_ref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Internal functions */
|
||||
static void
|
||||
gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
|
||||
SortElt *place)
|
||||
{
|
||||
gint n, i;
|
||||
GArray *children;
|
||||
GtkTreeIter *parent_iter = NULL;
|
||||
GtkTreeIter iter;
|
||||
SortElt elt;
|
||||
|
||||
if (place)
|
||||
parent_iter = & (place->iter);
|
||||
|
||||
|
||||
n = gtk_tree_model_iter_n_children (tree_model_sort->model, parent_iter);
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), n);
|
||||
|
||||
if (place)
|
||||
place->children = children;
|
||||
else
|
||||
tree_model_sort->root = children;
|
||||
|
||||
gtk_tree_model_iter_children (tree_model_sort->model,
|
||||
&iter,
|
||||
parent_iter);
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
elt.iter = iter;
|
||||
elt.parent = place;
|
||||
elt.children = NULL;
|
||||
elt.ref = 0;
|
||||
elt.offset = i;
|
||||
|
||||
g_array_append_vals (children, &elt, 1);
|
||||
i++;
|
||||
}
|
||||
while (gtk_tree_model_iter_next (tree_model_sort->model, &iter));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_model_sort_free_level (GArray *array)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < array->len; i++)
|
||||
{
|
||||
SortElt *elt;
|
||||
|
||||
elt = &g_array_index (array, SortElt, i);
|
||||
if (elt->children)
|
||||
gtk_tree_model_sort_free_level (array);
|
||||
}
|
||||
|
||||
g_array_free (array, TRUE);
|
||||
}
|
||||
|
||||
gint
|
||||
g_value_string_compare_func (const GValue *a,
|
||||
const GValue *b)
|
||||
{
|
||||
return strcmp (g_value_get_string (a),
|
||||
g_value_get_string (b));
|
||||
}
|
||||
|
||||
gint
|
||||
g_value_int_compare_func (const GValue *a,
|
||||
const GValue *b)
|
||||
{
|
||||
return g_value_get_int (a) < g_value_get_int (b);
|
||||
}
|
94
gtk/gtktreemodelsort.h
Normal file
94
gtk/gtktreemodelsort.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* gtktreemodelsort.h
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TREE_MODEL_SORT_H__
|
||||
#define __GTK_TREE_MODEL_SORT_H__
|
||||
|
||||
#include <gtk/gtktreemodel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define GTK_TYPE_TREE_MODEL_SORT (gtk_tree_model_sort_get_type ())
|
||||
#define GTK_TREE_MODEL_SORT(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSort))
|
||||
#define GTK_TREE_MODEL_SORT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSortClass))
|
||||
#define GTK_IS_TREE_MODEL_SORT(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
|
||||
#define GTK_IS_TREE_MODEL_SORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
|
||||
|
||||
typedef struct _GtkTreeModelSort GtkTreeModelSort;
|
||||
typedef struct _GtkTreeModelSortClass GtkTreeModelSortClass;
|
||||
|
||||
typedef gint (* GValueCompareFunc) (const GValue *a,
|
||||
const GValue *b);
|
||||
|
||||
struct _GtkTreeModelSort
|
||||
{
|
||||
GtkObject parent;
|
||||
|
||||
/* < private > */
|
||||
gpointer root;
|
||||
gint stamp;
|
||||
guint flags;
|
||||
GtkTreeModel *model;
|
||||
gint sort_col;
|
||||
GValueCompareFunc *func;
|
||||
};
|
||||
|
||||
struct _GtkTreeModelSortClass
|
||||
{
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
/* Will be moved into the GtkTreeModelIface eventually */
|
||||
void (* changed) (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter);
|
||||
void (* inserted) (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter);
|
||||
void (* child_toggled) (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter);
|
||||
void (* deleted) (GtkTreeModel *tree_model,
|
||||
GtkTreePath *path);
|
||||
};
|
||||
|
||||
|
||||
GtkType gtk_tree_model_sort_get_type (void);
|
||||
GtkTreeModel *gtk_tree_model_sort_new (void);
|
||||
GtkTreeModel *gtk_tree_model_sort_new_with_model (GtkTreeModel *model,
|
||||
GValueCompareFunc *func,
|
||||
gint sort_col);
|
||||
void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
|
||||
GtkTreeModel *model);
|
||||
void gtk_tree_model_sort_set_sort_col (GtkTreeModelSort *tree_model_sort,
|
||||
gint sort_col);
|
||||
void gtk_tree_model_sort_set_compare (GtkTreeModelSort *tree_model_sort,
|
||||
GValueCompareFunc *func);
|
||||
void gtk_tree_model_sort_resort (GtkTreeModelSort *tree_model_sort);
|
||||
GtkTreePath *gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
|
||||
GtkTreePath *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __GTK_TREE_MODEL_SORT_H__ */
|
@ -241,17 +241,20 @@ gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
|
||||
/**
|
||||
* gtk_tree_selection_get_selected:
|
||||
* @selection: A #GtkTreeSelection.
|
||||
* @model: A pointer set to the #GtkTreeModel, or NULL.
|
||||
* @iter: The #GtkTreeIter, or NULL.
|
||||
*
|
||||
* Sets @iter to the currently selected node if @selection is set to
|
||||
* #GTK_TREE_SELECTION_SINGLE. Otherwise, it uses the anchor. @iter may be
|
||||
* NULL if you just want to test if @selection has any selected nodes.
|
||||
* NULL if you just want to test if @selection has any selected nodes. @model
|
||||
* is filled with the current model as a convenience.
|
||||
*
|
||||
* Return value: TRUE, if there is a selected node.
|
||||
**/
|
||||
gboolean
|
||||
gtk_tree_selection_get_selected (GtkTreeSelection *selection,
|
||||
GtkTreeIter *iter)
|
||||
gtk_tree_selection_get_selected (GtkTreeSelection *selection,
|
||||
GtkTreeModel **model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkRBTree *tree;
|
||||
GtkRBNode *node;
|
||||
@ -274,9 +277,11 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection,
|
||||
! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
|
||||
/* We don't want to return the anchor if it isn't actually selected.
|
||||
*/
|
||||
|
||||
return FALSE;
|
||||
|
||||
if (model)
|
||||
*model = selection->tree_view->priv->model;
|
||||
|
||||
return gtk_tree_model_get_iter (selection->tree_view->priv->model,
|
||||
iter,
|
||||
selection->tree_view->priv->anchor);
|
||||
|
@ -79,6 +79,7 @@ gpointer gtk_tree_selection_get_user_data (GtkTreeSelection
|
||||
/* Only meaningful if GTK_TREE_SELECTION_SINGLE is set */
|
||||
/* Use selected_foreach for GTK_TREE_SELECTION_MULTI */
|
||||
gboolean gtk_tree_selection_get_selected (GtkTreeSelection *selection,
|
||||
GtkTreeModel **model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
/* FIXME: Get a more convenient get_selection function???? one returning GSList?? */
|
||||
|
@ -40,6 +40,7 @@ static guint tree_store_signals[LAST_SIGNAL] = { 0 };
|
||||
static void gtk_tree_store_init (GtkTreeStore *tree_store);
|
||||
static void gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class);
|
||||
static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
|
||||
static guint gtk_tree_store_get_flags (GtkTreeModel *tree_model);
|
||||
static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model);
|
||||
static GtkTreePath *gtk_tree_store_get_path (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
@ -58,11 +59,11 @@ static gint gtk_tree_store_iter_n_children (GtkTreeModel *tree_mode
|
||||
GtkTreeIter *iter);
|
||||
static gboolean gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *child,
|
||||
GtkTreeIter *parent,
|
||||
gint n);
|
||||
static gboolean gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
GtkTreeIter *parent);
|
||||
GtkTreeIter *child);
|
||||
|
||||
|
||||
GtkType
|
||||
@ -150,6 +151,7 @@ gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
|
||||
static void
|
||||
gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
|
||||
{
|
||||
iface->get_flags = gtk_tree_store_get_flags;
|
||||
iface->get_n_columns = gtk_tree_store_get_n_columns;
|
||||
iface->get_path = gtk_tree_store_get_path;
|
||||
iface->get_value = gtk_tree_store_get_value;
|
||||
@ -165,7 +167,7 @@ static void
|
||||
gtk_tree_store_init (GtkTreeStore *tree_store)
|
||||
{
|
||||
tree_store->root = g_node_new (NULL);
|
||||
tree_store->stamp = 1;
|
||||
tree_store->stamp = g_random_int ();
|
||||
}
|
||||
|
||||
GtkTreeStore *
|
||||
@ -242,10 +244,19 @@ gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
|
||||
* it is not visible to the tree or to the user., and the path "1" refers to the
|
||||
* first child of GtkTreeStore::root.
|
||||
*/
|
||||
|
||||
|
||||
static guint
|
||||
gtk_tree_store_get_flags (GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
|
||||
|
||||
return GTK_TREE_MODEL_ITERS_PERSIST;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail (tree_model != NULL, 0);
|
||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
|
||||
|
||||
return GTK_TREE_STORE (tree_model)->n_columns;
|
||||
@ -362,7 +373,10 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model,
|
||||
GtkTreeIter *parent)
|
||||
{
|
||||
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
|
||||
iter->tree_node = G_NODE (parent->tree_node)->children;
|
||||
if (parent)
|
||||
iter->tree_node = G_NODE (parent->tree_node)->children;
|
||||
else
|
||||
iter->tree_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
||||
|
||||
return iter->tree_node != NULL;
|
||||
}
|
||||
@ -388,10 +402,13 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
|
||||
|
||||
g_return_val_if_fail (tree_model != NULL, 0);
|
||||
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
|
||||
if (iter)
|
||||
g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
|
||||
|
||||
node = G_NODE (iter->tree_node)->children;
|
||||
if (iter == NULL)
|
||||
node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
|
||||
else
|
||||
node = G_NODE (iter->tree_node)->children;
|
||||
while (node)
|
||||
{
|
||||
i++;
|
||||
|
@ -2037,6 +2037,8 @@ gtk_tree_view_inserted (GtkTreeModel *model,
|
||||
}
|
||||
}
|
||||
|
||||
/* ref the node */
|
||||
gtk_tree_model_ref_iter (tree_view->priv->model, iter);
|
||||
max_height = gtk_tree_view_insert_iter_height (tree_view,
|
||||
tree,
|
||||
iter,
|
||||
@ -2245,6 +2247,8 @@ gtk_tree_view_build_tree (GtkTreeView *tree_view,
|
||||
tree,
|
||||
iter,
|
||||
depth);
|
||||
|
||||
gtk_tree_model_ref_iter (tree_view->priv->model, iter);
|
||||
temp = _gtk_rbtree_insert_after (tree, temp, max_height);
|
||||
if (recurse)
|
||||
{
|
||||
|
@ -145,12 +145,12 @@ gtk_real_tree_column_clicked (GtkTreeViewColumn *tree_column)
|
||||
*
|
||||
* Return value: A newly created #GtkTreeViewColumn.
|
||||
**/
|
||||
GtkObject *
|
||||
GtkTreeViewColumn *
|
||||
gtk_tree_view_column_new (void)
|
||||
{
|
||||
GtkObject *retval;
|
||||
GtkTreeViewColumn *retval;
|
||||
|
||||
retval = GTK_OBJECT (gtk_type_new (GTK_TYPE_TREE_COLUMN));
|
||||
retval = GTK_TREE_VIEW_COLUMN (gtk_type_new (GTK_TYPE_TREE_COLUMN));
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -168,22 +168,21 @@ gtk_tree_view_column_new (void)
|
||||
*
|
||||
* Return value: A newly created #GtkTreeViewColumn.
|
||||
**/
|
||||
GtkObject *
|
||||
GtkTreeViewColumn *
|
||||
gtk_tree_view_column_new_with_attributes (gchar *title,
|
||||
GtkCellRenderer *cell,
|
||||
...)
|
||||
{
|
||||
GtkObject *retval;
|
||||
GtkTreeViewColumn *retval;
|
||||
va_list args;
|
||||
|
||||
retval = gtk_tree_view_column_new ();
|
||||
|
||||
gtk_tree_view_column_set_title (GTK_TREE_VIEW_COLUMN (retval), title);
|
||||
gtk_tree_view_column_set_cell_renderer (GTK_TREE_VIEW_COLUMN (retval), cell);
|
||||
gtk_tree_view_column_set_title (retval, title);
|
||||
gtk_tree_view_column_set_cell_renderer (retval, cell);
|
||||
|
||||
va_start (args, cell);
|
||||
gtk_tree_view_column_set_attributesv (GTK_TREE_VIEW_COLUMN (retval),
|
||||
args);
|
||||
gtk_tree_view_column_set_attributesv (retval, args);
|
||||
va_end (args);
|
||||
|
||||
return retval;
|
||||
|
@ -82,51 +82,53 @@ struct _GtkTreeViewColumnClass
|
||||
};
|
||||
|
||||
|
||||
GtkType gtk_tree_view_column_get_type (void);
|
||||
GtkObject *gtk_tree_view_column_new (void);
|
||||
GtkObject *gtk_tree_view_column_new_with_attributes (gchar *title,
|
||||
GtkCellRenderer *cell,
|
||||
...);
|
||||
void gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell);
|
||||
void gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
|
||||
gchar *attribute,
|
||||
gint column);
|
||||
void gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
|
||||
...);
|
||||
void gtk_tree_view_column_set_cell_data (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
void gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
|
||||
gboolean visible);
|
||||
gboolean gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_col_type (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeViewColumnType type);
|
||||
gint gtk_tree_view_column_get_col_type (GtkTreeViewColumn *tree_column);
|
||||
gint gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_size (GtkTreeViewColumn *tree_column,
|
||||
gint size);
|
||||
void gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
|
||||
gint min_width);
|
||||
gint gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
|
||||
gint max_width);
|
||||
gint gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column);
|
||||
GtkType gtk_tree_view_column_get_type (void);
|
||||
GtkTreeViewColumn *gtk_tree_view_column_new (void);
|
||||
GtkTreeViewColumn *gtk_tree_view_column_new_with_attributes (gchar *title,
|
||||
GtkCellRenderer *cell,
|
||||
...);
|
||||
void gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell);
|
||||
void gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
|
||||
gchar *attribute,
|
||||
gint column);
|
||||
void gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
|
||||
...);
|
||||
void gtk_tree_view_column_set_cell_data (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter);
|
||||
void gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
|
||||
gboolean visible);
|
||||
gboolean gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_col_type (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeViewColumnType type);
|
||||
gint gtk_tree_view_column_get_col_type (GtkTreeViewColumn *tree_column);
|
||||
gint gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_size (GtkTreeViewColumn *tree_column,
|
||||
gint size);
|
||||
void gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
|
||||
gint min_width);
|
||||
gint gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
|
||||
gint max_width);
|
||||
gint gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column);
|
||||
|
||||
|
||||
|
||||
/* Options for manipulating the column headers
|
||||
*/
|
||||
void gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
|
||||
gchar *title);
|
||||
gchar *gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_header_active (GtkTreeViewColumn *tree_column,
|
||||
gboolean active);
|
||||
void gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
|
||||
GtkWidget *widget);
|
||||
GtkWidget *gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_justification (GtkTreeViewColumn *tree_column,
|
||||
GtkJustification justification);
|
||||
GtkJustification gtk_tree_view_column_get_justification (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
|
||||
gchar *title);
|
||||
gchar *gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_header_active (GtkTreeViewColumn *tree_column,
|
||||
gboolean active);
|
||||
void gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
|
||||
GtkWidget *widget);
|
||||
GtkWidget *gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column);
|
||||
void gtk_tree_view_column_set_justification (GtkTreeViewColumn *tree_column,
|
||||
GtkJustification justification);
|
||||
GtkJustification gtk_tree_view_column_get_justification (GtkTreeViewColumn *tree_column);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -7,8 +7,7 @@ static void
|
||||
selection_changed (GtkTreeSelection *selection,
|
||||
GtkWidget *button)
|
||||
{
|
||||
if (gtk_tree_selection_get_selected (selection,
|
||||
NULL))
|
||||
if (gtk_tree_selection_get_selected (selection, NULL, NULL))
|
||||
gtk_widget_set_sensitive (button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
@ -31,6 +30,7 @@ iter_remove (GtkWidget *button, GtkTreeView *tree_view)
|
||||
{
|
||||
GtkTreeIter selected;
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_remove (model, &selected);
|
||||
@ -46,6 +46,7 @@ iter_insert (GtkWidget *button, GtkTreeView *tree_view)
|
||||
|
||||
entry = gtk_object_get_user_data (GTK_OBJECT (button));
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert (model,
|
||||
@ -71,6 +72,7 @@ iter_insert_before (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert_before (model,
|
||||
@ -96,6 +98,7 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert_after (model,
|
||||
@ -121,6 +124,7 @@ iter_prepend (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_prepend (model,
|
||||
@ -144,6 +148,7 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_append (model, &iter, &selected);
|
||||
@ -159,13 +164,14 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
|
||||
static void
|
||||
make_window ()
|
||||
{
|
||||
GtkTreeModel *sort_model;
|
||||
GtkWidget *window;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox, *entry;
|
||||
GtkWidget *button;
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *tree_view;
|
||||
GtkObject *column;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkCellRenderer *cell;
|
||||
GtkObject *selection;
|
||||
|
||||
@ -175,7 +181,9 @@ make_window ()
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 350);
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model),
|
||||
NULL, 0);
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
|
||||
selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
|
||||
gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE);
|
||||
|
||||
@ -237,7 +245,7 @@ make_window ()
|
||||
/* The selected column */
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("nodes", cell, "text", 0, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
||||
|
||||
/* A few to start */
|
||||
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
|
||||
@ -254,7 +262,7 @@ main (int argc, char *argv[])
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
model = gtk_tree_store_new_with_values (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
|
||||
make_window ();
|
||||
make_window ();
|
||||
|
||||
|
@ -7,8 +7,7 @@ static void
|
||||
selection_changed (GtkTreeSelection *selection,
|
||||
GtkWidget *button)
|
||||
{
|
||||
if (gtk_tree_selection_get_selected (selection,
|
||||
NULL))
|
||||
if (gtk_tree_selection_get_selected (selection, NULL, NULL))
|
||||
gtk_widget_set_sensitive (button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
@ -31,6 +30,7 @@ iter_remove (GtkWidget *button, GtkTreeView *tree_view)
|
||||
{
|
||||
GtkTreeIter selected;
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_remove (model, &selected);
|
||||
@ -46,6 +46,7 @@ iter_insert (GtkWidget *button, GtkTreeView *tree_view)
|
||||
|
||||
entry = gtk_object_get_user_data (GTK_OBJECT (button));
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert (model,
|
||||
@ -71,6 +72,7 @@ iter_insert_before (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert_before (model,
|
||||
@ -96,6 +98,7 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_insert_after (model,
|
||||
@ -121,6 +124,7 @@ iter_prepend (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_prepend (model,
|
||||
@ -144,6 +148,7 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
|
||||
GtkTreeIter selected;
|
||||
|
||||
if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
|
||||
NULL,
|
||||
&selected))
|
||||
{
|
||||
gtk_tree_store_append (model, &iter, &selected);
|
||||
@ -159,13 +164,14 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
|
||||
static void
|
||||
make_window ()
|
||||
{
|
||||
GtkTreeModel *sort_model;
|
||||
GtkWidget *window;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox, *entry;
|
||||
GtkWidget *button;
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *tree_view;
|
||||
GtkObject *column;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkCellRenderer *cell;
|
||||
GtkObject *selection;
|
||||
|
||||
@ -175,7 +181,9 @@ make_window ()
|
||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 350);
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model),
|
||||
NULL, 0);
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
|
||||
selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
|
||||
gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE);
|
||||
|
||||
@ -237,7 +245,7 @@ make_window ()
|
||||
/* The selected column */
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("nodes", cell, "text", 0, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
||||
|
||||
/* A few to start */
|
||||
iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
|
||||
@ -254,7 +262,7 @@ main (int argc, char *argv[])
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
model = gtk_tree_store_new_with_values (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
|
||||
make_window ();
|
||||
make_window ();
|
||||
|
||||
|
Reference in New Issue
Block a user