[gnome-builder] tree: add gb_tree_node_rebuild()



commit 93a82ccf13f1de519f193053335a9dd410e632f4
Author: Christian Hergert <christian hergert me>
Date:   Fri Apr 10 18:35:43 2015 -0700

    tree: add gb_tree_node_rebuild()
    
    This is a convenience helper to rebuild starting from a given node in
    the tree. It should make doing partial updates and leaving the tree
    in-tact a lot easier.

 src/tree/gb-tree-node.c |   14 +++++++
 src/tree/gb-tree-node.h |    1 +
 src/tree/gb-tree.c      |   99 ++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 108 insertions(+), 6 deletions(-)
---
diff --git a/src/tree/gb-tree-node.c b/src/tree/gb-tree-node.c
index 0bd464d..3a2eba1 100644
--- a/src/tree/gb-tree-node.c
+++ b/src/tree/gb-tree-node.c
@@ -48,6 +48,9 @@ enum {
 
 static GParamSpec *gParamSpecs [LAST_PROP];
 
+extern void _gb_tree_rebuild_node (GbTree     *tree,
+                                   GbTreeNode *node);
+
 /**
  * gb_tree_node_new:
  *
@@ -405,6 +408,17 @@ gb_tree_node_get_area (GbTreeNode   *node,
   gtk_tree_path_free (path);
 }
 
+void
+gb_tree_node_rebuild (GbTreeNode *self)
+{
+  GbTree *tree;
+
+  g_return_if_fail (GB_IS_TREE_NODE (self));
+
+  tree = gb_tree_node_get_tree (self);
+  _gb_tree_rebuild_node (tree, self);
+}
+
 /**
  * gb_tree_node_finalize:
  * @object: (in): A #GbTreeNode.
diff --git a/src/tree/gb-tree-node.h b/src/tree/gb-tree-node.h
index 9d30994..a633059 100644
--- a/src/tree/gb-tree-node.h
+++ b/src/tree/gb-tree-node.h
@@ -75,6 +75,7 @@ void           gb_tree_node_expand        (GbTreeNode   *node,
 void           gb_tree_node_select        (GbTreeNode   *node);
 void           gb_tree_node_get_area      (GbTreeNode   *node,
                                            GdkRectangle *area);
+void           gb_tree_node_rebuild       (GbTreeNode   *node);
 
 G_END_DECLS
 
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index 06b40fb..9b76794 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -33,8 +33,8 @@ struct _GbTreePrivate
   GtkCellRenderer   *cell_pixbuf;
   GtkCellRenderer   *cell_text;
   GtkTreeStore      *store;
-  guint              building : 1;
   guint              show_icons : 1;
+  guint              building;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GbTree, gb_tree, GTK_TYPE_TREE_VIEW)
@@ -538,6 +538,90 @@ gb_tree_add_builder_foreach_cb (GtkTreeModel *model,
   IDE_RETURN (FALSE);
 }
 
+gboolean
+gb_tree_foreach (GbTree                  *tree,
+                 GtkTreeIter             *iter,
+                 GtkTreeModelForeachFunc  func,
+                 gpointer                 user_data)
+{
+  GbTreePrivate *priv = gb_tree_get_instance_private (tree);
+  GtkTreeModel *model;
+  GtkTreePath *path;
+  GtkTreeIter child;
+  gboolean ret;
+
+  g_assert (GB_IS_TREE (tree));
+  g_assert (iter != NULL);
+  g_assert (gtk_tree_store_iter_is_valid (priv->store, iter));
+  g_assert (func != NULL);
+
+  model = GTK_TREE_MODEL (priv->store);
+  path = gtk_tree_model_get_path (model, iter);
+  ret = func (model, path, iter, user_data);
+  gtk_tree_path_free (path);
+
+  if (ret)
+    return TRUE;
+
+  if (gtk_tree_model_iter_children (model, &child, iter))
+    {
+      do
+        {
+          if (gb_tree_foreach (tree, &child, func, user_data))
+            return TRUE;
+        }
+      while (gtk_tree_model_iter_next (model, &child));
+    }
+
+  return FALSE;
+}
+
+void
+_gb_tree_rebuild_node (GbTree     *tree,
+                       GbTreeNode *node)
+{
+  GbTreePrivate *priv = gb_tree_get_instance_private (tree);
+  GtkTreeModel *model;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+  GtkTreeIter child;
+  guint i;
+
+  g_return_if_fail (GB_IS_TREE (tree));
+  g_return_if_fail (GB_IS_TREE_NODE (node));
+
+  model = GTK_TREE_MODEL (priv->store);
+  path = gb_tree_node_get_path (node);
+  gtk_tree_model_get_iter (model, &iter, path);
+
+  if (gtk_tree_model_iter_children (model, &child, &iter))
+    {
+      while (gtk_tree_store_remove (priv->store, &child))
+        { /* Do Nothing */ }
+    }
+
+  priv->building++;
+  for (i = 0; i < priv->builders->len; i++)
+    {
+      GbTreeBuilder *builder;
+
+      /*
+       * FIXME:
+       *
+       * Refactor this to do all builders when walking each node.
+       */
+
+      builder = g_ptr_array_index (priv->builders, i);
+      gb_tree_foreach (tree,
+                       &iter,
+                       gb_tree_add_builder_foreach_cb,
+                       builder);
+      priv->building--;
+    }
+
+  gtk_tree_path_free (path);
+}
+
 /**
  * gb_tree_add_builder:
  * @tree: (in): A #GbTree.
@@ -550,6 +634,7 @@ gb_tree_add_builder (GbTree        *tree,
                      GbTreeBuilder *builder)
 {
   GbTreePrivate *priv;
+  GtkTreeIter iter;
 
   IDE_ENTRY;
 
@@ -560,11 +645,13 @@ gb_tree_add_builder (GbTree        *tree,
 
   g_object_set (builder, "tree", tree, NULL);
   g_ptr_array_add (priv->builders, g_object_ref_sink (builder));
-  priv->building = TRUE;
-  gtk_tree_model_foreach (GTK_TREE_MODEL (priv->store),
-                          gb_tree_add_builder_foreach_cb,
-                          builder);
-  priv->building = FALSE;
+
+  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->store), &iter))
+    {
+      priv->building++;
+      gb_tree_foreach (tree, &iter, gb_tree_add_builder_foreach_cb, builder);
+      priv->building--;
+    }
 
   if (GB_TREE_BUILDER_GET_CLASS (builder)->added)
     GB_TREE_BUILDER_GET_CLASS (builder)->added (builder, GTK_WIDGET (tree));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]