commit 342d7d389212c83863c74eb9500706f22176ff90
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/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..3c74667 100644
--- a/gtk/gtktreemodel.c
+++ b/gtk/gtktreemodel.c
@@ -1178,6 +1178,58 @@ 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.
+ **/
+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
