[gnome-builder/wip/large-project: 5/5] tree: add gb_tree_node_insert_sorted()



commit 9bd13006094ede7e44407e67c365f95584c6cc67
Author: Christian Hergert <christian hergert me>
Date:   Sun Jun 14 20:11:32 2015 -0700

    tree: add gb_tree_node_insert_sorted()
    
    Inserts a new child, sorting it among the sibling nodes.

 src/tree/gb-tree-node.c    |   12 +++++++++++
 src/tree/gb-tree-node.h    |    4 +++
 src/tree/gb-tree-private.h |    5 ++++
 src/tree/gb-tree-types.h   |    4 +++
 src/tree/gb-tree.c         |   47 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 72 insertions(+), 0 deletions(-)
---
diff --git a/src/tree/gb-tree-node.c b/src/tree/gb-tree-node.c
index b8c5630..5ea42c7 100644
--- a/src/tree/gb-tree-node.c
+++ b/src/tree/gb-tree-node.c
@@ -117,6 +117,18 @@ _gb_tree_node_set_tree (GbTreeNode *node,
         }
     }
 }
+
+void
+gb_tree_node_insert_sorted (GbTreeNode            *node,
+                            GbTreeNode            *child,
+                            GbTreeNodeCompareFunc  compare_func,
+                            gpointer               user_data)
+{
+  g_return_if_fail (GB_IS_TREE_NODE (node));
+  g_return_if_fail (GB_IS_TREE_NODE (child));
+  g_return_if_fail (compare_func != NULL);
+
+  _gb_tree_insert_sorted (node->tree, node, child, compare_func, user_data);
 }
 
 /**
diff --git a/src/tree/gb-tree-node.h b/src/tree/gb-tree-node.h
index b9f7488..94d3663 100644
--- a/src/tree/gb-tree-node.h
+++ b/src/tree/gb-tree-node.h
@@ -26,6 +26,10 @@ G_BEGIN_DECLS
 GbTreeNode    *gb_tree_node_new           (void);
 void           gb_tree_node_append        (GbTreeNode   *node,
                                            GbTreeNode   *child);
+void           gb_tree_node_insert_sorted (GbTreeNode   *node,
+                                           GbTreeNode   *child,
+                                           GbTreeNodeCompareFunc compare_func,
+                                           gpointer      user_data);
 const gchar   *gb_tree_node_get_icon_name (GbTreeNode   *node);
 GObject       *gb_tree_node_get_item      (GbTreeNode   *node);
 GbTreeNode    *gb_tree_node_get_parent    (GbTreeNode   *node);
diff --git a/src/tree/gb-tree-private.h b/src/tree/gb-tree-private.h
index d0f9a99..08caa39 100644
--- a/src/tree/gb-tree-private.h
+++ b/src/tree/gb-tree-private.h
@@ -33,6 +33,11 @@ void         _gb_tree_append                  (GbTree        *self,
 void         _gb_tree_prepend                 (GbTree        *self,
                                                GbTreeNode    *node,
                                                GbTreeNode    *child);
+void         _gb_tree_insert_sorted           (GbTree        *self,
+                                               GbTreeNode    *node,
+                                               GbTreeNode    *child,
+                                               GbTreeNodeCompareFunc compare_func,
+                                               gpointer       user_data);
 
 void         _gb_tree_node_set_tree           (GbTreeNode    *node,
                                                GbTree        *tree);
diff --git a/src/tree/gb-tree-types.h b/src/tree/gb-tree-types.h
index 4a3fb26..c95dfc1 100644
--- a/src/tree/gb-tree-types.h
+++ b/src/tree/gb-tree-types.h
@@ -31,6 +31,10 @@ G_DECLARE_DERIVABLE_TYPE (GbTree,        gb_tree,         GB, TREE,         GtkT
 G_DECLARE_DERIVABLE_TYPE (GbTreeBuilder, gb_tree_builder, GB, TREE_BUILDER, GInitiallyUnowned)
 G_DECLARE_FINAL_TYPE     (GbTreeNode,    gb_tree_node,    GB, TREE_NODE,    GInitiallyUnowned)
 
+typedef gint (*GbTreeNodeCompareFunc) (GbTreeNode *a,
+                                       GbTreeNode *b,
+                                       gpointer    user_data);
+
 G_END_DECLS
 
 #endif /* GB_TREE_TYPES_H */
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index 1746b4e..1d8a3f6 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -556,6 +556,53 @@ gb_tree_add (GbTree     *self,
     gb_tree_build_node (self, child);
 }
 
+void
+_gb_tree_insert_sorted (GbTree                *self,
+                        GbTreeNode            *node,
+                        GbTreeNode            *child,
+                        GbTreeNodeCompareFunc  compare_func,
+                        gpointer               user_data)
+{
+  GbTreePrivate *priv = gb_tree_get_instance_private (self);
+  GtkTreeModel *model;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+  GtkTreeIter move_iter;
+
+  g_return_if_fail (GB_IS_TREE (self));
+  g_return_if_fail (GB_IS_TREE_NODE (node));
+  g_return_if_fail (GB_IS_TREE_NODE (child));
+  g_return_if_fail (compare_func != NULL);
+
+  model = GTK_TREE_MODEL (priv->store);
+
+  gb_tree_add (self, node, child, TRUE);
+
+  path = gb_tree_node_get_path (child);
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_tree_path_free (path);
+
+  move_iter = iter;
+
+  while (gtk_tree_model_iter_next (model, &move_iter))
+    {
+      GbTreeNode *sibling = NULL;
+
+      gtk_tree_model_get (model, &move_iter, 0, &sibling, -1);
+
+      if (compare_func (child, sibling, user_data) <= 0)
+        {
+          g_clear_object (&sibling);
+          return;
+        }
+
+      gtk_tree_store_move_after (priv->store, &iter, &move_iter);
+      move_iter = iter;
+
+      g_clear_object (&sibling);
+    }
+}
+
 static void
 gb_tree_row_activated (GtkTreeView       *tree_view,
                        GtkTreePath       *path,


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