[gnome-builder/gnome-builder-3-18] tree: implement recursive search for tree nodes
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-18] tree: implement recursive search for tree nodes
- Date: Tue, 13 Oct 2015 07:41:56 +0000 (UTC)
commit 5141886b07ee12960ed9e2ea87c5cb3cd18d4066
Author: Christian Hergert <chergert redhat com>
Date: Mon Oct 12 19:49:17 2015 -0700
tree: implement recursive search for tree nodes
This will only filter items that have been loaded. If you have a tree that
needs to dynamically load data, you are expected to have done that, or
be doing that, in the background iteratively.
This will match the filters as items are added or already existing in
the underlying TreeStore.
src/tree/gb-tree.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 61 insertions(+), 3 deletions(-)
---
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index 7369c2b..e3ecd12 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -640,7 +640,6 @@ gb_tree_row_expanded (GtkTreeView *tree_view,
GtkTreePath *path)
{
GbTree *self = (GbTree *)tree_view;
- GbTreePrivate *priv = gb_tree_get_instance_private (self);
GtkTreeModel *model;
GbTreeNode *node;
@@ -648,7 +647,7 @@ gb_tree_row_expanded (GtkTreeView *tree_view,
g_assert (iter != NULL);
g_assert (path != NULL);
- model = GTK_TREE_MODEL (priv->store);
+ model = gtk_tree_view_get_model (tree_view);
gtk_tree_model_get (model, iter, 0, &node, -1);
@@ -1618,6 +1617,36 @@ filter_func_free (gpointer user_data)
}
static gboolean
+gb_tree_model_filter_recursive (GtkTreeModel *model,
+ GtkTreeIter *parent,
+ FilterFunc *filter)
+{
+ GtkTreeIter child;
+
+ if (gtk_tree_model_iter_children (model, &child, parent))
+ {
+ do
+ {
+ g_autoptr(GbTreeNode) node = NULL;
+
+ gtk_tree_model_get (model, &child, 0, &node, -1);
+
+ if (node != NULL)
+ {
+ if (filter->filter_func (filter->self, node, filter->filter_data))
+ return TRUE;
+
+ if (gb_tree_model_filter_recursive (model, &child, filter))
+ return TRUE;
+ }
+ }
+ while (gtk_tree_model_iter_next (model, &child));
+ }
+
+ return FALSE;
+}
+
+static gboolean
gb_tree_model_filter_visible_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
@@ -1626,11 +1655,40 @@ gb_tree_model_filter_visible_func (GtkTreeModel *model,
FilterFunc *filter = data;
gboolean ret;
+ /*
+ * This is a rather complex situation.
+ *
+ * We might not match, but one of our children nodes might match.
+ * Furthering the issue, the children might still need to be built.
+ * For some cases, this could be really expensive (think file tree)
+ * but for other things, it could be cheap. If you are going to use
+ * a filter func for your tree, you probably should avoid being
+ * too lazy and ensure the nodes are available.
+ *
+ * Therefore, we will only check available nodes, and ignore the
+ * case where the children nodes need to be built. *
+ *
+ * TODO: Another option would be to iteratively build the items after
+ * the initial filter.
+ */
+
gtk_tree_model_get (model, iter, 0, &node, -1);
ret = filter->filter_func (filter->self, node, filter->filter_data);
g_clear_object (&node);
- return ret;
+ /*
+ * Short circuit if we already matched.
+ */
+ if (ret)
+ return TRUE;
+
+ /*
+ * If any of our children match, we should match.
+ */
+ if (gb_tree_model_filter_recursive (model, iter, filter))
+ return TRUE;
+
+ return FALSE;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]