Index: gtktreeprivate.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeprivate.h,v
retrieving revision 1.69
diff -u -p -r1.69 gtktreeprivate.h
--- gtktreeprivate.h	24 Jan 2006 10:49:29 -0000	1.69
+++ gtktreeprivate.h	21 Feb 2006 08:53:48 -0000
@@ -231,6 +231,11 @@ struct _GtkTreeViewPrivate
   GtkTreeViewRowSeparatorFunc row_separator_func;
   gpointer row_separator_data;
   GtkDestroyNotify row_separator_destroy;
+
+  GtkTreeViewLineStyle grid_line_style;
+  GtkTreeViewLineStyle tree_line_style;
+  GdkGC *grid_line_gc;
+  GdkGC *tree_line_gc;
 };
 
 #ifdef __GNUC__
Index: gtktreeview.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeview.h,v
retrieving revision 1.67
diff -u -p -r1.67 gtktreeview.h
--- gtktreeview.h	24 Jan 2006 10:49:29 -0000	1.67
+++ gtktreeview.h	21 Feb 2006 08:53:49 -0000
@@ -42,6 +42,13 @@ typedef enum
   GTK_TREE_VIEW_DROP_INTO_OR_AFTER
 } GtkTreeViewDropPosition;
 
+typedef enum
+{
+  GTK_TREE_VIEW_LINE_STYLE_NONE,
+  GTK_TREE_VIEW_LINE_STYLE_SOLID,
+  GTK_TREE_VIEW_LINE_STYLE_DOTTED
+} GtkTreeViewLineStyle;
+
 #define GTK_TYPE_TREE_VIEW		(gtk_tree_view_get_type ())
 #define GTK_TREE_VIEW(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_VIEW, GtkTreeView))
 #define GTK_TREE_VIEW_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_VIEW, GtkTreeViewClass))
@@ -349,6 +356,12 @@ void                        gtk_tree_vie
 								  gpointer                    data,
 								  GtkDestroyNotify            destroy);
 
+GtkTreeViewLineStyle        gtk_tree_view_get_grid_line_style    (GtkTreeView                *tree_view);
+void                        gtk_tree_view_set_grid_line_style    (GtkTreeView                *tree_view,
+								  GtkTreeViewLineStyle        line_style);
+GtkTreeViewLineStyle        gtk_tree_view_get_tree_line_style    (GtkTreeView                *tree_view);
+void                        gtk_tree_view_set_tree_line_style    (GtkTreeView                *tree_view,
+								  GtkTreeViewLineStyle        line_style);
 
 G_END_DECLS
 
Index: gtktreeview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeview.c,v
retrieving revision 1.518
diff -u -p -r1.518 gtktreeview.c
--- gtktreeview.c	6 Feb 2006 18:32:59 -0000	1.518
+++ gtktreeview.c	21 Feb 2006 08:53:50 -0000
@@ -1198,6 +1198,9 @@ gtk_tree_view_init (GtkTreeView *tree_vi
           
   tree_view->priv->hover_selection = FALSE;
   tree_view->priv->hover_expand = FALSE;
+
+  tree_view->priv->grid_line_style = GTK_TREE_VIEW_LINE_STYLE_NONE;
+  tree_view->priv->tree_line_style = GTK_TREE_VIEW_LINE_STYLE_NONE;
 }
 
 
@@ -1632,6 +1635,10 @@ gtk_tree_view_realize (GtkWidget *widget
   for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next)
     _gtk_tree_view_column_realize_button (GTK_TREE_VIEW_COLUMN (tmp_list->data));
 
+  /* Need to call those here, since they craete GCs */
+  gtk_tree_view_set_grid_line_style (tree_view, tree_view->priv->grid_line_style);
+  gtk_tree_view_set_tree_line_style (tree_view, tree_view->priv->tree_line_style);
+
   install_presize_handler (tree_view); 
 }
 
@@ -3469,6 +3476,39 @@ draw_empty_focus (GtkTreeView *tree_view
 		     1, 1, w, h);
 }
 
+static void
+gtk_tree_view_draw_grid_lines (GtkTreeView    *tree_view,
+			       GdkEventExpose *event,
+			       gint            n_visible_columns)
+{
+  GList *list = tree_view->priv->columns;
+  gint i = 0;
+  gint current_x = 0;
+
+  if (tree_view->priv->grid_line_style == GTK_TREE_VIEW_LINE_STYLE_NONE)
+    return;
+
+  /* Only draw the lines for visible rows and columns */
+  for (list = tree_view->priv->columns; list; list = list->next, i++)
+    {
+      GtkTreeViewColumn *column = list->data;
+
+      /* We don't want a line for the list column */
+      if (i == n_visible_columns - 1)
+	break;
+
+      if (! column->visible)
+	continue;
+
+      current_x += column->width;
+
+      gdk_draw_line (event->window,
+		     tree_view->priv->grid_line_gc,
+		     current_x - 1, 0,
+		     current_x - 1, tree_view->priv->height);
+    }
+}
+
 /* Warning: Very scary function.
  * Modify at your own risk
  *
@@ -3770,6 +3810,79 @@ gtk_tree_view_bin_expose (GtkWidget     
                               background_area.width,
                               background_area.height);
 
+	  if (tree_view->priv->grid_line_style > GTK_TREE_VIEW_LINE_STYLE_NONE)
+	    {
+	      if (background_area.y > 0)
+		gdk_draw_line (event->window,
+			       tree_view->priv->grid_line_gc,
+			       background_area.x, background_area.y,
+			       background_area.x + background_area.width,
+			       background_area.y);
+	    }
+
+	  if (gtk_tree_view_is_expander_column (tree_view, column) &&
+	      tree_view->priv->tree_line_style > GTK_TREE_VIEW_LINE_STYLE_NONE)
+	    {
+	      if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT
+		  && depth > 1)
+	        {
+		  gdk_draw_line (event->window,
+				 tree_view->priv->tree_line_gc,
+			         background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+			         background_area.y + background_area.height / 2,
+			         background_area.x + tree_view->priv->expander_size * (depth - 1.1),
+			         background_area.y + background_area.height / 2);
+	        }
+	      else if (depth > 1)
+	        {
+		  gdk_draw_line (event->window,
+				 tree_view->priv->tree_line_gc,
+			         background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+			         background_area.y + background_area.height / 2,
+			         background_area.x + tree_view->priv->expander_size * (depth - 0.5),
+			         background_area.y + background_area.height / 2);
+		}
+
+	      if (depth > 1)
+	        {
+		  gint i;
+		  GtkRBNode *tmp_node;
+		  GtkRBTree *tmp_tree;
+
+	          if (!_gtk_rbtree_next (tree, node))
+		    gdk_draw_line (event->window,
+				   tree_view->priv->tree_line_gc,
+				   background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+				   background_area.y,
+				   background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+				   background_area.y + background_area.height / 2);
+		  else
+		    gdk_draw_line (event->window,
+				   tree_view->priv->tree_line_gc,
+				   background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+				   background_area.y,
+				   background_area.x + tree_view->priv->expander_size * (depth - 1.5),
+				   background_area.y + background_area.height);
+
+		  tmp_node = tree->parent_node;
+		  tmp_tree = tree->parent_tree;
+
+		  for (i = depth - 2; i > 0; i--)
+		    {
+	              if (_gtk_rbtree_next (tmp_tree, tmp_node))
+			gdk_draw_line (event->window,
+				       tree_view->priv->tree_line_gc,
+				       background_area.x + tree_view->priv->expander_size * (i - 0.5),
+				       background_area.y,
+				       background_area.x + tree_view->priv->expander_size * (i - 0.5),
+				       background_area.y + background_area.height);
+
+		      tmp_node = tmp_tree->parent_node;
+		      tmp_tree = tmp_tree->parent_tree;
+		    }
+		}
+	    }
+
 	  if (gtk_tree_view_is_expander_column (tree_view, column) &&
               TREE_VIEW_DRAW_EXPANDERS(tree_view))
 	    {
@@ -3955,6 +4068,7 @@ gtk_tree_view_bin_expose (GtkWidget     
       else
 	{
 	  gboolean done = FALSE;
+
 	  do
 	    {
 	      node = _gtk_rbtree_next (tree, node);
@@ -3991,6 +4105,8 @@ gtk_tree_view_bin_expose (GtkWidget     
   while (y_offset < event->area.height);
 
  done:
+  gtk_tree_view_draw_grid_lines (tree_view, event, n_visible_columns);
+
   if (cursor_path)
     gtk_tree_path_free (cursor_path);
 
@@ -6959,6 +7075,9 @@ gtk_tree_view_style_set (GtkWidget *widg
     {
       gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
       gdk_window_set_background (tree_view->priv->bin_window, &widget->style->base[widget->state]);
+
+      gtk_tree_view_set_grid_line_style (tree_view, tree_view->priv->grid_line_style);
+      gtk_tree_view_set_tree_line_style (tree_view, tree_view->priv->tree_line_style);
     }
 
   gtk_widget_style_get (widget,
@@ -13549,6 +13668,117 @@ gtk_tree_view_state_changed (GtkWidget  
 
   gtk_widget_queue_draw (widget);
 }
+
+GtkTreeViewLineStyle
+gtk_tree_view_get_grid_line_style (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), 0);
+
+  return tree_view->priv->grid_line_style;
+}
+
+void
+gtk_tree_view_set_grid_line_style (GtkTreeView          *tree_view,
+				   GtkTreeViewLineStyle  line_style)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (line_style >= GTK_TREE_VIEW_LINE_STYLE_NONE && line_style <= GTK_TREE_VIEW_LINE_STYLE_DOTTED);
+
+  tree_view->priv->grid_line_style = line_style;
+
+  widget = GTK_WIDGET (tree_view);
+
+  if (!GTK_WIDGET_REALIZED (widget))
+    return;
+
+  if (tree_view->priv->grid_line_gc)
+    g_object_unref (tree_view->priv->grid_line_gc);
+  
+  switch (tree_view->priv->grid_line_style)
+    {
+      case GTK_TREE_VIEW_LINE_STYLE_SOLID:
+	tree_view->priv->grid_line_gc = gdk_gc_new (widget->window);
+	gdk_gc_copy (tree_view->priv->grid_line_gc,
+		     widget->style->black_gc);
+	break;
+
+      case GTK_TREE_VIEW_LINE_STYLE_DOTTED:
+	tree_view->priv->grid_line_gc = gdk_gc_new (widget->window);
+	gdk_gc_copy (tree_view->priv->grid_line_gc,
+		     widget->style->black_gc);
+
+	gdk_gc_set_line_attributes (tree_view->priv->grid_line_gc, 1,
+				    GDK_LINE_ON_OFF_DASH,
+				    GDK_CAP_BUTT, GDK_JOIN_MITER);
+	gdk_gc_set_dashes (tree_view->priv->grid_line_gc, 0, "\1\1", 2);
+	break;
+
+      case GTK_TREE_VIEW_LINE_STYLE_NONE:
+      default:
+	tree_view->priv->grid_line_gc = NULL;
+	break;
+    }
+
+  gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+}
+
+GtkTreeViewLineStyle
+gtk_tree_view_get_tree_line_style (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), 0);
+
+  return tree_view->priv->tree_line_style;
+}
+
+void
+gtk_tree_view_set_tree_line_style (GtkTreeView          *tree_view,
+				   GtkTreeViewLineStyle  line_style)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (line_style >= GTK_TREE_VIEW_LINE_STYLE_NONE && line_style <= GTK_TREE_VIEW_LINE_STYLE_DOTTED);
+
+  tree_view->priv->tree_line_style = line_style;
+
+  widget = GTK_WIDGET (tree_view);
+
+  if (!GTK_WIDGET_REALIZED (widget))
+    return;
+
+  if (tree_view->priv->tree_line_gc)
+    g_object_unref (tree_view->priv->tree_line_gc);
+
+  switch (tree_view->priv->tree_line_style)
+    {
+      case GTK_TREE_VIEW_LINE_STYLE_SOLID:
+	tree_view->priv->tree_line_gc = gdk_gc_new (widget->window);
+	gdk_gc_copy (tree_view->priv->tree_line_gc,
+		     widget->style->black_gc);
+	break;
+
+      case GTK_TREE_VIEW_LINE_STYLE_DOTTED:
+	tree_view->priv->tree_line_gc = gdk_gc_new (widget->window);
+	gdk_gc_copy (tree_view->priv->tree_line_gc,
+		     widget->style->black_gc);
+
+	gdk_gc_set_line_attributes (tree_view->priv->tree_line_gc, 1,
+				    GDK_LINE_ON_OFF_DASH,
+				    GDK_CAP_BUTT, GDK_JOIN_MITER);
+	gdk_gc_set_dashes (tree_view->priv->tree_line_gc, 0, "\1\1", 2);
+	break;
+
+      case GTK_TREE_VIEW_LINE_STYLE_NONE:
+      default:
+	tree_view->priv->tree_line_gc = NULL;
+	break;
+    }
+
+  gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+}
+
 
 #define __GTK_TREE_VIEW_C__
 #include "gtkaliasdef.c"
