]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreemodelsort.c
Custom tab label
[~andy/gtk] / gtk / gtktreemodelsort.c
index 9ebe28d9d75c49bf1d354b44802adcb5e7fc1346..0a744aca7ed3ad07ce0d7d0b3820166906d69d01 100644 (file)
@@ -37,6 +37,7 @@
  * we warned you and we're not liable for any head injuries.
  */
 
+#include <config.h>
 #include <string.h>
 
 #include "gtktreemodelsort.h"
@@ -44,7 +45,9 @@
 #include "gtktreestore.h"
 #include "gtktreedatalist.h"
 #include "gtkintl.h"
+#include "gtkprivate.h"
 #include "gtktreednd.h"
+#include "gtkalias.h"
 
 typedef struct _SortElt SortElt;
 typedef struct _SortLevel SortLevel;
@@ -98,15 +101,13 @@ enum {
 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
 
-#define GET_CHILD_ITER(tree_model_sort,child_iter,sort_iter) gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT (tree_model_sort), child_iter, sort_iter);
+#define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter) gtk_tree_model_sort_convert_iter_to_child_iter((GtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter));
 
 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
 
-#define VALID_ITER(iter, tree_model_sort) (iter != NULL && iter->user_data != NULL && iter->user_data2 != NULL && tree_model_sort->stamp == iter->stamp)
+#define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->stamp == (iter)->stamp)
 
 /* general (object/interface init, etc) */
-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_tree_sortable_init    (GtkTreeSortableIface  *iface);
 static void gtk_tree_model_sort_drag_source_init      (GtkTreeDragSourceIface*iface);
@@ -235,68 +236,14 @@ static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTree
                                                                         GtkTreePath      *child_path,
                                                                         gboolean          build_levels);
 
-static GObjectClass *parent_class = NULL;
 
-GType
-gtk_tree_model_sort_get_type (void)
-{
-  static GType 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
-      };
-
-      static const GInterfaceInfo sortable_info =
-      {
-        (GInterfaceInitFunc) gtk_tree_model_sort_tree_sortable_init,
-        NULL,
-        NULL
-      };
-
-      static const GInterfaceInfo drag_source_info =
-      {
-        (GInterfaceInitFunc) gtk_tree_model_sort_drag_source_init,
-        NULL,
-        NULL
-      };
-
-      tree_model_sort_type =
-       g_type_register_static (G_TYPE_OBJECT, "GtkTreeModelSort",
-                               &tree_model_sort_info, 0);
-
-      g_type_add_interface_static (tree_model_sort_type,
-                                   GTK_TYPE_TREE_MODEL,
-                                   &tree_model_info);
-
-      g_type_add_interface_static (tree_model_sort_type,
-                                   GTK_TYPE_TREE_SORTABLE,
-                                   &sortable_info);
-
-      g_type_add_interface_static (tree_model_sort_type,
-                                   GTK_TYPE_TREE_DRAG_SOURCE,
-                                   &drag_source_info);
-    }
-
-  return tree_model_sort_type;
-}
+G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+                                               gtk_tree_model_sort_tree_model_init)
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
+                                               gtk_tree_model_sort_tree_sortable_init)
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
+                                               gtk_tree_model_sort_drag_source_init))
 
 static void
 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
@@ -314,7 +261,6 @@ gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
   GObjectClass *object_class;
 
   object_class = (GObjectClass *) class;
-  parent_class = g_type_class_peek_parent (class);
 
   object_class->set_property = gtk_tree_model_sort_set_property;
   object_class->get_property = gtk_tree_model_sort_get_property;
@@ -325,10 +271,10 @@ gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
   g_object_class_install_property (object_class,
                                    PROP_MODEL,
                                    g_param_spec_object ("model",
-                                                       _("TreeModelSort Model"),
-                                                       _("The model for the TreeModelSort to sort"),
+                                                       P_("TreeModelSort Model"),
+                                                       P_("The model for the TreeModelSort to sort"),
                                                        GTK_TYPE_TREE_MODEL,
-                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+                                                       GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -372,7 +318,7 @@ gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
  * gtk_tree_model_sort_new_with_model:
  * @child_model: A #GtkTreeModel
  *
- * Creates a new #GtkTreeModel, with @child_model as the child_model.
+ * Creates a new #GtkTreeModel, with @child_model as the child model.
  *
  * Return value: A new #GtkTreeModel.
  */
@@ -408,7 +354,7 @@ gtk_tree_model_sort_finalize (GObject *object)
     }
 
   /* must chain up */
-  parent_class->finalize (object);
+  G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
 }
 
 static void
@@ -491,6 +437,8 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
   level = iter.user_data;
   elt = iter.user_data2;
 
+  level->ref_count++;
+
   if (level->array->len < 2 ||
       (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
        tree_model_sort->default_sort_func == NO_SORT_FUNC))
@@ -502,9 +450,11 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
 
       gtk_tree_path_free (path);
 
+      level->ref_count--;
+
       return;
     }
-
+  
   if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
     {
       gtk_tree_model_get_iter (tree_model_sort->child_model,
@@ -607,6 +557,8 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
       g_free (new_order);
     }
 
+  level->ref_count--;
+
   /* emit row_changed signal (at new location) */
   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
   gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
@@ -691,22 +643,6 @@ gtk_tree_model_sort_row_inserted (GtkTreeModel          *s_model,
 
       if (!elt->children)
        {
-         GtkTreePath *tmppath;
-         GtkTreeIter  tmpiter;
-
-         tmpiter.stamp = tree_model_sort->stamp;
-         tmpiter.user_data = level;
-         tmpiter.user_data2 = elt;
-
-         tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &tmpiter);
-         if (tmppath)
-           {
-             gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data),
-                                                   tmppath,
-                                                   &tmpiter);
-             gtk_tree_path_free (tmppath);
-           }
-
          /* not covering this signal */
          goto done;
        }
@@ -719,6 +655,12 @@ gtk_tree_model_sort_row_inserted (GtkTreeModel          *s_model,
   if (!parent_level)
     goto done;
 
+  if (level->ref_count == 0 && level != tree_model_sort->root)
+    {
+      gtk_tree_model_sort_free_level (tree_model_sort, level);
+      goto done;
+    }
+
   if (!gtk_tree_model_sort_insert_value (tree_model_sort,
                                         parent_level,
                                         s_path,
@@ -768,7 +710,6 @@ gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
   gtk_tree_path_free (path);
 }
 
-/* FIXME: I still have doubts if this works */
 static void
 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
                                 GtkTreePath  *s_path,
@@ -805,12 +746,20 @@ gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
   while (elt->ref_count > 0)
     gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
 
-  if (level->ref_count == 0 && level != tree_model_sort->root)
+  if (level->ref_count == 0)
     {
-      /* This will prune the level, so I can just emit the signal and not worry
-       * about cleaning this level up. */
+      /* This will prune the level, so I can just emit the signal and 
+       * not worry about cleaning this level up. 
+       * Careful, root level is not cleaned up in increment stamp.
+       */
       gtk_tree_model_sort_increment_stamp (tree_model_sort);
       gtk_tree_path_free (path);
+      if (level == tree_model_sort->root)
+       {
+         gtk_tree_model_sort_free_level (tree_model_sort, 
+                                         tree_model_sort->root);
+         tree_model_sort->root = NULL;
+       }
       return;
     }
 
@@ -929,12 +878,12 @@ gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
 static GtkTreeModelFlags
 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreeModelFlags flags;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, 0);
 
-  flags = gtk_tree_model_get_flags (GTK_TREE_MODEL_SORT (tree_model)->child_model);
+  flags = gtk_tree_model_get_flags (tree_model_sort->child_model);
 
   if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
     return GTK_TREE_MODEL_LIST_ONLY;
@@ -947,8 +896,6 @@ gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
-
   if (tree_model_sort->child_model == 0)
     return 0;
 
@@ -959,10 +906,11 @@ 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)->child_model != NULL, G_TYPE_INVALID);
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
+
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, G_TYPE_INVALID);
 
-  return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->child_model, index);
+  return gtk_tree_model_get_column_type (tree_model_sort->child_model, index);
 }
 
 static gboolean
@@ -970,15 +918,13 @@ gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
                              GtkTreeIter  *iter,
                              GtkTreePath  *path)
 {
-  GtkTreeModelSort *tree_model_sort;
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   gint *indices;
   SortLevel *level;
   gint depth, i;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
 
-  tree_model_sort = (GtkTreeModelSort *) tree_model;
   indices = gtk_tree_path_get_indices (path);
 
   if (tree_model_sort->root == NULL)
@@ -1017,13 +963,13 @@ static GtkTreePath *
 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
                              GtkTreeIter  *iter)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreePath *retval;
   SortLevel *level;
   SortElt *elt;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, NULL);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, NULL);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
+  g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, NULL);
 
   retval = gtk_tree_path_new ();
   level = iter->user_data;
@@ -1045,14 +991,14 @@ gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
                               gint          column,
                               GValue       *value)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreeIter child_iter;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
+  g_return_if_fail (tree_model_sort->child_model != NULL);
+  g_return_if_fail (VALID_ITER (iter, tree_model_sort));
 
-  GET_CHILD_ITER (tree_model, &child_iter, iter);
-  gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->child_model,
+  GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
+  gtk_tree_model_get_value (tree_model_sort->child_model,
                            &child_iter, column, value);
 }
 
@@ -1060,12 +1006,12 @@ static gboolean
 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
                               GtkTreeIter  *iter)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   SortLevel *level;
   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)->child_model != NULL, FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
+  g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, FALSE);
 
   level = iter->user_data;
   elt = iter->user_data2;
@@ -1089,9 +1035,9 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
   SortLevel *level;
 
   iter->stamp = 0;
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
-  if (parent) g_return_val_if_fail (tree_model_sort->stamp == parent->stamp, FALSE);
+  if (parent) 
+    g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
 
   if (parent == NULL)
     {
@@ -1125,33 +1071,34 @@ static gboolean
 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
                                    GtkTreeIter  *iter)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreeIter child_iter;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
+  g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
 
-  GET_CHILD_ITER (tree_model, &child_iter, iter);
+  GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
 
-  return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
+  return gtk_tree_model_iter_has_child (tree_model_sort->child_model, &child_iter);
 }
 
 static gint
 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
                                     GtkTreeIter  *iter)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreeIter child_iter;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0);
-  if (iter) g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, 0);
+  if (iter) 
+    g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
 
   if (iter == NULL)
-    return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->child_model, NULL);
+    return gtk_tree_model_iter_n_children (tree_model_sort->child_model, NULL);
 
-  GET_CHILD_ITER (tree_model, &child_iter, iter);
+  GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
 
-  return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
+  return gtk_tree_model_iter_n_children (tree_model_sort->child_model, &child_iter);
 }
 
 static gboolean
@@ -1160,12 +1107,13 @@ gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
                                    GtkTreeIter  *parent,
                                    gint          n)
 {
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   SortLevel *level;
   /* We have this for the iter == parent case */
   GtkTreeIter children;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
-  if (parent) g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
+  if (parent) 
+    g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
 
   /* Use this instead of has_child to force us to build the level, if needed */
   if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
@@ -1181,7 +1129,7 @@ gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
       return FALSE;
     }
 
-  iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+  iter->stamp = tree_model_sort->stamp;
   iter->user_data = level;
   iter->user_data2 = &g_array_index (level->array, SortElt, n);
 
@@ -1192,19 +1140,19 @@ static gboolean
 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
                                 GtkTreeIter  *iter,
                                 GtkTreeIter  *child)
-{
+{ 
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   SortLevel *level;
 
   iter->stamp = 0;
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
-  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
+  g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
+  g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
 
   level = child->user_data;
 
   if (level->parent_level)
     {
-      iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+      iter->stamp = tree_model_sort->stamp;
       iter->user_data = level->parent_level;
       iter->user_data2 = level->parent_elt;
 
@@ -1222,13 +1170,12 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
   SortLevel *level;
   SortElt *elt;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
+  g_return_if_fail (tree_model_sort->child_model != NULL);
+  g_return_if_fail (VALID_ITER (iter, tree_model_sort));
 
-  GET_CHILD_ITER (tree_model, &child_iter, iter);
+  GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
 
-  gtk_tree_model_ref_node (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
+  gtk_tree_model_ref_node (tree_model_sort->child_model, &child_iter);
 
   level = iter->user_data;
   elt = iter->user_data2;
@@ -1263,18 +1210,19 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
                                     gboolean      propagate_unref)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
-  GtkTreeIter child_iter;
   SortLevel *level;
   SortElt *elt;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
-  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
-
-  GET_CHILD_ITER (tree_model, &child_iter, iter);
+  g_return_if_fail (tree_model_sort->child_model != NULL);
+  g_return_if_fail (VALID_ITER (iter, tree_model_sort));
 
   if (propagate_unref)
-    gtk_tree_model_unref_node (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
+    {
+      GtkTreeIter child_iter;
+
+      GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
+      gtk_tree_model_unref_node (tree_model_sort->child_model, &child_iter);
+    }
 
   level = iter->user_data;
   elt = iter->user_data2;
@@ -1316,16 +1264,15 @@ gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
-
-  if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
-    return FALSE;
-
   if (sort_column_id)
     *sort_column_id = tree_model_sort->sort_column_id;
   if (order)
     *order = tree_model_sort->order;
 
+  if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
+      tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
+    return FALSE;
+  
   return TRUE;
 }
 
@@ -1336,8 +1283,6 @@ gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
-
   if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
     {
       GtkTreeDataSortHeader *header = NULL;
@@ -1379,43 +1324,10 @@ gtk_tree_model_sort_set_sort_func (GtkTreeSortable        *sortable,
                                   GtkDestroyNotify        destroy)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
-  GtkTreeDataSortHeader *header = NULL;
-  GList *list;
-
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
-  g_return_if_fail (func != NULL);
-
-  for (list = tree_model_sort->sort_list; list; list = list->next)
-    {
-      GtkTreeDataSortHeader *list_header;
-
-      list_header = (GtkTreeDataSortHeader*) list->data;
-      if (list_header->sort_column_id == sort_column_id)
-       {
-         header = list_header;
-         break;
-       }
-    }
 
-  if (header == NULL)
-    {
-      header = g_new0 (GtkTreeDataSortHeader, 1);
-      header->sort_column_id = sort_column_id;
-      tree_model_sort->sort_list = g_list_append (tree_model_sort->sort_list,
-                                                 header);
-    }
-
-  if (header->destroy)
-    {
-      GtkDestroyNotify d = header->destroy;
-
-      header->destroy = NULL;
-      d (header->data);
-    }
-
-  header->func = func;
-  header->data = data;
-  header->destroy = destroy;
+  tree_model_sort->sort_list = _gtk_tree_data_list_set_header (tree_model_sort->sort_list,
+                                                              sort_column_id,
+                                                              func, data, destroy);
 
   if (tree_model_sort->sort_column_id == sort_column_id)
     gtk_tree_model_sort_sort (tree_model_sort);
@@ -1429,8 +1341,6 @@ gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
-
   if (tree_model_sort->default_sort_destroy)
     {
       GtkDestroyNotify d = tree_model_sort->default_sort_destroy;
@@ -1452,8 +1362,6 @@ gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
-
   return (tree_model_sort->default_sort_func != NULL);
 }
 
@@ -1466,9 +1374,6 @@ gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
   GtkTreePath *child_path;
   gboolean draggable;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (drag_source), FALSE);
-  g_return_val_if_fail (path != NULL, FALSE);
-
   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
                                                                path);
   draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path);
@@ -1486,11 +1391,7 @@ gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
   GtkTreePath *child_path;
   gboolean gotten;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (drag_source), FALSE);
-  g_return_val_if_fail (path != NULL, FALSE);
-
-  child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
-                                                               path);
+  child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
   gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path, selection_data);
   gtk_tree_path_free (child_path);
 
@@ -1505,11 +1406,7 @@ gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
   GtkTreePath *child_path;
   gboolean deleted;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (drag_source), FALSE);
-  g_return_val_if_fail (path != NULL, FALSE);
-
-  child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
-                                                               path);
+  child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
   deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path);
   gtk_tree_path_free (child_path);
 
@@ -1608,12 +1505,13 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
 
   SortData data;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
   g_return_if_fail (level != NULL);
 
   if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
     return;
 
+  level->ref_count++;
+
   /* Set up data */
   data.tree_model_sort = tree_model_sort;
   if (level->parent_elt)
@@ -1735,13 +1633,13 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
     }
 
   g_free (new_order);
+
+  level->ref_count--;
 }
 
 static void
 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
 {
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
-
   if (!tree_model_sort->root)
     return;
 
@@ -1919,18 +1817,17 @@ gtk_tree_model_sort_elt_get_path (SortLevel *level,
 /**
  * gtk_tree_model_sort_set_model:
  * @tree_model_sort: The #GtkTreeModelSort.
- * @child_model: A #GtkTreeModel, or NULL.
+ * @child_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.  The sort function is unset as a result of this call.
- * The model will be in an unsorted state until a sort function is set.
+ * Sets the model of @tree_model_sort to be @model.  If @model is %NULL, 
+ * then the old model is unset.  The sort function is unset as a result 
+ * of this call. The model will be in an unsorted state until a sort 
+ * function is set.
  **/
 static void
 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
                                GtkTreeModel     *child_model)
 {
-  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
-
   if (child_model)
     g_object_ref (child_model);
 
@@ -2008,7 +1905,7 @@ gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
  * Return value: the "child model" being sorted
  **/
 GtkTreeModel *
-gtk_tree_model_sort_get_model (GtkTreeModelSort  *tree_model)
+gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
 {
   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
 
@@ -2026,7 +1923,6 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode
   SortLevel *level;
   gint i;
 
-  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
   g_return_val_if_fail (child_path != NULL, NULL);
 
@@ -2085,8 +1981,8 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode
  * 
  * Converts @child_path to a path relative to @tree_model_sort.  That is,
  * @child_path points to a path in the child model.  The returned path will
- * point to the same row in the sorted model.  If @child_path isn't a valid path
- * on the child model, then %NULL is returned.
+ * point to the same row in the sorted 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
  **/
@@ -2140,10 +2036,11 @@ gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sor
  * @tree_model_sort: A #GtkTreeModelSort
  * @sorted_path: A #GtkTreePath to convert
  * 
- * Converts @sorted_path to a path on the child model of @tree_model_sort.  That
- * is, @sorted_path points to a location in @tree_model_sort.  The returned path
- * will point to the same location in the model not being sorted.  If @sorted_path 
- * does not point to a location in the child model, %NULL is returned.
+ * Converts @sorted_path to a path on the child model of @tree_model_sort.  
+ * That is, @sorted_path points to a location in @tree_model_sort.  The 
+ * returned path will point to the same location in the model not being 
+ * sorted.  If @sorted_path does not point to a location in the child model, 
+ * %NULL is returned.
  * 
  * Return value: A newly allocated #GtkTreePath, or %NULL
  **/
@@ -2209,8 +2106,7 @@ gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sor
   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
   g_return_if_fail (tree_model_sort->child_model != NULL);
   g_return_if_fail (child_iter != NULL);
-  g_return_if_fail (sorted_iter != NULL);
-  g_return_if_fail (sorted_iter->stamp == tree_model_sort->stamp);
+  g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
 
   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
     {
@@ -2308,7 +2204,7 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
          if (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter) == FALSE &&
              i < length - 1)
            {
-             g_warning ("There is a discrepency between the sort model and the child model.");
+             g_warning ("There is a discrepancy between the sort model and the child model.");
              return;
            }
        }
@@ -2475,8 +2371,9 @@ gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
  * @tree_model_sort: A #GtkTreeModelSort.
  * @iter: A #GtkTreeIter.
  *
- * WARNING: This function is slow. Only use it for debugging and/or testing
- * purposes.
+ * <warning><para>
+ * This function is slow. Only use it for debugging and/or testing purposes.
+ * </para></warning>
  *
  * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
  *
@@ -2497,3 +2394,6 @@ gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
   return gtk_tree_model_sort_iter_is_valid_helper (iter,
                                                   tree_model_sort->root);
 }
+
+#define __GTK_TREE_MODEL_SORT_C__
+#include "gtkaliasdef.c"