]> Pileus Git - ~andy/gtk/commitdiff
adapt to handle PangoColor
authorHavoc Pennington <hp@redhat.com>
Fri, 26 Jan 2001 21:12:05 +0000 (21:12 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Fri, 26 Jan 2001 21:12:05 +0000 (21:12 +0000)
2001-01-26  Havoc Pennington  <hp@redhat.com>

* gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor

* gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
not offset by TREE_VIEW_HEADER_HEIGHT
(gtk_tree_view_tree_to_widget_coords): fix to not offset by
TREE_VIEW_HEADER_HEIGHT

* configure.in (included_loaders): for me, --with-included-loaders
generates the error "the specified loader yes does not exist",
i.e. the arg defaults to "yes", so change test for value ""
to test for value "yes", and include all loaders in that case.

* gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function

* gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
handle TREE_VIEW_VERTICAL_SEPARATOR
(gtk_tree_view_bin_expose): fix to consider the row offset as
pointing halfway into vertical separator.
(gtk_tree_view_draw_node_focus_rect): ditto

* gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
--gtk-debug=updates, which causes gdk_window_set_debug_updates
(TRUE) to be called.

* gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
debug mode where the invalid region is colored in on invalidate,
so you can see the flicker and know whether your redraw code is
doing a good job.

* gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in
tree window coordinates (clip rect is in tree window coords)

* gtk/Makefile.am: add gtktreednd.[hc]

* gtk/gtkliststore.c: implement gtktreednd interfaces.

* gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
drag-and-drop data operations on a model (so we can set up tree
drag-and-drop automatically)

* gtk/testgtk.c: Add a window to change sensitivity in the
GtkLabel test; add a way to change the entry frame in GtkEntry
test

* gtk/gtkentry.c (gtk_entry_set_has_frame):
(gtk_entry_get_has_frame): new functions to remove the frame
around an entry
(gtk_entry_size_request): shrink requisition if no frame
(gtk_entry_draw_focus): don't draw frame if no frame

* gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
checks inside a cell renderer
(gtk_default_draw_option): ditto for options

* gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
children from the alignment, not the button
(gtk_tree_view_column_init): ref/sink the column, to emulate
GObject refcounting.

* gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink

* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
Use theme functions to draw the toggles

* gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors

* gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
GdkPangoAttrEmbossed to use in rendering insensitive text

* gdk/gdkpango.c (gdk_draw_layout_line): render new properties

* gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
using new GDK features

37 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
configure.in
gdk/gdkpango.c
gdk/gdkpango.h
gdk/gdkwindow.c
gdk/gdkwindow.h
gtk/Makefile.am
gtk/gtk.h
gtk/gtkcellrenderer.c
gtk/gtkcellrenderertoggle.c
gtk/gtkdebug.h
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtkliststore.c
gtk/gtkmain.c
gtk/gtkrbtree.c
gtk/gtkrbtree.h
gtk/gtkstyle.c
gtk/gtktextlayout.c
gtk/gtktextview.c
gtk/gtktreedatalist.c
gtk/gtktreedatalist.h
gtk/gtktreednd.c [new file with mode: 0644]
gtk/gtktreednd.h [new file with mode: 0644]
gtk/gtktreemodel.h
gtk/gtktreeview.c
gtk/gtktreeview.h
gtk/gtktreeviewcolumn.c
gtk/testgtk.c
tests/testgtk.c
tests/testtreeview.c

index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 79db30750d80dcd581984d305fa1aecf11bcdd34..d0e503736565a5f9eae2f9f7a6b6bbcb005040b7 100644 (file)
@@ -1,3 +1,79 @@
+2001-01-26  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextlayout.c (convert_color): adapt to handle PangoColor
+
+       * gtk/gtktreeview.c (gtk_tree_view_widget_to_tree_coords): fix to
+       not offset by TREE_VIEW_HEADER_HEIGHT
+       (gtk_tree_view_tree_to_widget_coords): fix to not offset by
+       TREE_VIEW_HEADER_HEIGHT
+
+       * configure.in (included_loaders): for me, --with-included-loaders
+       generates the error "the specified loader yes does not exist",
+       i.e. the arg defaults to "yes", so change test for value ""
+       to test for value "yes", and include all loaders in that case.
+
+       * gtk/gtkrbtree.c (_gtk_rbtree_get_depth): new function
+
+       * gtk/gtktreeview.c (gtk_tree_view_get_cell_rect): fix to properly
+       handle TREE_VIEW_VERTICAL_SEPARATOR
+       (gtk_tree_view_bin_expose): fix to consider the row offset as
+       pointing halfway into vertical separator.       
+       (gtk_tree_view_draw_node_focus_rect): ditto
+
+       * gtk/gtkdebug.h, gtk/gtkmain.c (gtk_init_check): Add
+       --gtk-debug=updates, which causes gdk_window_set_debug_updates
+       (TRUE) to be called.
+
+       * gdk/gdkwindow.c (gdk_window_set_debug_updates): Allow enabling a
+       debug mode where the invalid region is colored in on invalidate,
+       so you can see the flicker and know whether your redraw code is 
+       doing a good job.
+
+       * gtk/gtktreeview.c (gtk_tree_view_queue_draw_node): Work in 
+       tree window coordinates (clip rect is in tree window coords)
+
+       * gtk/Makefile.am: add gtktreednd.[hc]
+
+       * gtk/gtkliststore.c: implement gtktreednd interfaces.
+
+       * gtk/gtktreednd.c, gtk/gtktreednd.h: New interface to support
+       drag-and-drop data operations on a model (so we can set up tree
+       drag-and-drop automatically)
+
+       * gtk/testgtk.c: Add a window to change sensitivity in the
+       GtkLabel test; add a way to change the entry frame in GtkEntry
+       test
+
+       * gtk/gtkentry.c (gtk_entry_set_has_frame): 
+       (gtk_entry_get_has_frame): new functions to remove the frame
+       around an entry
+       (gtk_entry_size_request): shrink requisition if no frame
+       (gtk_entry_draw_focus): don't draw frame if no frame
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): draw custom look for
+       checks inside a cell renderer
+       (gtk_default_draw_option): ditto for options
+
+       * gtk/gtktreeviewcolumn.c (update_button_contents): add/remove
+       children from the alignment, not the button
+       (gtk_tree_view_column_init): ref/sink the column, to emulate
+       GObject refcounting.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_init): ref/sink
+       
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_render):
+       Use theme functions to draw the toggles 
+
+       * gdk/gdkpango.c (gdk_pango_get_gc): use GdkRGB to alloc colors
+
+       * gdk/gdkpango.h, gdk/gdkpango.c: Add GdkPangoAttrStipple and
+       GdkPangoAttrEmbossed to use in rendering insensitive text
+
+       * gdk/gdkpango.c (gdk_draw_layout_line): render new properties
+
+       * gtk/gtkstyle.c (gtk_default_draw_layout): handle sensitivity
+       using new GDK features
+       
 2001-01-24    <alexl@redhat.com>
 
        * gtk/gtkimage.c:
index 8448e73f7df325460dee72225679c3c73029b044..19652b4c25d4d2e2c1132dce227a472cfd1ee7d4 100644 (file)
@@ -914,7 +914,7 @@ AC_ARG_WITH(included_loaders, [  --with-included-loaders=LOADER1,LOADER2,... Bui
 all_loaders="png,bmp,wbmp,gif,ico,jpeg,pnm,ras,tiff,xpm"
 included_loaders=""
 # If no loaders specified, include all
-if test "x$with_included_loaders" = x ; then
+if test "x$with_included_loaders" = xyes ; then
   included_loaders="$all_loaders"
 else
   included_loaders="$with_included_loaders"
index 7f4d2e642337c22fa2cbded15c5624cbe62ad20d..53dc4f514aeb6fb18aa9f3669e970cb40d7f7a5b 100644 (file)
@@ -31,13 +31,18 @@ struct _GdkPangoContextInfo
   GdkColormap *colormap;
 };
 
+static PangoAttrType gdk_pango_attr_stipple_type;
+static PangoAttrType gdk_pango_attr_embossed_type;
+
 static void gdk_pango_get_item_properties (PangoItem      *item,
                                           PangoUnderline *uline,
                                            gint           *rise,
-                                          PangoAttrColor *fg_color,
+                                          PangoColor     *fg_color,
                                           gboolean       *fg_set,
-                                          PangoAttrColor *bg_color,
+                                          PangoColor     *bg_color,
                                           gboolean       *bg_set,
+                                           gboolean       *embossed,
+                                           GdkBitmap     **stipple,
                                           gboolean       *shape_set,
                                           PangoRectangle *ink_rect,
                                           PangoRectangle *logical_rect);
@@ -70,38 +75,40 @@ gdk_pango_context_get_info (PangoContext *context, gboolean create)
 
 static GdkGC *
 gdk_pango_get_gc (PangoContext   *context,
-                 PangoAttrColor *fg_color,
+                 PangoColor     *fg_color,
+                  GdkBitmap      *stipple,
                  GdkGC          *base_gc)
 {
-  GdkPangoContextInfo *info;
-  GdkColormap *colormap;
   GdkColor color;
+  GdkGC *result;
+  GdkPangoContextInfo *info;
   
   g_return_val_if_fail (context != NULL, NULL);
 
   info = gdk_pango_context_get_info (context, FALSE);
 
-  if (info && info->colormap)
-    colormap = info->colormap;
-  else
-    colormap = gdk_colormap_get_system();
-
-  /* FIXME. FIXME. FIXME. Only works for true color */
-
+  if (info == NULL || info->colormap == NULL)
+    {
+      g_warning ("you must set the colormap on a PangoContext before using it to draw a layout");
+      return NULL;
+    }
+  
   color.red = fg_color->red;
   color.green = fg_color->green;
   color.blue = fg_color->blue;
   
-  if (gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE))
-    {
-      GdkGC *result = gdk_gc_new (gdk_parent_root);
-      gdk_gc_copy (result, base_gc);
-      gdk_gc_set_foreground (result, &color);
+  result = gdk_gc_new (gdk_parent_root);
+  gdk_gc_copy (result, base_gc);
+  gdk_rgb_find_color (info->colormap, &color);
+  gdk_gc_set_foreground (result, &color);
 
-      return result;
+  if (stipple)
+    {
+      gdk_gc_set_fill (result, GDK_STIPPLED);
+      gdk_gc_set_stipple (result, stipple);
     }
-  else
-    return gdk_gc_ref (base_gc);
+  
+  return result;
 }
 
 static void
@@ -158,6 +165,8 @@ gdk_draw_layout_line (GdkDrawable      *drawable,
   PangoContext *context;
   gint x_off = 0;
   gint rise = 0;
+  gboolean embossed;
+  GdkBitmap *stipple;
   
   g_return_if_fail (drawable != NULL);
   g_return_if_fail (gc != NULL);
@@ -171,7 +180,7 @@ gdk_draw_layout_line (GdkDrawable      *drawable,
     {
       PangoUnderline uline = PANGO_UNDERLINE_NONE;
       PangoLayoutRun *run = tmp_list->data;
-      PangoAttrColor fg_color, bg_color;
+      PangoColor fg_color, bg_color;
       gboolean fg_set, bg_set, shape_set;
       GdkGC *fg_gc;
       gint risen_y;
@@ -182,6 +191,8 @@ gdk_draw_layout_line (GdkDrawable      *drawable,
                                      &rise,
                                      &fg_color, &fg_set,
                                      &bg_color, &bg_set,
+                                     &embossed,
+                                     &stipple,
                                      &shape_set,
                                      &ink_rect,
                                     &logical_rect);
@@ -201,28 +212,48 @@ gdk_draw_layout_line (GdkDrawable      *drawable,
 
       if (bg_set)
        {
-         GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, gc);
-
+         GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, stipple, gc);
+          
          gdk_draw_rectangle (drawable, bg_gc, TRUE,
                              x + (x_off + logical_rect.x) / PANGO_SCALE,
                              risen_y + overall_rect.y / PANGO_SCALE,
                              logical_rect.width / PANGO_SCALE,
                              overall_rect.height / PANGO_SCALE);
 
+          if (stipple)
+            gdk_gc_set_fill (bg_gc, GDK_SOLID);
+          
          gdk_pango_free_gc (context, bg_gc);
        }
 
-      if (fg_set)
-       fg_gc = gdk_pango_get_gc (context, &fg_color, gc);
+      if (fg_set || stipple)
+       fg_gc = gdk_pango_get_gc (context, &fg_color, stipple, gc);
       else
        fg_gc = gc;
-
+      
       if (!shape_set)
-       gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font,
-                        x + x_off / PANGO_SCALE,
-                         risen_y,
-                         run->glyphs);
+        {
+          gint gx, gy;
 
+          gx = x + x_off / PANGO_SCALE;
+          gy = risen_y;
+          
+          if (embossed)
+            {
+              PangoColor color = { 65535, 65535, 65535 };
+              GdkGC *white_gc = gdk_pango_get_gc (context, &color, stipple, fg_gc);
+              gdk_draw_glyphs (drawable, white_gc, run->item->analysis.font,
+                               gx + 1,
+                               gy + 1,
+                               run->glyphs);
+              gdk_pango_free_gc (context, white_gc);
+            }
+          
+          gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font,
+                           gx, gy,
+                           run->glyphs);
+        }
+      
       switch (uline)
        {
        case PANGO_UNDERLINE_NONE:
@@ -249,8 +280,8 @@ gdk_draw_layout_line (GdkDrawable      *drawable,
                          risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1);
          break;
        }
-
-      if (fg_set)
+      
+      if (fg_gc != gc)
        gdk_pango_free_gc (context, fg_gc);
 
       x_off += logical_rect.width;
@@ -307,10 +338,12 @@ static void
 gdk_pango_get_item_properties (PangoItem      *item,
                               PangoUnderline *uline,
                                gint           *rise,
-                              PangoAttrColor *fg_color,
+                              PangoColor     *fg_color,
                               gboolean       *fg_set,
-                              PangoAttrColor *bg_color,
+                              PangoColor     *bg_color,
                               gboolean       *bg_set,
+                               gboolean       *embossed,
+                               GdkBitmap     **stipple,
                               gboolean       *shape_set,
                               PangoRectangle *ink_rect,
                               PangoRectangle *logical_rect)
@@ -328,6 +361,12 @@ gdk_pango_get_item_properties (PangoItem      *item,
 
   if (rise)
     *rise = 0;
+
+  if (embossed)
+    *embossed = FALSE;
+
+  if (stipple)
+    *stipple = NULL;
   
   while (tmp_list)
     {
@@ -342,7 +381,7 @@ gdk_pango_get_item_properties (PangoItem      *item,
          
        case PANGO_ATTR_FOREGROUND:
          if (fg_color)
-           *fg_color = *((PangoAttrColor *)attr);
+           *fg_color = ((PangoAttrColor *)attr)->color;
          if (fg_set)
            *fg_set = TRUE;
          
@@ -350,7 +389,7 @@ gdk_pango_get_item_properties (PangoItem      *item,
          
        case PANGO_ATTR_BACKGROUND:
          if (bg_color)
-           *bg_color = *((PangoAttrColor *)attr);
+           *bg_color = ((PangoAttrColor *)attr)->color;
          if (bg_set)
            *bg_set = TRUE;
          
@@ -371,9 +410,144 @@ gdk_pango_get_item_properties (PangoItem      *item,
           break;
           
        default:
+          /* stipple_type and embossed_type aren't necessarily
+           * initialized, but they are 0, which is an
+           * invalid type so won't occur. 
+           */
+          if (stipple && attr->klass->type == gdk_pango_attr_stipple_type)
+            {
+              *stipple = ((GdkPangoAttrStipple*)attr)->stipple;
+            }
+          else if (embossed && attr->klass->type == gdk_pango_attr_embossed_type)
+            {
+              *embossed = ((GdkPangoAttrEmbossed*)attr);
+            }
          break;
        }
       tmp_list = tmp_list->next;
     }
 }
 
+
+static PangoAttribute *
+gdk_pango_attr_stipple_copy (const PangoAttribute *attr)
+{
+  const GdkPangoAttrStipple *src = (const GdkPangoAttrStipple*) attr;
+
+  return gdk_pango_attr_stipple_new (src->stipple);
+}
+
+static void
+gdk_pango_attr_stipple_destroy (PangoAttribute *attr)
+{
+  GdkPangoAttrStipple *st = (GdkPangoAttrStipple*) attr;
+
+  if (st->stipple)
+    g_object_unref (G_OBJECT (st->stipple));
+  
+  g_free (attr);
+}
+
+static gboolean
+gdk_pango_attr_stipple_compare (const PangoAttribute *attr1,
+                                    const PangoAttribute *attr2)
+{
+  const GdkPangoAttrStipple *a = (const GdkPangoAttrStipple*) attr1;
+  const GdkPangoAttrStipple *b = (const GdkPangoAttrStipple*) attr2;
+
+  return a->stipple == b->stipple;
+}
+
+/**
+ * gdk_pango_attr_stipple_new:
+ * @stipple: a bitmap to be set as stipple
+ *
+ * Creates a new attribute containing a stipple bitmap to be used when
+ * rendering the text.
+ *
+ * Return value: new #PangoAttribute
+ **/
+
+PangoAttribute *
+gdk_pango_attr_stipple_new (GdkBitmap *stipple)
+{
+  GdkPangoAttrStipple *result;
+  
+  static PangoAttrClass klass = {
+    0,
+    gdk_pango_attr_stipple_copy,
+    gdk_pango_attr_stipple_destroy,
+    gdk_pango_attr_stipple_compare
+  };
+
+  if (!klass.type)
+    klass.type = gdk_pango_attr_stipple_type =
+      pango_attr_type_register ("GdkPangoAttrStipple");
+
+  result = g_new (GdkPangoAttrStipple, 1);
+  result->attr.klass = &klass;
+
+  if (stipple)
+    g_object_ref (stipple);
+  
+  result->stipple = stipple;
+
+  return (PangoAttribute *)result;
+}
+
+static PangoAttribute *
+gdk_pango_attr_embossed_copy (const PangoAttribute *attr)
+{
+  const GdkPangoAttrEmbossed *e = (const GdkPangoAttrEmbossed*) attr;
+
+  return gdk_pango_attr_embossed_new (e->embossed);
+}
+
+static void
+gdk_pango_attr_embossed_destroy (PangoAttribute *attr)
+{
+  g_free (attr);
+}
+
+static gboolean
+gdk_pango_attr_embossed_compare (const PangoAttribute *attr1,
+                                 const PangoAttribute *attr2)
+{
+  const GdkPangoAttrEmbossed *e1 = (const GdkPangoAttrEmbossed*) attr1;
+  const GdkPangoAttrEmbossed *e2 = (const GdkPangoAttrEmbossed*) attr2;
+
+  return e1->embossed == e2->embossed;
+}
+
+/**
+ * gdk_pango_attr_embossed_new:
+ * @embossed: a bitmap to be set as embossed
+ *
+ * Creates a new attribute containing a embossed bitmap to be used when
+ * rendering the text.
+ *
+ * Return value: new #PangoAttribute
+ **/
+
+PangoAttribute *
+gdk_pango_attr_embossed_new (gboolean embossed)
+{
+  GdkPangoAttrEmbossed *result;
+  
+  static PangoAttrClass klass = {
+    0,
+    gdk_pango_attr_embossed_copy,
+    gdk_pango_attr_embossed_destroy,
+    gdk_pango_attr_embossed_compare
+  };
+
+  if (!klass.type)
+    klass.type = gdk_pango_attr_embossed_type =
+      pango_attr_type_register ("GdkPangoAttrEmbossed");
+
+  result = g_new (GdkPangoAttrEmbossed, 1);
+  result->attr.klass = &klass;
+  result->embossed = embossed;
+  
+  return (PangoAttribute *)result;
+}
index 8fc91a71f511b35d1f27783201c93248a5d22b5f..f553fa01dc8f488e445618e147cd92e04e18295a 100644 (file)
@@ -38,6 +38,26 @@ PangoContext *gdk_pango_context_get          (void);
 void          gdk_pango_context_set_colormap (PangoContext *context,
                                              GdkColormap  *colormap);
 
+/* Attributes use to render insensitive text in GTK+. */
+
+typedef struct _GdkPangoAttrStipple GdkPangoAttrStipple;
+typedef struct _GdkPangoAttrEmbossed GdkPangoAttrEmbossed;
+
+struct _GdkPangoAttrStipple
+{
+  PangoAttribute attr;
+  GdkBitmap *stipple;
+};
+
+struct _GdkPangoAttrEmbossed
+{
+  PangoAttribute attr;
+  gboolean embossed;
+};
+
+PangoAttribute *gdk_pango_attr_stipple_new  (GdkBitmap *bitmap);
+PangoAttribute *gdk_pango_attr_embossed_new (gboolean embossed);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 0a703045fd08b4bd5d861d42eb59fec547a385ad..55d5e9d590cb3fbbc2ce126406038dda0b6b48dd 100644 (file)
@@ -1637,6 +1637,7 @@ gdk_window_get_image (GdkDrawable *drawable,
 
 static GSList *update_windows = NULL;
 static guint update_idle = 0;
+static gboolean debug_updates = FALSE;
 
 static void
 gdk_window_process_updates_internal (GdkWindow *window)
@@ -1659,6 +1660,13 @@ gdk_window_process_updates_internal (GdkWindow *window)
          GdkRectangle window_rect;
           gint width, height;
 
+          if (debug_updates)
+            {
+              /* Make sure we see the red invalid area before redrawing. */
+              gdk_flush ();
+              g_usleep (70000);
+            }
+          
           gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
           
          window_rect.x = 0;
@@ -1725,9 +1733,9 @@ gdk_window_process_updates (GdkWindow *window,
 
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
-
+  
   if (private->update_area)
-    {
+    {      
       gdk_window_process_updates_internal (window);
       update_windows = g_slist_remove (update_windows, window);
     }
@@ -1798,6 +1806,28 @@ gdk_window_invalidate_region (GdkWindow *window,
 
   if (!gdk_region_empty (visible_region))
     {
+      if (debug_updates)
+        {
+          /* Draw ugly color all over the newly-invalid region */
+          GdkRectangle ugly_rect;
+          GdkGC *ugly_gc;
+          GdkColor ugly_color = { 0, 60000, 10000, 10000 };
+          
+          ugly_gc = gdk_gc_new (window);
+
+          gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
+          
+         gdk_region_get_clipbox (visible_region, &ugly_rect);
+
+          gdk_draw_rectangle (window,
+                              ugly_gc,
+                              TRUE,
+                              ugly_rect.x, ugly_rect.y,
+                              ugly_rect.width, ugly_rect.height);
+          
+          g_object_unref (G_OBJECT (ugly_gc));
+        }
+      
       if (private->update_area)
        {
          gdk_region_union (private->update_area, visible_region);
@@ -1916,3 +1946,8 @@ gdk_window_thaw_updates (GdkWindow *window)
                                   gdk_window_update_idle, NULL, NULL);
 }
 
+void
+gdk_window_set_debug_updates (gboolean setting)
+{
+  debug_updates = setting;
+}
index 12ab145ed950d8d0f365813bcccfd3c59bfcfa7a..435e5868dc33f32682d633fdec06734f8436dbfa 100644 (file)
@@ -413,7 +413,8 @@ void       gdk_window_process_all_updates (void);
 void       gdk_window_process_updates     (GdkWindow    *window,
                                           gboolean      update_children);
 
-
+/* Enable/disable flicker, so you can tell if your code is inefficient. */
+void       gdk_window_set_debug_updates   (gboolean      setting);
 
 #ifdef __cplusplus
 }
index bdd2659b576565febedae1ad3dbb6d647ce5a1a3..0869168b66839e9eee681b93610e41c2bccb20a6 100644 (file)
@@ -170,6 +170,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
        gtktoolbar.h            \
        gtktooltips.h           \
        gtktree.h               \
+       gtktreednd.h            \
        gtktreeitem.h           \
        gtktreemodel.h          \
        gtktreemodelsimple.h    \
@@ -335,6 +336,7 @@ gtk_c_sources = @STRIP_BEGIN@   \
        gtktree.c               \
        gtktreeitem.c           \
        gtktreedatalist.c       \
+       gtktreednd.c            \
        gtktreemodel.c          \
        gtktreemodelsimple.c    \
        gtktreemodelsort.c      \
index f07d5ab9bf2ba04bbb62d84af6c250e46cfa7b91..a84b83e2db1cd4006a7ec685b699ec9679a6fee0 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
 #include <gtk/gtktoolbar.h>
 #include <gtk/gtktooltips.h>
 #include <gtk/gtktree.h>
+#include <gtk/gtktreednd.h>
 #include <gtk/gtktreeitem.h>
 #include <gtk/gtktreemodel.h>
 #include <gtk/gtktreemodelsimple.h>
index 5324cbe92c0ab9bd1f55195f29206a64d9e94fe6..d7724f49ab97f7eb4ec979cedf96b7b9ed3f4e5c 100644 (file)
@@ -72,6 +72,10 @@ gtk_cell_renderer_get_type (void)
 static void
 gtk_cell_renderer_init (GtkCellRenderer *cell)
 {
+  /* FIXME remove on port to GtkObject */
+  gtk_object_ref (GTK_OBJECT (cell));
+  gtk_object_sink (GTK_OBJECT (cell));
+  
   cell->xpad = 0;
   cell->ypad = 0;
   cell->xalign = 0.5;
@@ -211,6 +215,27 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
   GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, width, height);
 }
 
+/**
+ * gtk_cell_renderer_render:
+ * @cell: a #GtkCellRenderer
+ * @window: a #GdkDrawable to draw to
+ * @widget: the widget owning @window
+ * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
+ * @cell_area: area normally rendered by a cell renderer
+ * @expose_area: area that actually needs updating
+ * @flags: flags that affect rendering
+ *
+ * Invokes the virtual render function of the #GtkCellRenderer. The
+ * three passed-in rectangles are areas of @window. Most renderers
+ * will draw to @cell_area; the xalign, yalign, xpad, and ypad fields
+ * of the #GtkCellRenderer should be honored with respect to
+ * @cell_area. @background_area includes the blank space around the
+ * cell, and also the area containing the tree expander; so the
+ * @background_area rectangles for all cells tile to cover the entire
+ * @window. Cell renderers can use the @background_area to draw custom expanders, for
+ * example. @expose_area is a clip rectangle.
+ * 
+ **/
 void
 gtk_cell_renderer_render (GtkCellRenderer     *cell,
                          GdkWindow           *window,
index d6dfa75471866068d58e0ac003fb644e0756f1ee..4ff6c7e520be0dcd94b8bee3175fdb9afe444464 100644 (file)
@@ -226,7 +226,9 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
   GtkCellRendererToggle *celltoggle = (GtkCellRendererToggle *) cell;
   gint width, height;
   gint real_xoffset, real_yoffset;
-
+  GtkShadowType shadow;
+  GtkStateType state;
+  
   width = MIN (TOGGLE_WIDTH, cell_area->width - cell->xpad * 2);
   height = MIN (TOGGLE_WIDTH, cell_area->height - cell->ypad * 2);
 
@@ -238,57 +240,33 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
   real_yoffset = cell->yalign * (cell_area->height - height - (2 * cell->ypad));
   real_yoffset = MAX (real_yoffset, 0) + cell->ypad;
 
-  gdk_gc_set_clip_rectangle (widget->style->black_gc, cell_area);
+  shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
 
-  if (!celltoggle->radio)
+  if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
+    state = GTK_STATE_SELECTED;
+  else
+    state = GTK_STATE_NORMAL;
+  
+  if (celltoggle->radio)
     {
-      gdk_draw_rectangle (window,
-                         widget->style->black_gc,
-                         FALSE,
-                         cell_area->x + real_xoffset,
-                         cell_area->y + real_yoffset,
-                         width, height);
-      if (celltoggle->active)
-       {
-         gdk_draw_line (window,
-                        widget->style->black_gc,
-                        cell_area->x + real_xoffset,
-                        cell_area->y + real_yoffset,
-                        cell_area->x + real_xoffset + width,
-                        cell_area->y + real_yoffset + height);
-         gdk_draw_line (window,
-                        widget->style->black_gc,
-                        cell_area->x + real_xoffset + width,
-                        cell_area->y + real_yoffset,
-                        cell_area->x + real_xoffset,
-                        cell_area->y + real_yoffset + height);
-       }
+      gtk_paint_option (widget->style,
+                        window,
+                        state, shadow,
+                        cell_area, widget, "cellradio",
+                        cell_area->x + real_xoffset,
+                        cell_area->y + real_yoffset,
+                        width, height);
     }
   else
     {
-      gdk_draw_arc (window,
-                   widget->style->black_gc,
-                   FALSE,
-                   cell_area->x + real_xoffset,
-                   cell_area->y + real_yoffset,
-                   width,
-                   height,
-                   0, 360*64);
-      if (celltoggle->active)
-       {
-         gdk_draw_arc (window,
-                       widget->style->black_gc,
-                       TRUE,
-                       cell_area->x + real_xoffset + 2,
-                       cell_area->y + real_yoffset + 2,
-                       width - 4,
-                       height - 4,
-                       0, 360*64);
-       }
+      gtk_paint_check (widget->style,
+                       window,
+                       state, shadow,
+                       cell_area, widget, "cellcheck",
+                       cell_area->x + real_xoffset,
+                       cell_area->y + real_yoffset,
+                       width, height);
     }
-
-
-  gdk_gc_set_clip_rectangle (widget->style->black_gc, NULL);
 }
 
 static gint
index 78e74d16b5476980cc7a80ee746ea7adca3fa34e..1a03e8af52fe0d635a84f2840b33ec57c28d3e55 100644 (file)
@@ -38,7 +38,8 @@ typedef enum {
   GTK_DEBUG_DND        = 1 << 3,
   GTK_DEBUG_PLUGSOCKET = 1 << 4,
   GTK_DEBUG_TEXT       = 1 << 5,
-  GTK_DEBUG_TREE       = 1 << 6
+  GTK_DEBUG_TREE       = 1 << 6,
+  GTK_DEBUG_UPDATES    = 1 << 7
 } GtkDebugFlag;
 
 #ifdef G_ENABLE_DEBUG
index ecfcb86a8313f2d25282b42b35e0d77d142f6b79..7f471229edd1514372a1f73b84112ea6b799c8b7 100644 (file)
@@ -675,6 +675,8 @@ gtk_entry_init (GtkEntry *entry)
   entry->visible = TRUE;
   entry->invisible_char = '*';
   entry->dnd_position = -1;
+
+  entry->has_frame = TRUE;
   
   gtk_drag_dest_set (GTK_WIDGET (entry),
                      GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_HIGHLIGHT,
@@ -760,8 +762,17 @@ gtk_entry_realize (GtkWidget *widget)
   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
   gdk_window_set_user_data (widget->window, entry);
 
-  attributes.x = widget->style->xthickness;
-  attributes.y = widget->style->ythickness;
+  if (entry->has_frame)
+    {
+      attributes.x = widget->style->xthickness;
+      attributes.y = widget->style->ythickness;
+    }
+  else
+    {
+      attributes.x = 0;
+      attributes.y = 0;
+    }
+  
   attributes.width = widget->allocation.width - attributes.x * 2;
   attributes.height = requisition.height - attributes.y * 2;
   attributes.cursor = gdk_cursor_new (GDK_XTERM);
@@ -816,6 +827,7 @@ gtk_entry_size_request (GtkWidget      *widget,
   PangoFontMetrics metrics;
   PangoFont *font;
   gchar *lang;
+  gint xborder, yborder;
   
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_ENTRY (widget));
@@ -835,10 +847,25 @@ gtk_entry_size_request (GtkWidget      *widget,
 
   entry->ascent = metrics.ascent;
   entry->descent = metrics.descent;
+
+  xborder = INNER_BORDER;
+  yborder = INNER_BORDER;
   
-  requisition->width = MIN_ENTRY_WIDTH + (widget->style->xthickness + INNER_BORDER) * 2;
+  if (entry->has_frame)
+    {
+      xborder += widget->style->xthickness;
+      yborder += widget->style->ythickness;
+    }
+  else
+    {
+      /* add 1 pixel to draw focus rect in widget->window */
+      xborder += 1;
+      yborder += 1;
+    }
+      
+  requisition->width = MIN_ENTRY_WIDTH + xborder * 2;
   requisition->height = ((metrics.ascent + metrics.descent) / PANGO_SCALE + 
-                        (widget->style->ythickness + INNER_BORDER) * 2);
+                         yborder * 2);
 }
 
 static void
@@ -847,7 +874,8 @@ gtk_entry_size_allocate (GtkWidget     *widget,
 {
   GtkEntry *entry;
   GtkEditable *editable;
-
+  gint xborder, yborder;
+  
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_ENTRY (widget));
   g_return_if_fail (allocation != NULL);
@@ -856,6 +884,18 @@ gtk_entry_size_allocate (GtkWidget     *widget,
   entry = GTK_ENTRY (widget);
   editable = GTK_EDITABLE (widget);
 
+  if (entry->has_frame)
+    {
+      xborder = widget->style->xthickness;
+      yborder = widget->style->ythickness;
+    }
+  else
+    {
+      /* 1 pixel for focus rect */
+      xborder = 1;
+      yborder = 1;
+    }
+  
   if (GTK_WIDGET_REALIZED (widget))
     {
       /* We call gtk_widget_get_child_requisition, since we want (for
@@ -870,10 +910,10 @@ gtk_entry_size_allocate (GtkWidget     *widget,
                              allocation->y + (allocation->height - requisition.height) / 2,
                              allocation->width, requisition.height);
       gdk_window_move_resize (entry->text_area,
-                             widget->style->xthickness,
-                             widget->style->ythickness,
-                             allocation->width - widget->style->xthickness * 2,
-                             requisition.height - widget->style->ythickness * 2);
+                              xborder,
+                              yborder,
+                             allocation->width - xborder * 2,
+                             requisition.height - yborder * 2);
 
       gtk_entry_recompute (entry);
     }
@@ -883,37 +923,45 @@ static void
 gtk_entry_draw_focus (GtkWidget *widget)
 {
   gint width, height;
-  gint x, y;
-
+  GtkEntry *entry;
+  
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_ENTRY (widget));
 
+  entry = GTK_ENTRY (widget);
+  
   if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      x = 0;
-      y = 0;
-      gdk_window_get_size (widget->window, &width, &height);
+    {      
+      if (entry->has_frame)
+        {
+          gint x = 0, y = 0;
 
-      if (GTK_WIDGET_HAS_FOCUS (widget))
-       {
-         x += 1;
-         y += 1;
-         width -= 2;
-         height -= 2;
-       }
+          gdk_window_get_size (widget->window, &width, &height);
+
+          if (GTK_WIDGET_HAS_FOCUS (widget))
+            {
+              x += 1;
+              y += 1;
+              width -= 2;
+              height -= 2;
+            }
 
-      gtk_paint_shadow (widget->style, widget->window,
-                       GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                       NULL, widget, "entry",
-                       x, y, width, height);
 
+          gtk_paint_shadow (widget->style, widget->window,
+                            GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                            NULL, widget, "entry",
+                            x, y, width, height);
+        }
+      else
+        gdk_window_clear (widget->window);
+        
       if (GTK_WIDGET_HAS_FOCUS (widget))
-       {
-          gdk_window_get_size (widget->window, &width, &height);
-          gtk_paint_focus (widget->style, widget->window, 
-                           NULL, widget, "entry",
-                           0, 0, width - 1, height - 1);
-       }
+        {
+          gdk_window_get_size (widget->window, &width, &height);
+          gtk_paint_focus (widget->style, widget->window, 
+                           NULL, widget, "entry",
+                           0, 0, width - 1, height - 1);
+        }
     }
 }
 
@@ -2582,6 +2630,43 @@ gtk_entry_set_max_length (GtkEntry     *entry,
   entry->text_max_length = max;
 }
 
+/**
+ * gtk_entry_set_has_frame:
+ * @entry: a #GtkEntry
+ * @setting: new value
+ * 
+ * Sets whether the entry has a beveled frame around it.
+ **/
+void
+gtk_entry_set_has_frame (GtkEntry *entry,
+                         gboolean  setting)
+{
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  setting = (setting != FALSE);
+  
+  if (entry->has_frame != setting)
+    gtk_widget_queue_resize (GTK_WIDGET (entry));
+  
+  entry->has_frame = setting;
+}
+
+/**
+ * gtk_entry_get_has_frame:
+ * @entry: a #GtkEntry
+ * 
+ * 
+ * 
+ * Return value: whether the entry has a beveled frame
+ **/
+gboolean
+gtk_entry_get_has_frame (GtkEntry *entry)
+{
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
+
+  return entry->has_frame;
+}
+
 /* Quick hack of a popup menu
  */
 static void
index 553837603de9c1e0571755e6dfdcb0366673d8d6..c8dbcdd8359732d9eddcc7628cf690ba7d5a9ce2 100644 (file)
@@ -76,6 +76,8 @@ struct _GtkEntry
 
   guint        need_im_reset : 1;
 
+  guint        has_frame : 1;
+  
   guint   button;
   guint   timer;
   guint   recompute_idle;
@@ -138,6 +140,9 @@ void       gtk_entry_set_invisible_char         (GtkEntry      *entry,
                                                  gunichar       ch);
 void       gtk_entry_set_editable              (GtkEntry      *entry,
                                                 gboolean       editable);
+void       gtk_entry_set_has_frame              (GtkEntry      *entry,
+                                                 gboolean       setting);
+gboolean   gtk_entry_get_has_frame              (GtkEntry      *entry);
 /* text is truncated if needed */
 void       gtk_entry_set_max_length            (GtkEntry      *entry,
                                                 guint16        max);
index b045f2e60d83f2a6ccf7f19b1c8c711ee029df64..ef3300430fd2bcb0dfcdce98125936f09065f30c 100644 (file)
@@ -22,6 +22,7 @@
 #include "gtkliststore.h"
 #include "gtktreedatalist.h"
 #include "gtksignal.h"
+#include "gtktreednd.h"
 #include <gobject/gvaluecollector.h>
 
 #define G_SLIST(x) ((GSList *) x)
@@ -39,6 +40,8 @@ static guint list_store_signals[LAST_SIGNAL] = { 0 };
 static void         gtk_list_store_init            (GtkListStore      *list_store);
 static void         gtk_list_store_class_init      (GtkListStoreClass *class);
 static void         gtk_list_store_tree_model_init (GtkTreeModelIface *iface);
+static void         gtk_list_store_drag_source_init(GtkTreeDragSourceIface *iface);
+static void         gtk_list_store_drag_dest_init  (GtkTreeDragDestIface   *iface);
 static guint        gtk_list_store_get_flags       (GtkTreeModel      *tree_model);
 static gint         gtk_list_store_get_n_columns   (GtkTreeModel      *tree_model);
 static GType        gtk_list_store_get_column_type (GtkTreeModel      *tree_model,
@@ -69,6 +72,15 @@ static gboolean     gtk_list_store_iter_parent     (GtkTreeModel      *tree_mode
                                                    GtkTreeIter       *iter,
                                                    GtkTreeIter       *child);
 
+static gboolean gtk_list_store_drag_data_delete   (GtkTreeDragSource *drag_source,
+                                                   GtkTreePath       *path);
+static gboolean gtk_list_store_drag_data_get      (GtkTreeDragSource *drag_source,
+                                                   GtkTreePath       *path,
+                                                   GtkSelectionData  *selection_data);
+static gboolean gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
+                                                   GtkTreePath       *dest,
+                                                   GtkSelectionData  *selection_data);
+
 
 GtkType
 gtk_list_store_get_type (void)
@@ -97,10 +109,30 @@ gtk_list_store_get_type (void)
        NULL
       };
 
+      static const GInterfaceInfo drag_source_info =
+      {
+       (GInterfaceInitFunc) gtk_list_store_drag_source_init,
+       NULL,
+       NULL
+      };
+
+      static const GInterfaceInfo drag_dest_info =
+      {
+       (GInterfaceInitFunc) gtk_list_store_drag_dest_init,
+       NULL,
+       NULL
+      };
+      
       list_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkListStore", &list_store_info, 0);
       g_type_add_interface_static (list_store_type,
                                   GTK_TYPE_TREE_MODEL,
                                   &tree_model_info);
+      g_type_add_interface_static (list_store_type,
+                                  GTK_TYPE_TREE_DRAG_SOURCE,
+                                  &drag_source_info);
+      g_type_add_interface_static (list_store_type,
+                                  GTK_TYPE_TREE_DRAG_DEST,
+                                  &drag_dest_info);
     }
 
   return list_store_type;
@@ -167,6 +199,19 @@ gtk_list_store_tree_model_init (GtkTreeModelIface *iface)
   iface->iter_parent = gtk_list_store_iter_parent;
 }
 
+static void
+gtk_list_store_drag_source_init (GtkTreeDragSourceIface *iface)
+{
+  iface->drag_data_delete = gtk_list_store_drag_data_delete;
+  iface->drag_data_get = gtk_list_store_drag_data_get;
+}
+
+static void
+gtk_list_store_drag_dest_init   (GtkTreeDragDestIface   *iface)
+{
+  iface->drag_data_received = gtk_list_store_drag_data_received;
+}
+
 static void
 gtk_list_store_init (GtkListStore *list_store)
 {
@@ -646,21 +691,17 @@ remove_link_saving_prev (GSList  *list,
   return list;
 }
 
-void
-gtk_list_store_remove (GtkListStore *list_store,
-                      GtkTreeIter  *iter)
+static void
+gtk_list_store_remove_silently (GtkListStore *list_store,
+                                GtkTreeIter  *iter,
+                                GtkTreePath  *path)
 {
-  GtkTreePath *path;
-
-  g_return_if_fail (list_store != NULL);
-  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
-  g_return_if_fail (iter->user_data != NULL);
-  
   if (G_SLIST (iter->user_data)->data)
-    _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data,
-                             list_store->column_headers);
-
-  path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
+    {
+      _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data,
+                                list_store->column_headers);
+      G_SLIST (iter->user_data)->data = NULL;
+    }
 
   {
     GSList *prev = NULL;
@@ -674,6 +715,23 @@ gtk_list_store_remove (GtkListStore *list_store,
   }
   
   list_store->stamp ++;
+}
+
+void
+gtk_list_store_remove (GtkListStore *list_store,
+                      GtkTreeIter  *iter)
+{
+  GtkTreePath *path;
+
+  g_return_if_fail (list_store != NULL);
+  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
+  g_return_if_fail (iter->user_data != NULL);
+  
+
+  path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
+
+  gtk_list_store_remove_silently (list_store, iter, path);
+
   gtk_signal_emit_by_name (GTK_OBJECT (list_store),
                           "deleted",
                           path);
@@ -901,3 +959,164 @@ gtk_list_store_append (GtkListStore *list_store,
                           path, iter);
   gtk_tree_path_free (path);
 }
+
+static gboolean
+gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source,
+                                 GtkTreePath       *path)
+{
+  GtkTreeIter iter;
+  g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE);
+  
+  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
+                               &iter,
+                               path))
+    {
+      gtk_list_store_remove (GTK_LIST_STORE (drag_source),
+                             &iter);
+      return TRUE;
+    }
+  else
+    {
+      return FALSE;
+    }
+}
+
+static gboolean
+gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source,
+                              GtkTreePath       *path,
+                              GtkSelectionData  *selection_data)
+{
+  g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE);
+
+  /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
+   * target, because the default handler does it for us, but
+   * we do anyway for the convenience of someone maybe overriding the
+   * default handler.
+   */
+
+  if (gtk_selection_data_set_tree_row (selection_data,
+                                       GTK_TREE_MODEL (drag_source),
+                                       path))
+    {
+      return TRUE;
+    }
+  else
+    {
+      /* FIXME handle text targets at least. */
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
+                                   GtkTreePath       *dest,
+                                   GtkSelectionData  *selection_data)
+{
+  GtkTreeModel *tree_model;
+  GtkListStore *list_store;
+  GtkTreeModel *src_model = NULL;
+  GtkTreePath *src_path = NULL;
+  gboolean retval = FALSE;
+  
+  g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE);
+
+  tree_model = GTK_TREE_MODEL (drag_dest);
+  list_store = GTK_LIST_STORE (drag_dest);
+  
+  if (gtk_selection_data_get_tree_row (selection_data,
+                                       &src_model,
+                                       &src_path) &&
+      src_model == tree_model)
+    {
+      /* Copy the given row to a new position */
+      GtkTreeIter src_iter;
+      GtkTreeIter dest_iter;
+      GtkTreePath *prev;
+      
+      if (!gtk_tree_model_get_iter (src_model,
+                                    &src_iter,
+                                    src_path))
+        goto out;
+
+      /* Get the path to insert _after_ (dest is the path to insert _before_) */
+      prev = gtk_tree_path_copy (dest);
+
+      if (!gtk_tree_path_prev (prev))
+        {
+          /* dest was the first spot in the list; which means we are supposed
+           * to prepend.
+           */
+          gtk_list_store_prepend (GTK_LIST_STORE (tree_model),
+                                  &dest_iter);
+          
+          retval = TRUE;
+        }
+      else
+        {
+          if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
+                                       &dest_iter,
+                                       prev))
+            {
+              GtkTreeIter tmp_iter = dest_iter;
+              gtk_list_store_insert_after (GTK_LIST_STORE (tree_model),
+                                           &dest_iter,
+                                           &tmp_iter);
+              retval = TRUE;
+            }
+        }
+
+      gtk_tree_path_free (prev);
+      
+      /* If we succeeded in creating dest_iter, copy data from src
+       */
+      if (retval)
+        {
+          GtkTreeDataList *dl = G_SLIST (src_iter.user_data)->data;
+          GtkTreeDataList *copy_head = NULL;
+          GtkTreeDataList *copy_prev = NULL;
+          GtkTreeDataList *copy_iter = NULL;
+          gint col;
+
+          col = 0;
+          while (dl)
+            {
+              copy_iter = _gtk_tree_data_list_node_copy (dl,
+                                                         list_store->column_headers[col]);
+
+              g_print ("copied col %d type %s\n", col,
+                       g_type_name (list_store->column_headers[col]));
+              
+              if (copy_head == NULL)
+                copy_head = copy_iter;
+
+              if (copy_prev)
+                copy_prev->next = copy_iter;
+
+              copy_prev = copy_iter;
+
+              dl = dl->next;
+              ++col;
+            }
+          
+          G_SLIST (dest_iter.user_data)->data = copy_head;
+          
+          gtk_signal_emit_by_name (GTK_OBJECT (tree_model),
+                                   "changed",
+                                   NULL, &dest_iter);
+        }
+    }
+  else
+    {
+      /* FIXME maybe add some data targets eventually, or handle text
+       * targets in the simple case.
+       */
+    }
+
+ out:
+  
+  if (src_path)
+    gtk_tree_path_free (src_path);
+  
+  return retval;  
+}
index d3ba241d4c46439390dc61eaa1ec6cf948f44153..ebb324efb01f6500e8c0a75174725b0585cc087f 100644 (file)
@@ -148,7 +148,8 @@ static const GDebugKey gtk_debug_keys[] = {
   {"dnd", GTK_DEBUG_DND},
   {"plugsocket", GTK_DEBUG_PLUGSOCKET},
   {"text", GTK_DEBUG_TEXT},
-  {"tree", GTK_DEBUG_TREE}
+  {"tree", GTK_DEBUG_TREE},
+  {"updates", GTK_DEBUG_UPDATES}
 };
 
 static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
@@ -346,6 +347,9 @@ gtk_init_check (int  *argc,
            }
        }
     }
+
+  if (gtk_debug_flags & GTK_DEBUG_UPDATES)
+    gdk_window_set_debug_updates (TRUE);
   
   /* load gtk modules */
   gtk_modules = g_slist_reverse (gtk_modules);
index 8259b91fde683afb043b9df67da93f35d2e4f8a2..e8bbf2d9d07a665b3596b521fd2049bb24014674 100644 (file)
@@ -641,7 +641,12 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree,
                              GtkRBNode *node)
 {
   GtkRBNode *last;
-  gint retval = node->left->offset;
+  gint retval;
+
+  g_assert (node);
+  g_assert (node->left);
+  
+  retval = node->left->offset;
 
   while (tree && node && node != tree->nil)
     {
@@ -904,6 +909,22 @@ _gtk_rbtree_prev_full (GtkRBTree  *tree,
     }
 }
 
+gint
+_gtk_rbtree_get_depth (GtkRBTree *tree)
+{
+  GtkRBTree *tmp_tree;
+  gint depth = 0;
+
+  tmp_tree = tree->parent_tree;
+  while (tmp_tree)
+    {
+      ++depth;
+      tmp_tree = tmp_tree->parent_tree;
+    }
+
+  return depth;
+}
+
 static void
 _gtk_rbtree_traverse_pre_order (GtkRBTree             *tree,
                                GtkRBNode             *node,
index 32aed44178fc29dfeee94865c06ef6dd8e7c9ad4..40c779320c18765b871dcd2a2bb0576b3ec95d17 100644 (file)
@@ -123,6 +123,7 @@ void       _gtk_rbtree_prev_full        (GtkRBTree              *tree,
                                         GtkRBTree             **new_tree,
                                         GtkRBNode             **new_node);
 
+gint       _gtk_rbtree_get_depth        (GtkRBTree              *tree);
 
 /* This func just checks the integrity of the tree */
 /* It will go away later. */
index d86986e525fa365b118ab9c7e291b8eb4b4b7db5..054bf21dfce581b36724599f67eb7239a7c66673 100644 (file)
@@ -2476,8 +2476,34 @@ gtk_default_draw_check (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
-                 x, y, width, height);
+  if (detail && strcmp (detail, "cellcheck") == 0)
+    {
+      gdk_draw_rectangle (window,
+                         widget->style->fg_gc[state_type],
+                         FALSE,
+                          x, y,
+                         width, height);
+
+      if (shadow_type == GTK_SHADOW_IN)
+       {
+         gdk_draw_line (window,
+                        widget->style->fg_gc[state_type],
+                         x, y,
+                         x + width,
+                         y + height);
+         gdk_draw_line (window,
+                        widget->style->fg_gc[state_type],
+                         x + width,
+                         y,
+                         x,
+                         y + height);
+       }
+    }
+  else
+    {
+      gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
+                     x, y, width, height);
+    }
 }
 
 static void 
@@ -2493,8 +2519,33 @@ gtk_default_draw_option (GtkStyle      *style,
                         gint           width,
                         gint           height)
 {
-  gtk_paint_diamond (style, window, state_type, shadow_type, area, widget, 
-                     detail, x, y, width, height);
+  if (detail && strcmp (detail, "cellradio") == 0)
+    {
+      gdk_draw_arc (window,
+                   widget->style->fg_gc[state_type],
+                   FALSE,
+                    x, y,
+                   width,
+                   height,
+                   0, 360*64);
+
+      if (shadow_type == GTK_SHADOW_IN)
+       {
+         gdk_draw_arc (window,
+                       widget->style->fg_gc[state_type],
+                       TRUE,
+                        x + 2,
+                        y + 2,
+                       width - 4,
+                       height - 4,
+                       0, 360*64);
+       }
+    }
+  else
+    {
+      gtk_paint_diamond (style, window, state_type, shadow_type, area, widget, 
+                         detail, x, y, width, height);
+    }
 }
 
 static void
@@ -3420,6 +3471,155 @@ gtk_default_draw_expander (GtkStyle        *style,
 #undef PM_SIZE
 }
 
+typedef struct _ByteRange ByteRange;
+
+struct _ByteRange
+{
+  guint start;
+  guint end;
+};
+
+static ByteRange*
+range_new (guint start,
+           guint end)
+{
+  ByteRange *br = g_new (ByteRange, 1);
+
+  br->start = start;
+  br->end = end;
+  
+  return br;
+}
+
+static PangoLayout*
+get_insensitive_layout (PangoLayout *layout)
+{
+  GSList *embossed_ranges = NULL;
+  GSList *stippled_ranges = NULL;
+  PangoLayoutIter *iter;
+  GSList *tmp_list = NULL;
+  PangoLayout *new_layout;
+  PangoAttrList *attrs;
+  GdkBitmap *stipple = NULL;
+  
+  iter = pango_layout_get_iter (layout);
+  
+  do
+    {
+      PangoLayoutRun *run;
+      PangoAttribute *attr;
+      gboolean need_stipple = FALSE;
+      ByteRange *br;
+      
+      run = pango_layout_iter_get_run (iter);
+
+      if (run)
+        {
+          tmp_list = run->item->extra_attrs;
+
+          while (tmp_list != NULL)
+            {
+              attr = tmp_list->data;
+              switch (attr->klass->type)
+                {
+                case PANGO_ATTR_FOREGROUND:
+                case PANGO_ATTR_BACKGROUND:
+                  need_stipple = TRUE;
+                  break;
+              
+                default:
+                  break;
+                }
+
+              if (need_stipple)
+                break;
+          
+              tmp_list = g_slist_next (tmp_list);
+            }
+
+          br = range_new (run->item->offset, run->item->offset + run->item->length);
+      
+          if (need_stipple)
+            stippled_ranges = g_slist_prepend (stippled_ranges, br);
+          else
+            embossed_ranges = g_slist_prepend (embossed_ranges, br);
+        }
+    }
+  while (pango_layout_iter_next_run (iter));
+
+  pango_layout_iter_free (iter);
+
+  new_layout = pango_layout_copy (layout);
+
+  attrs = pango_layout_get_attributes (new_layout);
+
+  if (attrs == NULL)
+    {
+      /* Create attr list if there wasn't one */
+      attrs = pango_attr_list_new ();
+      pango_layout_set_attributes (new_layout, attrs);
+      pango_attr_list_unref (attrs);
+    }
+  
+  tmp_list = embossed_ranges;
+  while (tmp_list != NULL)
+    {
+      PangoAttribute *attr;
+      ByteRange *br = tmp_list->data;
+
+      attr = gdk_pango_attr_embossed_new (TRUE);
+
+      attr->start_index = br->start;
+      attr->end_index = br->end;
+      
+      pango_attr_list_change (attrs, attr);
+
+      g_free (br);
+      
+      tmp_list = g_slist_next (tmp_list);
+    }
+
+  g_slist_free (embossed_ranges);
+  
+  tmp_list = stippled_ranges;
+  while (tmp_list != NULL)
+    {
+      PangoAttribute *attr;
+      ByteRange *br = tmp_list->data;
+
+      if (stipple == NULL)
+        {
+#define gray50_width 2
+#define gray50_height 2
+          static char gray50_bits[] = {
+            0x02, 0x01
+          };
+
+          stipple = gdk_bitmap_create_from_data (NULL,
+                                                 gray50_bits, gray50_width,
+                                                 gray50_height);
+        }
+      
+      attr = gdk_pango_attr_stipple_new (stipple);
+
+      attr->start_index = br->start;
+      attr->end_index = br->end;
+      
+      pango_attr_list_change (attrs, attr);
+
+      g_free (br);
+      
+      tmp_list = g_slist_next (tmp_list);
+    }
+
+  g_slist_free (stippled_ranges);
+  
+  if (stipple)
+    g_object_unref (G_OBJECT (stipple));
+
+  return new_layout;
+}
+
 static void
 gtk_default_draw_layout (GtkStyle        *style,
                          GdkWindow       *window,
@@ -3435,24 +3635,25 @@ gtk_default_draw_layout (GtkStyle        *style,
   g_return_if_fail (window != NULL);
   
   if (area)
-    {
-      gdk_gc_set_clip_rectangle (style->white_gc, area);
-      gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
-    }
+    gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
 
-  /* FIXME this is frickin' ugly with any kind of attributes set on the
-   * text being rendered
-   */
   if (state_type == GTK_STATE_INSENSITIVE)
-    gdk_draw_layout (window, style->white_gc, x + 1, y + 1, layout);
+    {
+      PangoLayout *ins;
 
-  gdk_draw_layout (window, style->fg_gc[state_type], x, y, layout);
+      ins = get_insensitive_layout (layout);
+      
+      gdk_draw_layout (window, style->fg_gc[state_type], x, y, ins);
 
-  if (area)
+      g_object_unref (G_OBJECT (ins));
+    }
+  else
     {
-      gdk_gc_set_clip_rectangle (style->white_gc, NULL);
-      gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
+      gdk_draw_layout (window, style->fg_gc[state_type], x, y, layout);
     }
+
+  if (area)
+    gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
 }
 
 static void
index ff9bdca23dc9906bd98b46e7a9977c35d66566dc..f220646b669db80a21c90f6fb78d0dc139c1c482 100644 (file)
@@ -1499,9 +1499,9 @@ static void
 convert_color (GdkColor       *result,
               PangoAttrColor *attr)
 {
-  result->red = attr->red;
-  result->blue = attr->blue;
-  result->green = attr->green;
+  result->red = attr->color.red;
+  result->blue = attr->color.blue;
+  result->green = attr->color.green;
 }
 
 /* This function is used to convert the preedit string attributes, which are
index e18340d65f493f91294757da811ba6818712403e..cc20068967acd8420b5f040f8da3b0f0ae46dba1 100644 (file)
@@ -4373,7 +4373,7 @@ gtk_text_view_drag_motion (GtkWidget        *widget,
     }                                 
   else if (gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
                                             &start, &end) &&
-      gtk_text_iter_in_range (&newplace, &start, &end))
+           gtk_text_iter_in_range (&newplace, &start, &end))
     {
       /* We're inside the selection. */
     }
index 6fdf9d2e9e9b19ba944a9f0b83fdbce7629a0edb..b55b730af50092c9c5a3f53c502eca9d4ed7b3dd 100644 (file)
@@ -234,4 +234,48 @@ _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
     }
 }
 
+GtkTreeDataList*
+_gtk_tree_data_list_node_copy (GtkTreeDataList *list,
+                               GType            type)
+{
+  GtkTreeDataList *new_list;
+  
+  new_list = _gtk_tree_data_list_alloc ();
+
+  switch (type)
+    {
+    case G_TYPE_UINT:
+    case G_TYPE_INT:
+    case G_TYPE_UCHAR:      
+    case G_TYPE_CHAR:
+    case G_TYPE_BOOLEAN:
+    case G_TYPE_POINTER:
+    case G_TYPE_FLOAT:
+      new_list->data = list->data;
+      break;
 
+    case G_TYPE_STRING:
+      new_list->data.v_pointer = g_strdup (list->data.v_pointer);
+      break;
+      
+    default:
+      if (g_type_is_a (type, G_TYPE_OBJECT))
+        {
+          new_list->data.v_pointer = list->data.v_pointer;
+          if (new_list->data.v_pointer)
+            g_object_ref (G_OBJECT (new_list->data.v_pointer));
+        }
+      else if (g_type_is_a (type, G_TYPE_BOXED))
+        {
+          if (list->data.v_pointer)
+            new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer);
+          else
+            new_list->data.v_pointer = NULL;
+        }
+      else
+        g_warning ("Unsupported node type (%s) copied.", g_type_name (type));
+      break;
+    }
+  
+  return new_list;
+}
index 1149fdad019ee0ed89fa0dd1654a09c6fd8d7ce0..66fe37592026f73d1998865bbdef7c1901c834b3 100644 (file)
@@ -50,6 +50,8 @@ void             _gtk_tree_data_list_node_to_value  (GtkTreeDataList *list,
 void             _gtk_tree_data_list_value_to_node  (GtkTreeDataList *list,
                                                     GValue          *value);
 
+GtkTreeDataList *_gtk_tree_data_list_node_copy      (GtkTreeDataList *list,
+                                                     GType            type);
 
 
 #endif /* __GTK_TREE_DATA_LIST_H__ */
diff --git a/gtk/gtktreednd.c b/gtk/gtktreednd.c
new file mode 100644 (file)
index 0000000..f798022
--- /dev/null
@@ -0,0 +1,265 @@
+/* gtktreednd.c
+ * Copyright (C) 2001  Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include "gtktreednd.h"
+
+GType
+gtk_tree_drag_source_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (!our_type)
+    {
+      static const GTypeInfo our_info =
+      {
+        sizeof (GtkTreeDragSourceIface), /* class_size */
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       NULL,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       0,
+       0,              /* n_preallocs */
+       NULL
+      };
+
+      our_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeDragSource", &our_info, 0);
+    }
+  
+  return our_type;
+}
+
+
+GType
+gtk_tree_drag_dest_get_type (void)
+{
+  static GType our_type = 0;
+
+  if (!our_type)
+    {
+      static const GTypeInfo our_info =
+      {
+        sizeof (GtkTreeDragDestIface), /* class_size */
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       NULL,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       0,
+       0,              /* n_preallocs */
+       NULL
+      };
+
+      our_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeDragDest", &our_info, 0);
+    }
+  
+  return our_type;
+}
+
+
+/**
+ * gtk_tree_drag_source_drag_data_delete:
+ * @drag_source: a #GtkTreeDragSource
+ * @path: row that was being dragged
+ * 
+ * Asks the #GtkTreeDragSource to delete the row at @path, because
+ * it was moved somewhere else via drag-and-drop. Returns %FALSE
+ * if the deletion fails because @path no longer exists, or for
+ * some model-specific reason. Should robustly handle a @path no
+ * longer found in the model!
+ * 
+ * Return value: %TRUE if the row was successfully deleted
+ **/
+gboolean
+gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source,
+                                       GtkTreePath       *path)
+{
+  GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source);
+
+  g_return_val_if_fail (iface->drag_data_delete != NULL, FALSE);
+  g_return_val_if_fail (path != NULL, FALSE);
+
+  return (* iface->drag_data_delete) (drag_source, path);
+}
+
+/**
+ * gtk_tree_drag_source_drag_data_get:
+ * @drag_source: a #GtkTreeDragSource
+ * @path: row that was dragged
+ * @selection_data: a #GtkSelectionData to fill with data from the dragged row
+ * 
+ * Asks the #GtkTreeDragSource to fill in @selection_data with a
+ * representation of the row at @path. @selection_data->target gives
+ * the required type of the data.  Should robustly handle a @path no
+ * longer found in the model!
+ * 
+ * Return value: %TRUE if data of the required type was provided 
+ **/
+gboolean
+gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
+                                       GtkTreePath       *path,
+                                       GtkSelectionData  *selection_data)
+{
+  GtkTreeDragSourceIface *iface = GTK_TREE_DRAG_SOURCE_GET_IFACE (drag_source);
+
+  g_return_val_if_fail (iface->drag_data_get != NULL, FALSE);
+  g_return_val_if_fail (path != NULL, FALSE);
+  g_return_val_if_fail (selection_data != NULL, FALSE);
+
+  return (* iface->drag_data_get) (drag_source, path, selection_data);
+}
+
+/**
+ * gtk_tree_drag_dest_drag_data_received:
+ * @drag_dest: a #GtkTreeDragDest
+ * @dest: row to drop in front of
+ * @selection_data: data to drop
+ * 
+ * Asks the #GtkTreeDragDest to insert a row before the path @dest,
+ * deriving the contents of the row from @selection_data. If @dest is
+ * outside the tree so that inserting before it is impossible, %FALSE
+ * will be returned. Also, %FALSE may be returned if the new row is
+ * not created for some model-specific reason.  Should robustly handle
+ * a @dest no longer found in the model!
+ * 
+ * Return value: whether a new row was created before position @dest
+ **/
+gboolean
+gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest  *drag_dest,
+                                       GtkTreePath      *dest,
+                                       GtkSelectionData *selection_data)
+{
+  GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE (drag_dest);
+
+  g_return_val_if_fail (iface->drag_data_received != NULL, FALSE);
+  g_return_val_if_fail (dest != NULL, FALSE);
+  g_return_val_if_fail (selection_data != NULL, FALSE);
+
+  return (* iface->drag_data_received) (drag_dest, dest, selection_data);
+}
+
+typedef struct _TreeRowData TreeRowData;
+
+struct _TreeRowData
+{
+  GtkTreeModel *model;
+  gchar path[4];
+};
+
+/**
+ * gtk_selection_data_set_tree_row:
+ * @selection_data: some #GtkSelectionData
+ * @tree_model: a #GtkTreeModel
+ * @path: a row in @tree_model
+ * 
+ * Sets selection data of target type %GTK_TREE_MODEL_ROW. Normally used
+ * in a drag_data_get handler.
+ * 
+ * Return value: %TRUE if the #GtkSelectionData had the proper target type to allow us to set a tree row
+ **/
+gboolean
+gtk_selection_data_set_tree_row (GtkSelectionData *selection_data,
+                                 GtkTreeModel     *tree_model,
+                                 GtkTreePath      *path)
+{
+  TreeRowData *trd;
+  gchar *path_str;
+  gint len;
+  gint struct_size;
+  
+  g_return_val_if_fail (selection_data != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
+  g_return_val_if_fail (path != NULL, FALSE);
+
+  if (selection_data->target != gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
+    return FALSE;
+  
+  path_str = gtk_tree_path_to_string (path);
+
+  len = strlen (path_str);
+
+  /* the old allocate-end-of-struct-to-hold-string trick */
+  struct_size = sizeof (TreeRowData) + len + 1 -
+    (sizeof (TreeRowData) - G_STRUCT_OFFSET (TreeRowData, path));
+
+  trd = g_malloc (struct_size); 
+
+  strcpy (trd->path, path_str);
+  
+  trd->model = tree_model;
+  
+  gtk_selection_data_set (selection_data,
+                          gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE),
+                          8, /* bytes */
+                          (void*)trd,
+                          struct_size);
+
+  g_free (trd);
+  
+  return TRUE;
+}
+
+/**
+ * gtk_selection_data_get_tree_row:
+ * @selection_data: a #GtkSelectionData
+ * @tree_model: a #GtkTreeModel
+ * @path: row in @tree_model
+ * 
+ * Obtains a @tree_model and @path from selection data of target type
+ * %GTK_TREE_MODEL_ROW. Normally called from a drag_data_received handler.
+ * This function can only be used if @selection_data originates from the same
+ * process that's calling this function, because a pointer to the tree model
+ * is being passed around. If you aren't in the same process, then you'll
+ * get memory corruption. In the #GtkTreeDragDest drag_data_received handler,
+ * you can assume that selection data of type %GTK_TREE_MODEL_ROW is
+ * in from the current process. The returned path must be freed with
+ * gtk_tree_path_free().
+ * 
+ * Return value: %TRUE if @selection_data had target type %GTK_TREE_MODEL_ROW and
+ *  is otherwise valid
+ **/
+gboolean
+gtk_selection_data_get_tree_row (GtkSelectionData *selection_data,
+                                 GtkTreeModel    **tree_model,
+                                 GtkTreePath     **path)
+{
+  TreeRowData *trd;
+  
+  g_return_val_if_fail (selection_data != NULL, FALSE);  
+
+  if (tree_model)
+    *tree_model = NULL;
+
+  if (path)
+    *path = NULL;
+  
+  if (selection_data->target != gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
+    return FALSE;
+
+  trd = (void*) selection_data->data;
+
+  if (tree_model)
+    *tree_model = trd->model;
+
+  if (path)
+    *path = gtk_tree_path_new_from_string (trd->path);
+  
+  return TRUE;
+}
diff --git a/gtk/gtktreednd.h b/gtk/gtktreednd.h
new file mode 100644 (file)
index 0000000..1257ed2
--- /dev/null
@@ -0,0 +1,109 @@
+/* gtktreednd.h
+ * Copyright (C) 2001  Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TREE_DND_H__
+#define __GTK_TREE_DND_H__
+
+#include <gtk/gtktreemodel.h>
+#include <gtk/gtkdnd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GTK_TYPE_TREE_DRAG_SOURCE            (gtk_tree_drag_source_get_type ())
+#define GTK_TREE_DRAG_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_SOURCE, GtkTreeDragSource))
+#define GTK_IS_TREE_DRAG_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_DRAG_SOURCE))
+#define GTK_TREE_DRAG_SOURCE_GET_IFACE(obj)  ((GtkTreeDragSourceIface *)g_type_interface_peek (((GTypeInstance *)GTK_TREE_DRAG_SOURCE (obj))->g_class, GTK_TYPE_TREE_DRAG_SOURCE))
+
+typedef struct _GtkTreeDragSource      GtkTreeDragSource; /* Dummy typedef */
+typedef struct _GtkTreeDragSourceIface GtkTreeDragSourceIface;
+
+struct _GtkTreeDragSourceIface
+{
+  GTypeInterface g_iface;
+
+  /* VTable - not signals */
+
+  gboolean     (* drag_data_get)        (GtkTreeDragSource   *dragsource,
+                                         GtkTreePath         *path,
+                                         GtkSelectionData    *selection_data);
+
+  gboolean     (* drag_data_delete)     (GtkTreeDragSource *dragsource,
+                                         GtkTreePath       *path);
+};
+
+GType           gtk_tree_drag_source_get_type   (void) G_GNUC_CONST;
+
+/* Deletes the given row, or returns FALSE if it can't */
+gboolean gtk_tree_drag_source_drag_data_delete (GtkTreeDragSource *drag_source,
+                                                GtkTreePath       *path);
+
+/* Fills in selection_data with type selection_data->target based on
+ * the row denoted by path, returns TRUE if it does anything
+ */
+gboolean gtk_tree_drag_source_drag_data_get    (GtkTreeDragSource *drag_source,
+                                                GtkTreePath       *path,
+                                                GtkSelectionData  *selection_data);
+
+#define GTK_TYPE_TREE_DRAG_DEST            (gtk_tree_drag_dest_get_type ())
+#define GTK_TREE_DRAG_DEST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_DRAG_DEST, GtkTreeDragDest))
+#define GTK_IS_TREE_DRAG_DEST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_DRAG_DEST))
+#define GTK_TREE_DRAG_DEST_GET_IFACE(obj)  ((GtkTreeDragDestIface *)g_type_interface_peek (((GTypeInstance *)GTK_TREE_DRAG_DEST (obj))->g_class, GTK_TYPE_TREE_DRAG_DEST))
+
+typedef struct _GtkTreeDragDest      GtkTreeDragDest; /* Dummy typedef */
+typedef struct _GtkTreeDragDestIface GtkTreeDragDestIface;
+
+struct _GtkTreeDragDestIface
+{
+  GTypeInterface g_iface;
+
+  /* VTable - not signals */
+
+  gboolean     (* drag_data_received) (GtkTreeDragDest   *dragdest,
+                                       GtkTreePath       *dest,
+                                       GtkSelectionData  *selection_data);
+
+};
+
+GType           gtk_tree_drag_dest_get_type   (void) G_GNUC_CONST;
+
+/* Inserts a row before dest which contains data in selection_data,
+ * or returns FALSE if it can't
+ */
+gboolean gtk_tree_drag_dest_drag_data_received (GtkTreeDragDest  *drag_dest,
+                                                GtkTreePath      *dest,
+                                                GtkSelectionData *selection_data);
+
+/* The selection data would normally have target type GTK_TREE_MODEL_ROW in this
+ * case. If the target is wrong these functions return FALSE.
+ */
+gboolean gtk_selection_data_set_tree_row     (GtkSelectionData         *selection_data,
+                                              GtkTreeModel             *tree_model,
+                                              GtkTreePath              *path);
+gboolean gtk_selection_data_get_tree_row     (GtkSelectionData         *selection_data,
+                                              GtkTreeModel           **tree_model,
+                                              GtkTreePath             **path);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_DND_H__ */
index 74fd34da7e863853279dca0c2db0533f746d01ae..b15b92b673afca63de5e2b39df6da13ef6a254c7 100644 (file)
@@ -179,7 +179,7 @@ gboolean     gtk_tree_model_iter_parent     (GtkTreeModel      *tree_model,
 void         gtk_tree_model_ref_iter        (GtkTreeModel      *tree_model,
                                             GtkTreeIter       *iter);
 void         gtk_tree_model_unref_iter      (GtkTreeModel      *tree_model,
-                                            GtkTreeIter       *iter);
+                                             GtkTreeIter       *iter);
 
 #ifdef __cplusplus
 }
index 78d093c56c7724af81a42fb4fdea36ef1c3266ed..73d5a9fd376e49a2d1af60afb62f483f06e8cbfb 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "gtktreeview.h"
 #include "gtkrbtree.h"
+#include "gtktreednd.h"
 #include "gtktreeprivate.h"
 #include "gtkcellrenderer.h"
 #include "gtksignal.h"
 #define TREE_VIEW_DRAG_WIDTH 6
 #define TREE_VIEW_EXPANDER_WIDTH 14
 #define TREE_VIEW_EXPANDER_HEIGHT 14
-#define TREE_VIEW_VERTICAL_SEPARATOR 2
+
+/* The TREE_VIEW_VERTICAL_SEPARATOR is the space between rows. The
+ * GTK_RBNODE_GET_HEIGHT() value includes the separators; the offset
+ * of each row points to the center of the inter-row space. For an odd
+ * separator, the extra pixel by convention goes _below_ the row.  So
+ * a node in the rbtree owns TREE_VIEW_VERTICAL_SEPARATOR/2 pixels
+ * above the row, and TREE_VIEW_VERTICAL_SEPARATOR/2 +
+ * TREE_VIEW_VERTICAL_SEPARATOR%2 pixels below the row. 
+ */
+
+/* Set to large number for debugging. Should normally be 2. */
+#define TREE_VIEW_VERTICAL_SEPARATOR 11
+
 #define TREE_VIEW_HORIZONTAL_SEPARATOR 0
 
+/* The "background" areas of all rows/cells add up to cover the entire tree.
+ * The background includes all inter-row and inter-cell spacing.
+ * The "cell" areas are the cell_area passed in to gtk_cell_renderer_render(),
+ * i.e. just the cells, no spacing.
+ */
+
+#define BACKGROUND_FIRST_PIXEL(tree_view,tree,node) (_gtk_rbtree_node_find_offset ((tree), (node)) + TREE_VIEW_HEADER_HEIGHT ((tree_view)))
+#define CELL_FIRST_PIXEL(tree_view,tree,node) (BACKGROUND_FIRST_PIXEL (tree_view,tree,node) + TREE_VIEW_VERTICAL_SEPARATOR/2)
+
+#define BACKGROUND_HEIGHT(node) (GTK_RBNODE_GET_HEIGHT (node))
+#define CELL_HEIGHT(node) (BACKGROUND_HEIGHT (node) - TREE_VIEW_VERTICAL_SEPARATOR);
+
+#define TREE_WINDOW_Y_TO_RBTREE_Y(tree_view,y) ((y) - TREE_VIEW_HEADER_HEIGHT (tree_view))
+#define RBTREE_Y_TO_TREE_WINDOW_Y(tree_view,y) ((y) + TREE_VIEW_HEADER_HEIGHT (tree_view))
 
 typedef struct _GtkTreeViewChild GtkTreeViewChild;
 
@@ -152,13 +179,16 @@ static void     gtk_tree_view_queue_draw_node      (GtkTreeView      *tree_view,
                                                    GtkRBTree        *tree,
                                                    GtkRBNode        *node,
                                                    GdkRectangle     *clip_rect);
+static void     gtk_tree_view_queue_draw_path      (GtkTreeView      *tree_view,
+                                                    GtkTreePath      *path,
+                                                    GdkRectangle     *clip_rect);
 static void     gtk_tree_view_draw_arrow           (GtkTreeView      *tree_view,
                                                     GtkRBTree        *tree,
                                                    GtkRBNode        *node,
                                                    gint              x,
                                                    gint              y);
-static void     gtk_tree_view_get_arrow_range      (GtkTreeView      *tree_view,
-                                                   gint              *x1,
+static void     gtk_tree_view_get_arrow_xrange     (GtkTreeView      *tree_view,
+                                                    gint              *x1,
                                                     gint              *x2);
 static gint     gtk_tree_view_new_column_width     (GtkTreeView      *tree_view,
                                                    gint              i,
@@ -821,9 +851,9 @@ gtk_tree_view_draw_node_focus_rect (GtkWidget   *widget,
                      widget->style->fg_gc[GTK_STATE_NORMAL],
                      FALSE,
                      0,
-                     _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view),
+                      BACKGROUND_FIRST_PIXEL (tree_view, tree, node),
                       bin_window_width - 2,
-                     GTK_RBNODE_GET_HEIGHT (node));
+                     BACKGROUND_HEIGHT (node) - 1);
 }
 
 GdkPixmap*
@@ -836,7 +866,6 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
   GtkCellRenderer *cell;
   gint i;
   gint cell_offset;
-  gint max_height;
   GList *list;
   GdkRectangle background_area;
   GtkWidget *widget;
@@ -860,20 +889,18 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                                 &iter,
                                 path))
     return NULL;
-  
-  max_height = GTK_RBNODE_GET_HEIGHT (node);
     
   cell_offset = x;
 
-  background_area.y = y + TREE_VIEW_VERTICAL_SEPARATOR;
-  background_area.height = max_height - TREE_VIEW_VERTICAL_SEPARATOR;
+  background_area.y = y;
+  background_area.height = BACKGROUND_HEIGHT (node);
 
   gdk_drawable_get_size (tree_view->priv->bin_window,
                          &bin_window_width, NULL);
   
   drawable = gdk_pixmap_new (tree_view->priv->bin_window,
                              bin_window_width + 2,
-                             max_height + 2,
+                             background_area.height + 2,
                              -1);
 
   gdk_draw_rectangle (drawable,
@@ -881,14 +908,14 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                       TRUE,
                       0, 0,
                       bin_window_width + 2,
-                      max_height + 2);
+                      background_area.height + 2);
 
   gdk_draw_rectangle (drawable,
                       widget->style->black_gc,
                       FALSE,
                       0, 0,
                       bin_window_width + 1,
-                      max_height + 1);
+                      background_area.height + 1);
   
   for (i = 0, list = tree_view->priv->columns; i < tree_view->priv->n_columns; i++, list = list->next)
     {
@@ -907,6 +934,9 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
       background_area.width = TREE_VIEW_COLUMN_WIDTH (column);
 
       cell_area = background_area;
+
+      cell_area.y += TREE_VIEW_VERTICAL_SEPARATOR / 2;
+      cell_area.height -= TREE_VIEW_VERTICAL_SEPARATOR;
       
       if (i == tree_view->priv->expander_column &&
           TREE_VIEW_DRAW_EXPANDERS(tree_view))
@@ -972,8 +1002,11 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
    * height to find the right node.
    */
   new_y = (event->area.y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):event->area.y;
+
+  /* y_offset is the */
+  
   y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree,
-                                      new_y - TREE_VIEW_HEADER_HEIGHT (tree_view),
+                                       TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
                                       &tree,
                                       &node) + new_y - event->area.y;
   if (node == NULL)
@@ -1015,13 +1048,13 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
         max_height = MAX (TREE_VIEW_EXPANDER_MIN_HEIGHT, GTK_RBNODE_GET_HEIGHT (node));
         else
       */
-      max_height = GTK_RBNODE_GET_HEIGHT (node);
+      max_height = BACKGROUND_HEIGHT (node);
 
       x_offset = -event->area.x;
       cell_offset = 0;
       highlight_x = 0; /* should match x coord of first cell */
       
-      background_area.y = y_offset + event->area.y + TREE_VIEW_VERTICAL_SEPARATOR;
+      background_area.y = y_offset + event->area.y + TREE_VIEW_VERTICAL_SEPARATOR / 2;
       background_area.height = max_height - TREE_VIEW_VERTICAL_SEPARATOR;
       flags = 0;
 
@@ -1236,11 +1269,11 @@ coords_are_over_arrow (GtkTreeView *tree_view,
   if ((node->flags & GTK_RBNODE_IS_PARENT) == 0)
     return FALSE;
   
-  arrow.y = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view);  
+  arrow.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
       
-  arrow.height = GTK_RBNODE_GET_HEIGHT (node);
+  arrow.height = BACKGROUND_HEIGHT (node);
 
-  gtk_tree_view_get_arrow_range (tree_view, &arrow.x, &x2);
+  gtk_tree_view_get_arrow_xrange (tree_view, &arrow.x, &x2);
 
   arrow.width = x2 - arrow.x;
 
@@ -1256,21 +1289,10 @@ do_unprelight (GtkTreeView *tree_view,
                gint x,
                gint y)
 {
-  gint y1, y2;
-  
   if (tree_view->priv->prelight_node == NULL)
     return;
   
-  y1 = _gtk_rbtree_node_find_offset (tree_view->priv->prelight_tree,
-                                     tree_view->priv->prelight_node) +
-    TREE_VIEW_HEADER_HEIGHT (tree_view);  
-      
-  y2 = y1 + GTK_RBNODE_GET_HEIGHT (tree_view->priv->prelight_node);
-  
-  if (tree_view->priv->prelight_node)
-    GTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node, GTK_RBNODE_IS_PRELIT);
-
-  /* FIXME queue draw on y1-y2 range */
+  GTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node, GTK_RBNODE_IS_PRELIT);
   
   if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT) &&
       !coords_are_over_arrow (tree_view,
@@ -1286,15 +1308,12 @@ do_unprelight (GtkTreeView *tree_view,
                                 tree_view->priv->prelight_tree,
                                 tree_view->priv->prelight_node,
                                 x,
-                                y);      
+                                y);  
 
     }
   
   tree_view->priv->prelight_node = NULL;
   tree_view->priv->prelight_tree = NULL;
-
-  /* FIXME */
-  gtk_widget_queue_draw (GTK_WIDGET (tree_view));
 }
 
 static void
@@ -1312,8 +1331,6 @@ do_prelight (GtkTreeView *tree_view,
   tree_view->priv->prelight_tree = tree;
 
   GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_PRELIT);
-
-  gtk_widget_queue_draw (GTK_WIDGET (tree_view));
 }
 
 static gboolean
@@ -1324,6 +1341,8 @@ gtk_tree_view_motion (GtkWidget      *widget,
   GtkRBTree *tree;
   GtkRBNode *node;
   gint new_y;
+  GtkRBTree *old_prelight_tree;
+  GtkRBNode *old_prelight_node;
   
   tree_view = (GtkTreeView *) widget;
   
@@ -1357,11 +1376,15 @@ gtk_tree_view_motion (GtkWidget      *widget,
 
   gtk_tree_view_maybe_begin_dragging_row (tree_view, event);
 
+  old_prelight_tree = tree_view->priv->prelight_tree;
+  old_prelight_node = tree_view->priv->prelight_node;
+  
   do_unprelight (tree_view, event->x, event->y);  
   
   new_y = ((gint)event->y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):(gint)event->y;
 
-  _gtk_rbtree_find_offset (tree_view->priv->tree, new_y - TREE_VIEW_HEADER_HEIGHT (tree_view),
+  _gtk_rbtree_find_offset (tree_view->priv->tree,
+                           TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
                            &tree,
                            &node);
 
@@ -1376,6 +1399,21 @@ gtk_tree_view_motion (GtkWidget      *widget,
 
   do_prelight (tree_view, tree, node, event->x, new_y);
 
+  if (old_prelight_node != tree_view->priv->prelight_node)
+    {
+      if (old_prelight_node)
+        gtk_tree_view_queue_draw_node (tree_view,
+                                       old_prelight_tree,
+                                       old_prelight_node,
+                                       NULL);
+
+      if (tree_view->priv->prelight_node)
+        gtk_tree_view_queue_draw_node (tree_view,
+                                       tree_view->priv->prelight_tree,
+                                       tree_view->priv->prelight_node,
+                                       NULL);
+    }
+  
   return TRUE;
 }
 
@@ -1411,7 +1449,7 @@ gtk_tree_view_enter_notify (GtkWidget        *widget,
   new_y = ((gint)event->y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):(gint)event->y;
 
   _gtk_rbtree_find_offset (tree_view->priv->tree,
-                           new_y - TREE_VIEW_HEADER_HEIGHT (tree_view),
+                           TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
                            &tree,
                            &node);
   
@@ -1420,6 +1458,12 @@ gtk_tree_view_enter_notify (GtkWidget        *widget,
 
   do_prelight (tree_view, tree, node, event->x, new_y);
 
+  if (tree_view->priv->prelight_node)
+    gtk_tree_view_queue_draw_node (tree_view,
+                                   tree_view->priv->prelight_tree,
+                                   tree_view->priv->prelight_node,
+                                   NULL);
+  
   return TRUE;
 }
 
@@ -1434,6 +1478,12 @@ gtk_tree_view_leave_notify (GtkWidget        *widget,
 
   tree_view = GTK_TREE_VIEW (widget);
 
+  if (tree_view->priv->prelight_node)
+    gtk_tree_view_queue_draw_node (tree_view,
+                                   tree_view->priv->prelight_tree,
+                                   tree_view->priv->prelight_node,
+                                   NULL);
+  
   do_unprelight (tree_view, -1000, -1000); /* coords not possibly over an arrow */
 
   return TRUE;
@@ -1491,7 +1541,7 @@ gtk_tree_view_button_press (GtkWidget      *widget,
       /* find the node that was clicked */
       new_y = ((gint)event->y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):(gint)event->y;
       y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree,
-                                          new_y - TREE_VIEW_HEADER_HEIGHT (tree_view),
+                                           TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
                                           &tree,
                                           &node) + new_y - (gint)event->y;
 
@@ -2233,7 +2283,8 @@ gtk_tree_view_forall (GtkContainer *container,
 
   for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next)
     {
-      column = tmp_list->data;
+      column = tmp_list->data;      
+      
       if (column->button)
        (* callback) (column->button, callback_data);
     }
@@ -2283,8 +2334,7 @@ gtk_tree_view_changed (GtkTreeModel *model,
     gtk_widget_queue_resize (GTK_WIDGET (data));
   else
     {
-      /* FIXME: just redraw the node */
-      gtk_widget_queue_draw (GTK_WIDGET (data));
+      gtk_tree_view_queue_draw_node (tree_view, tree, node, NULL);
     }
 }
 
@@ -2849,7 +2899,7 @@ gtk_tree_view_create_buttons (GtkTreeView *tree_view)
   for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++)
     {
       column = list->data;
-
+      
       if (column->button != NULL)
        continue;
 
@@ -3020,52 +3070,6 @@ _gtk_tree_view_find_node (GtkTreeView  *tree_view,
   while (1);
 }
 
-static void
-gtk_tree_view_get_arrow_range (GtkTreeView *tree_view,
-                               gint        *x1,
-                               gint        *x2)
-{
-  gint x_offset = 0;
-  GList *list;
-  GtkTreeViewColumn *tmp_column = NULL;
-  gint total_width;
-  gint i;
-  
-  i = 0;
-  total_width = 0;
-  for (list = tree_view->priv->columns; list; list = list->next)
-    {
-      tmp_column = list->data;
-
-      if (i == tree_view->priv->expander_column)
-        {
-          x_offset = total_width;
-          break;
-        }
-          
-      if (tmp_column->visible)
-        total_width += tmp_column->width;
-
-      ++i;
-    }
-
-  if (x1)
-    *x1 = x_offset;
-  
-  if (tmp_column && tmp_column->visible)
-    {
-      /* +1 because x2 isn't included in the range. */
-      if (x2)
-        *x2 = x_offset + tree_view->priv->tab_offset + 1;
-    }
-  else
-    {
-      /* return an empty range, the expander column is hidden */
-      if (x2)
-        *x2 = x_offset;
-    }
-}
-
 static void
 gtk_tree_view_queue_draw_node (GtkTreeView  *tree_view,
                               GtkRBTree    *tree,
@@ -3074,28 +3078,43 @@ gtk_tree_view_queue_draw_node (GtkTreeView  *tree_view,
 {
   GdkRectangle rect;
 
+  if (!GTK_WIDGET_REALIZED (tree_view))
+    return;
+  
   rect.x = 0;
   rect.width = tree_view->priv->width;
-  rect.y = _gtk_rbtree_node_find_offset (tree, node) +
-    TREE_VIEW_VERTICAL_SEPARATOR/2 +
-    TREE_VIEW_HEADER_HEIGHT (tree_view);
-  rect.height = GTK_RBNODE_GET_HEIGHT (node) + TREE_VIEW_VERTICAL_SEPARATOR;
+
+  rect.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
+  rect.height = BACKGROUND_HEIGHT (node);
+
   if (clip_rect)
     {
       GdkRectangle new_rect;
-       gdk_rectangle_intersect (clip_rect, &rect, &new_rect);
-       gtk_widget_queue_draw_area (GTK_WIDGET (tree_view),
-                                  new_rect.x, new_rect.y,
-                                  new_rect.width, new_rect.height);
+
+      gdk_rectangle_intersect (clip_rect, &rect, &new_rect);
+
+      gdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE);
     }
   else
     {
-       gtk_widget_queue_draw_area (GTK_WIDGET (tree_view),
-                                  rect.x, rect.y,
-                                  rect.width, rect.height);
+      gdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE);
     }
 }
 
+static void
+gtk_tree_view_queue_draw_path (GtkTreeView      *tree_view,
+                               GtkTreePath      *path,
+                               GdkRectangle     *clip_rect)
+{
+  GtkRBTree *tree = NULL;
+  GtkRBNode *node = NULL;
+  
+  _gtk_tree_view_find_node (tree_view, path, &tree, &node);
+
+  if (tree)
+    gtk_tree_view_queue_draw_node (tree_view, tree, node, clip_rect);
+}
+
 /* x and y are the mouse position
  */
 static void
@@ -3109,21 +3128,18 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
   GtkStateType state;
   GtkWidget *widget;
   gint x_offset = 0;
-  gint y_offset = 0;
   
   if (! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT))
     return;
 
   widget = GTK_WIDGET (tree_view);
 
-  y_offset = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view);
-
-  gtk_tree_view_get_arrow_range (tree_view, &x_offset, NULL);
+  gtk_tree_view_get_arrow_xrange (tree_view, &x_offset, NULL);
   
   area.x = x_offset;
-  area.y = y_offset + TREE_VIEW_VERTICAL_SEPARATOR;
+  area.y = CELL_FIRST_PIXEL (tree_view, tree, node);
   area.width = tree_view->priv->tab_offset - 2;
-  area.height = GTK_RBNODE_GET_HEIGHT (node) - TREE_VIEW_VERTICAL_SEPARATOR;
+  area.height = CELL_HEIGHT (node);
 
   if (node == tree_view->priv->button_pressed_node)
     {
@@ -3755,7 +3771,6 @@ gtk_tree_view_append_column (GtkTreeView       *tree_view,
   g_return_val_if_fail (column->tree_view == NULL, -1);
 
   g_object_ref (G_OBJECT (column));
-  gtk_object_sink (GTK_OBJECT (column));
   tree_view->priv->columns = g_list_append (tree_view->priv->columns, column);
   column->tree_view = GTK_WIDGET (tree_view);
 
@@ -3820,7 +3835,7 @@ gtk_tree_view_insert_column (GtkTreeView       *tree_view,
   g_return_val_if_fail (column->tree_view == NULL, -1);
 
   g_object_ref (G_OBJECT (column));
-  gtk_object_sink (GTK_OBJECT (column));
+
   tree_view->priv->columns = g_list_insert (tree_view->priv->columns,
                                            column, position);
   column->tree_view = GTK_WIDGET (tree_view);
@@ -3965,7 +3980,7 @@ gtk_tree_view_scroll_to_cell (GtkTreeView       *tree_view,
       return;
     }
 
-  gtk_tree_view_get_cell_rect (tree_view, path, column, &cell_rect);
+  gtk_tree_view_get_cell_area (tree_view, path, column, &cell_rect);
   gtk_tree_view_get_visible_rect (tree_view, &vis_rect);
 
   dest_x = vis_rect.x;
@@ -3999,14 +4014,16 @@ gtk_tree_view_scroll_to_cell (GtkTreeView       *tree_view,
  * @cell_x: A pointer where the X coordinate relative to the cell can be placed, or %NULL
  * @cell_y: A pointer where the Y coordinate relative to the cell can be placed, or %NULL
  * 
- * Finds the path at the point (@x, @y) relative to @window.  If @window is
- * NULL, then the point is found relative to the widget coordinates.  This
- * function is expected to be called after an event, with event->window being
- * passed in as @window.  It is primarily for things like popup menus.  If @path
- * is non-NULL, then it will be filled with the #GtkTreePath at that point.
- * This path should be freed with #gtk_tree_path_free.  If @column is non-NULL,
- * then it will be filled with the column at that point. @cell_x and @cell_y return
- * the coordinates relative to the cell.
+ * Finds the path at the point (@x, @y) relative to @window.  If
+ * @window is NULL, then the point is found relative to the widget
+ * coordinates.  This function is expected to be called after an
+ * event, with event->window being passed in as @window.  It is
+ * primarily for things like popup menus.  If @path is non-NULL, then
+ * it will be filled with the #GtkTreePath at that point.  This path
+ * should be freed with #gtk_tree_path_free.  If @column is non-NULL,
+ * then it will be filled with the column at that point. @cell_x and
+ * @cell_y return the coordinates relative to the cell background
+ * (i.e. the background_area passed to gtk_cell_renderer_render()).
  * 
  * Return value: TRUE if a row exists at that coordinate.
  **/
@@ -4086,7 +4103,7 @@ gtk_tree_view_get_path_at_pos (GtkTreeView        *tree_view,
   if (window)
     {
       y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree,
-                                          y - TREE_VIEW_HEADER_HEIGHT (tree_view),
+                                          TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y),
                                           &tree, &node);
     }
   else
@@ -4094,8 +4111,8 @@ gtk_tree_view_get_path_at_pos (GtkTreeView        *tree_view,
       if (y < TREE_VIEW_HEADER_HEIGHT (tree_view))
        return FALSE;
 
-      y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree, y - TREE_VIEW_HEADER_HEIGHT (tree_view) +
-                                          tree_view->priv->vadjustment->value,
+      y_offset = _gtk_rbtree_find_offset (tree_view->priv->tree,
+                                          TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y + tree_view->priv->vadjustment->value),
                                           &tree, &node);
     }
   
@@ -4111,28 +4128,182 @@ gtk_tree_view_get_path_at_pos (GtkTreeView        *tree_view,
   return TRUE;
 }
 
+
+static void
+gtk_tree_view_get_background_xrange (GtkTreeView       *tree_view,
+                                     GtkRBTree         *tree,
+                                     GtkTreeViewColumn *column,
+                                     gint              *x1,
+                                     gint              *x2)
+{
+  GtkTreeViewColumn *tmp_column = NULL;
+  gint total_width;
+  GList *list;
+  
+  if (x1)
+    *x1 = 0;
+
+  if (x2)
+    *x2 = 0;
+
+  total_width = 0;
+  for (list = tree_view->priv->columns; list; list = list->next)
+    {
+      tmp_column = list->data;
+      
+      if (tmp_column == column)
+        break;
+      
+      if (tmp_column->visible)
+        total_width += tmp_column->width;
+    }
+  
+  if (tmp_column != column)
+    {
+      g_warning (G_STRLOC": passed-in column isn't in the tree");
+      return;
+    }
+  
+  if (x1)
+    *x1 = total_width;
+  
+  if (x2)
+    {
+      if (column->visible)
+        *x2 = total_width + column->width;
+      else
+        *x2 = total_width; /* width of 0 */
+    }
+}
+
+static void
+gtk_tree_view_get_cell_xrange (GtkTreeView       *tree_view,
+                               GtkRBTree         *tree,
+                               GtkTreeViewColumn *column,
+                               gint              *x1,
+                               gint              *x2)
+{
+  GtkTreeViewColumn *tmp_column = NULL;
+  gint total_width;
+  GList *list;
+  gint i;
+  
+  if (x1)
+    *x1 = 0;
+
+  if (x2)
+    *x2 = 0;
+
+  i = 0;
+  total_width = 0;
+  for (list = tree_view->priv->columns; list; list = list->next)
+    {
+      tmp_column = list->data;
+      
+      if (tmp_column == column)
+        break;
+      
+      if (tmp_column->visible)
+        total_width += tmp_column->width;
+
+      ++i;
+    }
+  
+  if (tmp_column != column)
+    {
+      g_warning (G_STRLOC": passed-in column isn't in the tree");
+      return;
+    }
+
+  /* Remember we're getting the cell range, i.e. the cell_area passed
+   * to the cell renderer.
+   */
+
+  if (i == tree_view->priv->expander_column)
+    total_width += tree_view->priv->tab_offset * _gtk_rbtree_get_depth (tree);
+  
+  if (x1)
+    *x1 = total_width;
+  
+  if (x2)
+    {
+      if (column->visible)
+        *x2 = total_width + column->width;
+      else
+        *x2 = total_width; /* width of 0 */
+    }
+}
+
+static void
+gtk_tree_view_get_arrow_xrange (GtkTreeView *tree_view,
+                                gint        *x1,
+                                gint        *x2)
+{
+  gint x_offset = 0;
+  GList *list;
+  GtkTreeViewColumn *tmp_column = NULL;
+  gint total_width;
+  gint i;
+  
+  i = 0;
+  total_width = 0;
+  for (list = tree_view->priv->columns; list; list = list->next)
+    {
+      tmp_column = list->data;
+
+      if (i == tree_view->priv->expander_column)
+        {
+          x_offset = total_width;
+          break;
+        }
+          
+      if (tmp_column->visible)
+        total_width += tmp_column->width;
+
+      ++i;
+    }
+
+  if (x1)
+    *x1 = x_offset;
+  
+  if (tmp_column && tmp_column->visible)
+    {
+      /* +1 because x2 isn't included in the range. */
+      if (x2)
+        *x2 = x_offset + tree_view->priv->tab_offset + 1;
+    }
+  else
+    {
+      /* return an empty range, the expander column is hidden */
+      if (x2)
+        *x2 = x_offset;
+    }
+}
+
+
 /**
- * gtk_tree_view_get_cell_rect:
+ * gtk_tree_view_get_cell_area:
  * @tree_view: a #GtkTreeView
  * @path: a #GtkTreePath for the row, or %NULL to get only horizontal coordinates
  * @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes
  * @rect: rectangle to fill with cell rect
  * 
- * Fills the bounding rectangle in tree window coordinates for the cell
- * at the row specified by @path and the column specified by @column.
- * If @path is %NULL, the y and height fields of the rectangle will be filled
- * with 0. If @column is %NULL, the x and width fields will be filled with 0.
+ * Fills the bounding rectangle in tree window coordinates for the
+ * cell at the row specified by @path and the column specified by
+ * @column.  If @path is %NULL, the y and height fields of the
+ * rectangle will be filled with 0. If @column is %NULL, the x and
+ * width fields will be filled with 0.  The sum of all cell rects does
+ * not cover the entire tree; there are extra pixels in between rows,
+ * for example. The returned rectangle is equivalent to the @cell_area
+ * passed to gtk_cell_renderer_render().
  * 
  **/
 void
-gtk_tree_view_get_cell_rect (GtkTreeView        *tree_view,
+gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
                              GtkTreePath        *path,
                              GtkTreeViewColumn  *column,
                              GdkRectangle       *rect)
 {
-  GtkTreeViewColumn *tmp_column = NULL;
-  gint total_width;
-  GList *list;
   GtkRBTree *tree = NULL;
   GtkRBNode *node = NULL;
   
@@ -4157,35 +4328,85 @@ gtk_tree_view_get_cell_rect (GtkTreeView        *tree_view,
           return;
         }
 
-      rect->y = _gtk_rbtree_node_find_offset (tree, node) + TREE_VIEW_HEADER_HEIGHT (tree_view);  
+      /* Remember that the rbtree stores node height including the vertical
+       * separator, see comment at top of file.
+       */
+      rect->y = CELL_FIRST_PIXEL (tree_view, tree, node);
+
+      rect->height = CELL_HEIGHT (node);
+    }
+
+  if (column)
+    {
+      gint x2 = 0;
       
-      rect->height = GTK_RBNODE_GET_HEIGHT (node);
+      gtk_tree_view_get_cell_xrange (tree_view, tree, column, &rect->x, &x2);
+      rect->width = x2 - rect->x;
     }
+}
+
+
+/**
+ * gtk_tree_view_get_background_area:
+ * @tree_view: a #GtkTreeView
+ * @path: a #GtkTreePath for the row, or %NULL to get only horizontal coordinates
+ * @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes
+ * @rect: rectangle to fill with cell background rect
+ * 
+ * Fills the bounding rectangle in tree window coordinates for the
+ * cell at the row specified by @path and the column specified by
+ * @column.  If @path is %NULL, the y and height fields of the
+ * rectangle will be filled with 0. If @column is %NULL, the x and
+ * width fields will be filled with 0.  The returned rectangle is
+ * equivalent to the @background_area passed to
+ * gtk_cell_renderer_render().  These background areas tile to cover
+ * the entire tree window (except for the area used for header
+ * buttons). Contrast with the cell_area, returned by
+ * gtk_tree_view_get_cell_area(), which returns only the cell itself,
+ * excluding surrounding borders and the tree expander area.
+ * 
+ **/
+void
+gtk_tree_view_get_background_area (GtkTreeView        *tree_view,
+                                   GtkTreePath        *path,
+                                   GtkTreeViewColumn  *column,
+                                   GdkRectangle       *rect)
+{
+  GtkRBTree *tree = NULL;
+  GtkRBNode *node = NULL;
+  
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column));
+  g_return_if_fail (rect != NULL);
 
-  if (column && column->visible)
+  rect->x = 0;
+  rect->y = 0;
+  rect->width = 0;
+  rect->height = 0;
+  
+  if (path)
     {
-      total_width = 0;
-      for (list = tree_view->priv->columns; list; list = list->next)
-        {
-          tmp_column = list->data;
-          
-          if (tmp_column == column)
-            {
-              rect->x = total_width;
-              break;
-            }
-          
-          if (tmp_column->visible)
-            total_width += tmp_column->width;
-        }
+      /* Get vertical coords */
       
-      if (tmp_column != column)
+      _gtk_tree_view_find_node (tree_view, path, &tree, &node);
+      
+      if (tree == NULL)
         {
-          g_warning (G_STRLOC": passed-in column isn't in the tree");
+          g_warning (G_STRLOC": no row corresponding to path");
           return;
         }
-  
-      rect->width = column->width;
+
+      rect->y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
+
+      rect->height = BACKGROUND_HEIGHT (node);
+    }
+
+  if (column)
+    {
+      gint x2 = 0;
+      
+      gtk_tree_view_get_background_xrange (tree_view, tree, column, &rect->x, &x2);
+      rect->width = x2 - rect->x;
     }
 }
 
@@ -4458,8 +4679,7 @@ gtk_tree_view_widget_to_tree_coords (GtkTreeView *tree_view,
 
   if (ty)
     {
-      *ty = wy - TREE_VIEW_HEADER_HEIGHT (tree_view) +
-        tree_view->priv->vadjustment->value;
+      *ty = wy + tree_view->priv->vadjustment->value;
     }
 }
 
@@ -4491,13 +4711,45 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
 
   if (wy)
     {
-      *wy = ty + TREE_VIEW_HEADER_HEIGHT (tree_view) -
-        tree_view->priv->vadjustment->value;
+      *wy = ty - tree_view->priv->vadjustment->value;
     }
 }
 
 /* Drag-and-drop */
 
+void
+set_source_row (GdkDragContext *context,
+                GtkTreePath    *source_row)
+{
+  g_object_set_data_full (G_OBJECT (context),
+                          "gtk-tree-view-source-row",
+                          source_row ? gtk_tree_path_copy (source_row) : NULL,
+                          (GDestroyNotify) (source_row ? gtk_tree_path_free : NULL));
+}
+
+GtkTreePath*
+get_source_row (GdkDragContext *context)
+{
+  return g_object_get_data (G_OBJECT (context), "gtk-tree-view-source-row");  
+}
+
+
+void
+set_dest_row (GdkDragContext *context,
+              GtkTreePath    *dest_row)
+{
+  g_object_set_data_full (G_OBJECT (context),
+                          "gtk-tree-view-dest-row",
+                          dest_row ? gtk_tree_path_copy (dest_row) : NULL,
+                          (GDestroyNotify) (dest_row ? gtk_tree_path_free : NULL));
+}
+
+GtkTreePath*
+get_dest_row (GdkDragContext *context)
+{
+  return g_object_get_data (G_OBJECT (context), "gtk-tree-view-dest-row");
+}
+
 typedef struct _TreeViewDragInfo TreeViewDragInfo;
 
 struct _TreeViewDragInfo
@@ -4506,7 +4758,6 @@ struct _TreeViewDragInfo
   GtkTargetList *source_target_list;
   GdkDragAction source_actions;
   GClosure *row_draggable_closure;
-  GtkTreePath *source_row;
 
   GtkTargetList *dest_target_list;
   GClosure *location_droppable_closure;
@@ -4529,13 +4780,9 @@ clear_source_info (TreeViewDragInfo *di)
 
   if (di->row_draggable_closure)
     g_closure_unref (di->row_draggable_closure);
-
-  if (di->source_row)
-    gtk_tree_path_free (di->source_row);
   
   di->source_target_list = NULL;
   di->row_draggable_closure = NULL;
-  di->source_row = NULL;
 }
 
 static void
@@ -4766,7 +5013,6 @@ gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view)
     }
 }
 
-
 void
 gtk_tree_view_set_drag_dest_row (GtkTreeView            *tree_view,
                                  GtkTreePath            *path,
@@ -4778,21 +5024,42 @@ gtk_tree_view_set_drag_dest_row (GtkTreeView            *tree_view,
   
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
+  g_print ("drag dest row %p -> %p\n", tree_view->priv->drag_dest_row, path);
+  
   if (tree_view->priv->drag_dest_row)
     {
-      /* FIXME queue undraw on previous location */
+      gtk_tree_view_queue_draw_path (tree_view, tree_view->priv->drag_dest_row, NULL);
       gtk_tree_path_free (tree_view->priv->drag_dest_row);
     }
 
   tree_view->priv->drag_dest_pos = pos;
   
   if (path)
-    tree_view->priv->drag_dest_row = gtk_tree_path_copy (path);
+    {
+      tree_view->priv->drag_dest_row = gtk_tree_path_copy (path);
+      gtk_tree_view_queue_draw_path (tree_view, tree_view->priv->drag_dest_row, NULL);
+    }
   else
     tree_view->priv->drag_dest_row = NULL;
+}
+
+void
+gtk_tree_view_get_drag_dest_row (GtkTreeView              *tree_view,
+                                 GtkTreePath             **path,
+                                 GtkTreeViewDropPosition  *pos)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  
+  if (path)
+    {
+      if (tree_view->priv->drag_dest_row)
+        *path = gtk_tree_path_copy (tree_view->priv->drag_dest_row);
+      else
+        *path = NULL;
+    }
 
-  /* FIXME this is crap, queue draw only on the newly-highlighted row */
-  gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+  if (pos)
+    *pos = tree_view->priv->drag_dest_pos;
 }
 
 gboolean
@@ -4823,7 +5090,7 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView             *tree_view,
   if (path)
     *path = NULL;
 
-  /* remember that drag_x and drag_y are in widget coords, convert to rbtree */
+  /* remember that drag_x and drag_y are in widget coords, convert to tree window */
 
   gtk_tree_view_widget_to_tree_coords (tree_view, drag_x, drag_y,
                                        &x, &y);
@@ -4842,8 +5109,8 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView             *tree_view,
                                       &cell_y))
     return FALSE;  
 
-  gtk_tree_view_get_cell_rect (tree_view, tmp_path, column,
-                               &cell);
+  gtk_tree_view_get_background_area (tree_view, tmp_path, column,
+                                     &cell);
 
   offset_into_row = cell_y;
   
@@ -4879,24 +5146,6 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView             *tree_view,
   return TRUE;
 }
 
-gboolean
-gtk_selection_data_set_tree_row (GtkSelectionData *selection_data,
-                                 GtkTreeView      *tree_view,
-                                 GtkTreePath      *path)
-{
-
-  return FALSE;
-}
-
-gboolean
-gtk_selection_data_get_tree_row (GtkSelectionData *selection_data,
-                                 GtkTreeView     **tree_view,
-                                 GtkTreePath     **path)
-{
-  return FALSE;
-}
-
-
 static gboolean
 gtk_tree_view_maybe_begin_dragging_row (GtkTreeView      *tree_view,
                                         GdkEventMotion   *event)
@@ -4969,7 +5218,8 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView      *tree_view,
     gdk_pixmap_unref (row_pix);
   }
   
-  di->source_row = path;
+  set_source_row (context, path);
+  gtk_tree_path_free (path);
   
   return TRUE;
 }
@@ -4998,38 +5248,99 @@ gtk_tree_view_drag_data_get (GtkWidget        *widget,
                              guint             time)
 {
   GtkTreeView *tree_view;
-
+  GtkTreeModel *model;
+  TreeViewDragInfo *di;
+  GtkTreePath *source_row;
+  
   tree_view = GTK_TREE_VIEW (widget);
 
-  if (selection_data->target == gdk_atom_intern ("GTK_TREE_VIEW_ROW", FALSE))
-    {
-      TreeViewDragInfo *di;
+  model = gtk_tree_view_get_model (tree_view);
 
-      di = get_info (GTK_TREE_VIEW (widget));
+  if (model == NULL)
+    return;
 
-      if (di == NULL)
-        {
-          /* There's a race where someone could have unset
-           * drag source before the data is requested
-           */
-          return;
-        }
-      
+  di = get_info (GTK_TREE_VIEW (widget));
+  
+  if (di == NULL)    
+    return;
+
+  source_row = get_source_row (context);
+
+  if (source_row == NULL)
+    return;
+  
+  /* We can implement the GTK_TREE_MODEL_ROW target generically for
+   * any model; for DragSource models there are some other targets
+   * we also support.
+   */
+
+  if (GTK_IS_TREE_DRAG_SOURCE (model) &&
+      gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (model),
+                                          source_row,
+                                          selection_data))
+    return;
+
+  /* If drag_data_get does nothing, try providing row data. */
+  if (selection_data->target == gdk_atom_intern ("GTK_TREE_MODEL_ROW", FALSE))
+    {
       gtk_selection_data_set_tree_row (selection_data,
-                                       GTK_TREE_VIEW (widget),
-                                       di->source_row);
+                                       model,
+                                       source_row);
+    }
+}
+
+
+static gboolean
+check_model_dnd (GtkTreeModel *model,
+                 GType         required_iface,
+                 const gchar  *signal)
+{
+  if (model == NULL || !G_TYPE_CHECK_INSTANCE_TYPE ((model), required_iface))
+    {
+      g_warning ("You must override the default '%s' handler "
+                 "on GtkTreeView when using models that don't support "
+                 "the %s interface. The simplest way to do this "
+                 "is to connect to '%s' and call "
+                 "gtk_signal_emit_stop_by_name() in your signal handler to prevent "
+                 "the default handler from running. Look at the source code "
+                 "for the default handler in gtktreeview.c to get an idea what "
+                 "your handler should do. (gtktreeview.c is in the GTK source "
+                 "code.)",
+                 signal, g_type_name (required_iface), signal);
+      return FALSE;
     }
+  else
+    return TRUE;
 }
 
 static void
 gtk_tree_view_drag_data_delete (GtkWidget      *widget,
                                 GdkDragContext *context)
 {
-  /* FIXME we need to delete the source_row if we're doing automagical
-   * reordering stuff.
-   */
-}
+  TreeViewDragInfo *di;
+  GtkTreeModel *model;
+  GtkTreeView *tree_view;
+  GtkTreePath *source_row;
+  
+  tree_view = GTK_TREE_VIEW (widget);
+  model = gtk_tree_view_get_model (tree_view);
+
+  if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag_data_delete"))
+    return;
+  
+  di = get_info (tree_view);
 
+  if (di == NULL)
+    return;
+
+  source_row = get_source_row (context);
+  
+
+  gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (model),
+                                         source_row);
+      
+  set_source_row (context, NULL);
+}
 
 static void
 remove_open_timeout (GtkTreeView *tree_view)
@@ -5051,6 +5362,7 @@ gtk_tree_view_drag_leave (GtkWidget      *widget,
   di = get_info (GTK_TREE_VIEW (widget));
   
   /* unset any highlight row */
+  g_print ("drag leave\n");
   gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                    NULL,
                                    GTK_TREE_VIEW_DROP_BEFORE);
@@ -5078,21 +5390,24 @@ open_row_timeout (gpointer data)
     return TRUE;
 }
 
+/* Returns TRUE if event should not be propagated to parent widgets */
 static gboolean
-gtk_tree_view_drag_motion (GtkWidget        *widget,
-                           GdkDragContext   *context,
-                           gint              x,
-                           gint              y,
-                           guint             time)
+set_destination_row (GtkTreeView    *tree_view,
+                     GdkDragContext *context,
+                     gint            x,
+                     gint            y,
+                     GdkDragAction  *suggested_action)
 {
   GtkTreePath *path = NULL;
-  TreeViewDragInfo *di;
   GtkTreeViewDropPosition pos;
-  GtkTreeView *tree_view;
+  TreeViewDragInfo *di;
+  GtkWidget *widget;
 
-  tree_view = GTK_TREE_VIEW (widget);
+  *suggested_action = 0;
   
-  di = get_info (GTK_TREE_VIEW (widget));  
+  widget = GTK_WIDGET (tree_view);
+  
+  di = get_info (tree_view);
   
   if (di == NULL)
     {
@@ -5100,6 +5415,7 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
        * we return FALSE drag_leave isn't called
        */
 
+      g_print ("no longer a drag dest\n");
       gtk_tree_view_set_drag_dest_row (tree_view,
                                        NULL,
                                        GTK_TREE_VIEW_DROP_BEFORE);
@@ -5110,7 +5426,12 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
       return FALSE; /* no longer a drop site */
     }
 
-  ensure_scroll_timeout (tree_view);
+  /* We don't take this target */
+  if (gtk_drag_dest_find_target (widget, context, di->dest_target_list) == GDK_NONE)
+    {
+      g_print ("bad target, not accepting\n");
+      return FALSE;
+    }
   
   if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
                                           x, y,
@@ -5119,9 +5440,8 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
     {
       /* can't drop here */
       remove_open_timeout (tree_view);
-      
-      gdk_drag_status (context, 0, time);
 
+      g_print ("no drag row here\n");
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                        NULL,
                                        GTK_TREE_VIEW_DROP_BEFORE);
@@ -5141,13 +5461,11 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
          pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)))
     remove_open_timeout (tree_view);
   
-  if (TRUE /* FIXME if the location droppable predicate */ &&
-      gtk_drag_dest_find_target (widget, context, di->dest_target_list) != GDK_NONE)
+  if (TRUE /* FIXME if the location droppable predicate */)
     {
       GtkWidget *source_widget;
-      GdkDragAction suggested_action;
       
-      suggested_action = context->suggested_action;
+      *suggested_action = context->suggested_action;
       
       source_widget = gtk_drag_get_source_widget (context);
       
@@ -5157,34 +5475,73 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
            * pressed ctrl or alt to affect available actions
            */
           if ((context->actions & GDK_ACTION_MOVE) != 0)
-            suggested_action = GDK_ACTION_MOVE;
+            *suggested_action = GDK_ACTION_MOVE;
         }
-      
+
+      g_print ("setting drag dest row\n");
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                        path, pos);
-
-      if (tree_view->priv->open_dest_timeout == 0)
-        {
-          tree_view->priv->open_dest_timeout =
-            gtk_timeout_add (250, open_row_timeout, tree_view);      
-        }
-      
-      gdk_drag_status (context, suggested_action, time);
     }
   else
     {
       /* can't drop here */
       remove_open_timeout (tree_view);
       
-      gdk_drag_status (context, 0, time);
-
+      g_print ("droppable predicate false\n");
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                        NULL,
                                        GTK_TREE_VIEW_DROP_BEFORE);
     }
 
-  gtk_tree_path_free (path);
+  return TRUE;
+}
+
+static gboolean
+gtk_tree_view_drag_motion (GtkWidget        *widget,
+                           GdkDragContext   *context,
+                           gint              x,
+                           gint              y,
+                           guint             time)
+{
+  GtkTreePath *path = NULL;
+  GtkTreeViewDropPosition pos;
+  GtkTreeView *tree_view;
+  GdkDragAction suggested_action = 0;
+  
+  tree_view = GTK_TREE_VIEW (widget);
+  
+  g_print ("motion\n");
+
+  if (!set_destination_row (tree_view, context, x, y, &suggested_action))
+    return FALSE;
+
+  ensure_scroll_timeout (tree_view);
   
+  gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos);
+
+  if (path == NULL)
+    {
+      /* Can't drop here. */
+      g_print ("not over a dest row\n");
+      gdk_drag_status (context, 0, time);
+    }
+  else
+    {
+      if (tree_view->priv->open_dest_timeout == 0 &&
+          (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ||
+           pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE))
+        {
+          tree_view->priv->open_dest_timeout =
+            gtk_timeout_add (250, open_row_timeout, tree_view);      
+        }
+
+      g_print ("status\n");
+      gdk_drag_status (context, suggested_action, time);
+    }
+
+  if (path)
+    gtk_tree_path_free (path);
+
   return TRUE;
 }
 
@@ -5195,22 +5552,59 @@ gtk_tree_view_drag_drop (GtkWidget        *widget,
                          gint              y,
                          guint             time)
 {
+  GtkTreePath *path = NULL;
+  GtkTreeViewDropPosition pos;
+  GtkTreeView *tree_view;
+  GdkDragAction suggested_action = 0;
   GdkAtom target = GDK_NONE;
   TreeViewDragInfo *di;
-  GtkTreeView *tree_view;
-
+  GtkTreeModel *model;
+  
   tree_view = GTK_TREE_VIEW (widget);
 
+  model = gtk_tree_view_get_model (tree_view);
+  
+  g_print ("drop\n");
+  
   remove_scroll_timeout (GTK_TREE_VIEW (widget));
   remove_open_timeout (GTK_TREE_VIEW (widget));
-  
+
   di = get_info (tree_view);
 
-  if (di && tree_view->priv->drag_dest_row && di->dest_target_list)
-    target = gtk_drag_dest_find_target (widget, context, di->dest_target_list);
+  if (di == NULL)
+    return FALSE;
+  
+  if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_drop"))
+    return FALSE;
+  
+  if (!set_destination_row (tree_view, context, x, y, &suggested_action))
+    return FALSE;
 
+  gtk_tree_view_get_drag_dest_row (tree_view, &path, &pos);
+
+  if (path != NULL && di->dest_target_list)
+    {
+      target = gtk_drag_dest_find_target (widget, context, di->dest_target_list);
+      
+      if (target != GDK_NONE)
+        {
+          g_print ("have target\n");
+
+          set_dest_row (context, path);
+        }
+    }
+
+  if (path)
+    gtk_tree_path_free (path);
+  
+  /* Unset this thing */
+  gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
+                                   NULL,
+                                   GTK_TREE_VIEW_DROP_BEFORE);
+  
   if (target != GDK_NONE)
     {
+      g_print ("getting data\n");
       gtk_drag_get_data (widget, context, target, time);
       return TRUE;
     }
@@ -5226,21 +5620,48 @@ gtk_tree_view_drag_data_received (GtkWidget        *widget,
                                   GtkSelectionData *selection_data,
                                   guint             info,
                                   guint             time)
-{  
+{
+  TreeViewDragInfo *di;
+  gboolean accepted = FALSE;
+  GtkTreeModel *model;
+  GtkTreeView *tree_view;
+  GtkTreePath *dest_row;
+  
+  tree_view = GTK_TREE_VIEW (widget);
+
+  model = gtk_tree_view_get_model (tree_view);
+
+  if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_DEST, "drag_data_received"))
+    return;  
+
+  g_print ("drag data received\n");
+  
+  di = get_info (tree_view);
+
+  if (di == NULL)
+    return;
+
+  dest_row = get_dest_row (context);
+
+  if (dest_row == NULL)
+    return;
+  
   if (selection_data->length >= 0)
     {
-      /* FIXME respond to contents of selection_data */
-
+      if (gtk_tree_drag_dest_drag_data_received (GTK_TREE_DRAG_DEST (model),
+                                                 dest_row,
+                                                 selection_data))
+        accepted = TRUE;
+      
+      
+      /* Don't clear drop_row, we may need it in drag_data_delete */
     }
-
-  gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
-                                   NULL,
-                                   GTK_TREE_VIEW_DROP_BEFORE);
   
   gtk_drag_finish (context, 
-                   (selection_data->length >= 0),
+                   accepted,
                    (context->action == GDK_ACTION_MOVE),
-                   time);  
+                   time);
+  g_print ("accepted: %d\n", accepted);
 }
 
 
index d15109eff2f50ec80ea876dcd3f77a05edff0657..22890ae66ae53dcf6eee491d7e20a1c61c244c99 100644 (file)
@@ -125,7 +125,11 @@ gboolean               gtk_tree_view_get_path_at_pos     (GtkTreeView        *tr
                                                          GtkTreeViewColumn **column,
                                                           gint               *cell_x,
                                                           gint               *cell_y);
-void                   gtk_tree_view_get_cell_rect       (GtkTreeView        *tree_view,
+void                   gtk_tree_view_get_cell_area       (GtkTreeView        *tree_view,
+                                                          GtkTreePath        *path,
+                                                          GtkTreeViewColumn  *column,
+                                                          GdkRectangle       *rect);
+void                   gtk_tree_view_get_background_area (GtkTreeView        *tree_view,
                                                           GtkTreePath        *path,
                                                           GtkTreeViewColumn  *column,
                                                           GdkRectangle       *rect);
@@ -190,6 +194,9 @@ void     gtk_tree_view_unset_rows_drag_dest   (GtkTreeView *tree_view);
 void       gtk_tree_view_set_drag_dest_row    (GtkTreeView              *tree_view,
                                                GtkTreePath              *path,
                                                GtkTreeViewDropPosition   pos);
+void       gtk_tree_view_get_drag_dest_row   (GtkTreeView              *tree_view,
+                                              GtkTreePath             **path,
+                                              GtkTreeViewDropPosition  *pos);
 gboolean   gtk_tree_view_get_dest_row_at_pos  (GtkTreeView              *tree_view,
                                                gint                      drag_x,
                                                gint                      drag_y,
@@ -198,16 +205,6 @@ gboolean   gtk_tree_view_get_dest_row_at_pos  (GtkTreeView              *tree_vi
 GdkPixmap* gtk_tree_view_create_row_drag_icon (GtkTreeView              *tree_view,
                                                GtkTreePath              *path);
 
-/* The selection data would normally have target type GTK_TREE_VIEW_ROW in this
- * case. If the target is wrong these functions return FALSE.
- */
-gboolean gtk_selection_data_set_tree_row     (GtkSelectionData         *selection_data,
-                                              GtkTreeView              *tree_view,
-                                              GtkTreePath              *path);
-gboolean gtk_selection_data_get_tree_row     (GtkSelectionData         *selection_data,
-                                              GtkTreeView             **tree_view,
-                                              GtkTreePath             **path);
-
 
 
 #ifdef __cplusplus
index 140bbb6a7e97e06591be72768dea7085d6f16ccb..1d7dab0eee279e0defbb16242558359675b7f9c7 100644 (file)
@@ -212,6 +212,10 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
 static void
 gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
 {
+  /* FIXME remove on port to GtkObject */
+  gtk_object_ref (GTK_OBJECT (tree_column));
+  gtk_object_sink (GTK_OBJECT (tree_column));
+  
   tree_column->button = NULL;
   tree_column->justification = GTK_JUSTIFY_LEFT;
   tree_column->width = 1;
@@ -919,17 +923,18 @@ update_button_contents (GtkTreeViewColumn *tree_column)
 {
   if (tree_column->button)
     {
-      GtkWidget *current_child = GTK_BIN (GTK_BIN (tree_column->button)->child)->child;
+      GtkWidget *alignment = GTK_BIN (tree_column->button)->child;
+      GtkWidget *current_child = GTK_BIN (alignment)->child;
       
       if (tree_column->child)
         {
           if (current_child != tree_column->child)
             {
-              gtk_container_remove (GTK_CONTAINER (tree_column->button),
+              gtk_container_remove (GTK_CONTAINER (alignment),
                                     current_child);
 
-              gtk_container_add (GTK_CONTAINER (tree_column->button),
-                                                tree_column->child);
+              gtk_container_add (GTK_CONTAINER (alignment),
+                                 tree_column->child);
             }
         }
       else 
@@ -940,7 +945,7 @@ update_button_contents (GtkTreeViewColumn *tree_column)
 
               gtk_widget_show (current_child);
               
-              gtk_container_add (GTK_CONTAINER (tree_column->button),
+              gtk_container_add (GTK_CONTAINER (alignment),
                                  current_child);
             }
 
index 534c93736fab318dac955c9632a43777a9611108..acdaa65ed977ebbc1b9cab24eb223cf37563eb85 100644 (file)
@@ -2002,6 +2002,34 @@ create_get_image (void)
 /* 
  * Label Demo
  */
+static void
+sensitivity_toggled (GtkWidget *toggle,
+                     GtkWidget *widget)
+{
+  gtk_widget_set_sensitive (widget,  GTK_TOGGLE_BUTTON (toggle)->active);  
+}
+
+static GtkWidget*
+create_sensitivity_control (GtkWidget *widget)
+{
+  GtkWidget *button;
+  GtkWidget *toplevel;
+
+  button = gtk_toggle_button_new_with_label ("Sensitive");  
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+                                GTK_WIDGET_IS_SENSITIVE (widget));
+  
+  gtk_signal_connect (GTK_OBJECT (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (sensitivity_toggled),
+                      widget);
+  
+  gtk_widget_show_all (button);
+
+  return button;
+}
+
 void create_labels (void)
 {
   static GtkWidget *window = NULL;
@@ -2009,7 +2037,8 @@ void create_labels (void)
   GtkWidget *vbox;
   GtkWidget *frame;
   GtkWidget *label;
-
+  GtkWidget *button;
+  
   if (!window)
     {
       guint keyval;
@@ -2020,9 +2049,20 @@ void create_labels (void)
                          &window);
 
       gtk_window_set_title (GTK_WINDOW (window), "Label");
+
       vbox = gtk_vbox_new (FALSE, 5);
+      
       hbox = gtk_hbox_new (FALSE, 5);
-      gtk_container_add (GTK_CONTAINER (window), hbox);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+      button = create_sensitivity_control (hbox);
+
+      gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+      
+      vbox = gtk_vbox_new (FALSE, 5);
+      
       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
 
@@ -2127,8 +2167,8 @@ void create_labels (void)
       
       gtk_container_add (GTK_CONTAINER (frame), label);
       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
-      
     }
+  
   if (!GTK_WIDGET_VISIBLE (window))
     gtk_widget_show_all (window);
   else
@@ -3274,6 +3314,14 @@ create_scrolled_windows (void)
  * GtkEntry
  */
 
+static void
+entry_toggle_frame (GtkWidget *checkbutton,
+                    GtkWidget *entry)
+{
+   gtk_entry_set_has_frame (GTK_ENTRY(entry),
+                            GTK_TOGGLE_BUTTON(checkbutton)->active);
+}
+
 static void
 entry_toggle_editable (GtkWidget *checkbutton,
                       GtkWidget *entry)
@@ -3394,6 +3442,13 @@ create_entry (void)
       gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled",
                          GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry);
       gtk_widget_show (invisible_char_check);
+
+      editable_check = gtk_check_button_new_with_label("Has Frame");
+      gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
+      gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
+                         GTK_SIGNAL_FUNC(entry_toggle_frame), entry);
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE);
+      gtk_widget_show (editable_check);
       
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
index 534c93736fab318dac955c9632a43777a9611108..acdaa65ed977ebbc1b9cab24eb223cf37563eb85 100644 (file)
@@ -2002,6 +2002,34 @@ create_get_image (void)
 /* 
  * Label Demo
  */
+static void
+sensitivity_toggled (GtkWidget *toggle,
+                     GtkWidget *widget)
+{
+  gtk_widget_set_sensitive (widget,  GTK_TOGGLE_BUTTON (toggle)->active);  
+}
+
+static GtkWidget*
+create_sensitivity_control (GtkWidget *widget)
+{
+  GtkWidget *button;
+  GtkWidget *toplevel;
+
+  button = gtk_toggle_button_new_with_label ("Sensitive");  
+
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+                                GTK_WIDGET_IS_SENSITIVE (widget));
+  
+  gtk_signal_connect (GTK_OBJECT (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (sensitivity_toggled),
+                      widget);
+  
+  gtk_widget_show_all (button);
+
+  return button;
+}
+
 void create_labels (void)
 {
   static GtkWidget *window = NULL;
@@ -2009,7 +2037,8 @@ void create_labels (void)
   GtkWidget *vbox;
   GtkWidget *frame;
   GtkWidget *label;
-
+  GtkWidget *button;
+  
   if (!window)
     {
       guint keyval;
@@ -2020,9 +2049,20 @@ void create_labels (void)
                          &window);
 
       gtk_window_set_title (GTK_WINDOW (window), "Label");
+
       vbox = gtk_vbox_new (FALSE, 5);
+      
       hbox = gtk_hbox_new (FALSE, 5);
-      gtk_container_add (GTK_CONTAINER (window), hbox);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+      button = create_sensitivity_control (hbox);
+
+      gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+      
+      vbox = gtk_vbox_new (FALSE, 5);
+      
       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
 
@@ -2127,8 +2167,8 @@ void create_labels (void)
       
       gtk_container_add (GTK_CONTAINER (frame), label);
       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
-      
     }
+  
   if (!GTK_WIDGET_VISIBLE (window))
     gtk_widget_show_all (window);
   else
@@ -3274,6 +3314,14 @@ create_scrolled_windows (void)
  * GtkEntry
  */
 
+static void
+entry_toggle_frame (GtkWidget *checkbutton,
+                    GtkWidget *entry)
+{
+   gtk_entry_set_has_frame (GTK_ENTRY(entry),
+                            GTK_TOGGLE_BUTTON(checkbutton)->active);
+}
+
 static void
 entry_toggle_editable (GtkWidget *checkbutton,
                       GtkWidget *entry)
@@ -3394,6 +3442,13 @@ create_entry (void)
       gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled",
                          GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry);
       gtk_widget_show (invisible_char_check);
+
+      editable_check = gtk_check_button_new_with_label("Has Frame");
+      gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
+      gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
+                         GTK_SIGNAL_FUNC(entry_toggle_frame), entry);
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE);
+      gtk_widget_show (editable_check);
       
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
index 6181114d0465db8e4b9511862d322aafc0ff35e6..5ffcecb2553e93694e39c760935ce0f8e5717908 100644 (file)
@@ -314,11 +314,11 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type)
 
       image = gtk_image_new_from_pixbuf (pixbuf);
 
+      g_object_unref (G_OBJECT (pixbuf));
+      
       gtk_widget_show (image);
       
       gtk_tree_view_column_set_widget (col, image);
-
-      g_object_unref (G_OBJECT (pixbuf));
       
       g_object_unref (G_OBJECT (rend));
       g_object_unref (G_OBJECT (col));
@@ -346,6 +346,98 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type)
       g_object_unref (G_OBJECT (rend));
       g_object_unref (G_OBJECT (col));
 
+#if 0
+
+      rend = gtk_cell_renderer_text_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 5",
+                                                      rend,
+                                                      "text", 3,
+                                                      NULL);
+
+      setup_column (col);
+      
+      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_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 6",
+                                                      rend,
+                                                      "text", 4,
+                                                      NULL);
+
+      setup_column (col);
+      
+      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_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 7",
+                                                      rend,
+                                                      "text", 5,
+                                                      NULL);
+
+      setup_column (col);
+      
+      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_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 8",
+                                                      rend,
+                                                      "text", 6,
+                                                      NULL);
+
+      setup_column (col);
+      
+      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_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 9",
+                                                      rend,
+                                                      "text", 7,
+                                                      NULL);
+
+      setup_column (col);
+      
+      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_new ();
+      
+      col = gtk_tree_view_column_new_with_attributes ("Column 10",
+                                                      rend,
+                                                      "text", 8,
+                                                      NULL);
+
+      setup_column (col);
+      
+      gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), col);
+      
+      g_object_unref (G_OBJECT (rend));
+      g_object_unref (G_OBJECT (col));
+
+#endif
+      
       gtk_tree_view_set_expander_column (tree_view, 1);
       
       /* FALL THRU */
@@ -544,12 +636,12 @@ columns_selected (GtkOptionMenu *om, gpointer data)
 
 enum
 {
-  TARGET_GTK_TREE_VIEW_ROW
+  TARGET_GTK_TREE_MODEL_ROW
 };
 
 static GtkTargetEntry row_targets[] = {
-  { "GTK_TREE_VIEW_ROW", GTK_TARGET_SAME_APP,
-    TARGET_GTK_TREE_VIEW_ROW }
+  { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP,
+    TARGET_GTK_TREE_MODEL_ROW }
 };
 
 int