]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreemodelfilter.c
Fix a crash with icon themes
[~andy/gtk] / gtk / gtktreemodelfilter.c
index 4349004c50cc249a528c9d2507d4587143861fbc..53f0d57e5b3a2e8fd0b0fb69bd228e4923abeb65 100644 (file)
@@ -22,8 +22,8 @@
 #include "gtktreemodelfilter.h"
 #include "gtkintl.h"
 #include "gtktreednd.h"
-#include "gtkalias.h"
 #include "gtkprivate.h"
+#include "gtkalias.h"
 #include <string.h>
 
 /* ITER FORMAT:
@@ -105,6 +105,7 @@ struct _GtkTreeModelFilterPrivate
   gboolean modify_func_set;
 
   gboolean in_row_deleted;
+  gboolean virtual_root_deleted;
 
   /* signal ids */
   guint changed_id;
@@ -290,6 +291,7 @@ gtk_tree_model_filter_init (GtkTreeModelFilter *filter)
   filter->priv->visible_method_set = FALSE;
   filter->priv->modify_func_set = FALSE;
   filter->priv->in_row_deleted = FALSE;
+  filter->priv->virtual_root_deleted = FALSE;
 }
 
 static void
@@ -359,8 +361,11 @@ gtk_tree_model_filter_finalize (GObject *object)
 {
   GtkTreeModelFilter *filter = (GtkTreeModelFilter *) object;
 
-  if (filter->priv->virtual_root)
-    gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root);
+  if (filter->priv->virtual_root && !filter->priv->virtual_root_deleted)
+    {
+      gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root);
+      filter->priv->virtual_root_deleted = TRUE;
+    }
 
   gtk_tree_model_filter_set_model (filter, NULL);
 
@@ -624,18 +629,14 @@ gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter,
       FilterLevel *parent_level = filter_level->parent_level;
       FilterElt *parent_elt = filter_level->parent_elt;
 
-      do
+      while (parent_level)
         {
-          if (parent_elt)
-            parent_elt->zero_ref_count--;
+         parent_elt->zero_ref_count--;
 
-          if (parent_level)
-            {
-              parent_elt = parent_level->parent_elt;
-              parent_level = parent_level->parent_level;
-            }
+         parent_elt = parent_level->parent_elt;
+         parent_level = parent_level->parent_level;
         }
-      while (parent_level);
+
       if (filter_level != filter->priv->root)
         filter->priv->zero_ref_count--;
     }
@@ -927,10 +928,7 @@ gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
   g_array_insert_val (level->array, i, elt);
   *index = i;
 
-  if (i > 0)
-    i--;
-
-  for ( ; i < level->array->len; i++)
+  for (i = 0; i < level->array->len; i++)
     {
       FilterElt *e = &(g_array_index (level->array, FilterElt, i));
       if (e->children)
@@ -953,7 +951,7 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter,
 {
   FilterElt *elt, *parent;
   FilterLevel *level, *parent_level;
-  gint offset, i, length;
+  gint i, length;
 
   gboolean emit_child_toggled = FALSE;
 
@@ -964,7 +962,6 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter,
   parent_level = level->parent_level;
 
   length = level->array->len;
-  offset = elt->offset;
 
   /* we distinguish a couple of cases:
    *  - root level, length > 1: emit row-deleted and remove.
@@ -1606,8 +1603,8 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
   GtkTreePath *path;
   GtkTreeIter iter;
-  FilterElt *elt, *parent;
-  FilterLevel *level, *parent_level;
+  FilterElt *elt, *parent = NULL;
+  FilterLevel *level, *parent_level = NULL;
   gboolean emit_child_toggled = FALSE;
   gint offset;
   gint i;
@@ -1623,6 +1620,9 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
       GtkTreePath *path;
       FilterLevel *level = FILTER_LEVEL (filter->priv->root);
 
+      gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root);
+      filter->priv->virtual_root_deleted = TRUE;
+
       if (!level)
         return;
 
@@ -2569,19 +2569,16 @@ gtk_tree_model_filter_ref_node (GtkTreeModel *model,
       FilterElt *parent_elt = level->parent_elt;
 
       /* we were at zero -- time to decrease the zero_ref_count val */
-      do
+      while (parent_level)
         {
-          if (parent_elt)
-            parent_elt->zero_ref_count--;
+         parent_elt->zero_ref_count--;
 
-          if (parent_level)
-            {
-              parent_elt = parent_level->parent_elt;
-              parent_level = parent_level->parent_level;
-            }
+         parent_elt = parent_level->parent_elt;
+         parent_level = parent_level->parent_level;
         }
-      while (parent_level);
-      filter->priv->zero_ref_count--;
+
+      if (filter->priv->root != level)
+       filter->priv->zero_ref_count--;
     }
 }
 
@@ -2632,7 +2629,9 @@ gtk_tree_model_filter_real_unref_node (GtkTreeModel *model,
           parent_elt = parent_level->parent_elt;
           parent_level = parent_level->parent_level;
         }
-      filter->priv->zero_ref_count++;
+
+      if (filter->priv->root != level)
+       filter->priv->zero_ref_count++;
     }
 }
 
@@ -2838,7 +2837,10 @@ gtk_tree_model_filter_new (GtkTreeModel *child_model,
 
   filter = GTK_TREE_MODEL_FILTER (retval);
   if (filter->priv->virtual_root)
-    gtk_tree_model_filter_ref_path (filter, filter->priv->virtual_root);
+    {
+      gtk_tree_model_filter_ref_path (filter, filter->priv->virtual_root);
+      filter->priv->virtual_root_deleted = FALSE;
+    }
 
   return retval;
 }