summaryrefslogtreecommitdiff
path: root/gtk/gtktreemodelfilter.c
diff options
context:
space:
mode:
authorKristian Rietveld <kris@gtk.org>2011-05-14 14:42:31 +0200
committerKristian Rietveld <kris@gtk.org>2011-08-22 21:30:30 +0200
commit7b3c2751ee406afa49c12900adfd355a0e7a6f1b (patch)
treed63812c34d727f1c1c1b8481d08c4d7a1984d4ba /gtk/gtktreemodelfilter.c
parentbcb00d9a4382539c6fbf6330732e8bfb77cc681d (diff)
downloadgtk+-7b3c2751ee406afa49c12900adfd355a0e7a6f1b.tar.gz
Refactor emitting row-inserted for new nodes to a common code path
Suggested by Xavier Claessens / bug 621076.
Diffstat (limited to 'gtk/gtktreemodelfilter.c')
-rw-r--r--gtk/gtktreemodelfilter.c200
1 files changed, 99 insertions, 101 deletions
diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c
index eefc5cfe8f..acade02ada 100644
--- a/gtk/gtktreemodelfilter.c
+++ b/gtk/gtktreemodelfilter.c
@@ -1344,6 +1344,93 @@ find_elt_with_offset (GtkTreeModelFilter *filter,
/* TreeModel signals */
static void
+gtk_tree_model_filter_emit_row_inserted_for_path (GtkTreeModelFilter *filter,
+ GtkTreeModel *c_model,
+ GtkTreePath *c_path,
+ GtkTreeIter *c_iter)
+{
+ FilterLevel *level;
+ FilterElt *elt;
+ GtkTreePath *path;
+ GtkTreeIter iter, children;
+ gboolean signals_emitted = FALSE;
+
+ if (!filter->priv->root)
+ {
+ gtk_tree_model_filter_build_level (filter, NULL, -1, TRUE);
+
+ /* We will only proceed below if the item is found. If the item
+ * is found, we can be sure row-inserted has just been emitted
+ * for it.
+ */
+ if (filter->priv->root &&
+ FILTER_LEVEL (filter->priv->root)->visible_nodes)
+ signals_emitted = TRUE;
+ }
+
+ /* We need to disallow to build new levels, because we are then pulling
+ * in a child in an invisible level. We only want to find path if it
+ * is in a visible level (and thus has a parent that is visible).
+ */
+ path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
+ c_path,
+ FALSE,
+ TRUE);
+
+ if (!path)
+ /* parent is probably being filtered out */
+ return;
+
+ gtk_tree_model_filter_increment_stamp (filter);
+
+ gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
+
+ level = FILTER_LEVEL (iter.user_data);
+ elt = FILTER_ELT (iter.user_data2);
+
+ /* Make sure elt is visible. elt can already be visible in case
+ * it was pulled in above, so avoid increasing level->visible_nodes twice.
+ */
+ if (!elt->visible)
+ {
+ elt->visible = TRUE;
+ level->visible_nodes++;
+ }
+
+ /* Check whether the node and all of its parents are visible */
+ if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
+ {
+ /* visibility changed -- reget path */
+ gtk_tree_path_free (path);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
+
+ if (!signals_emitted)
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
+
+ if (level->parent_level && level->visible_nodes == 1)
+ {
+ /* We know that this is the first visible node in this level, so
+ * we need to emit row-has-child-toggled on the parent. This
+ * does not apply to the root level.
+ */
+
+ gtk_tree_path_up (path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
+
+ gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
+ path,
+ &iter);
+ }
+
+ if (!signals_emitted
+ && gtk_tree_model_iter_children (c_model, &children, c_iter))
+ gtk_tree_model_filter_update_children (filter, level, elt);
+ }
+
+ gtk_tree_path_free (path);
+}
+
+static void
gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
GtkTreePath *c_path,
GtkTreeIter *c_iter,
@@ -1361,7 +1448,6 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
gboolean requested_state;
gboolean current_state;
gboolean free_c_path = FALSE;
- gboolean signals_emitted = FALSE;
g_return_if_fail (c_path != NULL || c_iter != NULL);
@@ -1443,74 +1529,8 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
*/
g_return_if_fail (current_state == FALSE && requested_state == TRUE);
- /* make sure the new item has been pulled in */
- if (!filter->priv->root)
- {
- gtk_tree_model_filter_build_level (filter, NULL, -1, TRUE);
-
- /* We will only proceed below if the item is found. If the item
- * is found, we can be sure row-inserted has just been emitted
- * for it.
- */
- signals_emitted = TRUE;
- }
-
- gtk_tree_model_filter_increment_stamp (filter);
-
- /* We need to disallow to build new levels, because we are then pulling
- * in a child in an invisible level. We only want to find path if it
- * is in a visible level (and thus has a parent that is visible).
- */
- if (!path)
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
- c_path,
- FALSE,
- TRUE);
-
- if (!path)
- /* parent is probably being filtered out */
- goto done;
-
- gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
-
- level = FILTER_LEVEL (iter.user_data);
- elt = FILTER_ELT (iter.user_data2);
-
- /* elt->visible can be TRUE at this point if it was pulled in above */
- if (!elt->visible)
- {
- elt->visible = TRUE;
- level->visible_nodes++;
- }
-
- if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
- {
- /* visibility changed -- reget path */
- gtk_tree_path_free (path);
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
-
- if (!signals_emitted)
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
-
- if (level->parent_level && level->visible_nodes == 1)
- {
- /* We know that this is the first visible node in this level, so
- * we need to emit row-has-child-toggled on the parent. This
- * does not apply to the root level.
- */
-
- gtk_tree_path_up (path);
- gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
-
- gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
- path,
- &iter);
- }
-
- if (!signals_emitted
- && gtk_tree_model_iter_children (c_model, &children, c_iter))
- gtk_tree_model_filter_update_children (filter, level, elt);
- }
+ gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
+ c_path, c_iter);
done:
if (path)
@@ -1527,9 +1547,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
gpointer data)
{
GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
- GtkTreePath *path = NULL;
GtkTreePath *real_path = NULL;
- GtkTreeIter iter;
GtkTreeIter real_c_iter;
@@ -1540,6 +1558,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
gint i = 0, offset;
gboolean free_c_path = FALSE;
+ gboolean emit_row_inserted = FALSE;
g_return_if_fail (c_path != NULL || c_iter != NULL);
@@ -1594,9 +1613,9 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
if (filter->priv->root
&& FILTER_LEVEL (filter->priv->root)->visible_nodes)
- goto done_and_emit;
- else
- goto done;
+ emit_row_inserted = TRUE;
+
+ goto done;
}
/* subtract virtual root if necessary */
@@ -1685,36 +1704,15 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
/* insert_elt_in_level defaults to FALSE */
felt->visible = TRUE;
level->visible_nodes++;
- }
- /* don't emit the signal if we aren't visible */
- if (!gtk_tree_model_filter_visible (filter, &real_c_iter))
- goto done;
-
-done_and_emit:
- /* NOTE: pass c_path here and NOT real_path. This function does
- * root subtraction itself
- */
- path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
- c_path,
- FALSE, TRUE);
-
- if (!path)
- goto done;
-
- gtk_tree_model_filter_increment_stamp (filter);
-
- gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path);
-
- /* get a path taking only visible nodes into account */
- gtk_tree_path_free (path);
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter);
-
- gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
-
- gtk_tree_path_free (path);
+ emit_row_inserted = TRUE;
+ }
done:
+ if (emit_row_inserted)
+ gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
+ c_path, c_iter);
+
if (real_path)
gtk_tree_path_free (real_path);