when (un)reffing an element, also (un)ref its parent elements. (Fixes
authorKristian Rietveld <kris@gtk.org>
Sat, 10 Mar 2007 17:25:51 +0000 (17:25 +0000)
committerKristian Rietveld <kristian@src.gnome.org>
Sat, 10 Mar 2007 17:25:51 +0000 (17:25 +0000)
2007-03-10  Kristian Rietveld  <kris@gtk.org>

* gtk/gtktreemodelsort.c (gtk_tree_model_sort_ref_node),
(gtk_tree_model_sort_real_unref_node): when (un)reffing an
element, also (un)ref its parent elements. (Fixes #364946,
reported by many, testcase by Andreas Koehler).

svn path=/trunk/; revision=17457

ChangeLog
gtk/gtktreemodelsort.c

index 5201f2bbf505bab955b7e52a979d73b871ddb727..1f687e40f86d5055feac1a82a18736b4d6bbb0e1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-10  Kristian Rietveld  <kris@gtk.org>
+
+       * gtk/gtktreemodelsort.c (gtk_tree_model_sort_ref_node),
+       (gtk_tree_model_sort_real_unref_node): when (un)reffing an
+       element, also (un)ref its parent elements. (Fixes #364946,
+       reported by many, testcase by Andreas Koehler).
+
 2007-03-10  Matthias Clasen <mclasen@redhat.com>
 
        * gtk/gtkprintoperation-unix.c: Initialize the do_preview
index cf0094486570e26b380f033a243eb77f70745db3..f0d6e0467b2c990c8c6f43bc68b129feedf14cbb 100644 (file)
@@ -1172,6 +1172,7 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
   GtkTreeIter child_iter;
+  GtkTreeIter tmp_iter;
   SortLevel *level;
   SortElt *elt;
 
@@ -1180,13 +1181,29 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
 
   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
 
+  /* Reference the node in the child model */
   gtk_tree_model_ref_node (tree_model_sort->child_model, &child_iter);
 
+  /* Increase the reference count of this element and its level */
   level = iter->user_data;
   elt = iter->user_data2;
 
   elt->ref_count++;
   level->ref_count++;
+
+  /* Increase the reference count of all parent elements */
+  tmp_iter.stamp = tree_model_sort->stamp;
+  tmp_iter.user_data = level->parent_level;
+  tmp_iter.user_data2 = level->parent_elt;;
+
+  while (tmp_iter.user_data2)
+    {
+      gtk_tree_model_sort_ref_node (tree_model, &tmp_iter);
+
+      tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt;
+      tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level;
+    }
+
   if (level->ref_count == 1)
     {
       SortLevel *parent_level = level->parent_level;
@@ -1211,6 +1228,7 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
                                     gboolean      propagate_unref)
 {
   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
+  GtkTreeIter tmp_iter;
   SortLevel *level;
   SortElt *elt;
 
@@ -1233,6 +1251,19 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
   elt->ref_count--;
   level->ref_count--;
 
+  /* Decrease the reference count of all parent elements */
+  tmp_iter.stamp = tree_model_sort->stamp;
+  tmp_iter.user_data = level->parent_level;
+  tmp_iter.user_data2 = level->parent_elt;;
+
+  while (tmp_iter.user_data2)
+    {
+      gtk_tree_model_sort_real_unref_node (tree_model, &tmp_iter, FALSE);
+
+      tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt;
+      tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level;
+    }
+
   if (level->ref_count == 0)
     {
       SortLevel *parent_level = level->parent_level;