]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreemodelfilter.c
always set hide_tooltip to TRUE if we are handling a leave notify event.
[~andy/gtk] / gtk / gtktreemodelfilter.c
index 9668efbfa20fede660cda1c74d4ddfbaa01218a7..9d2b89587c52d5b9dc1018d0f8508559359c2c81 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:
@@ -97,7 +97,7 @@ struct _GtkTreeModelFilterPrivate
   GType *modify_types;
   GtkTreeModelFilterModifyFunc modify_func;
   gpointer modify_data;
-  gpointer modify_destroy;
+  GtkDestroyNotify modify_destroy;
 
   gint visible_column;
 
@@ -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);
 
@@ -370,8 +375,13 @@ gtk_tree_model_filter_finalize (GObject *object)
   if (filter->priv->root)
     gtk_tree_model_filter_free_level (filter, filter->priv->root);
 
-  if (filter->priv->modify_types)
-    g_free (filter->priv->modify_types);
+  g_free (filter->priv->modify_types);
+  
+  if (filter->priv->modify_destroy)
+    filter->priv->modify_destroy (filter->priv->modify_data);
+
+  if (filter->priv->visible_destroy)
+    filter->priv->visible_destroy (filter->priv->visible_data);
 
   /* must chain up */
   G_OBJECT_CLASS (gtk_tree_model_filter_parent_class)->finalize (object);
@@ -618,18 +628,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--;
     }
@@ -921,10 +927,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)
@@ -947,7 +950,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;
 
@@ -958,7 +961,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.
@@ -1600,8 +1602,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;
@@ -1617,6 +1619,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;
 
@@ -2563,19 +2568,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--;
     }
 }
 
@@ -2626,7 +2628,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++;
     }
 }
 
@@ -2832,7 +2836,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;
 }
@@ -2981,34 +2988,43 @@ gtk_tree_model_filter_set_visible_column (GtkTreeModelFilter *filter,
  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model.
  *
  * Sets @filter_iter to point to the row in @filter that corresponds to the
- * row pointed at by @child_iter.
+ * row pointed at by @child_iter.  If @filter_iter was not set, %FALSE is
+ * returned.
+ *
+ * Return value: %TRUE, if @filter_iter was set, i.e. if @child_iter is a
+ * valid iterator pointing to a visible row in child model.
  *
  * Since: 2.4
  */
-void
+gboolean
 gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter,
                                                   GtkTreeIter        *filter_iter,
                                                   GtkTreeIter        *child_iter)
 {
+  gboolean ret;
   GtkTreePath *child_path, *path;
 
-  g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
-  g_return_if_fail (filter->priv->child_model != NULL);
-  g_return_if_fail (filter_iter != NULL);
-  g_return_if_fail (child_iter != NULL);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), FALSE);
+  g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
+  g_return_val_if_fail (filter_iter != NULL, FALSE);
+  g_return_val_if_fail (child_iter != NULL, FALSE);
 
   filter_iter->stamp = 0;
 
   child_path = gtk_tree_model_get_path (filter->priv->child_model, child_iter);
-  g_return_if_fail (child_path != NULL);
+  g_return_val_if_fail (child_path != NULL, FALSE);
 
   path = gtk_tree_model_filter_convert_child_path_to_path (filter,
                                                            child_path);
   gtk_tree_path_free (child_path);
-  g_return_if_fail (path != NULL);
 
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path);
+  if (!path)
+    return FALSE;
+
+  ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path);
   gtk_tree_path_free (path);
+
+  return ret;
 }
 
 /**
@@ -3146,7 +3162,8 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte
  * Converts @child_path to a path relative to @filter. That is, @child_path
  * points to a path in the child model. The rerturned 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.
+ * child model or points to a row which is not visible in @filter, then %NULL
+ * is returned.
  *
  * Return value: A newly allocated #GtkTreePath, or %NULL.
  *
@@ -3165,12 +3182,15 @@ gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
                                                                 TRUE,
                                                                 TRUE);
 
+  if (!path)
+      return NULL;
+
   /* get a new path which only takes visible nodes into account.
    * -- if this gives any performance issues, we can write a special
    *    version of convert_child_path_to_path immediately returning
    *    a visible-nodes-only path.
    */
-  gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
+  gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
 
   gtk_tree_path_free (path);
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);