]> Pileus Git - ~andy/gtk/commitdiff
handle case where there are no rows in the model
authorHavoc Pennington <hp@redhat.com>
Tue, 9 Jan 2001 17:45:34 +0000 (17:45 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Tue, 9 Jan 2001 17:45:34 +0000 (17:45 +0000)
2001-01-09  Havoc Pennington  <hp@redhat.com>

* gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
there are no rows in the model

* gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
NULL, then return the start of the list

* gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
if we can't get any rows from an empty model

* gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
extraneous * after function pointer typedef usage

* Makefile.am: don't specify full path to cp and rm

* gtk/gtkcellrenderertextpixbuf.c
(gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
NULL before dereferencing, fixes a segfault that happened from
time to time

* gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
and reindent the function
(gtk_cell_renderer_pixbuf_get_size): indentation

* gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
we quit it
(gtk_dialog_add_buttons_valist): add g_return_if_fail
(gtk_dialog_set_default_response): New function, to set default
button
(gtk_dialog_set_response_sensitive): New function, to set
sensitivity of buttons

* gtk/gtkcellrendererpixbuf.c
(gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
(gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf

* gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
handle any G_TYPE_OBJECT subclass, not just the base class, and
also boxed types.
(_gtk_tree_data_list_value_to_node): ditto

* gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if
--gtk-debug=tree

* gtk/gtkmain.c: add GTK_DEBUG_TREE

* gtk/gtkdebug.h: add GTK_DEBUG_TREE

22 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
Makefile.am
gtk/gtkcellrendererpixbuf.c
gtk/gtkcellrenderertextpixbuf.c
gtk/gtkdebug.h
gtk/gtkdialog.c
gtk/gtkdialog.h
gtk/gtkliststore.c
gtk/gtkmain.c
gtk/gtkrbtree.c
gtk/gtktreedatalist.c
gtk/gtktreeview.c
gtk/gtktreeviewcolumn.c
gtk/gtktreeviewcolumn.h
tests/testtreeview-plan.txt
tests/testtreeview.c

index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index 65bcafe4d406a613aceed1d0a1bf90412b364047..40228ca7d50249953d1312c4c03db0040449a5e2 100644 (file)
@@ -1,3 +1,53 @@
+2001-01-09  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktreeview.c (gtk_tree_view_check_dirty): handle case where
+       there are no rows in the model
+
+       * gtk/gtkliststore.c (gtk_list_store_iter_children): if parent is
+       NULL, then return the start of the list
+
+       * gtk/gtktreeview.c (gtk_tree_view_setup_model): don't build tree
+       if we can't get any rows from an empty model 
+
+       * gtk/gtktreeviewcolumn.h (struct _GtkTreeViewColumn): remove
+       extraneous * after function pointer typedef usage
+
+       * Makefile.am: don't specify full path to cp and rm
+
+       * gtk/gtkcellrenderertextpixbuf.c
+       (gtk_cell_renderer_text_pixbuf_get_size): check width/height !=
+       NULL before dereferencing, fixes a segfault that happened from
+       time to time
+
+       * gtk/gtkcellrendererpixbuf.c (gtk_cell_renderer_pixbuf_render):
+       use gdk_pixbuf_render_to_drawable_alpha() to get alpha channel,
+       and reindent the function
+       (gtk_cell_renderer_pixbuf_get_size): indentation
+
+       * gtk/gtkdialog.c (gtk_dialog_run): destroy main loop only after
+       we quit it
+       (gtk_dialog_add_buttons_valist): add g_return_if_fail
+       (gtk_dialog_set_default_response): New function, to set default
+       button
+       (gtk_dialog_set_response_sensitive): New function, to set 
+       sensitivity of buttons
+
+       * gtk/gtkcellrendererpixbuf.c
+       (gtk_cell_renderer_pixbuf_get_property): allow getting a NULL pixbuf
+       (gtk_cell_renderer_pixbuf_set_property): allow setting a NULL pixbuf
+
+       * gtk/gtktreedatalist.c (_gtk_tree_data_list_node_to_value):
+       handle any G_TYPE_OBJECT subclass, not just the base class, and 
+       also boxed types.
+       (_gtk_tree_data_list_value_to_node): ditto
+
+       * gtk/gtkrbtree.c: Run _gtk_rbtree_test at strategic points if 
+       --gtk-debug=tree
+
+       * gtk/gtkmain.c: add GTK_DEBUG_TREE
+
+       * gtk/gtkdebug.h: add GTK_DEBUG_TREE
+
 2001-01-09  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/win32/gdkevents-win32.c: Implement better mouse
index aff671accf39c28d7021055f73265a14c012868c..e59df953bfc014a630dacba87e658f8d55ce0a24 100644 (file)
@@ -119,12 +119,12 @@ GDKTARGET=@gdktarget@
 
 ## Copy .pc files to target-specific names
 gtk+-$(GDKTARGET)-2.0.pc: gtk+-2.0.pc
-       /bin/rm -f gtk+-$(GDKTARGET)-2.0.pc && \
-       /bin/cp gtk+-2.0.pc gtk+-$(GDKTARGET)-2.0.pc
+       rm -f gtk+-$(GDKTARGET)-2.0.pc && \
+       cp gtk+-2.0.pc gtk+-$(GDKTARGET)-2.0.pc
 
 gdk-$(GDKTARGET)-2.0.pc: gdk-2.0.pc
-       /bin/rm -f gdk-$(GDKTARGET)-2.0.pc && \
-       /bin/cp gdk-2.0.pc gdk-$(GDKTARGET)-2.0.pc
+       rm -f gdk-$(GDKTARGET)-2.0.pc && \
+       cp gdk-2.0.pc gdk-$(GDKTARGET)-2.0.pc
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA= gdk-pixbuf-2.0.pc gdk-$(GDKTARGET)-2.0.pc gtk+-$(GDKTARGET)-2.0.pc
index fa21e59e8cad6c8d7dbcbfe08fcebc2000224f0c..61a557237023ab7f6b960f029d4ae7869a6c7221 100644 (file)
@@ -117,7 +117,8 @@ gtk_cell_renderer_pixbuf_get_property (GObject        *object,
   switch (param_id)
     {
     case PROP_PIXBUF:
-      g_value_set_object (value, G_OBJECT (cellpixbuf->pixbuf));
+      g_value_set_object (value,
+                          cellpixbuf->pixbuf ? G_OBJECT (cellpixbuf->pixbuf) : NULL);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -139,8 +140,9 @@ gtk_cell_renderer_pixbuf_set_property (GObject      *object,
   switch (param_id)
     {
     case PROP_PIXBUF:
-      pixbuf = GDK_PIXBUF (g_value_get_object (value));
-      g_object_ref (G_OBJECT (pixbuf));
+      pixbuf = (GdkPixbuf*) g_value_get_object (value);
+      if (pixbuf)
+        g_object_ref (G_OBJECT (pixbuf));
       if (cellpixbuf->pixbuf)
        g_object_unref (G_OBJECT (cellpixbuf->pixbuf));
       cellpixbuf->pixbuf = pixbuf;
@@ -154,7 +156,7 @@ gtk_cell_renderer_pixbuf_set_property (GObject      *object,
 GtkCellRenderer *
 gtk_cell_renderer_pixbuf_new (void)
 {
-       return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_pixbuf_get_type ()));
+  return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_pixbuf_get_type ()));
 }
 
 static void
@@ -163,15 +165,15 @@ gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
                                   gint            *width,
                                   gint            *height)
 {
-       GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
-
-       if (width)
-               *width = (gint) GTK_CELL_RENDERER (cellpixbuf)->xpad * 2 +
-                       (cellpixbuf->pixbuf ? gdk_pixbuf_get_width (cellpixbuf->pixbuf) : 0);
-
-       if (height)
-               *height = (gint) GTK_CELL_RENDERER (cellpixbuf)->ypad * 2 +
-                       (cellpixbuf->pixbuf ? gdk_pixbuf_get_height (cellpixbuf->pixbuf) : 0);
+  GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
+  
+  if (width)
+    *width = (gint) GTK_CELL_RENDERER (cellpixbuf)->xpad * 2 +
+      (cellpixbuf->pixbuf ? gdk_pixbuf_get_width (cellpixbuf->pixbuf) : 0);
+  
+  if (height)
+    *height = (gint) GTK_CELL_RENDERER (cellpixbuf)->ypad * 2 +
+      (cellpixbuf->pixbuf ? gdk_pixbuf_get_height (cellpixbuf->pixbuf) : 0);
 }
 
 static void
@@ -184,54 +186,45 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer    *cell,
                                 guint               flags)
 
 {
-       GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
-       GdkPixbuf *pixbuf;
-       guchar *pixels;
-       gint rowstride;
-       gint real_xoffset;
-       gint real_yoffset;
-       GdkGC *bg_gc = NULL;
-
-       pixbuf = cellpixbuf->pixbuf;
-
-       if (!pixbuf)
-               return;
-
-       if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
-               bg_gc = widget->style->bg_gc [GTK_STATE_SELECTED];
-       else
-               bg_gc = widget->style->base_gc [GTK_STATE_NORMAL];
-
-       gdk_gc_set_clip_rectangle (bg_gc, cell_area);
-
-       rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-       pixels = gdk_pixbuf_get_pixels (pixbuf);
-
-       real_xoffset = GTK_CELL_RENDERER (cellpixbuf)->xalign * (cell_area->width - gdk_pixbuf_get_width (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->xpad));
-       real_xoffset = MAX (real_xoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->xpad;
-       real_yoffset = GTK_CELL_RENDERER (cellpixbuf)->yalign * (cell_area->height - gdk_pixbuf_get_height (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->ypad));
-       real_yoffset = MAX (real_yoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->ypad;
-
-       if (gdk_pixbuf_get_has_alpha (pixbuf))
-               gdk_draw_rgb_32_image (window,
-                                      bg_gc,
-                                      cell_area->x + real_xoffset,
-                                      cell_area->y + real_yoffset,
-                                      gdk_pixbuf_get_width (pixbuf),
-                                      gdk_pixbuf_get_height (pixbuf),
-                                      GDK_RGB_DITHER_NORMAL,
-                                      pixels,
-                                      rowstride);
-       else
-               gdk_draw_rgb_image (window,
-                                   bg_gc,
-                                   cell_area->x + real_xoffset,
-                                   cell_area->y + real_yoffset,
-                                   gdk_pixbuf_get_width (pixbuf),
-                                   gdk_pixbuf_get_height (pixbuf),
-                                   GDK_RGB_DITHER_NORMAL,
-                                   pixels,
-                                   rowstride);
-
-       gdk_gc_set_clip_rectangle (bg_gc, NULL);
+  GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
+  GdkPixbuf *pixbuf;
+  guchar *pixels;
+  gint rowstride;
+  gint real_xoffset;
+  gint real_yoffset;
+  GdkRectangle pix_rect;
+  GdkRectangle draw_rect;
+
+  pixbuf = cellpixbuf->pixbuf;
+
+  if (!pixbuf)
+    return;
+
+  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+  pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+  real_xoffset = GTK_CELL_RENDERER (cellpixbuf)->xalign * (cell_area->width - gdk_pixbuf_get_width (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->xpad));
+  real_xoffset = MAX (real_xoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->xpad;
+  real_yoffset = GTK_CELL_RENDERER (cellpixbuf)->yalign * (cell_area->height - gdk_pixbuf_get_height (pixbuf) - (2 * GTK_CELL_RENDERER (cellpixbuf)->ypad));
+  real_yoffset = MAX (real_yoffset, 0) + GTK_CELL_RENDERER (cellpixbuf)->ypad;
+
+  pix_rect.x = cell_area->x + real_xoffset;
+  pix_rect.y = cell_area->y + real_yoffset;
+  pix_rect.width = gdk_pixbuf_get_width (pixbuf);
+  pix_rect.height = gdk_pixbuf_get_height (pixbuf);
+
+  if (gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect))
+    gdk_pixbuf_render_to_drawable_alpha (pixbuf,
+                                         window,
+                                         /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
+                                         draw_rect.x - pix_rect.x,
+                                         draw_rect.y - pix_rect.y,
+                                         draw_rect.x,
+                                         draw_rect.y,
+                                         draw_rect.width,
+                                         draw_rect.height,
+                                         GDK_PIXBUF_ALPHA_FULL,
+                                         0,
+                                         GDK_RGB_DITHER_NORMAL,
+                                         0, 0);
 }
index 712754fcfd5b83a12315e550253604bead5206d1..8d8fe804bbc99b3465b071716e2b36e43d11c9aa 100644 (file)
@@ -301,13 +301,17 @@ gtk_cell_renderer_text_pixbuf_get_size (GtkCellRenderer *cell,
   if (celltextpixbuf->pixbuf_pos == GTK_POS_LEFT ||
       celltextpixbuf->pixbuf_pos == GTK_POS_RIGHT)
     {
-      *width = pixbuf_width + text_width;
-      *height = MAX (pixbuf_height, text_height);
+      if (width)
+        *width = pixbuf_width + text_width;
+      if (height)
+        *height = MAX (pixbuf_height, text_height);
     }
   else
     {
-      *width = MAX (pixbuf_width, text_width);
-      *height = pixbuf_height + text_height;
+      if (width)
+        *width = MAX (pixbuf_width, text_width);
+      if (height)
+        *height = pixbuf_height + text_height;
     }
 }
 
index 9b7933f66a630db1d7cd0223e44b5750419101fa..78e74d16b5476980cc7a80ee746ea7adca3fa34e 100644 (file)
@@ -37,7 +37,8 @@ typedef enum {
   GTK_DEBUG_SIGNALS    = 1 << 2,
   GTK_DEBUG_DND        = 1 << 3,
   GTK_DEBUG_PLUGSOCKET = 1 << 4,
-  GTK_DEBUG_TEXT =       1 << 5
+  GTK_DEBUG_TEXT       = 1 << 5,
+  GTK_DEBUG_TREE       = 1 << 6
 } GtkDebugFlag;
 
 #ifdef G_ENABLE_DEBUG
index 491e3ae17cab1386d32ccb22e31c6b9a89673d3f..0f13d57a4e8fe82a860db8aaf2b5185e75a55e9c 100644 (file)
@@ -410,6 +410,8 @@ gtk_dialog_add_buttons_valist(GtkDialog      *dialog,
   const gchar* text;
   gint response_id;
 
+  g_return_if_fail (GTK_IS_DIALOG (dialog));
+  
   if (first_button_text == NULL)
     return;
   
@@ -443,8 +445,7 @@ void
 gtk_dialog_add_buttons (GtkDialog   *dialog,
                         const gchar *first_button_text,
                         ...)
-{
-  
+{  
   va_list args;
 
   va_start (args, first_button_text);
@@ -456,6 +457,78 @@ gtk_dialog_add_buttons (GtkDialog   *dialog,
   va_end (args);
 }
 
+/**
+ * gtk_dialog_set_response_sensitive:
+ * @dialog: a #GtkDialog
+ * @response_id: a response ID
+ * @setting: %TRUE for sensitive
+ *
+ * Calls gtk_widget_set_sensitive (widget, @setting) for each
+ * widget in the dialog's action area with the given @response_id.
+ * A convenient way to sensitize/desensitize dialog buttons.
+ * 
+ **/
+void
+gtk_dialog_set_response_sensitive (GtkDialog *dialog,
+                                   gint       response_id,
+                                   gboolean   setting)
+{
+  GList *children;
+  GList *tmp_list;
+
+  children = gtk_container_children (GTK_CONTAINER (dialog));
+
+  tmp_list = children;
+  while (tmp_list != NULL)
+    {
+      GtkWidget *widget = tmp_list->data;
+      ResponseData *rd = g_object_get_data (G_OBJECT (widget),
+                                            "gtk-dialog-response-data");
+
+      if (rd && rd->response_id == response_id)
+        gtk_widget_set_sensitive (widget, setting);
+
+      tmp_list = g_list_next (tmp_list);
+    }
+
+  g_list_free (children);
+}
+
+/**
+ * gtk_dialog_set_default_response:
+ * @dialog: a #GtkDialog
+ * @response_id: a response ID
+ * 
+ * Sets the last widget in the dialog's action area with the given @response_id
+ * as the default widget for the dialog. Pressing "Enter" normally activates
+ * the default widget.
+ * 
+ **/
+void
+gtk_dialog_set_default_response (GtkDialog *dialog,
+                                 gint       response_id)
+{
+  GList *children;
+  GList *tmp_list;
+
+  children = gtk_container_children (GTK_CONTAINER (dialog));
+
+  tmp_list = children;
+  while (tmp_list != NULL)
+    {
+      GtkWidget *widget = tmp_list->data;
+      ResponseData *rd = g_object_get_data (G_OBJECT (widget),
+                                            "gtk-dialog-response-data");
+
+      if (rd && rd->response_id == response_id)
+        gtk_widget_grab_default (widget);
+
+      tmp_list = g_list_next (tmp_list);
+    }
+
+  g_list_free (children);
+}
+
 /**
  * gtk_dialog_response:
  * @dialog: a #GtkDialog
@@ -488,12 +561,8 @@ typedef struct
 static void
 shutdown_loop (RunInfo *ri)
 {
-  if (ri->loop != NULL)
-    {
-      g_main_quit (ri->loop);
-      g_main_destroy (ri->loop);
-      ri->loop = NULL;
-    }
+  if (g_main_loop_is_running (ri->loop))
+    g_main_loop_quit (ri->loop);
 }
 
 static void
@@ -615,9 +684,11 @@ gtk_dialog_run (GtkDialog *dialog)
   
   ri.loop = g_main_new (FALSE);
 
-  g_main_run (ri.loop);
-  
-  g_assert (ri.loop == NULL);
+  g_main_loop_run (ri.loop);
+
+  g_main_loop_unref (ri.loop);
+
+  ri.loop = NULL;
   
   if (!GTK_OBJECT_DESTROYED (dialog))
     {
index 6135908d05fd934e6ca81c016cd2006b1ca4e5fe..fc0c178299fdf2981da1b4d14fe98617b5f445d6 100644 (file)
@@ -44,7 +44,7 @@ typedef enum
 
 } GtkDialogFlags;
 
-/* Convenience enum to use for action_id's.  Positive values are
+/* Convenience enum to use for response_id's.  Positive values are
  * totally user-interpreted. GTK will sometimes return
  * GTK_RESPONSE_NONE if no response_id is available.
  *
@@ -128,6 +128,12 @@ void       gtk_dialog_add_buttons       (GtkDialog   *dialog,
                                          const gchar *first_button_text,
                                          ...);
 
+void gtk_dialog_set_response_sensitive (GtkDialog *dialog,
+                                        gint       response_id,
+                                        gboolean   setting);
+void gtk_dialog_set_default_response   (GtkDialog *dialog,
+                                        gint       response_id);
+
 /* Emit response signal */
 void gtk_dialog_response           (GtkDialog *dialog,
                                     gint       response_id);
index 88d3c6fd538b3bcd7071a665f120858f00d87e94..8c6b4cff169ada74b191fc43348b260aa8bc6757 100644 (file)
@@ -355,10 +355,18 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model,
                              GtkTreeIter  *iter,
                              GtkTreeIter  *parent)
 {
-  iter->stamp = 0;
-  iter->user_data = NULL;
-
-  return FALSE;
+  if (parent)
+    {
+      iter->stamp = 0;      
+      iter->user_data = NULL;
+      return FALSE;
+    }
+  else
+    {
+      iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
+      iter->user_data = GTK_LIST_STORE (tree_model)->root;
+      return TRUE;
+    }
 }
 
 static gboolean
index 61e1556580c6b25110fe8cbda847839d3eb78e0a..c66f4922d27dcecd4d0db208866f78a1afa2e757 100644 (file)
@@ -147,7 +147,8 @@ static const GDebugKey gtk_debug_keys[] = {
   {"signals", GTK_DEBUG_SIGNALS},
   {"dnd", GTK_DEBUG_DND},
   {"plugsocket", GTK_DEBUG_PLUGSOCKET},
-  {"text", GTK_DEBUG_TEXT}
+  {"text", GTK_DEBUG_TEXT},
+  {"tree", GTK_DEBUG_TREE}
 };
 
 static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
index 6afc080ecf3c24f326abcbcf2dcb6e305546911e..0cc35821ef794290792f03f5cacda097aebb4556 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "gtkrbtree.h"
+#include "gtkdebug.h"
 
 static void       _gtk_rbnode_validate_allocator (GAllocator *allocator);
 static GtkRBNode *_gtk_rbnode_new                (GtkRBTree  *tree,
@@ -522,6 +523,9 @@ _gtk_rbtree_insert_after (GtkRBTree  *tree,
     }
   _gtk_rbtree_insert_fixup (tree, node);
 
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (tree);
+  
   return node;
 }
 
@@ -580,6 +584,9 @@ _gtk_rbtree_insert_before (GtkRBTree  *tree,
     }
   _gtk_rbtree_insert_fixup (tree, node);
 
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (tree);
+  
   return node;
 }
 
@@ -765,6 +772,9 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
   y->left = current_allocator->free_nodes;
   current_allocator->free_nodes = y;
   G_UNLOCK (current_allocator);
+
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (tree);
 }
 
 GtkRBNode *
index 1e9b7f570c8fde1e3cbada9a4de317238a14617c..6fdf9d2e9e9b19ba944a9f0b83fdbce7629a0edb 100644 (file)
@@ -181,12 +181,15 @@ _gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
     case G_TYPE_STRING:
       g_value_set_string (value, (gchar *) list->data.v_pointer);
       break;
-    case G_TYPE_OBJECT:
-      g_value_set_object (value, (GObject *) list->data.v_pointer);
-      break;
+
     default:
-      g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
-      return;
+      if (g_type_is_a (type, G_TYPE_OBJECT))
+        g_value_set_object (value, (GObject *) list->data.v_pointer);
+      else if (g_type_is_a (type, G_TYPE_BOXED))
+        g_value_set_boxed (value, (GObject *) list->data.v_pointer);
+      else
+        g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
+      break;
     }
 }
 
@@ -220,12 +223,14 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
     case G_TYPE_STRING:
       list->data.v_pointer = g_value_dup_string (value);
       break;
-    case G_TYPE_OBJECT:
-      list->data.v_pointer = g_value_dup_object (value);
-      break;
     default:
-      g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
-      return;
+      if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT))
+        list->data.v_pointer = g_value_dup_object (value);
+      else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_BOXED))
+        list->data.v_pointer = g_value_dup_boxed (value);
+      else
+        g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
+      break;
     }
 }
 
index d7c121fa0f8ad5f191aaa93fa8686a1cd46e0288..469b9e280c459ad39f0d089cf86c93a3f3090a0a 100644 (file)
@@ -2275,7 +2275,7 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
                         GtkTreeIter *iter,
                         gint         depth)
 {
-  GtkRBNode *temp = tree->root;
+  GtkRBNode *temp;
   GtkTreeIter child;
   GtkCellRenderer *cell;
   GList *list;
@@ -2285,6 +2285,7 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
 
   TREE_VIEW_INTERNAL_ASSERT_VOID (tree != NULL);
 
+  temp = tree->root;
   while (temp->left != tree->nil)
     temp = temp->left;
 
@@ -2434,7 +2435,8 @@ gtk_tree_view_check_dirty (GtkTreeView *tree_view)
   gboolean dirty = FALSE;
   GList *list;
   GtkTreeViewColumn *column;
-
+  GtkTreeIter iter;
+  
   for (list = tree_view->priv->columns; list; list = list->next)
     {
       column = list->data;
@@ -2451,16 +2453,14 @@ gtk_tree_view_check_dirty (GtkTreeView *tree_view)
     return;
 
   path = gtk_tree_path_new_root ();
-  if (path != NULL)
+  if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, path))
     {
-      GtkTreeIter iter;
-
-      gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
-      gtk_tree_path_free (path);
       gtk_tree_view_calc_size (tree_view, tree_view->priv->tree, &iter, 1);
       _gtk_tree_view_set_size (tree_view, -1, -1);
     }
-
+      
+  gtk_tree_path_free (path);
+  
   for (list = tree_view->priv->columns; list; list = list->next)
     {
       column = list->data;
@@ -2915,10 +2915,13 @@ gtk_tree_view_setup_model (GtkTreeView *tree_view)
     return;
 
   path = gtk_tree_path_new_root ();
-  gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
-  gtk_tree_path_free (path);
 
-  gtk_tree_view_build_tree (tree_view, tree_view->priv->tree, &iter, 1, FALSE, GTK_WIDGET_REALIZED (tree_view));
+  if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, path))
+    {
+      gtk_tree_view_build_tree (tree_view, tree_view->priv->tree, &iter, 1, FALSE, GTK_WIDGET_REALIZED (tree_view));
+    }
+  
+  gtk_tree_path_free (path);
 
   gtk_tree_view_create_buttons (tree_view);
 
index b456d20d07d9999a31cf4bc3c9ed505ae5f6ec8d..54d3a8586486c212bdfac126d2aa1c815695196a 100644 (file)
@@ -486,7 +486,7 @@ gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column)
  **/
 void
 gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
-                              gint               size)
+                                gint               size)
 {
   g_return_if_fail (tree_column != NULL);
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
index f1367caff790974c97d262abf0b7256bcf713158..bb5ca44be49be91e628e5e1fdbfdf822afe8414c 100644 (file)
@@ -64,7 +64,7 @@ struct _GtkTreeViewColumn
   gint min_width;
   gint max_width;
 
-  GtkTreeViewColumnFunc *func;
+  GtkTreeViewColumnFunc func;
   gpointer func_data;
   gchar *title;
   GtkCellRenderer *cell;
index 20753f124ec167652f8df1b710a6d9a78179bd2e..511a62a9ca469314cd9002c263e9418a21538277 100644 (file)
@@ -1,11 +1,87 @@
 This document is a laundry list of stuff to check if you want to
 verify that GtkTreeView and associated objects are working properly.
+It isn't a very formal test plan or anything.
+Launching:
+ - Launch testtreeview with --gtk-debug=tree, this will ensure that 
+   debugging code in the tree widget gets run.
+
+Automated tests:
+
+ - on startup, testtreeview runs some automated tests; these all have
+   to pass. 
 
 TreeModel testing:
 
  - all the TreeView/TreeModel tests in this document should be run 
-   with each of the different models testtreeview supports
+   with each of the different models testtreeview supports. The 
+   option menu at the top of testtreeview lets you swap in the 
+   various models. The option menu includes each of the 
+   models that comes with GTK, in various configurations, 
+   and also NULL (no model).
 
  - ensure that swapping in a new model for the tree view when there
-   was a preexisting one exists already 
+   was a preexisting one works OK 
+
+TreeViewColumn testing:
+ - clicking a column header pops up a property inspector for that 
+   column, use this to change column attributes for testing
+ - should test columns with 0, 1, and N columns in the tree view
+ - check that setting a column invisible works
+ - check that setting a column unclickable works
+
+ - check that setting the column width works 
+
+ - check that width of -1 unsets column width
+
+ - check that min/max widths can be set/unset and have the desired
+   effect
+
+ - check that setting the column title works
+
+ - check that the column with an image in it looks right, there should 
+   be such a column (once we support the custom widget feature)
+
+ - check that justification works
+
+TreeView testing:
+
+ - check that expansion/collapse of tree nodes with the expanders
+   works
+
+ - check that turning headers off works
+
+ - check that scrolling works properly
+
+ - check that autosize works (resize columns to a weird size, 
+   then click autosize to ensure they snap back to the original 
+   size)
+
+ - check move_to
+
+ - check expand_all, collapse_all
+
+Key navigation:
+ - FIXME, all the keybindings and what they are supposed to do
+
+TreeSelection testing:
+
+ - check that single and multi mode both work; single should allow zero 
+   or 1 rows selected, multi should allow any number.
+
+ - in multi, check that shift-select selects a contiguous region,
+   control-select selects a disjunct set of nodes
+
+ - check that retrieving the selection works
+
+ - check that foreach() works
+
+CellRenderer testing:
+
+ - these should be well-exercised by the multi-column test, be
+   sure everything looks correctly rendered
 
index 06f5f93e9f650b083413570c7526cd94754fc986..e224c3724cb5425c93b0da874d4c3ee3df317237 100644 (file)
@@ -2,7 +2,38 @@
 #include <gtk/gtk.h>
 #include <string.h>
 
+
+/* Don't copy this bad example; inline RGB data is always a better
+ * idea than inline XPMs.
+ */
+static char  *book_closed_xpm[] = {
+"16 16 6 1",
+"       c None s None",
+".      c black",
+"X      c red",
+"o      c yellow",
+"O      c #808080",
+"#      c white",
+"                ",
+"       ..       ",
+"     ..XX.      ",
+"   ..XXXXX.     ",
+" ..XXXXXXXX.    ",
+".ooXXXXXXXXX.   ",
+"..ooXXXXXXXXX.  ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX..  ",
+" .XX.ooXXX..#O  ",
+"  .XX.oo..##OO. ",
+"   .XX..##OO..  ",
+"    .X.#OO..    ",
+"     ..O..      ",
+"      ..        ",
+"                "
+};
+
 static GtkWidget* create_prop_editor (GObject *object);
+static void run_automated_tests (void);
 
 /* This custom model is to test custom model use. */
 
@@ -77,6 +108,104 @@ struct _GtkTreeModelTypesClass
 GtkType             gtk_tree_model_types_get_type      (void);
 GtkTreeModelTypes *gtk_tree_model_types_new           (void);
 
+typedef enum
+{
+  COLUMNS_NONE,
+  COLUMNS_ONE,
+  COLUMNS_LOTS,
+  COLUMNS_LAST
+} ColumnsType;
+
+#define N_COLUMNS 9
+
+static GType*
+get_model_types (void)
+{
+  static GType column_types[N_COLUMNS] = { 0 };
+  
+  if (column_types[0] == 0)
+    {
+      column_types[0] = G_TYPE_STRING;
+      column_types[1] = G_TYPE_STRING;
+      column_types[2] = GDK_TYPE_PIXBUF;
+      column_types[3] = G_TYPE_FLOAT;
+      column_types[4] = G_TYPE_UINT;
+      column_types[5] = G_TYPE_UCHAR;
+      column_types[6] = G_TYPE_CHAR;
+      column_types[7] = G_TYPE_BOOLEAN;
+      column_types[8] = G_TYPE_INT;
+    }
+
+  return column_types;
+}
+
+static void
+set_columns_type (GtkTreeView *tree_view, ColumnsType type)
+{
+  GtkTreeViewColumn *col;
+  GtkCellRenderer *rend;
+
+  col = gtk_tree_view_get_column (tree_view, 0);
+  while (col)
+    {
+      gtk_tree_view_remove_column (tree_view, col);
+
+      col = gtk_tree_view_get_column (tree_view, 0);
+    }
+
+  switch (type)
+    {
+    case COLUMNS_NONE:
+      break;
+
+    case COLUMNS_LOTS:      
+      rend = gtk_cell_renderer_text_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 1",
+                                                      rend,
+                                                      "text", 1,
+                                                      NULL);
+      
+      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+
+      rend = gtk_cell_renderer_text_pixbuf_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 2",
+                                                      rend,
+                                                      "text", 0,
+                                                      "pixbuf", 2,
+                                                      NULL);
+      
+      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+      
+      /* FALL THRU */
+      
+    case COLUMNS_ONE:
+      rend = gtk_cell_renderer_text_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 0",
+                                                      rend,
+                                                      "text", 0,
+                                                      NULL);
+      
+      gtk_tree_view_insert_column (GTK_TREE_VIEW (tree_view), col, 0);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+      
+    default:
+      break;
+    }
+}
+
+static GdkPixbuf *our_pixbuf;
+  
 typedef enum
 {
   /*   MODEL_TYPES, */
@@ -84,6 +213,8 @@ typedef enum
   MODEL_LIST,
   MODEL_SORTED_TREE,
   MODEL_SORTED_LIST,
+  MODEL_EMPTY_LIST,
+  MODEL_EMPTY_TREE,
   MODEL_NULL,
   MODEL_LAST
 } ModelType;
@@ -95,6 +226,8 @@ static const char *model_names[MODEL_LAST] = {
   "GtkListStore",
   "GtkTreeModelSort wrapping GtkTreeStore",
   "GtkTreeModelSort wrapping GtkListStore",
+  "Empty GtkListStore",
+  "Empty GtkTreeStore",
   "NULL (no model)"
 };
 
@@ -104,8 +237,14 @@ create_list_model (void)
   GtkListStore *store;
   GtkTreeIter iter;
   gint i;
+  GType *t;
+
+  t = get_model_types ();
   
-  store = gtk_list_store_new_with_types (2, G_TYPE_STRING, G_TYPE_STRING);
+  store = gtk_list_store_new_with_types (N_COLUMNS,
+                                         t[0], t[1], t[2],
+                                         t[3], t[4], t[5],
+                                         t[6], t[7], t[8]);
 
   i = 0;
   while (i < 200)
@@ -116,7 +255,12 @@ create_list_model (void)
 
       msg = g_strdup_printf ("%d", i);
       
-      gtk_list_store_set (store, &iter, 0, msg, 1, "Foo! Foo! Foo!", -1);
+      gtk_list_store_set (store, &iter, 0, msg, 1, "Foo! Foo! Foo!",
+                          2, our_pixbuf,
+                          3, 7.0, 4, (guint) 9000,
+                          5, 'f', 6, 'g',
+                          7, TRUE, 8, 23245454,
+                          -1);
 
       g_free (msg);
       
@@ -140,7 +284,12 @@ typesystem_recurse (GType        type,
   gtk_tree_store_append (store, &iter, parent_iter);
 
   str = g_strdup_printf ("%d", type);
-  gtk_tree_store_set (store, &iter, 0, str, 1, g_type_name (type), -1);
+  gtk_tree_store_set (store, &iter, 0, str, 1, g_type_name (type),
+                      2, our_pixbuf,
+                      3, 7.0, 4, (guint) 9000,
+                      5, 'f', 6, 'g',
+                      7, TRUE, 8, 23245454,
+                      -1);
   g_free (str);
   
   children = g_type_children (type, &n_children);
@@ -161,8 +310,25 @@ create_tree_model (void)
 {
   GtkTreeStore *store;
   gint i;
+  GType *t;
+  volatile GType dummy; /* G_GNUC_CONST makes the optimizer remove
+                         * get_type calls if you don't do something
+                         * like this
+                         */
   
-  store = gtk_tree_store_new_with_types (2, G_TYPE_STRING, G_TYPE_STRING);
+  /* Make the tree more interesting */
+  dummy = gtk_scrolled_window_get_type ();
+  dummy = gtk_label_get_type ();
+  dummy = gtk_hscrollbar_get_type ();
+  dummy = gtk_vscrollbar_get_type ();
+  dummy = pango_layout_get_type ();
+
+  t = get_model_types ();
+  
+  store = gtk_tree_store_new_with_types (N_COLUMNS,
+                                         t[0], t[1], t[2],
+                                         t[3], t[4], t[5],
+                                         t[6], t[7], t[8]);
 
   i = 0;
   while (i < G_TYPE_LAST_RESERVED_FUNDAMENTAL)
@@ -199,13 +365,13 @@ main (int    argc,
   GtkWidget *table;
   GtkWidget *om;
   GtkWidget *menu;
-  GtkTreeViewColumn *col;
-  GtkCellRenderer *rend;
   GtkTreeModel *model;
   gint i;
   
   gtk_init (&argc, &argv);
 
+  our_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) book_closed_xpm);  
+  
 #if 0
   models[MODEL_TYPES] = GTK_TREE_MODEL (gtk_tree_model_types_new ());
 #endif
@@ -219,8 +385,13 @@ main (int    argc,
   model = create_tree_model ();
   models[MODEL_SORTED_TREE] = gtk_tree_model_sort_new_with_model (model, NULL, 0);
   g_object_unref (G_OBJECT (model));
+
+  models[MODEL_EMPTY_LIST] = GTK_TREE_MODEL (gtk_list_store_new ());
+  models[MODEL_EMPTY_TREE] = GTK_TREE_MODEL (gtk_tree_store_new ());
   
   models[MODEL_NULL] = NULL;
+
+  run_automated_tests ();
   
   menu = gtk_menu_new ();
   
@@ -283,29 +454,7 @@ main (int    argc,
   
   gtk_container_add (GTK_CONTAINER (sw), tv);
 
-  rend = gtk_cell_renderer_text_new ();
-  
-  col = gtk_tree_view_column_new_with_attributes ("Type ID",
-                                                  rend,
-                                                  "text", 0,
-                                                  NULL);
-
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
-
-  g_object_unref (G_OBJECT (rend));
-  g_object_unref (G_OBJECT (col));
-  
-  rend = gtk_cell_renderer_text_new ();
-  
-  col = gtk_tree_view_column_new_with_attributes ("Name",
-                                                  rend,
-                                                  "text", 1,
-                                                  NULL);
-
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
-
-  g_object_unref (G_OBJECT (rend));
-  g_object_unref (G_OBJECT (col));
+  set_columns_type (GTK_TREE_VIEW (tv), COLUMNS_LOTS);
   
   gtk_widget_show_all (window);
   
@@ -1165,3 +1314,15 @@ create_prop_editor (GObject *object)
   return win;
 }
 
+/*
+ * Automated testing
+ */
+
+static void
+run_automated_tests (void)
+{
+  /* FIXME TreePath basic verification */
+
+  /* FIXME consistency checks on the models */
+  
+}