commit e511990a82dd7b3d3046c783b37cdb64ab75c1fe
Author: Szilárd Pfeiffer <mailbox@pfeifferszilard.hu>
Date:   Mon Aug 16 11:56:35 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/gtk/gtkliststore.c b/gtk/gtkliststore.c
index b8b01f6..8b08c4d 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,24 @@ 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;
+  gboolean retval;
+
+  g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
+  iter->user_data = g_sequence_iter_prev (iter->user_data);
+
+  retval = g_sequence_iter_is_begin (iter->user_data);
+  if (retval)
+    iter->stamp = 0;
+
+  return !retval;
+}
+
+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 b38d592..7686583 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -1196,6 +1196,56 @@ 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);
+
+  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.
+ **/
+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..8cb4bec 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;
@@ -617,6 +620,25 @@ gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
 }
 
 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)
+    {
+      iter->user_data = G_NODE (iter->user_data)->prev;
+      return TRUE;
+    }
+  else
+    {
+      iter->stamp = 0;
+      return FALSE;
+    }
+}
+
+static gboolean
 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
 			      GtkTreeIter  *iter,
 			      GtkTreeIter  *parent)
