handle case where there are no rows in the model

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
This commit is contained in:
Havoc Pennington 2001-01-09 17:45:34 +00:00 committed by Havoc Pennington
parent 0056107b5d
commit 637c61da76
22 changed files with 826 additions and 137 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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;
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;
pixbuf = cellpixbuf->pixbuf;
if (!pixbuf)
return;
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];
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
pixels = gdk_pixbuf_get_pixels (pixbuf);
gdk_gc_set_clip_rectangle (bg_gc, cell_area);
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;
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
pixels = gdk_pixbuf_get_pixels (pixbuf);
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);
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);
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);
}

View 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;
}
}

View 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

View 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))
{

View 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);

View 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

View 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);

View 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 *

View 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;
}
}

View 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);

View 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));

View File

@ -64,7 +64,7 @@ struct _GtkTreeViewColumn
gint min_width;
gint max_width;
GtkTreeViewColumnFunc *func;
GtkTreeViewColumnFunc func;
gpointer func_data;
gchar *title;
GtkCellRenderer *cell;

View 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

View 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 */
}