commit c03d15a2056cb55dfd8fdf2bf108cb99a00d7131
Author: Szilárd Pfeiffer <mailbox@pfeifferszilard.hu>
Date:   Sat Aug 21 19:14:59 2010 +0200

    Added iter_prev function to the virtual table of tree model interface.
    
    Implemented the the virtual iter prev function for list store and tree store
    and aded the necessary wrappper function for the model.

diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index a4aabbf..ad5fa53 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -3930,6 +3930,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_prev
 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 3281f2c..ac98a0f 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -3912,6 +3912,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_prev
 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 b8b01f6..b39147b 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_prev       (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_prev = gtk_list_store_iter_prev;
   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_prev (GtkTreeModel  *tree_model,
+			  GtkTreeIter   *iter)
+{
+  GtkListStore *list_store = GTK_LIST_STORE (tree_model);
+  GtkListStorePriv *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 15b978f..1aea635 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -1178,6 +1178,60 @@ gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
   return (* iface->iter_next) (tree_model, iter);
 }
 
+static gboolean
+gtk_tree_model_iter_prev_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_prev:
+ * @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_prev (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);
+  g_return_val_if_fail (iface->iter_prev != NULL, FALSE);
+
+  if (iface->iter_prev)
+    retval = (* iface->iter_prev) (tree_model, iter);
+  else
+    retval = gtk_tree_model_iter_prev_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 e7f59c6..da0ed59 100644
--- a/gtk/gtktreemodel.h
+++ b/gtk/gtktreemodel.h
@@ -100,6 +100,8 @@ struct _GtkTreeModelIface
 				    GValue       *value);
   gboolean     (* iter_next)       (GtkTreeModel *tree_model,
 				    GtkTreeIter  *iter);
+  gboolean     (* iter_prev)       (GtkTreeModel *tree_model,
+				    GtkTreeIter  *iter);
   gboolean     (* iter_children)   (GtkTreeModel *tree_model,
 				    GtkTreeIter  *iter,
 				    GtkTreeIter  *parent);
diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c
index 7047dfb..85c3032 100644
--- a/gtk/gtktreestore.c
+++ b/gtk/gtktreestore.c
@@ -53,6 +53,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_prev       (GtkTreeModel      *tree_model,
+						    GtkTreeIter       *iter);
 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
 						    GtkTreeIter       *iter,
 						    GtkTreeIter       *parent);
@@ -183,6 +185,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_prev = gtk_tree_store_iter_prev;
   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;
@@ -604,16 +607,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)->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_prev (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)->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
