PATCH: better gtk_tree_model_foreach



Hello,

This patch is a version of gtk_tree_model_foreach that keeps iterating even if the callback removes the iterator.
It also differs for not being a recursive algorithm, cause it was initially designed to be a foreach macro.
Extensive testing needed...

PS0: Applyed against gtk 2.18.3
PS1: Sorry for identation (Linux style)
PS2: Updated (optimized) code may be found here
PS3: Due to limited time, I couldn't compile/test inside gtk.

Regards,
bráulio

--- gtktreemodel-old.c  2010-03-06 01:42:31.563850438 -0300
+++ gtktreemodel.c      2010-03-06 01:57:50.183858584 -0300
@@ -1565,36 +1565,6 @@
   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
 }
 
-
-static gboolean
-gtk_tree_model_foreach_helper (GtkTreeModel            *model,
-                              GtkTreeIter             *iter,
-                              GtkTreePath             *path,
-                              GtkTreeModelForeachFunc  func,
-                              gpointer                 user_data)
-{
-  do
-    {
-      GtkTreeIter child;
-
-      if ((* func) (model, path, iter, user_data))
-       return TRUE;
-
-      if (gtk_tree_model_iter_children (model, &child, iter))
-       {
-         gtk_tree_path_down (path);
-         if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
-           return TRUE;
-         gtk_tree_path_up (path);
-       }
-
-      gtk_tree_path_next (path);
-    }
-  while (gtk_tree_model_iter_next (model, iter));
-
-  return FALSE;
-}
-
 /**
  * gtk_tree_model_foreach:
  * @model: A #GtkTreeModel
@@ -1610,21 +1580,44 @@
                        GtkTreeModelForeachFunc  func,
                        gpointer                 user_data)
 {
-  GtkTreePath *path;
-  GtkTreeIter iter;
 
   g_return_if_fail (GTK_IS_TREE_MODEL (model));
   g_return_if_fail (func != NULL);
 
-  path = gtk_tree_path_new_first ();
-  if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
-    {
-      gtk_tree_path_free (path);
-      return;
-    }
-
-  gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
-  gtk_tree_path_free (path);
+  GtkTreeIter iter;
+  GtkTreeIter parent;
+  gboolean coming_back = FALSE;
+  gboolean valid;
+
+  valid = gtk_tree_model_get_iter_first(tree_model, &iter);
+  while (valid == TRUE) {
+         GtkTreeIter user_iter;
+         
+         if (coming_back == FALSE)
+                 while (valid == TRUE && (parent = iter, 1) &&
+                        (valid = gtk_tree_model_iter_children(tree_model, &iter, &parent), 1));
+         user_iter = iter = parent;
+         if (!(valid = gtk_tree_model_iter_next(tree_model, &iter))) {
+                 if ((coming_back = gtk_tree_model_iter_parent(tree_model, &iter, &parent))) {
+                         valid = TRUE;
+                         parent = iter;
+                 } else {
+                         valid = gtk_tree_model_iter_next(tree_model, &parent);
+                         iter = parent;
+                 }
+         } else {
+                 parent = iter;
+                 coming_back = FALSE;
+         } 
+
+         GtkTreePath *tree_path;
+         tree_path = gtk_tree_model_get_path(tree_model, &user_iter);
+         if ((*func)(tree_model, tree_path, &user_iter, user_data)) {
+                 gtk_tree_path_free(tree_path);
+                 return;
+         }
+         gtk_tree_path_free(tree_path);
+  }
 }
--- gtktreemodel-old.c	2010-03-06 01:42:31.563850438 -0300
+++ gtktreemodel.c	2010-03-06 01:57:50.183858584 -0300
@@ -1565,36 +1565,6 @@
   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
 }
 
-
-static gboolean
-gtk_tree_model_foreach_helper (GtkTreeModel            *model,
-			       GtkTreeIter             *iter,
-			       GtkTreePath             *path,
-			       GtkTreeModelForeachFunc  func,
-			       gpointer                 user_data)
-{
-  do
-    {
-      GtkTreeIter child;
-
-      if ((* func) (model, path, iter, user_data))
-	return TRUE;
-
-      if (gtk_tree_model_iter_children (model, &child, iter))
-	{
-	  gtk_tree_path_down (path);
-	  if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
-	    return TRUE;
-	  gtk_tree_path_up (path);
-	}
-
-      gtk_tree_path_next (path);
-    }
-  while (gtk_tree_model_iter_next (model, iter));
-
-  return FALSE;
-}
-
 /**
  * gtk_tree_model_foreach:
  * @model: A #GtkTreeModel
@@ -1610,21 +1580,44 @@
 			GtkTreeModelForeachFunc  func,
 			gpointer                 user_data)
 {
-  GtkTreePath *path;
-  GtkTreeIter iter;
 
   g_return_if_fail (GTK_IS_TREE_MODEL (model));
   g_return_if_fail (func != NULL);
 
-  path = gtk_tree_path_new_first ();
-  if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
-    {
-      gtk_tree_path_free (path);
-      return;
-    }
-
-  gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
-  gtk_tree_path_free (path);
+  GtkTreeIter iter;
+  GtkTreeIter parent;
+  gboolean coming_back = FALSE;
+  gboolean valid;
+
+  valid = gtk_tree_model_get_iter_first(tree_model, &iter);
+  while (valid == TRUE) {
+	  GtkTreeIter user_iter;
+	  
+	  if (coming_back == FALSE)
+		  while (valid == TRUE && (parent = iter, 1) &&
+			 (valid = gtk_tree_model_iter_children(tree_model, &iter, &parent), 1));
+	  user_iter = iter = parent;
+	  if (!(valid = gtk_tree_model_iter_next(tree_model, &iter))) {
+		  if ((coming_back = gtk_tree_model_iter_parent(tree_model, &iter, &parent))) {
+			  valid = TRUE;
+			  parent = iter;
+		  } else {
+			  valid = gtk_tree_model_iter_next(tree_model, &parent);
+			  iter = parent;
+		  }
+	  } else {
+		  parent = iter;
+		  coming_back = FALSE;
+	  } 
+
+	  GtkTreePath *tree_path;
+	  tree_path = gtk_tree_model_get_path(tree_model, &user_iter);
+	  if ((*func)(tree_model, tree_path, &user_iter, user_data)) {
+		  gtk_tree_path_free(tree_path);
+		  return;
+	  }
+	  gtk_tree_path_free(tree_path);
+  }
 }
 
 


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