summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Hallendal <micke@codefactory.se>2002-03-02 01:59:38 +0000
committerMikael Hallendal <hallski@src.gnome.org>2002-03-02 01:59:38 +0000
commit36b3b070b965bf7f2e2abb683792b099928599ee (patch)
treed28bc6caae6d30b871478798c3ff6b00bc4663d3
parentbf75148ce99d3bb9c0fce594bb88f2ff44b08160 (diff)
downloadyelp-36b3b070b965bf7f2e2abb683792b099928599ee.tar.gz
use the column-enum to specify columns.
2002-03-02 Mikael Hallendal <micke@codefactory.se> * src/yelp-view-index.c: (yvi_index_selection_changed_cb): use the column-enum to specify columns. * src/yelp-index-model.c: (yim_init): initially set index_words to NULL. (yim_get_column_type): return the correct type. (yim_get_value): add support for the extra hidden section column. (yelp_index_model_set_words): inform that new lines have been added to the model. * src/yelp-index-model.h: added a column-enum * src/Makefile.am: removed gtktreemodelfilter Please don't report problems running/building Yelp after this commit, I'm in the middle of hacking and will finish this during the weekend.
-rw-r--r--ChangeLog18
-rw-r--r--src/Makefile.am8
-rw-r--r--src/gtktreemodelfilter.c2385
-rw-r--r--src/gtktreemodelfilter.h93
-rw-r--r--src/yelp-index-model.c53
-rw-r--r--src/yelp-index-model.h7
-rw-r--r--src/yelp-view-index.c2
7 files changed, 70 insertions, 2496 deletions
diff --git a/ChangeLog b/ChangeLog
index 84e69ce9..cab3a860 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
2002-03-02 Mikael Hallendal <micke@codefactory.se>
+ * src/yelp-view-index.c:
+ (yvi_index_selection_changed_cb): use the column-enum to specify
+ columns.
+
+ * src/yelp-index-model.c:
+ (yim_init): initially set index_words to NULL.
+ (yim_get_column_type): return the correct type.
+ (yim_get_value): add support for the extra hidden section column.
+ (yelp_index_model_set_words): inform that new lines have been
+ added to the model.
+
+ * src/yelp-index-model.h: added a column-enum
+
+ * src/Makefile.am: removed gtktreemodelfilter
+
+ * src/gtktreemodelfilter.[ch]: removed, not used and _kris_ is
+ doing the development in libegg now.
+
* src/yelp-view-index.c:
- replaced the old ListStore with the new YelpIndexModel.
(yvi_index_term_add): removed, not needed when using own model.
diff --git a/src/Makefile.am b/src/Makefile.am
index 68b17088..c3df17a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,13 +44,7 @@ yelp_SOURCES = \
yelp-window.c yelp-window.h
yelp_LDADD = \
- $(YELP_LIBS) \
- libgtktreemodelfilter.la
-
-noinst_LTLIBRARIES = libgtktreemodelfilter.la
-
-libgtktreemodelfilter_la_SOURCES = \
- gtktreemodelfilter.c gtktreemodelfilter.h
+ $(YELP_LIBS)
gnome_yelp_idl_sources = \
GNOME_Yelp-stubs.c \
diff --git a/src/gtktreemodelfilter.c b/src/gtktreemodelfilter.c
deleted file mode 100644
index 570a9705..00000000
--- a/src/gtktreemodelfilter.c
+++ /dev/null
@@ -1,2385 +0,0 @@
-/* gtktreemodelfilter.c
- * Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
- * Copyright (C) 2001,2002 Kristian Rietveld <kris@gtk.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "gtktreemodelfilter.h"
-#include <gtk/gtksignal.h>
-#include <string.h>
-
-//#define VERBOSE 1
-
-/* ITER FORMAT:
- *
- * iter->stamp = tree_model_filter->stamp
- * iter->user_data = FilterLevel
- * iter->user_data2 = FilterElt
- */
-
-typedef struct _FilterElt FilterElt;
-typedef struct _FilterLevel FilterLevel;
-
-struct _FilterElt
-{
- GtkTreeIter iter;
- FilterLevel *children;
- gint offset;
- gint ref_count;
- gint zero_ref_count;
- gboolean visible;
-};
-
-struct _FilterLevel
-{
- GArray *array;
- gint ref_count;
- FilterElt *parent_elt;
- FilterLevel *parent_level;
-};
-
-/* properties */
-enum {
- PROP_0,
- /* construct args */
- PROP_MODEL,
- PROP_FILTER_COLUMN,
- PROP_VROOT
-};
-
-#define GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS(tree_model_filter) \
- (((GtkTreeModelFilter *)tree_model_filter)->child_flags & GTK_TREE_MODEL_ITERS_PERSIST)
-#define FILTER_ELT(filter_elt) ((FilterElt *)filter_elt)
-#define FILTER_LEVEL(filter_level) ((FilterLevel *)filter_level)
-
-#define GET_CHILD_ITER(tree_model_filter,child_iter,filter_iter) gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER (tree_model_filter), child_iter, filter_iter);
-
-/* general code (object/interface init, properties, etc) */
-static void gtk_tree_model_filter_init (GtkTreeModelFilter *tree_model_filter);
-static void gtk_tree_model_filter_class_init (GtkTreeModelFilterClass *tree_model_filter_class);
-static void gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface);
-static void gtk_tree_model_filter_finalize (GObject *object);
-static void gtk_tree_model_filter_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_tree_model_filter_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-/* signal handlers */
-static void gtk_tree_model_filter_row_changed (GtkTreeModel *model,
- GtkTreePath *start_path,
- GtkTreeIter *start_iter,
- gpointer data);
-static void gtk_tree_model_filter_row_inserted (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data);
-static void gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data);
-static void gtk_tree_model_filter_row_deleted (GtkTreeModel *model,
- GtkTreePath *path,
- gpointer data);
-static void gtk_tree_model_filter_rows_reordered (GtkTreeModel *s_model,
- GtkTreePath *s_path,
- GtkTreeIter *s_iter,
- gint *new_order,
- gpointer data);
-
-/* TreeModel interface */
-static guint gtk_tree_model_filter_get_flags (GtkTreeModel *tree_model);
-static gint gtk_tree_model_filter_get_n_columns (GtkTreeModel *tree_model);
-static GType gtk_tree_model_filter_get_column_type (GtkTreeModel *tree_model,
- gint index);
-static gboolean gtk_tree_model_filter_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path);
-static GtkTreePath *gtk_tree_model_filter_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static void gtk_tree_model_filter_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value);
-static gboolean gtk_tree_model_filter_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean gtk_tree_model_filter_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent);
-static gboolean gtk_tree_model_filter_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gint gtk_tree_model_filter_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static gboolean gtk_tree_model_filter_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n);
-static gboolean gtk_tree_model_filter_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child);
-static void gtk_tree_model_filter_ref_node (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-static void gtk_tree_model_filter_unref_node (GtkTreeModel *tree_model,
- GtkTreeIter *iter);
-
-/* Private functions */
-static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *tree_model_filter,
- FilterLevel *parent_level,
- FilterElt *parent_elt);
-static void gtk_tree_model_filter_free_level (GtkTreeModelFilter *tree_model_filter,
- FilterLevel *filter_level);
-static void gtk_tree_model_filter_increment_stamp (GtkTreeModelFilter *tree_model_filter);
-static gboolean gtk_tree_model_filter_visible (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *child_iter);
-static GtkTreePath *gtk_tree_model_filter_elt_get_path (FilterLevel *level,
- FilterElt *elt,
- GtkTreePath *root);
-GtkTreeModel *gtk_tree_model_filter_get_model (GtkTreeModelFilter *tree_model);
-static void gtk_tree_model_filter_set_model (GtkTreeModelFilter *tree_model_filter,
- GtkTreeModel *child_model);
-static void gtk_tree_model_filter_set_filter_column (GtkTreeModelFilter *tree_model_filter,
- gint filter_column);
-static void gtk_tree_model_filter_set_root (GtkTreeModelFilter *filter,
- GtkTreePath *root);
-
-static GtkTreePath *gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *child_path,
- gboolean build_levels,
- gboolean fetch_childs);
-static void gtk_tree_model_filter_remove (GtkTreeModelFilter *filter,
- GtkTreeIter *iter,
- gboolean emit_signal);
-static gboolean gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
- FilterLevel *level,
- gint offset);
-static void gtk_tree_model_filter_row_back_child_updater (GtkTreeModelFilter *filter,
- FilterLevel *level,
- FilterElt *elt);
-static void gtk_tree_path_add (GtkTreePath *path1,
- GtkTreePath *path2);
-static GtkTreePath *gtk_tree_path_apply_root (GtkTreePath *path,
- GtkTreePath *root);
-
-static GObjectClass *parent_class = NULL;
-
-GType
-gtk_tree_model_filter_get_type (void)
-{
- static GType tree_model_filter_type = 0;
-
- if (!tree_model_filter_type)
- {
- static const GTypeInfo tree_model_filter_info =
- {
- sizeof (GtkTreeModelFilterClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_tree_model_filter_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkTreeModelFilter),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_tree_model_filter_init
- };
-
- static const GInterfaceInfo tree_model_info =
- {
- (GInterfaceInitFunc) gtk_tree_model_filter_tree_model_init,
- NULL,
- NULL
- };
-
- tree_model_filter_type = g_type_register_static (G_TYPE_OBJECT,
- "GtkTreeModelFilter",
- &tree_model_filter_info, 0);
-
- g_type_add_interface_static (tree_model_filter_type,
- GTK_TYPE_TREE_MODEL,
- &tree_model_info);
- }
-
- return tree_model_filter_type;
-}
-
-static void
-gtk_tree_model_filter_init (GtkTreeModelFilter *tree_model_filter)
-{
- tree_model_filter->filter_column = -1;
- tree_model_filter->filter_func = NULL;
- tree_model_filter->user_data = NULL;
- tree_model_filter->stamp = 0;
- tree_model_filter->zero_ref_count = 0;
- tree_model_filter->root = NULL;
-}
-
-static void
-gtk_tree_model_filter_class_init (GtkTreeModelFilterClass *tree_model_filter_class)
-{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) tree_model_filter_class;
- parent_class = g_type_class_peek_parent (tree_model_filter_class);
-
- object_class->set_property = gtk_tree_model_filter_set_property;
- object_class->get_property = gtk_tree_model_filter_get_property;
-
- object_class->finalize = gtk_tree_model_filter_finalize;
-
- /* Properties */
- g_object_class_install_property (object_class,
- PROP_MODEL,
- g_param_spec_object ("model",
- /* following 2 strings need translation? */
- "TreeModelFilter model",
- "The model for the TreeModelFilter to filter",
- GTK_TYPE_TREE_MODEL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_FILTER_COLUMN,
- g_param_spec_int ("filter_column",
- /* ditto */
- "TreeModelFilter filter column",
- "Column in the child model which should be used for the filtering information. This column should store Boolean values",
- 0, INT_MAX,
- G_TYPE_INT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_VROOT,
- g_param_spec_boxed ("virtual_root",
- /* ditto */
- "TreeModelFilter vroot path",
- "Path which points to the parent of the virtual root",
- GTK_TYPE_TREE_PATH,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void
-gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface)
-{
- iface->get_flags = gtk_tree_model_filter_get_flags;
- iface->get_n_columns = gtk_tree_model_filter_get_n_columns;
- iface->get_column_type = gtk_tree_model_filter_get_column_type;
- iface->get_iter = gtk_tree_model_filter_get_iter;
- iface->get_path = gtk_tree_model_filter_get_path;
- iface->get_value = gtk_tree_model_filter_get_value;
- iface->iter_next = gtk_tree_model_filter_iter_next;
- iface->iter_children = gtk_tree_model_filter_iter_children;
- iface->iter_has_child = gtk_tree_model_filter_iter_has_child;
- iface->iter_n_children = gtk_tree_model_filter_iter_n_children;
- iface->iter_nth_child = gtk_tree_model_filter_iter_nth_child;
- iface->iter_parent = gtk_tree_model_filter_iter_parent;
- iface->ref_node = gtk_tree_model_filter_ref_node;
- iface->unref_node = gtk_tree_model_filter_unref_node;
-}
-
-/**
- * gtk_tree_model_filter_new_with_model:
- * @child_model: A #GtkTreeModel
- * @filter_column: column in the child model which contains filter information
- * @root: the virtual root, or %NULL for the regular root.
- *
- * Creates a new #GtkTreeModel, with @child_model as the child_model.
- *
- * Return value: A new #GtkTreeModel.
- */
-GtkTreeModel *
-gtk_tree_model_filter_new_with_model (GtkTreeModel *child_model,
- gint filter_column,
- GtkTreePath *root)
-{
- GtkTreeModel *retval;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
-
- retval = GTK_TREE_MODEL (g_object_new (gtk_tree_model_filter_get_type (), NULL));
-
- gtk_tree_model_filter_set_model (GTK_TREE_MODEL_FILTER (retval), child_model);
- gtk_tree_model_filter_set_filter_column (GTK_TREE_MODEL_FILTER (retval), filter_column);
- gtk_tree_model_filter_set_root (GTK_TREE_MODEL_FILTER (retval), root);
-
- return retval;
-}
-
-/* GObject callbacks */
-static void
-gtk_tree_model_filter_finalize (GObject *object)
-{
- GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *) object;
-
- gtk_tree_model_filter_set_model (tree_model_filter, NULL);
-
- if (tree_model_filter->virtual_root)
- gtk_tree_path_free (tree_model_filter->virtual_root);
-
- if (tree_model_filter->root)
- gtk_tree_model_filter_free_level (tree_model_filter,
- tree_model_filter->root);
-
- /* must chain up */
- parent_class->finalize (object);
-}
-
-static void
-gtk_tree_model_filter_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkTreeModelFilter *tree_model_filter = GTK_TREE_MODEL_FILTER (object);
-
- switch (prop_id)
- {
- case PROP_MODEL:
- gtk_tree_model_filter_set_model (tree_model_filter, g_value_get_object (value));
- break;
- case PROP_FILTER_COLUMN:
- gtk_tree_model_filter_set_filter_column (tree_model_filter, g_value_get_int (value));
- break;
- case PROP_VROOT:
- gtk_tree_model_filter_set_root (tree_model_filter, g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gtk_tree_model_filter_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkTreeModelFilter *tree_model_filter = GTK_TREE_MODEL_FILTER (object);
-
- switch (prop_id)
- {
- case PROP_MODEL:
- g_value_set_object (value, gtk_tree_model_filter_get_model(tree_model_filter));
- break;
- case PROP_FILTER_COLUMN:
- g_value_set_int (value, tree_model_filter->filter_column);
- break;
- case PROP_VROOT:
- g_value_set_boxed (value, tree_model_filter->virtual_root);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* helpers */
-static void
-gtk_tree_model_filter_row_back_child_updater (GtkTreeModelFilter *filter,
- FilterLevel *level,
- FilterElt *elt)
-{
- int i, len;
- GArray *a = NULL;
- GtkTreeIter childs;
-
-#ifdef VERBOSE
- g_print ("row back child updater v1.0\n");
-
- if (!elt->visible)
- g_print ("elt not visible, bailing out\n");
-#endif
-
- if (!elt->visible)
- return;
-
- if (elt->children)
- a = elt->children->array;
-
- {
- GtkTreeIter iter;
- GtkTreeIter foo;
-
- iter.stamp = filter->stamp;
- iter.user_data = level;
- iter.user_data2 = elt;
-
- gtk_tree_model_filter_convert_iter_to_child_iter (filter, &foo, &iter);
-
- len = gtk_tree_model_iter_n_children (filter->child_model, &foo);
- gtk_tree_model_iter_children (filter->child_model, &childs, &foo);
- }
-
- for (i = 0; i < len; i++)
- {
- gint j, index = -1;
- GValue val = {0,};
-
- if (a)
- {
- for (j = 0; j < a->len; j++)
- if (g_array_index (a, FilterElt, j).offset == i)
- {
- index = i;
- break;
- }
- }
-
- gtk_tree_model_get_value (filter->child_model, &childs,
- filter->filter_column, &val);
-
- if (g_value_get_boolean (&val))
- {
- /* insert row */
- if (index == -1)
- {
- FilterElt *e;
- GtkTreePath *path;
- GtkTreeIter it, tmp;
-
- /* bring it back in */
-#ifdef VERBOSE
- g_print ("need to bring row back in...\n");
-#endif
- if (!a && !elt->children)
- {
- FilterLevel *new_level = NULL;
-
- new_level = g_new (FilterLevel, 1);
- new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (FilterElt), 0);
- new_level->ref_count = 0;
- new_level->parent_elt = elt;
- new_level->parent_level = level;
-
- elt->children = new_level;
- a = elt->children->array;
- }
-
- gtk_tree_model_filter_fetch_child (filter,
- elt->children, i);
-
- for (j = 0; j < a->len; j++)
- if (g_array_index (a, FilterElt, j).offset == i)
- {
- index = j;
- break;
- }
-
- if (index == -1)
- {
- g_warning ("gtk_tree_model_filter_fetch_child failed!\n");
- return;
- }
-
- e = &g_array_index (a, FilterElt, index);
- e->visible = FALSE;
-
- it.stamp = filter->stamp;
- it.user_data = elt->children;
- it.user_data2 = e;
-
- gtk_tree_model_ref_node (GTK_TREE_MODEL (filter), &it);
- gtk_tree_model_filter_increment_stamp (filter);
- gtk_tree_model_unref_node (GTK_TREE_MODEL (filter), &it);
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &it);
-
- e->visible = TRUE;
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &it);
- gtk_tree_path_free (path);
-
- if (gtk_tree_model_iter_children (GTK_TREE_MODEL (filter), &tmp, &it))
- gtk_tree_model_filter_row_back_child_updater (filter,
- elt->children, e);
- }
- else
- {
- FilterElt *e = &g_array_index (a, FilterElt, index);
- GtkTreePath *path;
- GtkTreeIter i, tmp;
-
- if (!e->visible)
- {
- e->visible = FALSE;
-
-#ifdef VERBOSE
- g_print ("-> row back\n");
-#endif
-
- gtk_tree_model_filter_increment_stamp (filter);
-
- i.stamp = filter->stamp;
- i.user_data = elt->children;
- i.user_data2 = e;
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &i);
- e->visible = TRUE;
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &i);
- gtk_tree_path_free (path);
-
- if (gtk_tree_model_iter_children (GTK_TREE_MODEL (filter), &tmp, &i))
- gtk_tree_model_filter_row_back_child_updater (filter,
- elt->children, e);
- }
- }
- }
- else
- {
- /* remove the iter */
- if (index != -1)
- {
- FilterElt *e = &g_array_index (a, FilterElt, index);
- GtkTreeIter i;
-
-#ifdef VERBOSE
- g_print ("removing iter in silence\n");
-#endif
-
- i.stamp = filter->stamp;
- i.user_data = elt->children;
- i.user_data2 = e;
-
- gtk_tree_model_filter_remove (filter, &i, FALSE);
- }
- }
-
- gtk_tree_model_iter_next (filter->child_model, &childs);
- }
-}
-
-static void
-gtk_tree_model_filter_remove (GtkTreeModelFilter *filter,
- GtkTreeIter *iter,
- gboolean emit_signal)
-{
- FilterElt *elt, *parent;
- FilterLevel *level, *parent_level;
- gint offset, i, length;
-
- level = FILTER_LEVEL (iter->user_data);
- elt = FILTER_ELT (iter->user_data2);
- parent = level->parent_elt;
- parent_level = level->parent_level;
- length = level->array->len;
-
- offset = elt->offset;
-
-#ifdef VERBOSE
- g_print ("------- remove \n");
-#endif
-
- /* ref couting */
- while (elt->ref_count > 0)
- gtk_tree_model_filter_unref_node (GTK_TREE_MODEL (filter), iter);
-
- if (emit_signal)
- {
- GtkTreePath *path;
-
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), iter);
- gtk_tree_model_filter_increment_stamp (filter);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
- gtk_tree_path_free (path);
- }
-
- if (length == 1 && emit_signal && iter->user_data != filter->root)
- {
- /* the code above destroyed the level */
- goto emit_has_child_toggled;
- }
-
- for (i = 0; i < level->array->len; i++)
- if (elt->offset == g_array_index (level->array, FilterElt, i).offset)
- break;
-
- g_array_remove_index (level->array, i);
-
- for (i = 0; i < level->array->len; i++)
- {
- elt = &g_array_index (level->array, FilterElt, i);
- if (elt->children)
- elt->children->parent_elt = elt;
- }
-
-emit_has_child_toggled:
- /* children are being handled first, so we can check it this way */
- if ((parent && parent->children && parent->children->array->len <= 1)
- || (length == 1 && emit_signal && iter->user_data != filter->root))
- {
- /* we're about to remove the latest child */
- GtkTreeIter piter;
- GtkTreePath *ppath;
-
- piter.stamp = filter->stamp;
- piter.user_data = parent_level;
- piter.user_data2 = parent;
-
- ppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &piter);
-
-#ifdef VERBOSE
- g_print ("emit has_child_toggled (in filter_remove)\n");
-#endif
- gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
- ppath, &piter);
- gtk_tree_path_free (ppath);
- }
-}
-
-/* TreeModel signals */
-static void
-gtk_tree_model_filter_row_changed (GtkTreeModel *s_model,
- GtkTreePath *start_path,
- GtkTreeIter *start_iter,
- gpointer data)
-{
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
- GtkTreeIter iter;
- GtkTreeIter siter;
- GtkTreePath *path;
-
- FilterElt *elt;
- FilterLevel *level;
- gint offset;
-
- gboolean new;
- gboolean free_start_path = FALSE;
-
- g_return_if_fail (start_path != NULL || start_iter != NULL);
-
- if (!start_path)
- {
- start_path = gtk_tree_model_get_path (s_model, start_iter);
- free_start_path = TRUE;
- }
-
- if (!start_iter)
- gtk_tree_model_get_iter (s_model, &siter, start_path);
- else
- siter = *start_iter;
-
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, start_path, FALSE, TRUE);
- if (!path)
- {
- if (free_start_path)
- gtk_tree_path_free (start_path);
-#ifdef VERBOSE
- g_print ("couldn't convert path, bailing out\n");
-#endif
- return;
- }
-
-#ifdef VERBOSE
- g_print ("_row_changed handling %s\n", gtk_tree_path_to_string (path));
-#endif
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
- gtk_tree_path_free (path);
- if (free_start_path)
- gtk_tree_path_free (start_path);
-
- {
- GValue val = {0, };
-
- gtk_tree_model_get_value (s_model, &siter, filter->filter_column, &val);
- new = g_value_get_boolean (&val);
- g_value_unset (&val);
- }
-
- level = FILTER_LEVEL (iter.user_data);
- elt = FILTER_ELT (iter.user_data2);
- offset = elt->offset;
-
- if (elt->visible == TRUE && new == FALSE)
- {
-#ifdef VERBOSE
- g_print ("visible to false -> delete row\n");
-#endif
- gtk_tree_model_filter_remove (filter, &iter, TRUE);
- }
- else if (elt->visible == FALSE && new == TRUE)
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
- GtkTreeIter tmp;
-
-#ifdef VERBOSE
- g_print ("visible to true -> insert row\n");
-#endif
- elt->visible = TRUE;
-
- gtk_tree_model_filter_increment_stamp (filter);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
-
- if (gtk_tree_model_iter_children (s_model, &tmp, start_iter))
- gtk_tree_model_filter_row_back_child_updater (filter, level, elt);
-
- gtk_tree_path_free (path);
- }
- else if (elt->visible == FALSE && new == FALSE)
- {
-#ifdef VERBOSE
- g_print ("remove iter in silence\n");
-#endif
- gtk_tree_model_filter_remove (filter, &iter, FALSE);
- }
- else
- {
- GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
- GtkTreeIter tmp;
-#ifdef VERBOSE
- g_print ("visible didn't change -- pass row_changed\n");
-#endif
- gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter);
-
- if (gtk_tree_model_iter_children (s_model, &tmp, start_iter)
- && elt->visible)
- gtk_tree_model_filter_row_back_child_updater (filter, level, elt);
-
- gtk_tree_path_free (path);
- }
-}
-
-static void
-gtk_tree_model_filter_row_inserted (GtkTreeModel *s_model,
- GtkTreePath *s_path,
- GtkTreeIter *s_iter,
- gpointer data)
-{
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
- GtkTreePath *path;
- GtkTreePath *real_path;
- GtkTreeIter iter;
-
- GtkTreeIter real_s_iter;
-
- FilterElt *elt;
- FilterLevel *level;
- FilterLevel *parent_level;
-
- gint i = 0, offset, index;
-
- gboolean free_s_path = FALSE;
-
- g_return_if_fail (s_path != NULL || s_iter != NULL);
-
- if (!s_path)
- {
- s_path = gtk_tree_model_get_path (s_model, s_iter);
- free_s_path = TRUE;
- }
-
- if (s_iter)
- real_s_iter = *s_iter;
- else
- gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
-
- /* only insert the row if it's visible */
- if (!gtk_tree_model_filter_visible (filter, s_iter))
- goto done;
-
- if (!filter->root)
- {
- gtk_tree_model_filter_build_level (filter, NULL, NULL);
- /* that already put the inserted iter in the level */
-
- goto done_and_submit;
- }
-
- parent_level = level = FILTER_LEVEL (filter->root);
-
- /* subtract virtual root if needed */
- if (filter->virtual_root)
- {
- real_path = gtk_tree_path_apply_root (s_path, filter->virtual_root);
- /* not our root */
- if (!real_path)
- goto done;
- }
- else
- real_path = gtk_tree_path_copy (s_path);
-
- if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
- {
- /* find the parent level */
- while (i < gtk_tree_path_get_depth (real_path) - 1)
- {
- gint j;
-
- if (!level)
- /* we don't cover this signal */
- goto done;
-
- if (level->array->len < gtk_tree_path_get_indices (real_path)[i])
- {
- g_warning ("A node was inserted with a parent that's not in the tree.\nThis possibly means that a GtkTreeModel inserted a child node before the parent was insterted.");
- goto done;
- }
-
- elt = NULL;
- for (j = 0; j < level->array->len; j++)
- if (g_array_index (level->array, FilterElt, j).offset == gtk_tree_path_get_indices (s_path)[i])
- {
- elt = &g_array_index (level->array, FilterElt, j);
- break;
- }
-
- if (!elt)
- /* parent was probably filtered out */
- goto done;
-
- if (!elt->children)
- {
- GtkTreePath *tmppath;
- GtkTreeIter tmpiter;
-
- tmpiter.stamp = filter->stamp;
- tmpiter.user_data = level;
- tmpiter.user_data2 = elt;
-
- tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (data),
- &tmpiter);
-
- if (tmppath)
- {
-#ifdef VERBOSE
- g_print ("has_child_toggled in row_inserted\n");
-#endif
- gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data),
- tmppath, &tmpiter);
- gtk_tree_path_free (tmppath);
- }
-
- /* not covering this signal */
- goto done;
- }
-
- level = elt->children;
- parent_level = level;
- i++;
- }
- }
-
- if (!parent_level)
- goto done;
-
- /* let's try to insert the value */
- i = 0;
- offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
-
- if (gtk_tree_model_filter_visible (filter, &real_s_iter))
- {
- FilterElt felt;
-
- if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
- felt.iter = real_s_iter;
- felt.offset = offset;
- felt.zero_ref_count = 0;
- felt.ref_count = 0;
- felt.visible = FALSE;
- felt.children = NULL;
-
- for (i = 0; i < level->array->len; i++)
- if (g_array_index (level->array, FilterElt, i).offset > offset)
- break;
-
- g_array_insert_val (level->array, i, felt);
- index = i;
- }
-
- for (i = 0; i < level->array->len; i++)
- {
- FilterElt *e = &g_array_index (level->array, FilterElt, i);
- if ((e->offset >= offset) && i != index)
- e->offset++;
- if (e->children)
- e->children->parent_elt = e;
- }
-
- if (!gtk_tree_model_filter_visible (filter, &real_s_iter))
- goto done;
-
- done_and_submit:
- /* s_path here! AND NOT real_path, because this function does
- * root subtraction */
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
- s_path,
- FALSE, TRUE);
- if (!path)
- return;
-
- gtk_tree_model_filter_increment_stamp (filter);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
-
- done:
- if (free_s_path)
- gtk_tree_path_free (s_path);
-
- return;
-}
-
-static void
-gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *s_model,
- GtkTreePath *s_path,
- GtkTreeIter *s_iter,
- gpointer data)
-{
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
- GtkTreePath *path;
- GtkTreeIter iter;
-
- g_return_if_fail (s_path != NULL && s_iter != NULL);
-
- /* FIXME: this code hasn't been tested and looks broken ... I need
- * to investigate it */
-
- if (!gtk_tree_model_filter_visible (filter, s_iter))
- return;
-
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, s_path, FALSE, TRUE);
- if (!path)
- return;
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
-#ifdef VERBOSE
- if (!FILTER_ELT (iter.user_data2)->visible)
- g_warning ("visible flag mismatch\n");
- g_print ("has child toggled pass on\n");
-#endif
- gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
-
- gtk_tree_path_free (path);
-}
-
-static void
-gtk_tree_model_filter_row_deleted (GtkTreeModel *s_model,
- GtkTreePath *s_path,
- gpointer data)
-{
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
- GtkTreePath *path;
- GtkTreeIter iter;
- FilterElt *elt;
- FilterLevel *level;
- gint offset;
- gboolean visible;
- gint i;
-
- g_return_if_fail (s_path != NULL);
-
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, s_path, FALSE, TRUE);
- if (!path)
- return;
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
-
- level = FILTER_LEVEL (iter.user_data);
- elt = FILTER_ELT (iter.user_data2);
- offset = elt->offset;
- visible = elt->visible;
-
- if (visible)
- {
- if (level->ref_count == 0 && level != filter->root)
- {
- gtk_tree_model_filter_increment_stamp (filter);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
-
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_model_filter_increment_stamp (filter);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
-
- while (elt->ref_count > 0)
- gtk_tree_model_filter_unref_node (GTK_TREE_MODEL (data), &iter);
- }
-
- /* remove the row */
- for (i = 0; i < level->array->len; i++)
- if (elt->offset == g_array_index (level->array, FilterElt, i).offset)
- break;
-
- offset = g_array_index (level->array, FilterElt, i).offset;
- g_array_remove_index (level->array, i);
-
- for (i = 0; i < level->array->len; i++)
- {
- elt = &g_array_index (level->array, FilterElt, i);
- if (elt->offset > offset)
- elt->offset--;
- if (elt->children)
- elt->children->parent_elt = elt;
- }
-
- gtk_tree_path_free (path);
-}
-
-static void
-gtk_tree_model_filter_rows_reordered (GtkTreeModel *s_model,
- GtkTreePath *s_path,
- GtkTreeIter *s_iter,
- gint *new_order,
- gpointer data)
-{
- FilterElt *elt;
- FilterLevel *level;
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
-
- GtkTreePath *path;
- GtkTreeIter iter;
-
- gint *tmp_array;
- gint i, j, elt_count;
- gint length;
-
- GArray *new_array;
-
- g_return_if_fail (new_order != NULL);
-
- if (s_path == NULL || gtk_tree_path_get_indices (s_path) == NULL)
- {
- if (filter->root == NULL)
- return;
-
- length = gtk_tree_model_iter_n_children (s_model, NULL);
-
- if (filter->virtual_root)
- {
- gint new_pos = -1;
-
- /* reorder root level of path */
- for (i = 0; i < length; i++)
- if (new_order[i] == gtk_tree_path_get_indices (filter->virtual_root)[0])
- new_pos = i;
-
- if (new_pos < 0)
- return;
-
- gtk_tree_path_get_indices (filter->virtual_root)[0] = new_pos;
- return;
- }
-
- path = gtk_tree_path_new ();
- level = FILTER_LEVEL (filter->root);
- }
- else
- {
- GtkTreeIter child_iter;
-
- /* virtual root anchor reordering */
- if (filter->virtual_root &&
- gtk_tree_path_get_depth (s_path) <
- gtk_tree_path_get_depth (filter->virtual_root))
- {
- gint new_pos = -1;
- gint length;
- gint level;
- GtkTreeIter real_s_iter;
-
- level = gtk_tree_path_get_depth (s_path);
-
- if (s_iter)
- real_s_iter = *s_iter;
- else
- gtk_tree_model_get_iter (s_model, &real_s_iter,
- s_path);
-
- length = gtk_tree_model_iter_n_children (s_model, &real_s_iter);
-
- for (i = 0; i < length; i++)
- if (new_order[i] == gtk_tree_path_get_indices (filter->virtual_root)[level])
- new_pos = i;
-
- if (new_pos < 0)
- return;
-
- gtk_tree_path_get_indices (filter->virtual_root)[level] = new_pos;
- return;
- }
-
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, s_path, FALSE, FALSE);
- if (!path && filter->virtual_root &&
- gtk_tree_path_compare (s_path, filter->virtual_root))
- return;
-
- if (!path && !filter->virtual_root)
- return;
-
- if (!path)
- {
- /* root level mode */
- if (!s_iter)
- gtk_tree_model_get_iter (s_model, s_iter, s_path);
- length = gtk_tree_model_iter_n_children (s_model, s_iter);
- path = gtk_tree_path_new ();
- level = FILTER_LEVEL (filter->root);
- }
- else
- {
- gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
-
- level = FILTER_LEVEL (iter.user_data);
- elt = FILTER_ELT (iter.user_data2);
-
- if (!elt->children)
- {
- gtk_tree_path_free (path);
- return;
- }
-
- level = elt->children;
-
- GET_CHILD_ITER (filter, &child_iter, &iter);
- length = gtk_tree_model_iter_n_children (s_model, &child_iter);
- }
- }
-
- if (level->array->len < 1)
- return;
-
- /* note: we do not bail out here if level->array->len < 2, like
- * the GtkTreeModelSort does. This because we do some special tricky
- * reordering
- */
-
- /* construct a new array */
- new_array = g_array_sized_new (FALSE, FALSE, sizeof (FilterElt), level->array->len);
- tmp_array = g_new (gint, level->array->len);
-
-#ifdef VERBOSE
- g_print ("reorder: running with length = %d\n", length);
-#endif
-
- for (i = 0, elt_count = 0; i < length; i++)
- {
- FilterElt *e = NULL;
- gint old_offset = -1;
-
- for (j = 0; j < level->array->len; j++)
- if (g_array_index (level->array, FilterElt, j).offset == new_order[i])
- {
- e = &g_array_index (level->array, FilterElt, j);
- old_offset = j;
- break;
- }
-
- if (!e)
- continue;
-
- tmp_array[elt_count] = old_offset;
- g_array_append_val (new_array, *e);
- g_array_index (new_array, FilterElt, elt_count).offset = i;
- elt_count++;
- }
-
-#ifdef VERBOSE
- g_print ("length: old %d, new %d\n", level->array->len,
- new_array->len);
-#endif
-
- g_array_free (level->array, TRUE);
- level->array = new_array;
-
-#ifdef VERBOSE
- for (j = 0; j < length; j++)
- g_print ("%3d", new_order[j]);
- g_print ("\n");
-
- for (j = 0; j < level->array->len; j++)
- g_print ("%3d", tmp_array[j]);
- g_print ("\n");
-
- for (j = 0; j < level->array->len; j++)
- g_print ("%3d", g_array_index (level->array, FilterElt, j).offset);
- g_print ("\n");
-#endif
-
- /* fix up stuff */
- for (i = 0; i < level->array->len; i++)
- {
- FilterElt *e = &g_array_index (level->array, FilterElt, i);
- if (e->children)
- e->children->parent_elt = e;
- }
-
- /* emit rows_reordered */
- if (!gtk_tree_path_get_indices (path))
- gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, NULL,
- tmp_array);
- else
- gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, &iter,
- tmp_array);
-
- /* done */
- g_free (tmp_array);
- gtk_tree_path_free (path);
-}
-
-/* TreeModelIface implemtation */
-static guint
-gtk_tree_model_filter_get_flags (GtkTreeModel *tree_model)
-{
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), 0);
-
- return 0;
-}
-
-static gint
-gtk_tree_model_filter_get_n_columns (GtkTreeModel *tree_model)
-{
- GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *) tree_model;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), 0);
-
- if (tree_model_filter->child_model == 0)
- return 0;
-
- return gtk_tree_model_get_n_columns (tree_model_filter->child_model);
-}
-
-static GType
-gtk_tree_model_filter_get_column_type (GtkTreeModel *tree_model,
- gint index)
-{
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), G_TYPE_INVALID);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, G_TYPE_INVALID);
-
- return gtk_tree_model_get_column_type (GTK_TREE_MODEL_FILTER (tree_model)->child_model, index);
-}
-
-static gboolean
-gtk_tree_model_filter_get_iter (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- GtkTreeModelFilter *tree_model_filter;
- gint *indices;
- FilterLevel *level;
- gint depth, i;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, FALSE);
-
- tree_model_filter = (GtkTreeModelFilter *) tree_model;
- indices = gtk_tree_path_get_indices (path);
-
- if (tree_model_filter->root == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter, NULL, NULL);
- level = FILTER_LEVEL (tree_model_filter->root);
-
- depth = gtk_tree_path_get_depth (path);
- if (depth == 0)
- return FALSE;
-
- for (i = 0; i < depth - 1; i++)
- {
- if ((level == NULL) ||
- (level->array->len < indices[i]))
- return FALSE;
-
- if (g_array_index (level->array, FilterElt, indices[i]).children == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter, level, &g_array_index (level->array, FilterElt, indices[i]));
- level = g_array_index (level->array, FilterElt, indices[i]).children;
- }
-
- if (level == NULL)
- return FALSE;
- iter->stamp = tree_model_filter->stamp;
- iter->user_data = level;
- iter->user_data2 = &g_array_index (level->array, FilterElt, indices[depth - 1]);
- return TRUE;
-}
-
-static GtkTreePath *
-gtk_tree_model_filter_get_path (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- GtkTreePath *retval;
- FilterLevel *level;
- FilterElt *elt;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), NULL);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, NULL);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp, NULL);
-
- retval = gtk_tree_path_new ();
- level = iter->user_data;
- elt = iter->user_data2;
- while (level != NULL)
- {
- gtk_tree_path_prepend_index (retval, elt - (FilterElt *)level->array->data);
- elt = level->parent_elt;
- level = level->parent_level;
- }
-
- return retval;
-}
-
-static void
-gtk_tree_model_filter_get_value (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint column,
- GValue *value)
-{
- GtkTreeIter child_iter;
-
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model));
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL);
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp);
-
- GET_CHILD_ITER (tree_model, &child_iter, iter);
- gtk_tree_model_get_value (GTK_TREE_MODEL_FILTER (tree_model)->child_model,
- &child_iter, column, value);
-}
-
-static gboolean
-gtk_tree_model_filter_iter_next (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- FilterLevel *level;
- FilterElt *elt;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp, FALSE);
-
- level = iter->user_data;
- elt = iter->user_data2;
-
- if (elt - (FilterElt *)level->array->data >= level->array->len - 1)
- {
- iter->stamp = 0;
- return FALSE;
- }
- iter->user_data2 = elt + 1;
-
- return TRUE;
-}
-
-static gboolean
-gtk_tree_model_filter_iter_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent)
-{
- GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *) tree_model;
- FilterLevel *level;
-
- iter->stamp = 0;
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- g_return_val_if_fail (tree_model_filter->child_model != NULL, FALSE);
- if (parent) g_return_val_if_fail (tree_model_filter->stamp == parent->stamp, FALSE);
-
- if (parent == NULL)
- {
- if (tree_model_filter->root == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter, NULL, NULL);
- if (tree_model_filter->root == NULL)
- return FALSE;
-
- level = tree_model_filter->root;
- iter->stamp = tree_model_filter->stamp;
- iter->user_data = level;
- iter->user_data2 = level->array->data;
- }
- else
- {
- if (((FilterElt *)parent->user_data2)->children == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter,
- (FilterLevel *)parent->user_data,
- (FilterElt *)parent->user_data2);
- if (((FilterElt *)parent->user_data2)->children == NULL)
- return FALSE;
- iter->stamp = tree_model_filter->stamp;
- iter->user_data = ((FilterElt *)parent->user_data2)->children;
- iter->user_data2 = ((FilterLevel *)iter->user_data)->array->data;
- }
-
- return TRUE;
-}
-
-static gboolean
-gtk_tree_model_filter_iter_has_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- GtkTreeIter child_iter;
- GtkTreeModelFilter *filter;
- FilterElt *elt;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp, FALSE);
-
- filter = GTK_TREE_MODEL_FILTER (tree_model);
-
- GET_CHILD_ITER (tree_model, &child_iter, iter);
- elt = FILTER_ELT (iter->user_data2);
-
- if (!elt->children
- && gtk_tree_model_iter_has_child (filter->child_model, &child_iter))
- gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data),
- elt);
-
- if (elt->children && elt->children->array->len > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gint
-gtk_tree_model_filter_iter_n_children (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- GtkTreeIter child_iter;
- GtkTreeModelFilter *filter;
- FilterElt *elt;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), 0);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, 0);
- if (iter)
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp, 0);
-
- filter = GTK_TREE_MODEL_FILTER (tree_model);
-
- if (!iter)
- {
- if (!GTK_TREE_MODEL_FILTER (tree_model)->root)
- gtk_tree_model_filter_build_level (GTK_TREE_MODEL_FILTER (tree_model), NULL, NULL);
-
-#ifdef VERBOSE
- g_print ("- length %d\n", FILTER_LEVEL (GTK_TREE_MODEL_FILTER (tree_model)->root)->array->len);
-#endif
-
- return FILTER_LEVEL (GTK_TREE_MODEL_FILTER (tree_model)->root)->array->len;
- }
-
- elt = FILTER_ELT (iter->user_data2);
- GET_CHILD_ITER (tree_model, &child_iter, iter);
-
- if (!elt->children &&
- gtk_tree_model_iter_has_child (filter->child_model, &child_iter))
- gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data),
- elt);
-
- if (elt->children && elt->children->array->len)
- return elt->children->array->len;
-
-
- return 0;
-}
-
-static gboolean
-gtk_tree_model_filter_iter_nth_child (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n)
-{
- FilterLevel *level;
- /* We have this for the iter == parent case */
- GtkTreeIter children;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- if (parent) g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == parent->stamp, FALSE);
-
- /* Use this instead of has_child to force us to build the level, if needed */
- if (gtk_tree_model_filter_iter_children (tree_model, &children, parent) == FALSE)
- {
- iter->stamp = 0;
- return FALSE;
- }
-
- level = children.user_data;
- if (n >= level->array->len)
- {
- iter->stamp = 0;
- return FALSE;
- }
-
- iter->stamp = GTK_TREE_MODEL_FILTER (tree_model)->stamp;
- iter->user_data = level;
- iter->user_data2 = &g_array_index (level->array, FilterElt, n);
-
- return TRUE;
-}
-
-static gboolean
-gtk_tree_model_filter_iter_parent (GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- GtkTreeIter *child)
-{
- FilterLevel *level;
-
- iter->stamp = 0;
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL, FALSE);
- g_return_val_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == child->stamp, FALSE);
-
- level = child->user_data;
-
- if (level->parent_level)
- {
- iter->stamp = GTK_TREE_MODEL_FILTER (tree_model)->stamp;
- iter->user_data = level->parent_level;
- iter->user_data2 = level->parent_elt;
-
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-gtk_tree_model_filter_ref_node (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *) tree_model;
- FilterLevel *level;
- FilterElt *elt;
-
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model));
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL);
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp);
-
- level = iter->user_data;
- elt = iter->user_data2;
-
- elt->ref_count++;
- level->ref_count++;
- if (level->ref_count == 1)
- {
- FilterLevel *parent_level = level->parent_level;
- FilterElt *parent_elt = level->parent_elt;
- /* We were at zero -- time to decrement the zero_ref_count val */
- do
- {
- if (parent_elt)
- parent_elt->zero_ref_count--;
- else
- tree_model_filter->zero_ref_count--;
-
- if (parent_level)
- {
- parent_elt = parent_level->parent_elt;
- parent_level = parent_level->parent_level;
- }
- }
- while (parent_level);
- }
-}
-
-static void
-gtk_tree_model_filter_unref_node (GtkTreeModel *tree_model,
- GtkTreeIter *iter)
-{
- GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *) tree_model;
- FilterLevel *level;
- FilterElt *elt;
-
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model));
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->child_model != NULL);
- g_return_if_fail (GTK_TREE_MODEL_FILTER (tree_model)->stamp == iter->stamp);
-
- level = iter->user_data;
- elt = iter->user_data2;
-
- g_return_if_fail (elt->ref_count > 0);
-
- elt->ref_count--;
- level->ref_count--;
- if (level->ref_count == 0)
- {
- FilterLevel *parent_level = level->parent_level;
- FilterElt *parent_elt = level->parent_elt;
-
- /* We are at zero -- time to increment the zero_ref_count val */
- while (parent_level)
- {
- parent_elt->zero_ref_count++;
-
- parent_elt = parent_level->parent_elt;
- parent_level = parent_level->parent_level;
- }
- tree_model_filter->zero_ref_count++;
- }
-}
-
-/* ModelFilter API */
-
-/**
- * gtk_tree_model_filter_set_model:
- * @tree_model_filter: The #GtkTreeModelFilter.
- * @child_model: A #GtkTreeModel, or NULL.
- *
- * Sets the model of @tree_model_filter to be @model. If @model is NULL, then the
- * old model is unset. The filter function is unset as a result of this call.
- * The model will be in an unfiltered state until a filter function is set.
- **/
-static void
-gtk_tree_model_filter_set_model (GtkTreeModelFilter *tree_model_filter,
- GtkTreeModel *child_model)
-{
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter));
-
- if (child_model)
- g_object_ref (G_OBJECT (child_model));
-
- if (tree_model_filter->child_model)
- {
- g_signal_handler_disconnect (G_OBJECT (tree_model_filter->child_model),
- tree_model_filter->changed_id);
- g_signal_handler_disconnect (G_OBJECT (tree_model_filter->child_model),
- tree_model_filter->inserted_id);
- g_signal_handler_disconnect (G_OBJECT (tree_model_filter->child_model),
- tree_model_filter->has_child_toggled_id);
- g_signal_handler_disconnect (G_OBJECT (tree_model_filter->child_model),
- tree_model_filter->deleted_id);
- g_signal_handler_disconnect (G_OBJECT (tree_model_filter->child_model),
- tree_model_filter->reordered_id);
-
- /* reset our state */
- gtk_tree_model_filter_free_level (tree_model_filter, tree_model_filter->root);
- tree_model_filter->root = NULL;
- g_object_unref (G_OBJECT (tree_model_filter->child_model));
- tree_model_filter->filter_column = -1;
- }
-
- tree_model_filter->child_model = child_model;
-
- if (child_model)
- {
- gint n_columns;
-
- g_object_ref (tree_model_filter->child_model);
- tree_model_filter->changed_id =
- g_signal_connect (child_model, "row_changed",
- G_CALLBACK (gtk_tree_model_filter_row_changed),
- tree_model_filter);
- tree_model_filter->inserted_id =
- g_signal_connect (child_model, "row_inserted",
- G_CALLBACK (gtk_tree_model_filter_row_inserted),
- tree_model_filter);
- tree_model_filter->has_child_toggled_id =
- g_signal_connect (child_model, "row_has_child_toggled",
- G_CALLBACK (gtk_tree_model_filter_row_has_child_toggled),
- tree_model_filter);
- tree_model_filter->deleted_id =
- g_signal_connect (child_model, "row_deleted",
- G_CALLBACK (gtk_tree_model_filter_row_deleted),
- tree_model_filter);
- tree_model_filter->reordered_id =
- g_signal_connect (child_model, "rows_reordered",
- G_CALLBACK (gtk_tree_model_filter_rows_reordered),
- tree_model_filter);
-
- tree_model_filter->child_flags = gtk_tree_model_get_flags (child_model);
- n_columns = gtk_tree_model_get_n_columns (child_model);
-
- tree_model_filter->stamp = g_random_int ();
- }
-}
-
-static void
-gtk_tree_model_filter_set_filter_column (GtkTreeModelFilter *tree_model_filter,
- gint filter_column)
-{
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter));
- g_return_if_fail (filter_column >= 0);
-
- tree_model_filter->filter_column = filter_column;
-}
-
-static void
-gtk_tree_model_filter_set_root (GtkTreeModelFilter *filter,
- GtkTreePath *root)
-{
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
-
- if (!root)
- filter->virtual_root = NULL;
- else
- filter->virtual_root = gtk_tree_path_copy (root);
-}
-
-static GtkTreePath *
-gtk_tree_model_filter_elt_get_path (FilterLevel *level,
- FilterElt *elt,
- GtkTreePath *root)
-{
- FilterLevel *walker = level;
- FilterElt *walker2 = elt;
- GtkTreePath *path;
- GtkTreePath *real_path;
-
- g_return_val_if_fail (level != NULL, NULL);
- g_return_val_if_fail (elt != NULL, NULL);
-
- path = gtk_tree_path_new ();
-
- while (walker)
- {
- gtk_tree_path_prepend_index (path, walker2->offset);
-
- walker2 = walker->parent_elt;
- walker = walker->parent_level;
- }
-
- if (root)
- {
- real_path = gtk_tree_path_copy (root);
-
- gtk_tree_path_add (real_path, path);
- gtk_tree_path_free (path);
- return real_path;
- }
-
- return path;
-}
-
-/**
- * gtk_tree_model_filter_get_model:
- * @tree_model: a #GtkTreeModelFilter
- *
- * Returns the model the #GtkTreeModelFilter is filtering.
- *
- * Return value: the "child model" being filtered
- **/
-GtkTreeModel *
-gtk_tree_model_filter_get_model (GtkTreeModelFilter *tree_model)
-{
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model), NULL);
-
- return tree_model->child_model;
-}
-
-static gboolean
-gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
- FilterLevel *level,
- gint offset)
-{
- int i = 0;
- int len;
- GtkTreePath *s_path = NULL;
- GtkTreeIter s_iter;
- FilterElt elt;
-
-#ifdef VERBOSE
- g_print ("_fetch_child for offset %d\n", offset);
-#endif
-
- if (level->parent_level)
- {
- s_path = gtk_tree_model_filter_elt_get_path (level->parent_level, level->parent_elt, filter->virtual_root);
- if (!s_path)
- return FALSE;
- gtk_tree_model_get_iter (filter->child_model, &s_iter, s_path);
-
- len = gtk_tree_model_iter_n_children (filter->child_model, &s_iter);
- }
- else
- len = gtk_tree_model_iter_n_children (filter->child_model, NULL);
-
- if (offset >= len)
- {
- if (s_path)
- gtk_tree_path_free (s_path);
- return FALSE;
- }
-
- /* add child */
- elt.offset = offset;
- elt.zero_ref_count = 0;
- elt.ref_count = 0;
- elt.children = NULL;
- elt.visible = FALSE;
- if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
- {
- if (!s_path)
- {
- if (filter->virtual_root)
- s_path = gtk_tree_path_copy (filter->virtual_root);
- else
- s_path = gtk_tree_path_new ();
- }
- gtk_tree_path_append_index (s_path, offset);
-#ifdef VERBOSE
- g_print ("fetching %s...\n", gtk_tree_path_to_string (s_path));
-#endif
-
- gtk_tree_model_get_iter (filter->child_model, &elt.iter, s_path);
-#ifdef VERBOSE
- g_print ("Fetch child, got iter c%p\n", elt.iter.user_data);
-#endif
- }
-
- if (s_path)
- gtk_tree_path_free (s_path);
-
- /* find index */
- for (i = 0; i < level->array->len; i++)
- if (g_array_index (level->array, FilterElt, i).offset > offset)
- break;
-
- g_array_insert_val (level->array, i, elt);
-
- for (i = 0; i < level->array->len; i++)
- {
- FilterElt *e = &(g_array_index (level->array, FilterElt, i));
- if (e->children)
- e->children->parent_elt = e;
- }
-
- return TRUE;
-}
-
-static GtkTreePath *
-gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *child_path,
- gboolean build_levels,
- gboolean fetch_childs)
-{
- gint *child_indices;
- GtkTreePath *retval;
- GtkTreePath *real_path;
- FilterLevel *level;
- gint i;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter), NULL);
- g_return_val_if_fail (tree_model_filter->child_model != NULL, NULL);
- g_return_val_if_fail (child_path != NULL, NULL);
-
- if (!tree_model_filter->virtual_root)
- real_path = gtk_tree_path_copy (child_path);
- else
- real_path = gtk_tree_path_apply_root (child_path, tree_model_filter->virtual_root);
-
- if (!real_path)
- return NULL;
-
- retval = gtk_tree_path_new ();
- child_indices = gtk_tree_path_get_indices (real_path);
-
- if (tree_model_filter->root == NULL && build_levels)
- gtk_tree_model_filter_build_level (tree_model_filter, NULL, NULL);
- level = FILTER_LEVEL (tree_model_filter->root);
-
- for (i = 0; i < gtk_tree_path_get_depth (real_path); i++)
- {
- gint j;
- gboolean found_child = FALSE;
-
- if (!level)
- {
- gtk_tree_path_free (real_path);
- gtk_tree_path_free (retval);
- return NULL;
- }
-
- for (j = 0; j < level->array->len; j++)
- {
- if ((g_array_index (level->array, FilterElt, j)).offset == child_indices[i])
- {
- gtk_tree_path_append_index (retval, j);
- if (g_array_index (level->array, FilterElt, j).children == NULL && build_levels)
- gtk_tree_model_filter_build_level (tree_model_filter, level, &g_array_index (level->array, FilterElt, j));
- level = g_array_index (level->array, FilterElt, j).children;
- found_child = TRUE;
- break;
- }
- }
- if (! found_child && fetch_childs)
- {
- /* hrm child not found, try to bring it back */
- if (!gtk_tree_model_filter_fetch_child (tree_model_filter, level, child_indices[i]))
- {
- gtk_tree_path_free (real_path);
- gtk_tree_path_free (retval);
- return NULL;
- }
-
- for (j = 0; j < level->array->len; j++)
- {
- if ((g_array_index (level->array, FilterElt, j)).offset == child_indices[i])
- {
- gtk_tree_path_append_index (retval, j);
- if (g_array_index (level->array, FilterElt, j).children == NULL && build_levels)
- gtk_tree_model_filter_build_level (tree_model_filter, level, &g_array_index (level->array, FilterElt, j));
- level = g_array_index (level->array, FilterElt, j).children;
- found_child = TRUE;
- break;
- }
- }
-
- if (!found_child)
- {
- /* our happy fun fetch attempt failed ?!?!? */
- gtk_tree_path_free (real_path);
- gtk_tree_path_free (retval);
- return NULL;
- }
- }
- else if (!found_child && !fetch_childs)
- {
- /* no path */
- gtk_tree_path_free (real_path);
- gtk_tree_path_free (retval);
- return NULL;
- }
- }
-
- gtk_tree_path_free (real_path);
- return retval;
-}
-
-/**
- * gtk_tree_model_filter_convert_child_path_to_path:
- * @tree_model_filter: A #GtkTreeModelFilter
- * @child_path: A #GtkTreePath to convert
- *
- * Converts @child_path to a path relative to @tree_model_filter. That is,
- * @child_path points to a path in the child model. The returned path will
- * point to the same row in the filtered model. If @child_path isn't a valid path
- * on the child model, then %NULL is returned.
- *
- * Return value: A newly allocated #GtkTreePath, or %NULL
- **/
-GtkTreePath *
-gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *child_path)
-{
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter), NULL);
- g_return_val_if_fail (tree_model_filter->child_model != NULL, NULL);
- g_return_val_if_fail (child_path != NULL, NULL);
-
- return gtk_real_tree_model_filter_convert_child_path_to_path (tree_model_filter, child_path, TRUE, TRUE);
-}
-
-/**
- * gtk_tree_model_filter_convert_child_iter_to_iter:
- * @tree_model_filter: A #GtkTreeModelFilter
- * @filter_iter: An uninitialized #GtkTreeIter.
- * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
- *
- * Sets @filter_iter to point to the row in @tree_model_filter that corresponds to
- * the row pointed at by @child_iter.
- **/
-void
-gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *filter_iter,
- GtkTreeIter *child_iter)
-{
- GtkTreePath *child_path, *path;
-
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter));
- g_return_if_fail (filter_iter != NULL);
- g_return_if_fail (child_iter != NULL);
-
- filter_iter->stamp = 0;
-
- child_path = gtk_tree_model_get_path (tree_model_filter->child_model, child_iter);
- g_return_if_fail (child_path != NULL);
-
- path = gtk_tree_model_filter_convert_child_path_to_path (tree_model_filter, child_path);
- gtk_tree_path_free (child_path);
- g_return_if_fail (path != NULL);
-
- gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_filter), filter_iter, path);
- gtk_tree_path_free (path);
-}
-
-/**
- * gtk_tree_model_filter_convert_path_to_child_path:
- * @tree_model_filter: A #GtkTreeModelFilter
- * @filtered_path: A #GtkTreePath to convert
- *
- * Converts @filter_path to a path on the child model of @tree_model_filter. That
- * is, @filter_path points ot a location in @tree_model_filter. The returned path
- * will point to the same location in the model not being filtered. If @path does not point to a
- *
- * Return value: A newly allocated #GtkTreePath, or %NULLL
- **/
-GtkTreePath *
-gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *filtered_path)
-{
- gint *filtered_indices;
- GtkTreePath *retval;
- FilterLevel *level;
- gint i;
- /* FIXME: THIS IS BROKEN!!!!!!!!!!!!!!!!!!!! */
-
- /* FIXME: this needs virtual root support */
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter), NULL);
- g_return_val_if_fail (tree_model_filter->child_model != NULL, NULL);
- g_return_val_if_fail (filtered_path != NULL, NULL);
-
- g_warning ("_convert_path_to_child_path: THIS FUNCTION IS BROKEN!\n");
-
- retval = gtk_tree_path_new ();
- filtered_indices = gtk_tree_path_get_indices (filtered_path);
- if (tree_model_filter->root == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter, NULL, NULL);
- level = FILTER_LEVEL (tree_model_filter->root);
-
- for (i = 0; i < gtk_tree_path_get_depth (filtered_path); i++)
- {
- if ((level == NULL) ||
- (level->array->len < filtered_indices[i]))
- {
- gtk_tree_path_free (retval);
- return NULL;
- }
- if (g_array_index (level->array, FilterElt, filtered_indices[i]).children == NULL)
- gtk_tree_model_filter_build_level (tree_model_filter, level, &g_array_index (level->array, FilterElt, filtered_indices[i]));
- if (level == NULL)
-
- gtk_tree_path_append_index (retval, g_array_index (level->array, FilterElt, i).offset);
- }
-
- return retval;
-}
-
-/**
- * gtk_tree_model_filter_convert_iter_to_child_iter:
- * @tree_model_filter: A #GtkTreeModelFilter
- * @child_iter: An uninitialized #GtkTreeIter
- * @filtered_iter: A valid #GtkTreeIter pointing to a row on @tree_model_filter.
- *
- * Sets @child_iter to point to the row pointed to by *filtered_iter.
- **/
-void
-gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *child_iter,
- GtkTreeIter *filtered_iter)
-{
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter));
- g_return_if_fail (tree_model_filter->child_model != NULL);
- g_return_if_fail (child_iter != NULL);
- g_return_if_fail (filtered_iter != NULL);
- g_return_if_fail (filtered_iter->stamp == tree_model_filter->stamp);
-
- if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (tree_model_filter))
- {
- *child_iter = FILTER_ELT (filtered_iter->user_data2)->iter;
- }
- else
- {
- GtkTreePath *path;
- FilterElt *elt;
- FilterLevel *level;
-
- elt = FILTER_ELT (filtered_iter->user_data2);
- level = FILTER_LEVEL (filtered_iter->user_data);
-
- path = gtk_tree_model_filter_elt_get_path (level, elt,
- tree_model_filter->virtual_root);
-
- gtk_tree_model_get_iter (tree_model_filter->child_model, child_iter, path);
- gtk_tree_path_free (path);
- }
-}
-
-static void
-gtk_tree_model_filter_build_level (GtkTreeModelFilter *tree_model_filter,
- FilterLevel *parent_level,
- FilterElt *parent_elt)
-{
- GtkTreeIter iter;
- GtkTreeIter root;
- FilterLevel *new_level;
- gint length = 0;
- gint i;
-
- g_assert (tree_model_filter->child_model != NULL);
-
- if (parent_level == NULL)
- {
- if (tree_model_filter->virtual_root)
- {
- if (gtk_tree_model_get_iter (tree_model_filter->child_model, &root, tree_model_filter->virtual_root) == FALSE)
- return;
- length = gtk_tree_model_iter_n_children (tree_model_filter->child_model, &root);
-#ifdef VERBOSE
- g_print ("--- vroot %d children\n", length);
-#endif
-
- if (gtk_tree_model_iter_children (tree_model_filter->child_model, &iter, &root) == FALSE)
- return;
- }
- else
- {
- if (gtk_tree_model_get_iter_root (tree_model_filter->child_model, &iter) == FALSE)
- return;
- length = gtk_tree_model_iter_n_children (tree_model_filter->child_model, NULL);
- }
- }
- else
- {
- GtkTreeIter parent_iter;
- GtkTreeIter child_parent_iter;
-
- parent_iter.stamp = tree_model_filter->stamp;
- parent_iter.user_data = parent_level;
- parent_iter.user_data2 = parent_elt;
-
- gtk_tree_model_filter_convert_iter_to_child_iter (tree_model_filter,
- &child_parent_iter,
- &parent_iter);
- if (gtk_tree_model_iter_children (tree_model_filter->child_model,
- &iter,
- &child_parent_iter) == FALSE)
- return;
- length = gtk_tree_model_iter_n_children (tree_model_filter->child_model, &child_parent_iter);
- }
-
- g_return_if_fail (length > 0);
-
- new_level = g_new (FilterLevel, 1);
- new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (FilterElt), length); new_level->ref_count = 0;
- new_level->parent_elt = parent_elt;
- new_level->parent_level = parent_level;
-
- if (parent_elt)
- parent_elt->children = new_level;
- else
- tree_model_filter->root = new_level;
-
- /* increase the count of zero ref_counts.*/
- while (parent_level)
- {
- parent_elt->zero_ref_count++;
-
- parent_elt = parent_level->parent_elt;
- parent_level = parent_level->parent_level;
- }
- if (new_level != tree_model_filter->root)
- tree_model_filter->zero_ref_count++;
-
- i = 0;
- do
- {
- if (gtk_tree_model_filter_visible (tree_model_filter, &iter))
- {
- FilterElt filter_elt;
-
- filter_elt.offset = i;
- filter_elt.zero_ref_count = 0;
- filter_elt.ref_count = 0;
- filter_elt.children = NULL;
- filter_elt.visible = TRUE;
-
- if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (tree_model_filter))
- filter_elt.iter = iter;
-
- g_array_append_val (new_level->array, filter_elt);
- }
- i++;
- } while (gtk_tree_model_iter_next (tree_model_filter->child_model, &iter));
-}
-
-static void
-gtk_tree_model_filter_free_level (GtkTreeModelFilter *tree_model_filter,
- FilterLevel *filter_level)
-{
- gint i;
-
-#ifdef VERBOSE
- g_print ("freeing level: %p, %p (ref = %d)\n", filter_level,
- filter_level->array, filter_level->ref_count);
- g_print ("-- parents - elt: %p, level %p\n",
- filter_level->parent_elt, filter_level->parent_level);
-#endif
-
- g_assert (filter_level);
-
-#ifdef VERBOSE
- g_print ("-- freeing current level (ref = %d)\n",filter_level->ref_count);
-#endif
-
- if (filter_level->ref_count == 0)
- {
- FilterLevel *parent_level = filter_level->parent_level;
- FilterElt *parent_elt = filter_level->parent_elt;
-
- do
- {
- if (parent_elt)
- parent_elt->zero_ref_count--;
- else
- tree_model_filter->zero_ref_count--;
-
- if (parent_level)
- {
- parent_elt = parent_level->parent_elt;
- parent_level = parent_level->parent_level;
- }
- }
- while (parent_level);
- }
-
-#ifdef VERBOSE
- g_print ("-- freeing children\n");
-#endif
-
- for (i = 0; i < filter_level->array->len; i++)
- {
- if (g_array_index (filter_level->array, FilterElt, i).children)
- gtk_tree_model_filter_free_level (tree_model_filter,
- FILTER_LEVEL(g_array_index (filter_level->array, FilterElt, i).children));
- }
-
- if (filter_level->parent_elt)
- {
- filter_level->parent_elt->children = NULL;
- }
- else
- {
- tree_model_filter->root = NULL;
- }
-
-#ifdef VERBOSE
- g_print ("free %p\n", filter_level->array);
-#endif
-
- g_array_free (filter_level->array, TRUE);
- filter_level->array = NULL;
-
-#ifdef VERBOSE
- g_print ("free %p\n", filter_level);
-#endif
-
- g_free (filter_level);
- filter_level = NULL;
-
-#ifdef VERBOSE
- g_print ("-------- done ---------\n");
-#endif
-}
-
-static void
-gtk_tree_model_filter_increment_stamp (GtkTreeModelFilter *tree_model_filter)
-{
- while (tree_model_filter->stamp == 0) tree_model_filter->stamp++;
-
- gtk_tree_model_filter_clear_cache (tree_model_filter);
-}
-
-static gboolean
-gtk_tree_model_filter_visible (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *child_iter)
-{
- GValue val = {0, };
-
- gtk_tree_model_get_value (tree_model_filter->child_model,
- child_iter, tree_model_filter->filter_column,
- &val);
-
- if (g_value_get_boolean (&val))
- {
- g_value_unset (&val);
- return TRUE;
- }
-
- g_value_unset (&val);
- return FALSE;
-}
-
-static void
-gtk_tree_path_add (GtkTreePath *path1,
- GtkTreePath *path2)
-{
- int i;
- gint depth;
- gint *indices;
-
- g_return_if_fail (path1 != NULL);
- g_return_if_fail (path2 != NULL);
-
- depth = gtk_tree_path_get_depth (path2);
- indices = gtk_tree_path_get_indices (path2);
-
- for (i = 0; i < depth; i++)
- gtk_tree_path_append_index (path1, indices[i]);
-}
-
-static GtkTreePath *
-gtk_tree_path_apply_root (GtkTreePath *path,
- GtkTreePath *root)
-{
- GtkTreePath *retval;
- int i;
- gint depth;
- gint *indices;
-
- if (gtk_tree_path_get_depth (path) <= gtk_tree_path_get_depth (root))
- return NULL;
-
- depth = gtk_tree_path_get_depth (path);
- indices = gtk_tree_path_get_indices (path);
-
- for (i = 0; i < gtk_tree_path_get_depth (root); i++)
- if (indices[i] != gtk_tree_path_get_indices (root)[i])
- return NULL;
-
- retval = gtk_tree_path_new ();
-
- for (; i < depth; i++)
- gtk_tree_path_append_index (retval, indices[i]);
-
- return retval;
-}
-
-static void
-gtk_tree_model_filter_clear_cache_helper (GtkTreeModelFilter *tree_model_filter,
- FilterLevel *level)
-{
- gint i;
-
- g_assert (level != NULL);
-
- for (i = 0; i < level->array->len; i++)
- {
- if (g_array_index (level->array, FilterElt, i).zero_ref_count > 0)
- gtk_tree_model_filter_clear_cache_helper (tree_model_filter, g_array_index (level->array, FilterElt, i).children);
- }
-
- if (level->ref_count == 0 && level != tree_model_filter->root)
- {
- gtk_tree_model_filter_free_level (tree_model_filter, level);
- return;
- }
-}
-
-/**
- * gtk_tree_model_filter_clear_cache:
- * @tree_model_filter: A #GtkTreeModelFilter
- *
- * This function should almost never be called. It clears the @tree_model_filter
- * of any cached iterators that haven't been reffed with
- * gtk_tree_model_ref_node(). This might be useful if the child model being
- * filtered is static (and doesn't change often) and there has been a lot of
- * unreffed access to nodes. As a side effect of this function, all unreffed
- * iters will be invalid.
- **/
-void
-gtk_tree_model_filter_clear_cache (GtkTreeModelFilter *tree_model_filter)
-{
- g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (tree_model_filter));
-
- if (tree_model_filter->zero_ref_count)
- gtk_tree_model_filter_clear_cache_helper (tree_model_filter, (FilterLevel *)tree_model_filter->root);
-}
diff --git a/src/gtktreemodelfilter.h b/src/gtktreemodelfilter.h
deleted file mode 100644
index 47778a19..00000000
--- a/src/gtktreemodelfilter.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* gtktreemodelfilter.h
- * Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
- * Copyright (C) 2001,2002 Kristian Rietveld <kris@gtk.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GTK_TREE_MODEL_FILTER_H__
-#define __GTK_TREE_MODEL_FILTER_H__
-
-#include <gtk/gtktreemodel.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define GTK_TYPE_TREE_MODEL_FILTER (gtk_tree_model_filter_get_type ())
-#define GTK_TREE_MODEL_FILTER(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilter))
-#define GTK_TREE_MODEL_FILTER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilterClass))
-#define GTK_IS_TREE_MODEL_FILTER(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_MODEL_FILTER))
-#define GTK_IS_TREE_MODEL_FILTER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TREE_MODEL_FILTER))
-#define GTK_TREE_MODEL_FILTER_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilterClass))
-
-typedef struct _GtkTreeModelFilter GtkTreeModelFilter;
-typedef struct _GtkTreeModelFilterClass GtkTreeModelFilterClass;
-
-struct _GtkTreeModelFilter
-{
- GObject parent;
-
- /* < private > */
- gpointer root;
- gint stamp;
- guint child_flags;
- GtkTreeModel *child_model;
- gint zero_ref_count;
-
- gint filter_column;
-
- gpointer filter_func;
- gpointer user_data;
-
- GtkTreePath *virtual_root;
-
- /* signal ids */
- guint changed_id;
- guint inserted_id;
- guint has_child_toggled_id;
- guint deleted_id;
- guint reordered_id;
-};
-
-struct _GtkTreeModelFilterClass
-{
- GObjectClass parent_class;
-};
-
-GtkType gtk_tree_model_filter_get_type (void);
-GtkTreeModel *gtk_tree_model_filter_new_with_model (GtkTreeModel *child_model,
- gint filter_column,
- GtkTreePath *virtual_root);
-void gtk_tree_model_filter_clear_cache (GtkTreeModelFilter *tree_model_filter);
-
-void gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *filter_iter,
- GtkTreeIter *child_iter);
-void gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *tree_model_filter,
- GtkTreeIter *child_iter,
- GtkTreeIter *filtered_iter);
-GtkTreePath *gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *child_path);
-GtkTreePath *gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *tree_model_filter,
- GtkTreePath *filtered_path);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __GTK_TREE_MODEL_FILTER_H__ */
diff --git a/src/yelp-index-model.c b/src/yelp-index-model.c
index 5b40b61e..1f471628 100644
--- a/src/yelp-index-model.c
+++ b/src/yelp-index-model.c
@@ -148,7 +148,9 @@ yim_init (YelpIndexModel *model)
do {
priv->stamp = g_random_int ();
} while (priv->stamp == 0);
-
+
+ priv->index_words = NULL;
+
model->priv = priv;
}
@@ -172,14 +174,23 @@ yim_finalize (GObject *object)
static gint
yim_get_n_columns (GtkTreeModel *tree_model)
{
- return 1;
+ return YELP_INDEX_MODEL_NR_OF_COLS;
}
static GType
yim_get_column_type (GtkTreeModel *tree_model,
gint column)
{
- return G_TYPE_STRING;
+ switch (column) {
+ case YELP_INDEX_MODEL_COL_NAME:
+ return G_TYPE_STRING;
+ break;
+ case YELP_INDEX_MODEL_COL_SECTION:
+ return G_TYPE_POINTER;
+ break;
+ default:
+ return G_TYPE_INVALID;
+ }
}
static gboolean
@@ -258,9 +269,14 @@ yim_get_value (GtkTreeModel *tree_model,
section = (YelpSection *) (G_LIST(iter->user_data)->data);
switch (column) {
- case 0:
+ case YELP_INDEX_MODEL_COL_NAME:
+ g_value_init (value, G_TYPE_STRING);
g_value_set_string (value, section->name);
break;
+ case YELP_INDEX_MODEL_COL_SECTION:
+ g_value_init (value, G_TYPE_POINTER);
+ g_value_set_pointer (value, section);
+ break;
default:
g_warning ("Bad column %d requested", column);
}
@@ -375,20 +391,37 @@ YelpIndexModel *
yelp_index_model_new (void)
{
YelpIndexModel *model;
- YelpIndexModelPriv *priv;
model = g_object_new (YELP_TYPE_INDEX_MODEL, NULL);
- priv = model->priv;
-
-
return model;
}
void
yelp_index_model_set_words (YelpIndexModel *model, GList *index_words)
{
- g_return_if_fail (YELP_IS_INDEX_MODEL (model));
+ YelpIndexModelPriv *priv;
+ GList *node;
+ gint i = 0;
+ GtkTreePath *path;
+ GtkTreeIter iter;
- model->priv->index_words = index_words;
+ g_return_if_fail (YELP_IS_INDEX_MODEL (model));
+
+ priv = model->priv;
+
+ priv->index_words = index_words;
+
+ for (node = priv->index_words; node; node = node->next) {
+ path = gtk_tree_path_new ();
+
+ gtk_tree_path_append_index (path, i);
+
+ yim_get_iter (GTK_TREE_MODEL (model), &iter, path);
+
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (model),
+ path, &iter);
+
+ gtk_tree_path_free (path);
+ }
}
diff --git a/src/yelp-index-model.h b/src/yelp-index-model.h
index e4504320..f1a28ed2 100644
--- a/src/yelp-index-model.h
+++ b/src/yelp-index-model.h
@@ -51,6 +51,13 @@ struct _YelpIndexModelClass
GObjectClass parent_class;
};
+enum {
+ YELP_INDEX_MODEL_COL_NAME,
+ YELP_INDEX_MODEL_COL_SECTION,
+ YELP_INDEX_MODEL_NR_OF_COLS
+};
+
+
GtkType yelp_index_model_get_type (void);
YelpIndexModel *yelp_index_model_new (void);
diff --git a/src/yelp-view-index.c b/src/yelp-view-index.c
index 184396a6..642e6a3d 100644
--- a/src/yelp-view-index.c
+++ b/src/yelp-view-index.c
@@ -145,7 +145,7 @@ yvi_index_selection_changed_cb (GtkTreeSelection *selection,
if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
gtk_tree_model_get (GTK_TREE_MODEL (priv->model), &iter,
- 1, &section,
+ YELP_INDEX_MODEL_COL_SECTION, &section,
-1);
/* FIXME: Emit index:string */