Factor out find_elt_with_offset

Suggested by Xavier Claessens / bug 621076.
This commit is contained in:
Kristian Rietveld 2011-05-14 14:09:51 +02:00
parent 60f3f92e95
commit f064d07bda

View File

@ -1298,6 +1298,50 @@ bsearch_elt_with_offset (GArray *array,
return NULL; return NULL;
} }
/* Path is relative to the child model (this is on search on elt offset)
* but with the virtual root already removed if necesssary.
*/
static gboolean
find_elt_with_offset (GtkTreeModelFilter *filter,
GtkTreePath *path,
FilterLevel **level_,
FilterElt **elt_)
{
int i = 0;
FilterLevel *level;
FilterLevel *parent_level = NULL;
FilterElt *elt = NULL;
level = FILTER_LEVEL (filter->priv->root);
while (i < gtk_tree_path_get_depth (path))
{
int j;
if (!level)
return FALSE;
elt = bsearch_elt_with_offset (level->array,
gtk_tree_path_get_indices (path)[i],
&j);
if (!elt)
return FALSE;
parent_level = level;
level = elt->children;
i++;
}
if (level_)
*level_ = parent_level;
if (elt_)
*elt_ = elt;
return TRUE;
}
/* TreeModel signals */ /* TreeModel signals */
static void static void
gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
@ -1489,9 +1533,9 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
GtkTreeIter real_c_iter; GtkTreeIter real_c_iter;
FilterElt *elt; FilterElt *elt = NULL;
FilterLevel *level; FilterLevel *level = NULL;
FilterLevel *parent_level; FilterLevel *parent_level = NULL;
gint i = 0, offset; gint i = 0, offset;
@ -1555,8 +1599,6 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
goto done; goto done;
} }
parent_level = level = FILTER_LEVEL (filter->priv->root);
/* subtract virtual root if necessary */ /* subtract virtual root if necessary */
if (filter->priv->virtual_root) if (filter->priv->virtual_root)
{ {
@ -1571,54 +1613,50 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
if (gtk_tree_path_get_depth (real_path) - 1 >= 1) if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
{ {
/* find the parent level */ gboolean found = FALSE;
while (i < gtk_tree_path_get_depth (real_path) - 1) GtkTreePath *parent = gtk_tree_path_copy (real_path);
{ gtk_tree_path_up (parent);
gint j;
if (!level) found = find_elt_with_offset (filter, parent, &parent_level, &elt);
/* we don't cover this signal */
goto done;
elt = bsearch_elt_with_offset (level->array, gtk_tree_path_free (parent);
gtk_tree_path_get_indices (real_path)[i],
&j);
if (!elt) if (!found)
/* parent is probably being filtered out */ /* Parent is not in the cache and probably being filtered out */
goto done; goto done;
if (!elt->children) level = elt->children;
{
GtkTreePath *tmppath;
GtkTreeIter tmpiter;
tmpiter.stamp = filter->priv->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;
}
level = elt->children;
parent_level = level;
i++;
}
} }
else
level = FILTER_LEVEL (filter->priv->root);
if (!parent_level) if (!level)
goto done; {
if (elt && elt->visible)
{
/* The level in which the new node should be inserted does not
* exist, but the parent, elt, does. If elt is visible, emit
* row-has-child-toggled.
*/
GtkTreePath *tmppath;
GtkTreeIter tmpiter;
tmpiter.stamp = filter->priv->stamp;
tmpiter.user_data = parent_level;
tmpiter.user_data2 = elt;
tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
&tmpiter);
if (tmppath)
{
gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
tmppath, &tmpiter);
gtk_tree_path_free (tmppath);
}
}
goto done;
}
/* let's try to insert the value */ /* let's try to insert the value */
offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1]; offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
@ -1881,35 +1919,24 @@ gtk_tree_model_filter_row_deleted_invisible_node (GtkTreeModelFilter *filter,
else else
real_path = gtk_tree_path_copy (c_path); real_path = gtk_tree_path_copy (c_path);
i = 0;
if (gtk_tree_path_get_depth (real_path) - 1 >= 1) if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
{ {
/* find the level where the deletion occurred */ gboolean found = FALSE;
while (i < gtk_tree_path_get_depth (real_path) - 1) GtkTreePath *parent = gtk_tree_path_copy (real_path);
gtk_tree_path_up (parent);
found = find_elt_with_offset (filter, parent, &level, &elt);
gtk_tree_path_free (parent);
if (!found)
{ {
gint j; /* parent is filtered out, so no level */
gtk_tree_path_free (real_path);
if (!level) return;
{
/* we don't cover this */
gtk_tree_path_free (real_path);
return;
}
elt = bsearch_elt_with_offset (level->array,
gtk_tree_path_get_indices (real_path)[i],
&j);
if (!elt || !elt->children)
{
/* parent is filtered out, so no level */
gtk_tree_path_free (real_path);
return;
}
level = elt->children;
i++;
} }
level = elt->children;
} }
offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1]; offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];