[gtk+] Add gtk_tree_model_iter_previous() vfunc



commit 8219ed3a26ef4e2a824d8070eb39e3aa95489fd8
Author: Szilárd Pfeiffer <mailbox pfeifferszilard hu>
Date:   Wed Jan 5 23:39:11 2011 -0500

    Add gtk_tree_model_iter_previous() vfunc
    
    https://bugzilla.gnome.org/show_bug.cgi?id=128058

 docs/reference/gtk/gtk3-sections.txt |    1 +
 gtk/gtk.symbols                      |    1 +
 gtk/gtkliststore.c                   |   23 +++++++++
 gtk/gtktreemodel.c                   |   53 +++++++++++++++++++++
 gtk/gtktreemodel.h                   |    4 ++
 gtk/gtktreemodelfilter.c             |   38 +++++++++++++++
 gtk/gtktreemodelsort.c               |   28 +++++++++++
 gtk/gtktreestore.c                   |   28 ++++++++++--
 gtk/tests/liststore.c                |   83 ++++++++++++++++++++++++++++++++++
 gtk/tests/treestore.c                |   83 ++++++++++++++++++++++++++++++++++
 10 files changed, 338 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 0b8559f..73c7c9a 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -3948,6 +3948,7 @@ gtk_tree_model_get_iter_first
 gtk_tree_model_get_path
 gtk_tree_model_get_value
 gtk_tree_model_iter_next
+gtk_tree_model_iter_previous
 gtk_tree_model_iter_children
 gtk_tree_model_iter_has_child
 gtk_tree_model_iter_n_children
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 001c345..d423df6 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -3135,6 +3135,7 @@ gtk_tree_model_iter_n_children
 gtk_tree_model_iter_next
 gtk_tree_model_iter_nth_child
 gtk_tree_model_iter_parent
+gtk_tree_model_iter_previous
 gtk_tree_model_ref_node
 gtk_tree_model_row_changed
 gtk_tree_model_row_deleted
diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c
index fc43eba..4d9c1dd 100644
--- a/gtk/gtkliststore.c
+++ b/gtk/gtkliststore.c
@@ -75,6 +75,8 @@ static void         gtk_list_store_get_value       (GtkTreeModel      *tree_mode
 						    GValue            *value);
 static gboolean     gtk_list_store_iter_next       (GtkTreeModel      *tree_model,
 						    GtkTreeIter       *iter);
+static gboolean     gtk_list_store_iter_previous   (GtkTreeModel      *tree_model,
+						    GtkTreeIter       *iter);
 static gboolean     gtk_list_store_iter_children   (GtkTreeModel      *tree_model,
 						    GtkTreeIter       *iter,
 						    GtkTreeIter       *parent);
@@ -187,6 +189,7 @@ gtk_list_store_tree_model_init (GtkTreeModelIface *iface)
   iface->get_path = gtk_list_store_get_path;
   iface->get_value = gtk_list_store_get_value;
   iface->iter_next = gtk_list_store_iter_next;
+  iface->iter_previous = gtk_list_store_iter_previous;
   iface->iter_children = gtk_list_store_iter_children;
   iface->iter_has_child = gtk_list_store_iter_has_child;
   iface->iter_n_children = gtk_list_store_iter_n_children;
@@ -550,6 +553,26 @@ gtk_list_store_iter_next (GtkTreeModel  *tree_model,
 }
 
 static gboolean
+gtk_list_store_iter_previous (GtkTreeModel *tree_model,
+                              GtkTreeIter  *iter)
+{
+  GtkListStore *list_store = GTK_LIST_STORE (tree_model);
+  GtkListStorePrivate *priv = list_store->priv;
+
+  g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
+
+  if (g_sequence_iter_is_begin (iter->user_data))
+    {
+      iter->stamp = 0;
+      return FALSE;
+    }
+
+  iter->user_data = g_sequence_iter_prev (iter->user_data);
+
+  return TRUE;
+}
+
+static gboolean
 gtk_list_store_iter_children (GtkTreeModel *tree_model,
 			      GtkTreeIter  *iter,
 			      GtkTreeIter  *parent)
diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c
index c65287c..7b6622f 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -1180,6 +1180,59 @@ gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
   return (* iface->iter_next) (tree_model, iter);
 }
 
+static gboolean
+gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
+                                      GtkTreeIter  *iter)
+{
+  gboolean retval;
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (tree_model, iter);
+  if (path == NULL)
+    return FALSE;
+
+  retval = gtk_tree_path_prev (path) &&
+           gtk_tree_model_get_iter (tree_model, iter, path);
+  if (retval == FALSE)
+    iter->stamp = 0;
+
+  gtk_tree_path_free (path);
+
+  return retval;
+}
+
+/**
+ * gtk_tree_model_iter_previous:
+ * @tree_model: a #GtkTreeModel
+ * @iter: (inout): the #GtkTreeIter
+ *
+ * Sets @iter to point to the previous node at the current level. If there
+ * is no previous @iter, %FALSE is returned and @iter is set to be invalid.
+ *
+ * Return value: %TRUE if @iter has been changed to the previous node
+ *
+ * Since: 3.0
+ */
+gboolean
+gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
+                              GtkTreeIter  *iter)
+{
+  gboolean retval;
+  GtkTreeModelIface *iface;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
+  g_return_val_if_fail (iter != NULL, FALSE);
+
+  iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
+
+  if (iface->iter_previous)
+    retval = (* iface->iter_previous) (tree_model, iter);
+  else
+    retval = gtk_tree_model_iter_previous_default (tree_model, iter);
+
+  return retval;
+}
+
 /**
  * gtk_tree_model_iter_children:
  * @tree_model: A #GtkTreeModel.
diff --git a/gtk/gtktreemodel.h b/gtk/gtktreemodel.h
index b706a00..b290f83 100644
--- a/gtk/gtktreemodel.h
+++ b/gtk/gtktreemodel.h
@@ -97,6 +97,8 @@ struct _GtkTreeModelIface
 				    GValue       *value);
   gboolean     (* iter_next)       (GtkTreeModel *tree_model,
 				    GtkTreeIter  *iter);
+  gboolean     (* iter_previous)   (GtkTreeModel *tree_model,
+				    GtkTreeIter  *iter);
   gboolean     (* iter_children)   (GtkTreeModel *tree_model,
 				    GtkTreeIter  *iter,
 				    GtkTreeIter  *parent);
@@ -206,6 +208,8 @@ void              gtk_tree_model_get_value       (GtkTreeModel *tree_model,
 						  GtkTreeIter  *iter,
 						  gint          column,
 						  GValue       *value);
+gboolean          gtk_tree_model_iter_previous   (GtkTreeModel *tree_model,
+						  GtkTreeIter  *iter);
 gboolean          gtk_tree_model_iter_next       (GtkTreeModel *tree_model,
 						  GtkTreeIter  *iter);
 gboolean          gtk_tree_model_iter_children   (GtkTreeModel *tree_model,
diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c
index d7a155a..18e0d59 100644
--- a/gtk/gtktreemodelfilter.c
+++ b/gtk/gtktreemodelfilter.c
@@ -215,6 +215,8 @@ static void         gtk_tree_model_filter_get_value                       (GtkTr
                                                                            GValue                 *value);
 static gboolean     gtk_tree_model_filter_iter_next                       (GtkTreeModel           *model,
                                                                            GtkTreeIter            *iter);
+static gboolean     gtk_tree_model_filter_iter_previous                   (GtkTreeModel           *model,
+                                                                           GtkTreeIter            *iter);
 static gboolean     gtk_tree_model_filter_iter_children                   (GtkTreeModel           *model,
                                                                            GtkTreeIter            *iter,
                                                                            GtkTreeIter            *parent);
@@ -385,6 +387,7 @@ gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface)
   iface->get_path = gtk_tree_model_filter_get_path;
   iface->get_value = gtk_tree_model_filter_get_value;
   iface->iter_next = gtk_tree_model_filter_iter_next;
+  iface->iter_previous = gtk_tree_model_filter_iter_previous;
   iface->iter_children = gtk_tree_model_filter_iter_children;
   iface->iter_has_child = gtk_tree_model_filter_iter_has_child;
   iface->iter_n_children = gtk_tree_model_filter_iter_n_children;
@@ -2515,6 +2518,41 @@ gtk_tree_model_filter_iter_next (GtkTreeModel *model,
 }
 
 static gboolean
+gtk_tree_model_filter_iter_previous (GtkTreeModel *model,
+                                     GtkTreeIter  *iter)
+{
+  int i;
+  FilterLevel *level;
+  FilterElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, FALSE);
+
+  level = iter->user_data;
+  elt = iter->user_data2;
+
+  i = elt - FILTER_ELT (level->array->data);
+
+  while (i > 0)
+    {
+      i--;
+      elt--;
+
+      if (elt->visible)
+        {
+          iter->user_data2 = elt;
+          return TRUE;
+        }
+    }
+
+  /* no previous visible iter */
+  iter->stamp = 0;
+
+  return FALSE;
+}
+
+static gboolean
 gtk_tree_model_filter_iter_children (GtkTreeModel *model,
                                      GtkTreeIter  *iter,
                                      GtkTreeIter  *parent)
diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c
index 5582da7..1fc5226 100644
--- a/gtk/gtktreemodelsort.c
+++ b/gtk/gtktreemodelsort.c
@@ -189,6 +189,8 @@ static void         gtk_tree_model_sort_get_value          (GtkTreeModel
                                                             GValue                *value);
 static gboolean     gtk_tree_model_sort_iter_next          (GtkTreeModel          *tree_model,
                                                             GtkTreeIter           *iter);
+static gboolean     gtk_tree_model_sort_iter_previous      (GtkTreeModel          *tree_model,
+                                                            GtkTreeIter           *iter);
 static gboolean     gtk_tree_model_sort_iter_children      (GtkTreeModel          *tree_model,
                                                             GtkTreeIter           *iter,
                                                             GtkTreeIter           *parent);
@@ -325,6 +327,7 @@ gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
   iface->get_path = gtk_tree_model_sort_get_path;
   iface->get_value = gtk_tree_model_sort_get_value;
   iface->iter_next = gtk_tree_model_sort_iter_next;
+  iface->iter_previous = gtk_tree_model_sort_iter_previous;
   iface->iter_children = gtk_tree_model_sort_iter_children;
   iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
   iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
@@ -1081,6 +1084,31 @@ gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
 }
 
 static gboolean
+gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
+                                   GtkTreeIter  *iter)
+{
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
+  GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
+  SortLevel *level;
+  SortElt *elt;
+
+  g_return_val_if_fail (priv->child_model != NULL, FALSE);
+  g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
+
+  level = iter->user_data;
+  elt = iter->user_data2;
+
+  if (elt == (SortElt *)level->array->data)
+    {
+      iter->stamp = 0;
+      return FALSE;
+    }
+  iter->user_data2 = elt - 1;
+
+  return TRUE;
+}
+
+static gboolean
 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
 				   GtkTreeIter  *iter,
 				   GtkTreeIter  *parent)
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index fd0b3ff..d9a76a9 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -104,6 +104,8 @@ static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_mode
 						    GValue            *value);
 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
 						    GtkTreeIter       *iter);
+static gboolean     gtk_tree_store_iter_previous   (GtkTreeModel      *tree_model,
+						    GtkTreeIter       *iter);
 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
 						    GtkTreeIter       *iter,
 						    GtkTreeIter       *parent);
@@ -236,6 +238,7 @@ gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
   iface->get_path = gtk_tree_store_get_path;
   iface->get_value = gtk_tree_store_get_value;
   iface->iter_next = gtk_tree_store_iter_next;
+  iface->iter_previous = gtk_tree_store_iter_previous;
   iface->iter_children = gtk_tree_store_iter_children;
   iface->iter_has_child = gtk_tree_store_iter_has_child;
   iface->iter_n_children = gtk_tree_store_iter_n_children;
@@ -671,16 +674,33 @@ gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
   g_return_val_if_fail (iter->user_data != NULL, FALSE);
   g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->priv->stamp, FALSE);
 
-  if (G_NODE (iter->user_data)->next)
+  if (G_NODE (iter->user_data)->next == NULL)
     {
-      iter->user_data = G_NODE (iter->user_data)->next;
-      return TRUE;
+      iter->stamp = 0;
+      return FALSE;
     }
-  else
+
+  iter->user_data = G_NODE (iter->user_data)->next;
+
+  return TRUE;
+}
+
+static gboolean
+gtk_tree_store_iter_previous (GtkTreeModel *tree_model,
+                              GtkTreeIter  *iter)
+{
+  g_return_val_if_fail (iter->user_data != NULL, FALSE);
+  g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->priv->stamp, FALSE);
+
+  if (G_NODE (iter->user_data)->prev == NULL)
     {
       iter->stamp = 0;
       return FALSE;
     }
+
+  iter->user_data = G_NODE (iter->user_data)->prev;
+
+  return TRUE;
 }
 
 static gboolean
diff --git a/gtk/tests/liststore.c b/gtk/tests/liststore.c
index 6452fc2..e710d9b 100644
--- a/gtk/tests/liststore.c
+++ b/gtk/tests/liststore.c
@@ -168,6 +168,13 @@ list_store_test_insert_high_values (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -205,6 +212,13 @@ list_store_test_append (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -242,6 +256,13 @@ list_store_test_prepend (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -280,6 +301,20 @@ list_store_test_insert_after (void)
 
   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -313,6 +348,16 @@ list_store_test_insert_after_NULL (void)
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
   g_assert (iters_equal (&iter2, &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -353,6 +398,20 @@ list_store_test_insert_before (void)
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter3, &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -385,6 +444,13 @@ list_store_test_insert_before_NULL (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -854,6 +920,20 @@ list_store_test_move_before_single (void)
 /* iter invalidation */
 
 static void
+list_store_test_iter_previous_invalid (ListStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
+                                          &iter) == FALSE);
+  g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
 list_store_test_iter_next_invalid (ListStore     *fixture,
                                    gconstpointer  user_data)
 {
@@ -1025,6 +1105,9 @@ main (int    argc,
 		   list_store_test_move_before_single);
 
   /* iter invalidation */
+  g_test_add ("/list-store/iter-prev-invalid", ListStore, NULL,
+              list_store_setup, list_store_test_iter_previous_invalid,
+              list_store_teardown);
   g_test_add ("/list-store/iter-next-invalid", ListStore, NULL,
               list_store_setup, list_store_test_iter_next_invalid,
               list_store_teardown);
diff --git a/gtk/tests/treestore.c b/gtk/tests/treestore.c
index c9dbcff..663eaaf 100644
--- a/gtk/tests/treestore.c
+++ b/gtk/tests/treestore.c
@@ -171,6 +171,13 @@ tree_store_test_insert_high_values (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -208,6 +215,13 @@ tree_store_test_append (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -245,6 +259,13 @@ tree_store_test_prepend (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -283,6 +304,20 @@ tree_store_test_insert_after (void)
 
   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -316,6 +351,16 @@ tree_store_test_insert_after_NULL (void)
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
   g_assert (iters_equal (&iter2, &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -356,6 +401,20 @@ tree_store_test_insert_before (void)
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter3, &iter_copy));
 
+  g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
+  g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 2));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter3, &iter_copy));
+  g_assert (iter_position (store, &iter3, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+
   g_object_unref (store);
 }
 
@@ -388,6 +447,13 @@ tree_store_test_insert_before_NULL (void)
 
   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
   g_assert (iters_equal (&iter2, &iter_copy));
+  g_assert (iter_position (store, &iter2, 1));
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
+  g_assert (iters_equal (&iter, &iter_copy));
+  g_assert (iter_position (store, &iter, 0));
+
+  g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
 
   g_object_unref (store);
 }
@@ -857,6 +923,20 @@ tree_store_test_move_before_single (void)
 /* iter invalidation */
 
 static void
+tree_store_test_iter_previous_invalid (TreeStore     *fixture,
+                                       gconstpointer  user_data)
+{
+  GtkTreeIter iter;
+
+  gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
+
+  g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
+                                          &iter) == FALSE);
+  g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE);
+  g_assert (iter.stamp == 0);
+}
+
+static void
 tree_store_test_iter_next_invalid (TreeStore     *fixture,
                                    gconstpointer  user_data)
 {
@@ -1028,6 +1108,9 @@ main (int    argc,
 		   tree_store_test_move_before_single);
 
   /* iter invalidation */
+  g_test_add ("/tree-store/iter-prev-invalid", TreeStore, NULL,
+              tree_store_setup, tree_store_test_iter_previous_invalid,
+              tree_store_teardown);
   g_test_add ("/tree-store/iter-next-invalid", TreeStore, NULL,
               tree_store_setup, tree_store_test_iter_next_invalid,
               tree_store_teardown);



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