]> Pileus Git - ~andy/gtk/commitdiff
remove validation idle
authorHavoc Pennington <hp@redhat.com>
Thu, 8 Feb 2001 23:36:53 +0000 (23:36 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Thu, 8 Feb 2001 23:36:53 +0000 (23:36 +0000)
2001-02-08  Havoc Pennington  <hp@redhat.com>

* gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
validation idle

* demos/gtk-demo/main.c (create_tree): adjust to changes in text
cell renderer

* demos/pixbuf-demo.c (timeout): remove deprecated
gtk_widget_draw

* demos/testpixbuf-save.c (main): remove deprecated
gtk_drawing_area_size

* gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
buttons even if the model isn't setup. gtk_tree_view_check_dirty()
at the start of the allocation.
(gtk_tree_view_check_dirty): handle column->button == NULL, handle
unsetup or NULL model.

* gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the
even/odd/sorted cells in the tree view.

* gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
bugfixes

* gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
backgrounds with draw_flat_box using different detail for even/odd
rows.

* gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
row, so we can draw the alternating colors thing

* gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
property from a synonym property, notify for the synonym.
Also, nuke the background_gdk_set and foreground_gdk_set synonyms
(gtk_text_tag_get_property): Always return the font, even if
all its fields aren't set

* gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
store the attr list; it leaves us with no way to change attributes
in _render according to the render flags, and no way to implement
get_property. Instead store all the specific text attributes.
Separate whether an attribute is enabled from its value. Sync all
properties with GtkTextTag, make them all consistent, etc.

* gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
renderers can highlight the sort row/column

* gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
accessor functions to get values; this has the side effect of
showing up which accessor functions were missing. Added those.

* gtk/gtktreeviewcolumn.h: Replace set_justification with
set_alignment, to be consistent with GtkLabel, GtkMisc

* gtk/gtktreeviewcolumn.c: Added code to display sort indicator
arrow.

* gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h

* gtk/gtktreesortable.h: updates in here

30 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
demos/gtk-demo/main.c
demos/pixbuf-demo.c
demos/testpixbuf-save.c
gtk/Makefile.am
gtk/gtkcellrenderer.h
gtk/gtkcellrenderertext.c
gtk/gtkcellrenderertext.h
gtk/gtkliststore.c
gtk/gtkrbtree.c
gtk/gtkrbtree.h
gtk/gtkstyle.c
gtk/gtktexttag.c
gtk/gtktextview.c
gtk/gtktreemodelsort.c
gtk/gtktreeprivate.h
gtk/gtktreeselection.c
gtk/gtktreesortable.h
gtk/gtktreestore.c
gtk/gtktreeview.c
gtk/gtktreeview.h
gtk/gtktreeviewcolumn.c
gtk/gtktreeviewcolumn.h
tests/testtreeview.c

index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3b88af8b9bf21dc613c620da2bdd03855c0da7ec..7404d8f92588c99d95b5ff762e1c92938e8f82dc 100644 (file)
@@ -1,3 +1,66 @@
+2001-02-08  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_destroy_layout): remove
+       validation idle
+
+       * demos/gtk-demo/main.c (create_tree): adjust to changes in text
+       cell renderer
+
+       * demos/pixbuf-demo.c (timeout): remove deprecated
+       gtk_widget_draw
+
+       * demos/testpixbuf-save.c (main): remove deprecated
+       gtk_drawing_area_size
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_allocate): allocate
+       buttons even if the model isn't setup. gtk_tree_view_check_dirty()
+       at the start of the allocation.
+       (gtk_tree_view_check_dirty): handle column->button == NULL, handle
+       unsetup or NULL model.
+
+       * gtk/gtkstyle.c (gtk_default_draw_flat_box): drawing for the 
+       even/odd/sorted cells in the tree view.
+
+       * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all):
+       bugfixes
+
+       * gtk/gtktreeview.c: assorted bugfixy stuff. Draw the row
+       backgrounds with draw_flat_box using different detail for even/odd
+       rows.
+
+       * gtk/gtkrbtree.c, gtkrbtree.h: Keep track of the parity of each
+       row, so we can draw the alternating colors thing
+
+       * gtk/gtktexttag.c (gtk_text_tag_set_property): if we change a
+       property from a synonym property, notify for the synonym.
+       Also, nuke the background_gdk_set and foreground_gdk_set synonyms
+       (gtk_text_tag_get_property): Always return the font, even if
+       all its fields aren't set
+
+       * gtk/gtkcellrenderertext.h (struct _GtkCellRendererText): don't
+       store the attr list; it leaves us with no way to change attributes
+       in _render according to the render flags, and no way to implement
+       get_property. Instead store all the specific text attributes. 
+       Separate whether an attribute is enabled from its value. Sync all
+       properties with GtkTextTag, make them all consistent, etc.
+
+       * gtk/gtkcellrenderer.h: Add a flag GTK_CELL_RENDERER_SORTED so
+       renderers can highlight the sort row/column     
+
+       * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_get_property): use
+       accessor functions to get values; this has the side effect of
+       showing up which accessor functions were missing. Added those.
+
+       * gtk/gtktreeviewcolumn.h: Replace set_justification with
+       set_alignment, to be consistent with GtkLabel, GtkMisc
+
+       * gtk/gtktreeviewcolumn.c: Added code to display sort indicator
+       arrow.
+
+       * gtk/Makefile.am (gtk_public_h_sources): add gtktreesortable.h
+
+       * gtk/gtktreesortable.h: updates in here
+
 2001-02-07  Sven Neumann  <sven@convergence.de>
 
        * gtk/gtkentry.c (gtk_entry_draw_text): convert area_height to 
index 3d545d70f581644d5c696c1d51394edcb8a3f11a..e03ad041a033c3689dfddfaa15945f15c7f50b4d 100644 (file)
@@ -380,11 +380,17 @@ create_tree (void)
     }
 
   cell = gtk_cell_renderer_text_new ();
+
+  g_object_set (G_OBJECT (cell),
+                "style", PANGO_STYLE_ITALIC,
+                NULL);
+  
   column = gtk_tree_view_column_new_with_attributes ("Widget (double click for demo)",
                                                     cell,
                                                     "text", TITLE_COLUMN,
-                                                    "italic", ITALIC_COLUMN,
+                                                    "style_set", ITALIC_COLUMN,
                                                     NULL);
+  
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
                               GTK_TREE_VIEW_COLUMN (column));
 
index ae9a0998e206942d6c5ac8dc8ed5ff2a67f7840c..0ee8aca460a041d5b7e2a22f716a1db8e348c454 100644 (file)
@@ -175,7 +175,7 @@ timeout (gpointer data)
                                               : MAX (127, fabs (255 * cos (f * 2.0 * M_PI)))));
        }
 
-       gtk_widget_draw (da, NULL);
+       gtk_widget_queue_draw (da);
 
        frame_num++;
        return TRUE;
index 802f984946d846e63bd24d8b9a279725e61cab43..a97fd95858bb1ca3ac480e7e7125cf4f56d9e260 100644 (file)
@@ -135,9 +135,9 @@ main (int argc, char **argv)
         gtk_container_add (GTK_CONTAINER (window), vbox);  
    
         drawing_area = gtk_drawing_area_new ();
-        gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area),
-                               gdk_pixbuf_get_width (pixbuf),
-                               gdk_pixbuf_get_height (pixbuf));
+        gtk_widget_set_usize (GTK_WIDGET (drawing_area),
+                              gdk_pixbuf_get_width (pixbuf),
+                              gdk_pixbuf_get_height (pixbuf));
         gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
                             GTK_SIGNAL_FUNC (expose_cb), NULL);
 
index 230f78445dbf47b62aa4a9bfa813de67990b0ad8..92b76f99aa3ce84f4abe6128cdfee27734a887a3 100644 (file)
@@ -175,6 +175,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
        gtktreemodelsimple.h    \
        gtktreemodelsort.h      \
        gtktreeselection.h      \
+       gtktreesortable.h       \
        gtktreestore.h          \
        gtktreeview.h           \
        gtktreeviewcolumn.h     \
index bf1855395720b51d51f7f21698d23ec1bc8d9e5d..27694571d37b124eaa3d5fb63a016f43011f90cc 100644 (file)
@@ -32,7 +32,9 @@ typedef enum
 {
   GTK_CELL_RENDERER_SELECTED    = 1 << 0,
   GTK_CELL_RENDERER_PRELIT      = 1 << 1,
-  GTK_CELL_RENDERER_INSENSITIVE = 1 << 2
+  GTK_CELL_RENDERER_INSENSITIVE = 1 << 2,
+  /* this flag means the cell is in the sort column/row */
+  GTK_CELL_RENDERER_SORTED      = 1 << 3
 } GtkCellRendererState;
 
 #define GTK_TYPE_CELL_RENDERER           (gtk_cell_renderer_get_type ())
index 751659fc5ca6b5f187197c20122d2753261c977a..7ad67797cb3c688f2aeec67c2749297978919d6e 100644 (file)
@@ -23,6 +23,7 @@
 
 static void gtk_cell_renderer_text_init       (GtkCellRendererText      *celltext);
 static void gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class);
+static void gtk_cell_renderer_text_finalize   (GObject                  *object);
 
 static void gtk_cell_renderer_text_get_property  (GObject                  *object,
                                                  guint                     param_id,
@@ -47,21 +48,48 @@ static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
                                               guint                     flags);
 
 
+
 enum {
-  PROP_ZERO,
+  PROP_0,
+
   PROP_TEXT,
-  PROP_FONT,
+  
+  /* Style args */
   PROP_BACKGROUND,
-  PROP_BACKGROUND_GDK,
   PROP_FOREGROUND,
+  PROP_BACKGROUND_GDK,
   PROP_FOREGROUND_GDK,
+  PROP_FONT,
+  PROP_FONT_DESC,
+  PROP_FAMILY,
+  PROP_STYLE,
+  PROP_VARIANT,
+  PROP_WEIGHT,
+  PROP_STRETCH,
+  PROP_SIZE,
+  PROP_SIZE_POINTS,
+  PROP_EDITABLE,
   PROP_STRIKETHROUGH,
   PROP_UNDERLINE,
-  PROP_EDITABLE,
-  PROP_ITALIC,
-  PROP_BOLD
+  PROP_RISE,
+  
+  /* Whether-a-style-arg-is-set args */
+  PROP_BACKGROUND_SET,
+  PROP_FOREGROUND_SET,
+  PROP_FAMILY_SET,
+  PROP_STYLE_SET,
+  PROP_VARIANT_SET,
+  PROP_WEIGHT_SET,
+  PROP_STRETCH_SET,
+  PROP_SIZE_SET,
+  PROP_EDITABLE_SET,
+  PROP_STRIKETHROUGH_SET,
+  PROP_UNDERLINE_SET,
+  PROP_RISE_SET
 };
 
+static gpointer parent_class;
+
 GtkType
 gtk_cell_renderer_text_get_type (void)
 {
@@ -91,12 +119,10 @@ gtk_cell_renderer_text_get_type (void)
 static void
 gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
 {
-  celltext->attr_list = pango_attr_list_new ();
   GTK_CELL_RENDERER (celltext)->xalign = 0.0;
   GTK_CELL_RENDERER (celltext)->yalign = 0.5;
   GTK_CELL_RENDERER (celltext)->xpad = 2;
   GTK_CELL_RENDERER (celltext)->ypad = 2;
-  celltext->underline = FALSE;
 }
 
 static void
@@ -105,87 +131,241 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
   GObjectClass *object_class = G_OBJECT_CLASS (class);
   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
 
+  parent_class = g_type_class_peek_parent (class);
+  
+  object_class->finalize = gtk_cell_renderer_text_finalize;
+  
   object_class->get_property = gtk_cell_renderer_text_get_property;
   object_class->set_property = gtk_cell_renderer_text_set_property;
 
   cell_class->get_size = gtk_cell_renderer_text_get_size;
   cell_class->render = gtk_cell_renderer_text_render;
-  
+
   g_object_class_install_property (object_class,
-                                  PROP_TEXT,
-                                  g_param_spec_string ("text",
-                                                       _("Text String"),
-                                                       _("The text of the renderer."),
-                                                       "",
-                                                       G_PARAM_READABLE |
-                                                       G_PARAM_WRITABLE));
+                                   PROP_TEXT,
+                                   g_param_spec_string ("text",
+                                                        _("Text"),
+                                                        _("Text to render"),
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
   
   g_object_class_install_property (object_class,
-                                  PROP_FONT,
-                                  g_param_spec_string ("font",
-                                                       _("Font String"),
-                                                       _("The string of the font."),
-                                                       "",
-                                                       G_PARAM_WRITABLE));
-  
+                                   PROP_BACKGROUND,
+                                   g_param_spec_string ("background",
+                                                        _("Background color name"),
+                                                        _("Background color as a string"),
+                                                        NULL,
+                                                        G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_BACKGROUND_GDK,
+                                   g_param_spec_boxed ("background_gdk",
+                                                       _("Background color"),
+                                                       _("Background color as a GdkColor"),
+                                                       GTK_TYPE_GDK_COLOR,
+                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));  
+
+  g_object_class_install_property (object_class,
+                                   PROP_FOREGROUND,
+                                   g_param_spec_string ("foreground",
+                                                        _("Foreground color name"),
+                                                        _("Foreground color as a string"),
+                                                        NULL,
+                                                        G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_FOREGROUND_GDK,
+                                   g_param_spec_boxed ("foreground_gdk",
+                                                       _("Foreground color"),
+                                                       _("Foreground color as a GdkColor"),
+                                                       GTK_TYPE_GDK_COLOR,
+                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+
+  g_object_class_install_property (object_class,
+                                   PROP_EDITABLE,
+                                   g_param_spec_boolean ("editable",
+                                                         _("Editable"),
+                                                         _("Whether the text can be modified by the user"),
+                                                         TRUE,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_FONT,
+                                   g_param_spec_string ("font",
+                                                        _("Font"),
+                                                        _("Font description as a string"),
+                                                        NULL,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+
   g_object_class_install_property (object_class,
-                                  PROP_BACKGROUND,
-                                  g_param_spec_string ("background",
-                                                       _("Background Color string"),
-                                                       _("The color for the background of the text."),
-                                                       "white",
-                                                       G_PARAM_WRITABLE));
+                                   PROP_FONT_DESC,
+                                   g_param_spec_boxed ("font_desc",
+                                                       _("Font"),
+                                                       _("Font description as a PangoFontDescription struct"),
+                                                       GTK_TYPE_PANGO_FONT_DESCRIPTION,
+                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
+
   
   g_object_class_install_property (object_class,
-                                  PROP_FOREGROUND,
-                                  g_param_spec_string ("foreground",
-                                                       _("Foreground Color string"),
-                                                       _("The color for the background of the text."),
-                                                       "black",
-                                                       G_PARAM_WRITABLE));
+                                   PROP_FAMILY,
+                                   g_param_spec_string ("family",
+                                                        _("Font family"),
+                                                        _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
+                                                        NULL,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_STYLE,
+                                   g_param_spec_enum ("style",
+                                                      _("Font style"),
+                                                      _("Font style"),
+                                                      PANGO_TYPE_STYLE,
+                                                      PANGO_STYLE_NORMAL,
+                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_VARIANT,
+                                   g_param_spec_enum ("variant",
+                                                     _("Font variant"),
+                                                     _("Font variant"),
+                                                      PANGO_TYPE_VARIANT,
+                                                      PANGO_VARIANT_NORMAL,
+                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
   
   g_object_class_install_property (object_class,
-                                  PROP_STRIKETHROUGH,
-                                  g_param_spec_boolean ("strikethrough",
-                                                        _("Strikethrough"),
-                                                        _("Draw a line through the text."),
-                                                        FALSE,
-                                                        G_PARAM_READABLE |
-                                                        G_PARAM_WRITABLE));
+                                   PROP_WEIGHT,
+                                   g_param_spec_int ("weight",
+                                                     _("Font weight"),
+                                                     _("Font weight"),
+                                                     0,
+                                                     G_MAXINT,
+                                                     PANGO_WEIGHT_NORMAL,
+                                                     G_PARAM_READABLE | G_PARAM_WRITABLE));
   
+
   g_object_class_install_property (object_class,
-                                  PROP_UNDERLINE,
-                                  g_param_spec_boolean ("underline",
-                                                        _("Underline"),
-                                                        _("Underline the text."),
-                                                        FALSE,
-                                                        G_PARAM_READABLE |
-                                                        G_PARAM_WRITABLE));
+                                   PROP_STRETCH,
+                                   g_param_spec_enum ("stretch",
+                                                      _("Font stretch"),
+                                                      _("Font stretch"),
+                                                      PANGO_TYPE_STRETCH,
+                                                      PANGO_STRETCH_NORMAL,
+                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
   
   g_object_class_install_property (object_class,
-                                  PROP_EDITABLE,
-                                  g_param_spec_boolean ("editable",
-                                                        _("Editable"),
-                                                        _("Make the text editable."),
-                                                        FALSE,
-                                                        G_PARAM_READABLE |
-                                                        G_PARAM_WRITABLE));
+                                   PROP_SIZE,
+                                   g_param_spec_int ("size",
+                                                     _("Font size"),
+                                                     _("Font size"),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_SIZE_POINTS,
+                                   g_param_spec_double ("size_points",
+                                                        _("Font points"),
+                                                        _("Font size in points"),
+                                                        0.0,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));  
   
   g_object_class_install_property (object_class,
-                                  PROP_ITALIC,
-                                  g_param_spec_boolean ("italic",
-                                                        _("Italic"),
-                                                        _("Make the text italic."),
-                                                        FALSE,
-                                                        G_PARAM_WRITABLE));
+                                   PROP_RISE,
+                                   g_param_spec_int ("rise",
+                                                     _("Rise"),
+                                                     _("Offset of text above the baseline (below the baseline if rise is negative)"),
+                                                     -G_MAXINT,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+
+  g_object_class_install_property (object_class,
+                                   PROP_STRIKETHROUGH,
+                                   g_param_spec_boolean ("strikethrough",
+                                                         _("Strikethrough"),
+                                                         _("Whether to strike through the text"),
+                                                         FALSE,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
   
   g_object_class_install_property (object_class,
-                                  PROP_BOLD,
-                                  g_param_spec_boolean ("bold",
-                                                        _("Bold"),
-                                                        _("Make the text bold."),
-                                                        FALSE,
-                                                        G_PARAM_WRITABLE));
+                                   PROP_UNDERLINE,
+                                   g_param_spec_enum ("underline",
+                                                      _("Underline"),
+                                                      _("Style of underline for this text"),
+                                                      PANGO_TYPE_UNDERLINE,
+                                                      PANGO_UNDERLINE_NONE,
+                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  /* Style props are set or not */
+
+#define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
+
+  ADD_SET_PROP ("background_set", PROP_BACKGROUND_SET,
+                _("Background set"),
+                _("Whether this tag affects the background color"));
+
+  ADD_SET_PROP ("foreground_set", PROP_FOREGROUND_SET,
+                _("Foreground set"),
+                _("Whether this tag affects the foreground color"));
+  
+  ADD_SET_PROP ("editable_set", PROP_EDITABLE_SET,
+                _("Editability set"),
+                _("Whether this tag affects text editability"));
+
+  ADD_SET_PROP ("family_set", PROP_FAMILY_SET,
+                _("Font family set"),
+                _("Whether this tag affects the font family"));  
+
+  ADD_SET_PROP ("style_set", PROP_STYLE_SET,
+                _("Font style set"),
+                _("Whether this tag affects the font style"));
+
+  ADD_SET_PROP ("variant_set", PROP_VARIANT_SET,
+                _("Font variant set"),
+                _("Whether this tag affects the font variant"));
+
+  ADD_SET_PROP ("weight_set", PROP_WEIGHT_SET,
+                _("Font weight set"),
+                _("Whether this tag affects the font weight"));
+
+  ADD_SET_PROP ("stretch_set", PROP_STRETCH_SET,
+                _("Font stretch set"),
+                _("Whether this tag affects the font stretch"));
+
+  ADD_SET_PROP ("size_set", PROP_SIZE_SET,
+                _("Font size set"),
+                _("Whether this tag affects the font size"));
+
+  ADD_SET_PROP ("rise_set", PROP_RISE_SET,
+                _("Rise set"),
+                _("Whether this tag affects the rise"));
+
+  ADD_SET_PROP ("strikethrough_set", PROP_STRIKETHROUGH_SET,
+                _("Strikethrough set"),
+                _("Whether this tag affects strikethrough"));
+
+  ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
+                _("Underline set"),
+                _("Whether this tag affects underlining"));
+}
+
+static void
+gtk_cell_renderer_text_finalize (GObject *object)
+{
+  GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
+
+  if (celltext->font.family_name)
+    g_free (celltext->font.family_name);
+
+  if (celltext->text)
+    g_free (celltext->text);
+  
+  (* G_OBJECT_CLASS (parent_class)->finalize) (object);
 }
 
 static void
@@ -196,26 +376,146 @@ gtk_cell_renderer_text_get_property (GObject        *object,
                                     const gchar    *trailer)
 {
   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
-  PangoAttrIterator *attr_iter;
-  PangoAttribute *attr;
 
   switch (param_id)
     {
     case PROP_TEXT:
       g_value_set_string (value, celltext->text);
       break;
-    case PROP_STRIKETHROUGH:
-      attr_iter = pango_attr_list_get_iterator (celltext->attr_list);
-      attr = pango_attr_iterator_get (attr_iter,
-                                     PANGO_ATTR_STRIKETHROUGH);
-      g_value_set_boolean (value, ((PangoAttrInt*) attr)->value);
+      
+    case PROP_BACKGROUND_GDK:
+      {
+        GdkColor color;
+        
+        color.red = celltext->background.red;
+        color.green = celltext->background.green;
+        color.blue = celltext->background.blue;
+        
+        g_value_set_boxed (value, &color);
+      }
       break;
-    case PROP_UNDERLINE:
-      g_value_set_boolean (value, celltext->underline);
+
+    case PROP_FOREGROUND_GDK:
+      {
+        GdkColor color;
+        
+        color.red = celltext->foreground.red;
+        color.green = celltext->foreground.green;
+        color.blue = celltext->foreground.blue;
+        
+        g_value_set_boxed (value, &color);
+      }
+      break;
+
+    case PROP_FONT:
+      {
+        /* FIXME GValue imposes a totally gratuitous string copy
+         * here, we could just hand off string ownership
+         */
+        gchar *str = pango_font_description_to_string (&celltext->font);
+        g_value_set_string (value, str);
+        g_free (str);
+      }
       break;
+      
+    case PROP_FONT_DESC:
+      g_value_set_boxed (value, &celltext->font);
+      break;
+
+    case PROP_FAMILY:
+      g_value_set_string (value, celltext->font.family_name);
+      break;
+
+    case PROP_STYLE:
+      g_value_set_enum (value, celltext->font.style);
+      break;
+
+    case PROP_VARIANT:
+      g_value_set_enum (value, celltext->font.variant);
+      break;
+
+    case PROP_WEIGHT:
+      g_value_set_int (value, celltext->font.weight);
+      break;
+
+    case PROP_STRETCH:
+      g_value_set_enum (value, celltext->font.stretch);
+      break;
+
+    case PROP_SIZE:
+      g_value_set_int (value, celltext->font.size);
+      break;
+
+    case PROP_SIZE_POINTS:
+      g_value_set_double (value, ((double)celltext->font.size) / (double)PANGO_SCALE);
+      break;
+
     case PROP_EDITABLE:
       g_value_set_boolean (value, celltext->editable);
       break;
+
+    case PROP_STRIKETHROUGH:
+      g_value_set_boolean (value, celltext->strikethrough);
+      break;
+
+    case PROP_UNDERLINE:
+      g_value_set_enum (value, celltext->underline_style);
+      break;
+
+    case PROP_RISE:
+      g_value_set_int (value, celltext->rise);
+      break;  
+
+    case PROP_BACKGROUND_SET:
+      g_value_set_boolean (value, celltext->background_set);
+      break;
+
+    case PROP_FOREGROUND_SET:
+      g_value_set_boolean (value, celltext->foreground_set);
+      break;
+
+    case PROP_FAMILY_SET:
+      g_value_set_boolean (value, celltext->family_set);
+      break;
+
+    case PROP_STYLE_SET:
+      g_value_set_boolean (value, celltext->style_set);
+      break;
+
+    case PROP_VARIANT_SET:
+      g_value_set_boolean (value, celltext->variant_set);
+      break;
+
+    case PROP_WEIGHT_SET:
+      g_value_set_boolean (value, celltext->weight_set);
+      break;
+
+    case PROP_STRETCH_SET:
+      g_value_set_boolean (value, celltext->stretch_set);
+      break;
+
+    case PROP_SIZE_SET:
+      g_value_set_boolean (value, celltext->size_set);
+      break;
+
+    case PROP_EDITABLE_SET:
+      g_value_set_boolean (value, celltext->editable_set);
+      break;
+
+    case PROP_STRIKETHROUGH_SET:
+      g_value_set_boolean (value, celltext->strikethrough_set);
+      break;
+
+    case PROP_UNDERLINE_SET:
+      g_value_set_boolean (value, celltext->underline_set);
+      break;
+
+    case  PROP_RISE_SET:
+      g_value_set_boolean (value, celltext->rise_set);
+      break;
+      
+    case PROP_BACKGROUND:
+    case PROP_FOREGROUND:
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -223,6 +523,121 @@ gtk_cell_renderer_text_get_property (GObject        *object,
 }
 
 
+static void
+set_bg_color (GtkCellRendererText *celltext,
+              GdkColor            *color)
+{
+  if (color)
+    {
+      if (!celltext->background_set)
+        {
+          celltext->background_set = TRUE;
+          g_object_notify (G_OBJECT (celltext), "background_set");
+        }
+      
+      celltext->background.red = color->red;
+      celltext->background.green = color->green;
+      celltext->background.blue = color->blue;
+    }
+  else
+    {
+      if (celltext->background_set)
+        {
+          celltext->background_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "background_set");
+        }
+    }
+}
+
+
+static void
+set_fg_color (GtkCellRendererText *celltext,
+              GdkColor            *color)
+{
+  if (color)
+    {
+      if (!celltext->foreground_set)
+        {
+          celltext->foreground_set = TRUE;
+          g_object_notify (G_OBJECT (celltext), "foreground_set");
+        }
+      
+      celltext->foreground.red = color->red;
+      celltext->foreground.green = color->green;
+      celltext->foreground.blue = color->blue;
+    }
+  else
+    {
+      if (celltext->foreground_set)
+        {
+          celltext->foreground_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "foreground_set");
+        }
+    }
+}
+
+static void
+set_font_description (GtkCellRendererText  *celltext,
+                      PangoFontDescription *font_desc)
+{
+  if (font_desc != NULL)
+    {
+      /* pango_font_description_from_string() will sometimes return
+       * a NULL family or -1 size, so handle those cases.
+       */
+      
+      if (font_desc->family_name)
+        g_object_set (G_OBJECT (celltext),
+                      "family", font_desc->family_name,
+                      NULL);
+      
+      if (font_desc->size >= 0)
+        g_object_set (G_OBJECT (celltext),
+                      "size", font_desc->size,
+                      NULL);
+        
+      g_object_set (G_OBJECT (celltext),
+                    "style", font_desc->style,
+                    "variant", font_desc->variant,
+                    "weight", font_desc->weight,
+                    "stretch", font_desc->stretch,
+                    NULL);
+    }
+  else
+    {
+      if (celltext->family_set)
+        {
+          celltext->family_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "family_set");
+        }
+      if (celltext->style_set)
+        {
+          celltext->style_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "style_set");
+        }
+      if (celltext->variant_set)
+        {
+          celltext->variant_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "variant_set");
+        }
+      if (celltext->weight_set)
+        {
+          celltext->weight_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "weight_set");
+        }
+      if (celltext->stretch_set)
+        {
+          celltext->stretch_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "stretch_set");
+        }
+      if (celltext->size_set)
+        {
+          celltext->size_set = FALSE;
+          g_object_notify (G_OBJECT (celltext), "size_set");
+        }
+    }
+}
+
 static void
 gtk_cell_renderer_text_set_property (GObject      *object,
                                     guint         param_id,
@@ -232,99 +647,206 @@ gtk_cell_renderer_text_set_property (GObject      *object,
 {
   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
 
-  GdkColor color;
-  PangoFontDescription *font_desc;
-  gchar *string;
-  PangoAttribute *attribute;
-  gchar *font;
-
   switch (param_id)
     {
     case PROP_TEXT:
-      g_free (celltext->text);
-      celltext->text = g_value_dup_string (value);
-      break;
-    case PROP_FONT:
-      font = g_value_get_string (value);
-
-      if (font)
-       {
-         font_desc = pango_font_description_from_string (font);
-         attribute = pango_attr_font_desc_new (font_desc);
-         attribute->start_index = 0;
-         attribute->end_index = G_MAXINT;
-         pango_font_description_free (font_desc);
-         pango_attr_list_change (celltext->attr_list,
-                                 attribute);
-       }
+      if (celltext->text)
+        g_free (celltext->text);
+      celltext->text = g_strdup (g_value_get_string (value));
       break;
+      
     case PROP_BACKGROUND:
-      string = g_value_get_string (value);
-      if (string && gdk_color_parse (string, &color))
-       {
-         attribute = pango_attr_background_new (color.red,
-                                                color.green,
-                                                color.blue);
-         attribute->start_index = 0;
-         attribute->end_index = G_MAXINT;
-         pango_attr_list_change (celltext->attr_list,
-                                 attribute);
-       }
-      break;
-    case PROP_BACKGROUND_GDK:
+      {
+        GdkColor color;
+
+        if (gdk_color_parse (g_value_get_string (value), &color))
+          set_bg_color (celltext, &color);
+        else
+          g_warning ("Don't know color `%s'", g_value_get_string (value));
+
+        g_object_notify (G_OBJECT (celltext), "background_gdk");
+      }
       break;
+      
     case PROP_FOREGROUND:
-      string = g_value_get_string (value);
-      if (string && gdk_color_parse (string, &color))
-       {
-         attribute = pango_attr_foreground_new (color.red,
-                                                color.green,
-                                                color.blue);
-         attribute->start_index = 0;
-         attribute->end_index = G_MAXINT;
-         pango_attr_list_change (celltext->attr_list,
-                                 attribute);
-       }
+      {
+        GdkColor color;
+
+        if (gdk_color_parse (g_value_get_string (value), &color))
+          set_bg_color (celltext, &color);
+        else
+          g_warning ("Don't know color `%s'", g_value_get_string (value));
+
+        g_object_notify (G_OBJECT (celltext), "foreground_gdk");
+      }
+      break;
+
+    case PROP_BACKGROUND_GDK:
+      set_bg_color (celltext, g_value_get_boxed (value));
       break;
+
     case PROP_FOREGROUND_GDK:
+      set_fg_color (celltext, g_value_get_boxed (value));
+      break;
+
+    case PROP_FONT:
+      {
+        PangoFontDescription *font_desc = NULL;
+        const gchar *name;
+
+        name = g_value_get_string (value);
+
+        if (name)
+          font_desc = pango_font_description_from_string (name);
+
+        set_font_description (celltext, font_desc);
+        
+        if (font_desc)
+          pango_font_description_free (font_desc);
+      }
+      break;
+
+    case PROP_FONT_DESC:
+      set_font_description (celltext, g_value_get_boxed (value));
+      break;
+
+    case PROP_FAMILY:
+      if (celltext->font.family_name)
+        g_free (celltext->font.family_name);
+      celltext->font.family_name = g_strdup (g_value_get_string (value));
+
+      celltext->family_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "family_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_STYLE:
+      celltext->font.style = g_value_get_enum (value);
+
+      celltext->style_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "style_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_VARIANT:
+      celltext->font.variant = g_value_get_enum (value);
+
+      celltext->variant_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "variant_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_WEIGHT:
+      celltext->font.weight = g_value_get_int (value);
+      
+      celltext->weight_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "weight_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_STRETCH:
+      celltext->font.stretch = g_value_get_enum (value);
+
+      celltext->stretch_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "stretch_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_SIZE:
+      celltext->font.size = g_value_get_int (value);
+
+      celltext->size_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "size_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
       break;
+
+    case PROP_SIZE_POINTS:
+      celltext->font.size = g_value_get_double (value) * PANGO_SCALE;
+
+      celltext->size_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "size_set");
+      g_object_notify (G_OBJECT (celltext), "font_desc");
+      g_object_notify (G_OBJECT (celltext), "font");
+      break;
+
+    case PROP_EDITABLE:
+      celltext->editable = g_value_get_boolean (value);
+      celltext->editable_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "editable_set");
+      break;
+
     case PROP_STRIKETHROUGH:
-      attribute = pango_attr_strikethrough_new (g_value_get_boolean (value));
-      attribute->start_index = 0;
-      attribute->end_index = G_MAXINT;
-      pango_attr_list_change (celltext->attr_list,
-                             attribute);
+      celltext->strikethrough = g_value_get_boolean (value);
+      celltext->strikethrough_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "strikethrough_set");
       break;
+
     case PROP_UNDERLINE:
-      celltext->underline = g_value_get_boolean (value);
-      attribute = pango_attr_underline_new (celltext->underline ?
-                                           PANGO_UNDERLINE_SINGLE :
-                                           PANGO_UNDERLINE_NONE);
-      attribute->start_index = 0;
-      attribute->end_index = G_MAXINT;
-      pango_attr_list_change (celltext->attr_list,
-                             attribute);
+      celltext->underline_style = g_value_get_enum (value);
+      celltext->underline_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "underline_set");
       break;
-    case PROP_EDITABLE:
+
+    case PROP_RISE:
+      celltext->rise = g_value_get_int (value);
+      celltext->rise_set = TRUE;
+      g_object_notify (G_OBJECT (celltext), "rise_set");
+      break;  
+
+    case PROP_BACKGROUND_SET:
+      celltext->background_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_FOREGROUND_SET:
+      celltext->foreground_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_FAMILY_SET:
+      celltext->family_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_STYLE_SET:
+      celltext->style_set = g_value_get_boolean (value);
       break;
-    case PROP_ITALIC:
-      attribute = pango_attr_style_new (g_value_get_boolean (value) ?
-                                       PANGO_STYLE_ITALIC :
-                                       PANGO_STYLE_NORMAL);
-      attribute->start_index = 0;
-      attribute->end_index = G_MAXINT;
-      pango_attr_list_change (celltext->attr_list,
-                             attribute);
-      break;
-    case PROP_BOLD:
-      attribute = pango_attr_weight_new (g_value_get_boolean (value) ?
-                                        PANGO_WEIGHT_BOLD :
-                                        PANGO_WEIGHT_NORMAL);
-      attribute->start_index = 0;
-      attribute->end_index = G_MAXINT;
-      pango_attr_list_change (celltext->attr_list,
-                             attribute);
+
+    case PROP_VARIANT_SET:
+      celltext->variant_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_WEIGHT_SET:
+      celltext->weight_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_STRETCH_SET:
+      celltext->stretch_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_SIZE_SET:
+      celltext->size_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_EDITABLE_SET:
+      celltext->editable_set = g_value_get_boolean (value);
       break;
+
+    case PROP_STRIKETHROUGH_SET:
+      celltext->strikethrough_set = g_value_get_boolean (value);
+      break;
+
+    case PROP_UNDERLINE_SET:
+      celltext->underline_set = g_value_get_boolean (value);
+      break;
+
+    case  PROP_RISE_SET:
+      celltext->rise_set = g_value_get_boolean (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -347,7 +869,108 @@ gtk_cell_renderer_text_set_property (GObject      *object,
 GtkCellRenderer *
 gtk_cell_renderer_text_new (void)
 {
-  return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_text_get_type ()));
+  return GTK_CELL_RENDERER (g_object_new (gtk_cell_renderer_text_get_type (), NULL));
+}
+
+static void
+add_attr (PangoAttrList  *attr_list,
+          PangoAttribute *attr)
+{
+  attr->start_index = 0;
+  attr->end_index = G_MAXINT;
+  
+  pango_attr_list_insert (attr_list, attr);
+}
+
+static PangoLayout*
+get_layout (GtkCellRendererText *celltext,
+            GtkWidget           *widget,
+            gboolean             will_render,
+            GtkCellRendererState flags)
+{
+  PangoAttrList *attr_list;
+  PangoLayout *layout;
+  PangoUnderline uline;
+  
+  layout = gtk_widget_create_pango_layout (widget, celltext->text);
+  
+  attr_list = pango_attr_list_new ();
+
+  if (will_render)
+    {
+      /* Add options that affect appearance but not size */
+      
+      /* note that background doesn't go here, since it affects
+       * background_area not the PangoLayout area
+       */
+      
+      if (celltext->foreground_set)
+        {
+          PangoColor color;
+
+          color = celltext->foreground;
+          
+          add_attr (attr_list,
+                    pango_attr_foreground_new (color.red, color.green, color.blue));
+        }
+
+      if (celltext->strikethrough_set)
+        add_attr (attr_list,
+                  pango_attr_strikethrough_new (celltext->strikethrough));
+    }
+
+  if (celltext->family_set &&
+      celltext->font.family_name)
+    add_attr (attr_list, pango_attr_family_new (celltext->font.family_name));
+  
+  if (celltext->style_set)
+    add_attr (attr_list, pango_attr_style_new (celltext->font.style));
+
+  if (celltext->variant_set)
+    add_attr (attr_list, pango_attr_variant_new (celltext->font.variant));
+
+  if (celltext->weight_set)
+    add_attr (attr_list, pango_attr_weight_new (celltext->font.weight));
+
+  if (celltext->stretch_set)
+    add_attr (attr_list, pango_attr_stretch_new (celltext->font.stretch));
+
+  if (celltext->size_set &&
+      celltext->font.size >= 0)
+    add_attr (attr_list, pango_attr_size_new (celltext->font.size));
+
+  if (celltext->underline_set)
+    uline = celltext->underline_style;
+  else
+    uline = PANGO_UNDERLINE_NONE;
+  
+  if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT)
+    {
+      switch (uline)
+        {
+        case PANGO_UNDERLINE_NONE:
+          uline = PANGO_UNDERLINE_SINGLE;
+          break;
+
+        case PANGO_UNDERLINE_SINGLE:
+          uline = PANGO_UNDERLINE_DOUBLE;
+          break;
+
+        default:
+          break;
+        }
+    }
+
+  if (uline != PANGO_UNDERLINE_NONE)
+    add_attr (attr_list, pango_attr_underline_new (celltext->underline_style));
+
+  if (celltext->rise_set)
+    add_attr (attr_list, pango_attr_rise_new (celltext->rise));
+  
+  pango_layout_set_attributes (layout, attr_list);
+  pango_layout_set_width (layout, -1);
+
+  return layout;
 }
 
 static void
@@ -359,21 +982,9 @@ gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
   GtkCellRendererText *celltext = (GtkCellRendererText *)cell;
   PangoRectangle rect;
   PangoLayout *layout;
-  PangoAttribute *attr;
-  PangoUnderline underline;
 
-  layout = gtk_widget_create_pango_layout (widget, celltext->text);
-  underline = celltext->underline ?
-    PANGO_UNDERLINE_DOUBLE :
-    PANGO_UNDERLINE_NONE;
-
-  attr = pango_attr_underline_new (underline);
-  attr->start_index = 0;
-  attr->end_index = G_MAXINT;
-
-  pango_attr_list_change (celltext->attr_list, attr);
-  pango_layout_set_attributes (layout, celltext->attr_list);
-  pango_layout_set_width (layout, -1);
+  layout = get_layout (celltext, widget, FALSE, 0);
+  
   pango_layout_get_pixel_extents (layout, NULL, &rect);
 
   if (width)
@@ -398,40 +1009,15 @@ gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
   PangoRectangle rect;
   PangoLayout *layout;
-  PangoAttribute *attr;
-  PangoUnderline underline;
   GtkStateType state;
   
   gint real_xoffset;
   gint real_yoffset;
 
-  layout = gtk_widget_create_pango_layout (widget, celltext->text);
+  layout = get_layout (celltext, widget, TRUE, flags);
 
-  if (celltext->underline)
-    underline = PANGO_UNDERLINE_SINGLE;
-  else
-    underline = PANGO_UNDERLINE_NONE;
-
-  attr = pango_attr_underline_new (underline);
-  attr->start_index = 0;
-  attr->end_index = G_MAXINT;
-  pango_attr_list_change (celltext->attr_list, attr);
-  pango_layout_set_attributes (layout, celltext->attr_list);
-
-  pango_layout_set_width (layout, -1);
   pango_layout_get_pixel_extents (layout, NULL, &rect);
 
-  if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT)
-    underline = (celltext->underline) ? PANGO_UNDERLINE_DOUBLE:PANGO_UNDERLINE_SINGLE;
-  else
-    underline = (celltext->underline) ? PANGO_UNDERLINE_SINGLE:PANGO_UNDERLINE_NONE;
-
-  attr = pango_attr_underline_new (underline);
-  attr->start_index = 0;
-  attr->end_index = G_MAXINT;
-  pango_attr_list_change (celltext->attr_list, attr);
-  pango_layout_set_attributes (layout, celltext->attr_list);
-
   real_xoffset = cell->xalign * (cell_area->width - rect.width - (2 * cell->xpad));
   real_xoffset = MAX (real_xoffset, 0) + cell->xpad;
   real_yoffset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
@@ -441,6 +1027,30 @@ gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
     state = GTK_STATE_SELECTED;
   else
     state = GTK_STATE_NORMAL;
+
+  if (celltext->background_set && state != GTK_STATE_SELECTED)
+    {
+      GdkColor color;
+      GdkGC *gc;
+      
+      color.red = celltext->background.red;
+      color.green = celltext->background.green;
+      color.blue = celltext->background.blue;
+
+      gc = gdk_gc_new (window);
+
+      gdk_gc_set_rgb_fg_color (gc, &color);
+      
+      gdk_draw_rectangle (window,
+                          gc,
+                          TRUE,
+                          background_area->x,
+                          background_area->y,
+                          background_area->width,
+                          background_area->height);
+
+      g_object_unref (G_OBJECT (gc));
+    }
   
   gtk_paint_layout (widget->style,
                     window,
index 762705413cb1a66ce4256bb8660dfe390f79092a..b2270b3de0d1cc4a3524b978034068e0cd71e6a5 100644 (file)
@@ -43,10 +43,37 @@ struct _GtkCellRendererText
 
   /*< private >*/
   gchar *text;
-  PangoAttrList *attr_list;
+  PangoFontDescription font;
+  PangoColor foreground;
+  PangoColor background;
 
+  PangoUnderline underline_style;
+
+  gint rise;
+  
+  guint strikethrough : 1;
+
+  /* editable feature doesn't work */
   guint editable  : 1;
-  guint underline : 1;
+
+  /* font elements set */
+  guint family_set : 1;
+  guint style_set : 1;
+  guint variant_set : 1;
+  guint weight_set : 1;
+  guint stretch_set : 1;
+  guint size_set : 1;
+
+  guint foreground_set : 1;
+  guint background_set : 1;
+  
+  guint underline_set : 1;
+
+  guint rise_set : 1;
+  
+  guint strikethrough_set : 1;
+
+  guint editable_set : 1;
 };
 
 struct _GtkCellRendererTextClass
index 619594894e92b0f7526f1fdb4d1777d148001a8e..e740dd2bde4ced1b0d0fc586820fedac34a82812 100644 (file)
@@ -1250,7 +1250,6 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                     &src_iter,
                                     src_path))
         {
-          g_print ("can't get source path as iter\n");
           goto out;
         }
 
@@ -1266,8 +1265,6 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                   &dest_iter);
           
           retval = TRUE;
-
-          g_print ("prepending to list\n");
         }
       else
         {
@@ -1280,11 +1277,7 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                            &dest_iter,
                                            &tmp_iter);
               retval = TRUE;
-
-              g_print ("inserting into list\n");
             }
-          else
-            g_print ("can't get iter to insert after\n");
         }
 
       gtk_tree_path_free (prev);
@@ -1304,9 +1297,6 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
             {
               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;
@@ -1332,7 +1322,6 @@ gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
       /* FIXME maybe add some data targets eventually, or handle text
        * targets in the simple case.
        */
-      g_print ("not accepting target\n");
     }
 
  out:
index e8bbf2d9d07a665b3596b521fd2049bb24014674..2765599a5d8cd8d15089a231c8709781d08c4d7c 100644 (file)
@@ -110,6 +110,7 @@ _gtk_rbnode_new (GtkRBTree *tree,
   node->right = tree->nil;
   node->parent = tree->nil;
   node->flags = GTK_RBNODE_RED;
+  node->parity = 1;
   node->count = 1;
   node->children = NULL;
   node->offset = height;
@@ -122,6 +123,17 @@ _gtk_rbnode_free (GtkRBNode *node)
   G_LOCK (current_allocator);
   node->left = current_allocator->free_nodes;
   current_allocator->free_nodes = node;
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    {
+      /* unfortunately node->left has to continue to point to
+       * a node...
+       */
+      node->right = (gpointer) 0xdeadbeef;
+      node->parent = (gpointer) 0xdeadbeef;
+      node->offset = 56789;
+      node->count = 56789;
+      node->flags = 0;
+    }
   G_UNLOCK (current_allocator);
 }
 
@@ -130,6 +142,7 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree,
                         GtkRBNode *node)
 {
   gint node_height, right_height;
+  guint node_parity, right_parity;
   GtkRBNode *right = node->right;
 
   g_return_if_fail (node != tree->nil);
@@ -143,6 +156,15 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree,
     (right->right?right->right->offset:0) -
     (right->children?right->children->root->offset:0);
 
+  node_parity = node->parity -
+    (node->left?node->left->parity:0) -
+    (node->right?node->right->parity:0) -
+    (node->children?node->children->root->parity:0);
+  right_parity = right->parity -
+    (right->left?right->left->parity:0) -
+    (right->right?right->right->parity:0) -
+    (right->children?right->children->root->parity:0);
+    
   node->right = right->left;
   if (right->left != tree->nil)
     right->left->parent = node;
@@ -167,6 +189,7 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree,
     (node->right?node->right->count:0);
   right->count = 1 + (right->left?right->left->count:0) +
     (right->right?right->right->count:0);
+
   node->offset = node_height +
     (node->left?node->left->offset:0) +
     (node->right?node->right->offset:0) +
@@ -175,6 +198,15 @@ _gtk_rbnode_rotate_left (GtkRBTree *tree,
     (right->left?right->left->offset:0) +
     (right->right?right->right->offset:0) +
     (right->children?right->children->root->offset:0);
+
+  node->parity = node_parity +
+    (node->left?node->left->parity:0) +
+    (node->right?node->right->parity:0) +
+    (node->children?node->children->root->parity:0);
+  right->parity = right_parity +
+    (right->left?right->left->parity:0) +
+    (right->right?right->right->parity:0) +
+    (right->children?right->children->root->parity:0);
 }
 
 static void
@@ -182,6 +214,7 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree,
                          GtkRBNode *node)
 {
   gint node_height, left_height;
+  guint node_parity, left_parity;
   GtkRBNode *left = node->left;
 
   g_return_if_fail (node != tree->nil);
@@ -195,6 +228,15 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree,
     (left->right?left->right->offset:0) -
     (left->children?left->children->root->offset:0);
 
+  node_parity = node->parity -
+    (node->left?node->left->parity:0) -
+    (node->right?node->right->parity:0) -
+    (node->children?node->children->root->parity:0);
+  left_parity = left->parity -
+    (left->left?left->left->parity:0) -
+    (left->right?left->right->parity:0) -
+    (left->children?left->children->root->parity:0);
+  
   node->left = left->right;
   if (left->right != tree->nil)
     left->right->parent = node;
@@ -222,6 +264,7 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree,
     (node->right?node->right->count:0);
   left->count = 1 + (left->left?left->left->count:0) +
     (left->right?left->right->count:0);
+
   node->offset = node_height +
     (node->left?node->left->offset:0) +
     (node->right?node->right->offset:0) +
@@ -230,6 +273,15 @@ _gtk_rbnode_rotate_right (GtkRBTree *tree,
     (left->left?left->left->offset:0) +
     (left->right?left->right->offset:0) +
     (left->children?left->children->root->offset:0);
+  
+  node->parity = node_parity +
+    (node->left?node->left->parity:0) +
+    (node->right?node->right->parity:0) +
+    (node->children?node->children->root->parity:0);
+  left->parity = left_parity +
+    (left->left?left->left->parity:0) +
+    (left->right?left->right->parity:0) +
+    (left->children?left->children->root->parity:0);
 }
 
 static void
@@ -412,6 +464,7 @@ _gtk_rbtree_new (void)
   retval->nil->flags = GTK_RBNODE_BLACK;
   retval->nil->count = 0;
   retval->nil->offset = 0;
+  retval->nil->parity = 0;
 
   retval->root = retval->nil;
   return retval;
@@ -451,12 +504,21 @@ _gtk_rbtree_remove (GtkRBTree *tree)
   GtkRBNode *tmp_node;
 
   gint height = tree->root->offset;
+
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (G_STRLOC, tree);
+  
   tmp_tree = tree->parent_tree;
   tmp_node = tree->parent_node;
 
   while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
     {
       tmp_node->offset -= height;
+
+      /* If the removed tree was odd, flip all parents */
+      if (tree->root->parity)
+        tmp_node->parity = !tmp_node->parity;
+      
       tmp_node = tmp_node->parent;
       if (tmp_node == tmp_tree->nil)
        {
@@ -464,7 +526,13 @@ _gtk_rbtree_remove (GtkRBTree *tree)
          tmp_tree = tmp_tree->parent_tree;
        }
     }
+
+  tmp_tree = tree->parent_tree;
+  
   _gtk_rbtree_free (tree);
+
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (G_STRLOC, tmp_tree);
 }
 
 
@@ -476,8 +544,11 @@ _gtk_rbtree_insert_after (GtkRBTree  *tree,
   GtkRBNode *node;
   gboolean right = TRUE;
   GtkRBNode *tmp_node;
-  GtkRBTree *tmp_tree;
+  GtkRBTree *tmp_tree;  
 
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (G_STRLOC, tree);
+  
   if (current != NULL && current->right != tree->nil)
     {
       current = current->right;
@@ -513,6 +584,8 @@ _gtk_rbtree_insert_after (GtkRBTree  *tree,
        * started in. */
       if (tmp_tree == tree)
        tmp_node->count++;
+
+      tmp_node->parity += 1;
       tmp_node->offset += height;
       tmp_node = tmp_node->parent;
       if (tmp_node == tmp_tree->nil)
@@ -524,7 +597,7 @@ _gtk_rbtree_insert_after (GtkRBTree  *tree,
   _gtk_rbtree_insert_fixup (tree, node);
 
   if (gtk_debug_flags & GTK_DEBUG_TREE)
-    _gtk_rbtree_test (tree);
+    _gtk_rbtree_test (G_STRLOC, tree);
   
   return node;
 }
@@ -539,6 +612,9 @@ _gtk_rbtree_insert_before (GtkRBTree  *tree,
   GtkRBNode *tmp_node;
   GtkRBTree *tmp_tree;
 
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (G_STRLOC, tree);
+  
   if (current != NULL && current->left != tree->nil)
     {
       current = current->left;
@@ -574,6 +650,8 @@ _gtk_rbtree_insert_before (GtkRBTree  *tree,
        * started in. */
       if (tmp_tree == tree)
        tmp_node->count++;
+
+      tmp_node->parity += 1;
       tmp_node->offset += height;
       tmp_node = tmp_node->parent;
       if (tmp_node == tmp_tree->nil)
@@ -585,7 +663,7 @@ _gtk_rbtree_insert_before (GtkRBTree  *tree,
   _gtk_rbtree_insert_fixup (tree, node);
 
   if (gtk_debug_flags & GTK_DEBUG_TREE)
-    _gtk_rbtree_test (tree);
+    _gtk_rbtree_test (G_STRLOC, tree);
   
   return node;
 }
@@ -670,6 +748,41 @@ _gtk_rbtree_node_find_offset (GtkRBTree *tree,
   return retval;
 }
 
+gint
+_gtk_rbtree_node_find_parity (GtkRBTree *tree,
+                              GtkRBNode *node)
+{
+  GtkRBNode *last;
+  gint retval;  
+  
+  g_assert (node);
+  g_assert (node->left);
+  
+  retval = node->left->parity;
+
+  while (tree && node && node != tree->nil)
+    {
+      last = node;
+      node = node->parent;
+
+      /* Add left branch, plus children, iff we came from the right */
+      if (node->right == last)
+       retval += node->parity - node->right->parity;
+      
+      if (node == tree->nil)
+       {
+         node = tree->parent_node;
+         tree = tree->parent_tree;
+
+          /* Add the parent node, plus the left branch. */
+         if (node)
+           retval += node->left->parity + 1; /* 1 == GTK_RBNODE_GET_PARITY() */
+       }
+    }
+  
+  return retval % 2;
+}
+
 gint
 _gtk_rbtree_find_offset (GtkRBTree  *tree,
                         gint        height,
@@ -734,14 +847,20 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
                         GtkRBNode *node)
 {
   GtkRBNode *x, *y;
-
+  GtkRBTree *tmp_tree;
+  GtkRBNode *tmp_node;
+  
   g_return_if_fail (tree != NULL);
   g_return_if_fail (node != NULL);
+  
   /* make sure we're deleting a node that's actually in the tree */
   for (x = node; x->parent != tree->nil; x = x->parent)
     ;
   g_return_if_fail (x == tree->root);
 
+  if (gtk_debug_flags & GTK_DEBUG_TREE)
+    _gtk_rbtree_test (G_STRLOC, tree);
+  
   if (node->left == tree->nil || node->right == tree->nil)
     {
       y = node;
@@ -753,9 +872,31 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
       while (y->left != tree->nil)
        y = y->left;
     }
+
+  /* adjust count only beneath tree */
   for (x = y; x != tree->nil; x = x->parent)
     x->count--;
-  y->count = node->count;
+
+  /*   y->count = node->count; */
+
+  /* offsets and parity adjust all the way up through parent trees */
+  
+  tmp_tree = tree;
+  tmp_node = y;
+
+  while (tmp_tree && tmp_node && tmp_node != tmp_tree->nil)
+    {
+      /*       tmp_node->offset -= y->offset; */
+      tmp_node->parity -= (guint) 1; /* parity of y is always 1 */
+      
+      tmp_node = tmp_node->parent;
+      if (tmp_node == tmp_tree->nil)
+       {
+         tmp_node = tmp_tree->parent_node;
+         tmp_tree = tmp_tree->parent_tree;
+       }
+    }
+  
   /* x is y's only child */
   if (y->left != tree->nil)
     x = y->left;
@@ -778,13 +919,10 @@ _gtk_rbtree_remove_node (GtkRBTree *tree,
   if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
     _gtk_rbtree_remove_node_fixup (tree, x);
 
-  G_LOCK (current_allocator);
-  y->left = current_allocator->free_nodes;
-  current_allocator->free_nodes = y;
-  G_UNLOCK (current_allocator);
+  _gtk_rbnode_free (y);
 
   if (gtk_debug_flags & GTK_DEBUG_TREE)
-    _gtk_rbtree_test (tree);
+    _gtk_rbtree_test (G_STRLOC, tree);
 }
 
 GtkRBNode *
@@ -989,6 +1127,9 @@ _count_nodes (GtkRBTree *tree,
   if (node == tree->nil)
     return 0;
 
+  g_assert (node->left);
+  g_assert (node->right);
+  
   res = (_count_nodes (tree, node->left) +
         _count_nodes (tree, node->right) + 1);
 
@@ -997,41 +1138,113 @@ _count_nodes (GtkRBTree *tree,
   return res;
 }
 
-void
-_gtk_rbtree_test (GtkRBTree *tree)
+static guint
+get_parity (GtkRBNode *node)
 {
-  if ((_count_nodes (tree, tree->root->left) +
-       _count_nodes (tree, tree->root->right) + 1) == tree->root->count)
-    g_print ("Tree passed\n");
+  guint child_total = 0;
+  guint rem;
+
+  /* The parity of a node is node->parity minus
+   * the parity of left, right, and children.
+   *
+   * This is equivalent to saying that if left, right, children
+   * sum to 0 parity, then node->parity is the parity of node,
+   * and if left, right, children are odd parity, then
+   * node->parity is the reverse of the node's parity.
+   */
+  
+  child_total += (guint) node->left->parity;
+  child_total += (guint) node->right->parity;
+
+  if (node->children)
+    child_total += (guint) node->children->root->parity;
+
+  rem = child_total % 2;
+  
+  if (rem == 0)
+    return node->parity;
   else
-    g_print ("Tree failed\n");
+    return !node->parity;
+}
 
+static guint
+count_parity (GtkRBTree *tree,
+              GtkRBNode *node)
+{
+  guint res;
+  
+  if (node == tree->nil)
+    return 0;
+  
+  res =
+    count_parity (tree, node->left) +
+    count_parity (tree, node->right) +
+    (guint)1 +
+    (node->children ? count_parity (node->children, node->children->root) : 0);
+
+  res = res % (guint)2;
+  
+  if (res != node->parity)
+    g_print ("parity incorrect for node\n");
+
+  if (get_parity (node) != 1)
+    g_error ("Node has incorrect parity %d", get_parity (node));
+  
+  return res;
 }
 
 static void
-_gtk_rbtree_test_height_helper (GtkRBTree *tree,
-                               GtkRBNode *node,
-                               gint       height)
+_gtk_rbtree_test_height (GtkRBTree *tree,
+                         GtkRBNode *node)
 {
-  if (node == tree->nil)
-    return;
+  gint computed_offset = 0;
 
-  if (node->offset -
-      (node->left?node->left->offset:0) -
-      (node->right?node->right->offset:0) -
-      (node->children?node->children->root->offset:0) != height)
-    g_error ("tree failed\n");
+  /* This whole test is sort of a useless truism. */
+  
+  if (node->left != tree->nil)
+    computed_offset += node->left->offset;
 
-  _gtk_rbtree_test_height_helper (tree, node->left, height);
-  _gtk_rbtree_test_height_helper (tree, node->right, height);
-  if (node->children)
-    _gtk_rbtree_test_height_helper (node->children, node->children->root, height);
+  if (node->right != tree->nil)
+    computed_offset += node->right->offset;
+
+  if (node->children && node->children->root != node->children->nil)
+    computed_offset += node->children->root->offset;
+
+  if (GTK_RBNODE_GET_HEIGHT (node) + computed_offset != node->offset)
+    g_error ("node has broken offset\n");
 
+  if (node->left != tree->nil)
+    _gtk_rbtree_test_height (tree, node->left);
+
+  if (node->right != tree->nil)
+    _gtk_rbtree_test_height (tree, node->right);
+
+  if (node->children && node->children->root != node->children->nil)
+    _gtk_rbtree_test_height (node->children, node->children->root);
 }
 
 void
-_gtk_rbtree_test_height (GtkRBTree *tree,
-                        gint       height)
+_gtk_rbtree_test (const gchar *where,
+                  GtkRBTree   *tree)
 {
-  _gtk_rbtree_test_height_helper (tree, tree->root, height);
+  GtkRBTree *tmp_tree;
+
+  /* Test the entire tree */
+  tmp_tree = tree;
+  while (tmp_tree->parent_tree)
+    tmp_tree = tmp_tree->parent_tree;
+  
+  g_print ("%s: whole tree offset is %d\n", where, tmp_tree->root->offset);
+
+  if (tmp_tree->root != tmp_tree->nil)
+    {
+      g_assert ((_count_nodes (tmp_tree, tmp_tree->root->left) +
+                 _count_nodes (tmp_tree, tmp_tree->root->right) + 1) == tmp_tree->root->count);
+      
+      
+      _gtk_rbtree_test_height (tmp_tree, tmp_tree->root);
+  
+      g_assert (count_parity (tmp_tree, tmp_tree->root) == tmp_tree->root->parity);
+    }
 }
+
index 40c779320c18765b871dcd2a2bb0576b3ec95d17..eea9160b626492cbe6b11933a606396652c3afa9 100644 (file)
@@ -33,6 +33,7 @@ typedef enum
   GTK_RBNODE_IS_SELECTED = 1 << 3,
   GTK_RBNODE_IS_PRELIT = 1 << 4,
   GTK_RBNODE_IS_VIEW = 1 << 5
+
 } GtkRBNodeColor;
 
 typedef struct _GtkRBTree GtkRBTree;
@@ -53,7 +54,20 @@ struct _GtkRBTree
 
 struct _GtkRBNode
 {
-  guint flags;
+  guint flags : 14;
+
+  /* We keep track of whether the aggregate count of children plus 1
+   * for the node itself comes to an even number.  The parity flag is
+   * the total count of children mod 2, where the total count of
+   * children gets computed in the same way that the total offset gets
+   * computed. i.e. not the same as the "count" field below which
+   * doesn't include children. We could replace parity with a
+   * full-size int field here, and then take % 2 to get the parity flag,
+   * but that would use extra memory.
+   */
+
+  guint parity : 1;
+  
   GtkRBNode *left;
   GtkRBNode *right;
   GtkRBNode *parent;
@@ -62,13 +76,15 @@ struct _GtkRBNode
    * i.e. node->left->count + node->right->count + 1
    */
   gint count;
-
+  
   /* this is the total of sizes of
    * node->left, node->right, our own height, and the height
    * of all trees in ->children, iff children exists because
    * the thing is expanded.
    */
   gint offset;
+
+  /* Child trees */
   GtkRBTree *children;
 };
 
@@ -101,6 +117,8 @@ void       _gtk_rbtree_node_set_height  (GtkRBTree              *tree,
                                         gint                    height);
 gint       _gtk_rbtree_node_find_offset (GtkRBTree              *tree,
                                         GtkRBNode              *node);
+gint       _gtk_rbtree_node_find_parity (GtkRBTree              *tree,
+                                        GtkRBNode              *node);
 gint       _gtk_rbtree_find_offset      (GtkRBTree              *tree,
                                         gint                    offset,
                                         GtkRBTree             **new_tree,
@@ -127,7 +145,8 @@ gint       _gtk_rbtree_get_depth        (GtkRBTree              *tree);
 
 /* This func just checks the integrity of the tree */
 /* It will go away later. */
-void       _gtk_rbtree_test             (GtkRBTree              *tree);
+void       _gtk_rbtree_test             (const gchar            *where,
+                                         GtkRBTree              *tree);
 
 
 #ifdef __cplusplus
index 30c75cf9078844d4853017c8f0294f8180e6b75e..7b6c04e01b478a75f077e5d3ab5c4af426bc57b2 100644 (file)
@@ -2416,6 +2416,29 @@ gtk_default_draw_box (GtkStyle      *style,
                     x, y, width, height);
 }
 
+static GdkGC*
+get_darkened_gc (GdkWindow *window,
+                 GdkColor  *color,
+                 gint       darken_count)
+{
+  GdkColor src = *color;
+  GdkColor shaded;
+  GdkGC *gc;
+  
+  gc = gdk_gc_new (window);
+
+  while (darken_count)
+    {
+      gtk_style_shade (&src, &shaded, 1.3);
+      src = shaded;
+      --darken_count;
+    }
+  
+  gdk_gc_set_rgb_fg_color (gc, &shaded);
+
+  return gc;
+}
+
 static void 
 gtk_default_draw_flat_box (GtkStyle      *style,
                            GdkWindow     *window,
@@ -2430,6 +2453,7 @@ gtk_default_draw_flat_box (GtkStyle      *style,
                            gint           height)
 {
   GdkGC *gc1;
+  GdkGC *freeme = NULL;
   
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (window != NULL);
@@ -2443,14 +2467,60 @@ gtk_default_draw_flat_box (GtkStyle      *style,
   
   if (detail)
     {
-      if (!strcmp ("text", detail) && state_type == GTK_STATE_SELECTED)
-       gc1 = style->bg_gc[GTK_STATE_SELECTED];
-      else if (!strcmp ("viewportbin", detail))
-       gc1 = style->bg_gc[GTK_STATE_NORMAL];
-      else if (!strcmp ("entry_bg", detail))
-       gc1 = style->base_gc[state_type];
+      if (state_type == GTK_STATE_SELECTED)
+        {
+          if (!strcmp ("text", detail))
+            gc1 = style->bg_gc[GTK_STATE_SELECTED];
+          else if (!strcmp ("cell_even_sorted", detail) ||
+                   !strcmp ("cell_odd_sorted", detail) ||
+                   !strcmp ("cell_even_ruled_sorted", detail) ||
+                   !strcmp ("cell_odd_ruled_sorted", detail))
+            {
+              freeme = get_darkened_gc (window, &style->bg[state_type], 1);
+              gc1 = freeme;
+            }
+          else
+            {
+              gc1 = style->bg_gc[state_type];
+            }
+        }
       else
-       gc1 = style->bg_gc[state_type];
+        {
+          if (!strcmp ("viewportbin", detail))
+            gc1 = style->bg_gc[GTK_STATE_NORMAL];
+          else if (!strcmp ("entry_bg", detail))
+            gc1 = style->base_gc[state_type];
+
+          /* For trees: even rows are base color, odd rows are a shade of
+           * the base color, the sort column is a shade of the original color
+           * for that row.
+           */
+
+          /* FIXME when we have style properties, clean this up.
+           */
+          
+          else if (!strcmp ("cell_even", detail) ||
+                   !strcmp ("cell_odd", detail) ||
+                   !strcmp ("cell_even_ruled", detail))
+            {
+              gc1 = style->base_gc[state_type];
+            }
+          else if (!strcmp ("cell_even_sorted", detail) ||
+                   !strcmp ("cell_odd_sorted", detail) ||
+                   !strcmp ("cell_odd_ruled", detail) ||
+                   !strcmp ("cell_even_ruled_sorted", detail))
+            {
+              freeme = get_darkened_gc (window, &style->base[state_type], 1);
+              gc1 = freeme;
+            }
+          else if (!strcmp ("cell_odd_ruled_sorted", detail))
+            {
+              freeme = get_darkened_gc (window, &style->base[state_type], 2);
+              gc1 = freeme;
+            }
+          else
+            gc1 = style->bg_gc[state_type];
+        }
     }
   else
     gc1 = style->bg_gc[state_type];
@@ -2475,6 +2545,10 @@ gtk_default_draw_flat_box (GtkStyle      *style,
     gtk_style_apply_default_background (style, window,
                                         widget && !GTK_WIDGET_NO_WINDOW (widget),
                                         state_type, area, x, y, width, height);
+
+
+  if (freeme)
+    g_object_unref (G_OBJECT (freeme));
 }
 
 static void 
index 153f3417e15a7de733640560c23b923a22245bb0..4340000ff9b7ee337711188c681f464533ae1608 100644 (file)
@@ -106,8 +106,6 @@ enum {
   /* Whether-a-style-arg-is-set args */
   PROP_BACKGROUND_SET,
   PROP_FOREGROUND_SET,
-  PROP_BACKGROUND_GDK_SET,
-  PROP_FOREGROUND_GDK_SET,
   PROP_BACKGROUND_STIPPLE_SET,
   PROP_FOREGROUND_STIPPLE_SET,
   PROP_FAMILY_SET,
@@ -507,10 +505,6 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
                 _("Background full height set"),
                 _("Whether this tag affects background height"));
 
-  ADD_SET_PROP ("background_gdk_set", PROP_BACKGROUND_GDK_SET,
-                _("Background set"),
-                _("Whether this tag affects the background color"));
-
   ADD_SET_PROP ("background_stipple_set", PROP_BACKGROUND_STIPPLE_SET,
                 _("Background stipple set"),
                 _("Whether this tag affects the background stipple"));  
@@ -519,10 +513,6 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
                 _("Foreground set"),
                 _("Whether this tag affects the foreground color"));
 
-  ADD_SET_PROP ("foreground_gdk_set", PROP_FOREGROUND_GDK_SET,
-                _("Foreground set"),
-                _("Whether this tag affects the foreground color"));
-
   ADD_SET_PROP ("foreground_stipple_set", PROP_FOREGROUND_STIPPLE_SET,
                 _("Foreground stipple set"),
                 _("Whether this tag affects the foreground stipple"));
@@ -814,6 +804,8 @@ gtk_text_tag_set_property (GObject      *object,
           set_bg_color (text_tag, &color);
         else
           g_warning ("Don't know color `%s'", g_value_get_string (value));
+
+        g_object_notify (G_OBJECT (text_tag), "background_gdk");
       }
       break;
 
@@ -825,6 +817,8 @@ gtk_text_tag_set_property (GObject      *object,
           set_fg_color (text_tag, &color);
         else
           g_warning ("Don't know color `%s'", g_value_get_string (value));
+
+        g_object_notify (G_OBJECT (text_tag), "foreground_gdk");
       }
       break;
 
@@ -847,7 +841,7 @@ gtk_text_tag_set_property (GObject      *object,
         GdkBitmap *bitmap = g_value_get_as_pointer (value);
 
         text_tag->bg_stipple_set = TRUE;
-        g_object_notify (G_OBJECT (text_tag), "bg_stipple_set");
+        g_object_notify (G_OBJECT (text_tag), "background_stipple_set");
         
         if (text_tag->values->appearance.bg_stipple != bitmap)
           {
@@ -867,7 +861,7 @@ gtk_text_tag_set_property (GObject      *object,
         GdkBitmap *bitmap = g_value_get_as_pointer (value);
 
         text_tag->fg_stipple_set = TRUE;
-        g_object_notify (G_OBJECT (text_tag), "fg_stipple_set");
+        g_object_notify (G_OBJECT (text_tag), "foreground_stipple_set");
 
         if (text_tag->values->appearance.fg_stipple != bitmap)
           {
@@ -895,8 +889,8 @@ gtk_text_tag_set_property (GObject      *object,
         set_font_description (text_tag, font_desc);
         
         if (font_desc)
-          pango_font_description_free (font_desc); 
-
+          pango_font_description_free (font_desc);
+        
         size_changed = TRUE;
       }
       break;
@@ -919,6 +913,8 @@ gtk_text_tag_set_property (GObject      *object,
       text_tag->values->font.family_name = g_strdup (g_value_get_string (value));
       text_tag->family_set = TRUE;
       g_object_notify (G_OBJECT (text_tag), "family_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
@@ -926,6 +922,8 @@ gtk_text_tag_set_property (GObject      *object,
       text_tag->values->font.style = g_value_get_enum (value);
       text_tag->style_set = TRUE;
       g_object_notify (G_OBJECT (text_tag), "style_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
@@ -933,6 +931,8 @@ gtk_text_tag_set_property (GObject      *object,
       text_tag->values->font.variant = g_value_get_enum (value);
       text_tag->variant_set = TRUE;
       g_object_notify (G_OBJECT (text_tag), "variant_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
@@ -940,6 +940,8 @@ gtk_text_tag_set_property (GObject      *object,
       text_tag->values->font.weight = g_value_get_int (value);
       text_tag->weight_set = TRUE;
       g_object_notify (G_OBJECT (text_tag), "weight_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
@@ -947,20 +949,28 @@ gtk_text_tag_set_property (GObject      *object,
       text_tag->values->font.stretch = g_value_get_enum (value);
       text_tag->stretch_set = TRUE;
       g_object_notify (G_OBJECT (text_tag), "stretch_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
     case PROP_SIZE:
       text_tag->values->font.size = g_value_get_int (value);
       text_tag->size_set = TRUE;
+      g_object_notify (G_OBJECT (text_tag), "size_points");
       g_object_notify (G_OBJECT (text_tag), "size_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
 
     case PROP_SIZE_POINTS:
       text_tag->values->font.size = g_value_get_double (value) * PANGO_SCALE;
       text_tag->size_set = TRUE;
+      g_object_notify (G_OBJECT (text_tag), "size");
       g_object_notify (G_OBJECT (text_tag), "size_set");
+      g_object_notify (G_OBJECT (text_tag), "font_desc");
+      g_object_notify (G_OBJECT (text_tag), "font");
       size_changed = TRUE;
       break;
       
@@ -1086,12 +1096,10 @@ gtk_text_tag_set_property (GObject      *object,
       /* Whether the value should be used... */
 
     case PROP_BACKGROUND_SET:
-    case PROP_BACKGROUND_GDK_SET:
       text_tag->bg_color_set = g_value_get_boolean (value);
       break;
 
     case PROP_FOREGROUND_SET:
-    case PROP_FOREGROUND_GDK_SET:
       text_tag->fg_color_set = g_value_get_boolean (value);
       break;
 
@@ -1289,12 +1297,6 @@ gtk_text_tag_get_property (GObject      *object,
       break;
 
     case PROP_FONT:
-      if (tag->family_set &&
-          tag->style_set &&
-          tag->variant_set &&
-          tag->size_set &&
-          tag->stretch_set &&
-          tag->weight_set)
         {
           /* FIXME GValue imposes a totally gratuitous string copy
            * here, we could just hand off string ownership
@@ -1306,13 +1308,7 @@ gtk_text_tag_get_property (GObject      *object,
       break;
 
     case PROP_FONT_DESC:
-      if (tag->family_set &&
-          tag->style_set &&
-          tag->variant_set &&
-          tag->size_set &&
-          tag->stretch_set &&
-          tag->weight_set)
-        g_value_set_boxed (value, &tag->values->font);
+      g_value_set_boxed (value, &tag->values->font);
       break;
 
     case PROP_FAMILY:
@@ -1413,12 +1409,10 @@ gtk_text_tag_get_property (GObject      *object,
       break;
       
     case PROP_BACKGROUND_SET:
-    case PROP_BACKGROUND_GDK_SET:
       g_value_set_boolean (value, tag->bg_color_set);
       break;
 
     case PROP_FOREGROUND_SET:
-    case PROP_FOREGROUND_GDK_SET:
       g_value_set_boolean (value, tag->fg_color_set);
       break;
 
index 76859fdd38772f87f8f605841ca897f6f23bdfdf..df233806b800744a74267b5607beaa9218c2143e 100644 (file)
@@ -4176,9 +4176,16 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
 {
   if (text_view->layout)
     {
-      /* Remove layout from all anchored children */
       GSList *tmp_list;
 
+      if (text_view->incremental_validate_idle)
+        {
+          g_source_remove (text_view->incremental_validate_idle);
+          text_view->incremental_validate_idle = 0;
+        }
+
+      /* Remove layout from all anchored children */
+      
       tmp_list = text_view->children;
       while (tmp_list != NULL)
         {
index 99a704761b6d35de9aa4003b0b280156329fcbbc..17735cec5c57a57e9e372a8b42285a4af80b0b13 100644 (file)
@@ -419,7 +419,7 @@ gtk_tree_model_sort_changed (GtkTreeModel *s_model,
                                                 array,
                                                 (GtkTreeIter *) elt,
                                                 TRUE);
-  g_print ("index is %d\n", index);
+
   gtk_signal_emit_by_name (GTK_OBJECT (data), "changed", path, &iter);
 
   gtk_tree_path_free (path);
index 6b2daa56962ceb85019497b79948a57cd04e9b76..63e81c0760eef1d011610d622ee171d872f255e6 100644 (file)
@@ -110,6 +110,9 @@ struct _GtkTreeViewPrivate
   GtkTreeViewColumn *scroll_to_column;
   gfloat scroll_to_row_align;
   gfloat scroll_to_col_align;
+
+  /* hint to display rows in alternating colors */
+  guint has_rules : 1;
 };
 
 #ifdef __GNUC__
index 509b270d45f67acf184db893f22273614b340dd2..baf424a141b7dc5a58bf17d8b74d39cd1b62fd3e 100644 (file)
@@ -707,6 +707,9 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
                                &node);
 
       gtk_tree_path_free (anchor_path);
+
+      if (tree == NULL)
+        return FALSE;
       
       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
        {
@@ -976,6 +979,7 @@ gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
        selected = TRUE;
       gtk_tree_path_free (path);
     }
+  
   if (selected == TRUE)
     {
       node->flags ^= GTK_RBNODE_IS_SELECTED;
index 403073e5b9b6d0e4cf461261fa33e3eae01c25b4..8c7ed59b9efeb00ce2aa965855c364c2b68ac488 100644 (file)
 extern "C" {
 #endif /* __cplusplus */
 
+typedef enum
+{
+  GTK_TREE_SORT_ASCENDING,
+  GTK_TREE_SORT_DESCENDING
+} GtkTreeSortOrder;
+
 #define GTK_TYPE_TREE_SORTABLE            (gtk_tree_sortable_get_type ())
 #define GTK_TREE_SORTABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_SORTABLE, GtkTreeSortable))
 #define GTK_IS_TREE_SORTABLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_SORTABLE))
@@ -38,14 +44,19 @@ struct _GtkTreeSortableIface
 {
   GTypeInterface g_iface;
 
-  /* FIXME think about sorting reverse when the column is clicked
-   * a second time.
-   */
-  gboolean     (* column_sortable) (GtkTreeSortable *sortable,
-                                    gint             column);
-  gint         (* get_sort_column) (GtkTreeSortable *sortable);
-  void         (* set_sort_column) (GtkTreeSortable *sortable,
-                                    gint             column);
+  /* This one is a signal */
+  void         (* sort_column_changed) (GtkTreeSortable  *sortable);
+
+  /* virtual methods */
+  gboolean     (* column_sortable)     (GtkTreeSortable  *sortable,
+                                        gint              column,
+                                        GtkTreeSortOrder  order);
+  void         (* get_sort_column)     (GtkTreeSortable  *sortable,
+                                        gint             *column,
+                                        GtkTreeSortOrder *order);
+  void         (* set_sort_column)     (GtkTreeSortable  *sortable,
+                                        gint              column,
+                                        GtkTreeSortOrder  order);
 };
 
 
index d44c46819713f6e9b97aff01163c430e2e195569..d54bab9d35ae597784f9fd5394e83378ee280742 100644 (file)
@@ -1061,14 +1061,12 @@ gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
                                &iter,
                                path))
     {
-      g_print ("data_delete deleting tree row\n");
       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
                              &iter);
       return TRUE;
     }
   else
     {
-      g_print ("data_delete path not in tree\n");
       return FALSE;
     }
 }
@@ -1117,9 +1115,6 @@ copy_node_data (GtkTreeStore *tree_store,
       copy_iter = _gtk_tree_data_list_node_copy (dl,
                                                  tree_store->column_headers[col]);
 
-      g_print ("copied col %d type %s\n", col,
-               g_type_name (tree_store->column_headers[col]));
-              
       if (copy_head == NULL)
         copy_head = copy_iter;
 
@@ -1205,7 +1200,6 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                     &src_iter,
                                     src_path))
         {
-          g_print ("can't get source path as iter\n");
           goto out;
         }
 
@@ -1240,8 +1234,6 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                   dest_parent_p);
           
           retval = TRUE;
-
-          g_print ("prepending to tree\n");
         }
       else
         {
@@ -1256,10 +1248,7 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
                                            &tmp_iter);
               retval = TRUE;
 
-              g_print ("inserting into tree\n");
             }
-          else
-            g_print ("can't get iter to insert after\n");
         }
 
       gtk_tree_path_free (prev);
@@ -1280,7 +1269,7 @@ gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
       /* FIXME maybe add some data targets eventually, or handle text
        * targets in the simple case.
        */
-      g_print ("not accepting target\n");
+
     }
 
  out:
index db5de4e46b030f2b8a23161b029aed9bf6fb35f6..b30eeefb139f936038b7e6f643cdc3f02e394373 100644 (file)
@@ -28,6 +28,8 @@
 #include "gtkbutton.h"
 #include "gtkalignment.h"
 #include "gtklabel.h"
+#include "gtkhbox.h"
+#include "gtkarrow.h"
 
 #include <gdk/gdkkeysyms.h>
 
@@ -437,10 +439,6 @@ gtk_tree_view_realize (GtkWidget *widget)
 
   tree_view = GTK_TREE_VIEW (widget);
 
-  if (!GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_MODEL_SETUP) &&
-      tree_view->priv->model)
-    gtk_tree_view_setup_model (tree_view);
-
   gtk_tree_view_check_dirty (GTK_TREE_VIEW (widget));
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
@@ -768,7 +766,9 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   widget->allocation = *allocation;
 
   tree_view = GTK_TREE_VIEW (widget);
-
+  
+  gtk_tree_view_check_dirty (tree_view);
+  
   tmp_list = tree_view->priv->children;
 
   while (tmp_list)
@@ -788,28 +788,25 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
       gtk_widget_size_allocate (child->widget, &allocation);
     }
 
+  gtk_tree_view_size_allocate_buttons (widget);
+  
   if (GTK_WIDGET_REALIZED (widget))
     {
       gdk_window_move_resize (widget->window,
                              allocation->x, allocation->y,
                              allocation->width, allocation->height);
+
       gdk_window_move_resize (tree_view->priv->header_window,
                              0, 0,
                              MAX (tree_view->priv->width, allocation->width),
                              tree_view->priv->header_height);
     }
-
-  /* FIXME I don't think the invariant that the model must be setup
-   * before touching the buttons is maintained in most of the
-   * rest of the code, e.g. in realize, so something is wrong
-   */
-  if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_MODEL_SETUP))
-    gtk_tree_view_size_allocate_buttons (widget);
   
   tree_view->priv->hadjustment->page_size = allocation->width;
   tree_view->priv->hadjustment->page_increment = allocation->width / 2;
   tree_view->priv->hadjustment->lower = 0;
   tree_view->priv->hadjustment->upper = tree_view->priv->width;
+
   if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
     tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
   gtk_signal_emit_by_name (GTK_OBJECT (tree_view->priv->hadjustment), "changed");
@@ -818,9 +815,11 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   tree_view->priv->vadjustment->page_increment = (allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view)) / 2;
   tree_view->priv->vadjustment->lower = 0;
   tree_view->priv->vadjustment->upper = tree_view->priv->height;
+
   if (tree_view->priv->vadjustment->value + allocation->height > tree_view->priv->height)
     gtk_adjustment_set_value (tree_view->priv->vadjustment,
                              (gfloat) MAX (tree_view->priv->height - allocation->height, 0));
+
   gtk_signal_emit_by_name (GTK_OBJECT (tree_view->priv->vadjustment), "changed");
 }
 
@@ -879,12 +878,14 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
 
   depth = gtk_tree_path_get_depth (path);
 
-  if (_gtk_tree_view_find_node (tree_view,
-                               path,
-                               &tree,
-                               &node))
-    return NULL;
+  _gtk_tree_view_find_node (tree_view,
+                            path,
+                            &tree,
+                            &node);
 
+  if (tree == NULL)
+    return NULL;
+  
   if (!gtk_tree_model_get_iter (tree_view->priv->model,
                                 &iter,
                                 path))
@@ -970,9 +971,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   GtkTreePath *path;
   GtkRBTree *tree;
   GList *list;
-  GtkRBNode *node, *last_node = NULL;
+  GtkRBNode *node;
   GtkRBNode *cursor = NULL;
-  GtkRBTree *cursor_tree = NULL, *last_tree = NULL;
+  GtkRBTree *cursor_tree = NULL;
   GtkRBNode *drag_highlight = NULL;
   GtkRBTree *drag_highlight_tree = NULL;
   GtkTreeIter iter;
@@ -984,7 +985,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   GdkRectangle background_area;
   GdkRectangle cell_area;
   guint flags;
-  gboolean last_selected;
   gint highlight_x;
   gint bin_window_width;
   GtkTreePath *cursor_path;
@@ -1014,10 +1014,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   if (node == NULL)
     return TRUE;
 
-  /* See if the last node was selected */
-  _gtk_rbtree_prev_full (tree, node, &last_tree, &last_node);
-  last_selected = (last_node && GTK_RBNODE_FLAG_SET (last_node, GTK_RBNODE_IS_SELECTED));
-
   /* find the path for the node */
   path = _gtk_tree_view_find_path ((GtkTreeView *)widget,
                                   tree,
@@ -1060,45 +1056,39 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
         max_height = MAX (TREE_VIEW_EXPANDER_MIN_HEIGHT, GTK_RBNODE_GET_HEIGHT (node));
         else
       */
+      gboolean parity;
+      
       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 / 2;
-      background_area.height = max_height - TREE_VIEW_VERTICAL_SEPARATOR;
+      background_area.y = y_offset + event->area.y;
+      background_area.height = max_height;
       flags = 0;
 
       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PRELIT))
        flags |= GTK_CELL_RENDERER_PRELIT;
 
+      parity = _gtk_rbtree_node_find_parity (tree, node);
+      
       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
-       {
-         flags |= GTK_CELL_RENDERER_SELECTED;
-
-         /* Draw the selection */
-         gdk_draw_rectangle (event->window,
-                             GTK_WIDGET (tree_view)->style->bg_gc [GTK_STATE_SELECTED],
-                             TRUE,
-                             event->area.x,
-                             background_area.y - (last_selected?TREE_VIEW_VERTICAL_SEPARATOR:0),
-                             event->area.width,
-                             background_area.height + (last_selected?TREE_VIEW_VERTICAL_SEPARATOR:0));
-         last_selected = TRUE;
-       }
-      else
-       {
-         last_selected = FALSE;
-       }
-
+        flags |= GTK_CELL_RENDERER_SELECTED;
+      
       for (i = 0, list = tree_view->priv->columns; i < tree_view->priv->n_columns; i++, list = list->next)
        {
          GtkTreeViewColumn *column = list->data;
-
+          const gchar *detail = NULL;
+          
          if (!column->visible)
-           continue;
+            continue;
 
+          if (column->show_sort_indicator)
+            flags |= GTK_CELL_RENDERER_SORTED;
+          else
+            flags &= ~GTK_CELL_RENDERER_SORTED;
+          
          cell = column->cell;
          gtk_tree_view_column_set_cell_data (column,
                                              tree_view->priv->model,
@@ -1106,10 +1096,75 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
          background_area.x = cell_offset;
          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;
+
+          /* Select the detail for drawing the cell.  relevant
+           * factors are parity, sortedness, and whether to
+           * display rules.
+           */
+
+          /* FIXME when we have style properties, clean this up.
+           */
+
+#if 1
+          if (tree_view->priv->has_rules)
+            {
+              if (flags & GTK_CELL_RENDERER_SORTED)
+                {
+                  if (parity)
+                    detail = "cell_odd_ruled_sorted";
+                  else
+                    detail = "cell_even_ruled_sorted";
+                }
+              else
+                {
+                  if (parity)
+                    detail = "cell_odd_ruled";
+                  else
+                    detail = "cell_even_ruled";
+                }
+            }
+          else
+            {
+              if (flags & GTK_CELL_RENDERER_SORTED)
+                {
+                  if (parity)
+                    detail = "cell_odd_sorted";
+                  else
+                    detail = "cell_even_sorted";
+                }
+              else
+                {
+                  if (parity)
+                    detail = "cell_odd";
+                  else
+                    detail = "cell_even";
+                }
+            }
+
+          g_assert (detail);
+#endif
+          
+          /* Draw background */
+          gtk_paint_flat_box (widget->style,
+                              event->window,
+                              (flags & GTK_CELL_RENDERER_SELECTED) ?
+                              GTK_STATE_SELECTED : GTK_STATE_NORMAL,
+                              GTK_SHADOW_NONE,
+                              &event->area,
+                              widget,
+                              detail,
+                              background_area.x,
+                              background_area.y,
+                              background_area.width,
+                              background_area.height);
+          
          if (i == tree_view->priv->expander_column &&
               TREE_VIEW_DRAW_EXPANDERS(tree_view))
            {
-             cell_area = background_area;
              cell_area.x += depth*tree_view->priv->tab_offset;
              cell_area.width -= depth*tree_view->priv->tab_offset;
 
@@ -1118,7 +1173,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                * level of the tree we're dropping at.
                */
               highlight_x = cell_area.x;
-              
+                
              gtk_cell_renderer_render (cell,
                                        event->window,
                                        widget,
@@ -1126,6 +1181,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                                        &cell_area,
                                        &event->area,
                                        flags);
+
              if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
                {
                  gint x, y;
@@ -1137,8 +1193,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                }
            }
          else
-           {
-             cell_area = background_area;
+           {              
              gtk_cell_renderer_render (cell,
                                        event->window,
                                        widget,
@@ -1196,6 +1251,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
          tree = node->children;
          node = tree->root;
+
+          g_assert (node != tree->nil);
+          
          while (node->left != tree->nil)
            node = node->left;
          has_child = gtk_tree_model_iter_children (tree_view->priv->model,
@@ -1246,7 +1304,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
        }
     }
   while (y_offset < event->area.height);
-
+  
   if (cursor_path)
     gtk_tree_path_free (cursor_path);
 
@@ -1284,6 +1342,9 @@ coords_are_over_arrow (GtkTreeView *tree_view,
   GdkRectangle arrow;
   gint x2;
 
+  if (!GTK_WIDGET_REALIZED (tree_view))
+    return FALSE;
+  
   if ((node->flags & GTK_RBNODE_IS_PARENT) == 0)
     return FALSE;
   
@@ -1351,6 +1412,12 @@ do_prelight (GtkTreeView *tree_view,
   GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_PRELIT);
 }
 
+static void
+ensure_unprelighted (GtkTreeView *tree_view)
+{
+  do_unprelight (tree_view, -1000, -1000); /* coords not possibly over an arrow */
+}
+
 static gboolean
 gtk_tree_view_motion (GtkWidget      *widget,
                      GdkEventMotion *event)
@@ -1406,7 +1473,7 @@ gtk_tree_view_motion (GtkWidget      *widget,
                            &tree,
                            &node);
 
-  if (node == NULL)
+  if (tree == NULL)
     return TRUE;
 
   /* If we are currently pressing down a button, we don't want to prelight anything else. */
@@ -1502,7 +1569,7 @@ gtk_tree_view_leave_notify (GtkWidget        *widget,
                                    tree_view->priv->prelight_node,
                                    NULL);
   
-  do_unprelight (tree_view, -1000, -1000); /* coords not possibly over an arrow */
+  ensure_unprelighted (tree_view);
 
   return TRUE;
 }
@@ -1756,14 +1823,14 @@ gtk_tree_view_button_release (GtkWidget      *widget,
              tree_view->priv->button_pressed_node->children->parent_tree = tree_view->priv->button_pressed_tree;
              tree_view->priv->button_pressed_node->children->parent_node = tree_view->priv->button_pressed_node;
              gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
-             gtk_tree_model_iter_children (tree_view->priv->model, &child, &iter);
-
-             gtk_tree_view_build_tree (tree_view,
-                                       tree_view->priv->button_pressed_node->children,
-                                       &child,
-                                       gtk_tree_path_get_depth (path) + 1,
-                                       FALSE,
-                                       GTK_WIDGET_REALIZED (widget));
+              
+             if (gtk_tree_model_iter_children (tree_view->priv->model, &child, &iter))
+                gtk_tree_view_build_tree (tree_view,
+                                          tree_view->priv->button_pressed_node->children,
+                                          &child,
+                                          gtk_tree_path_get_depth (path) + 1,
+                                          FALSE,
+                                          GTK_WIDGET_REALIZED (widget));
            }
          else
            {
@@ -2422,6 +2489,9 @@ gtk_tree_view_changed (GtkTreeModel *model,
     /* We aren't actually showing the node */
     return;
 
+  if (tree == NULL)
+    return;
+  
   dirty_marked = gtk_tree_view_discover_dirty_iter (tree_view,
                                                    iter,
                                                    gtk_tree_path_get_depth (path),
@@ -2554,6 +2624,9 @@ gtk_tree_view_child_toggled (GtkTreeModel *model,
     /* We aren't actually showing the node */
     return;
 
+  if (tree == NULL)
+    return;
+  
   has_child = gtk_tree_model_iter_has_child (model, &real_iter);
   /* Sanity check.
    */
@@ -2596,12 +2669,15 @@ gtk_tree_view_deleted (GtkTreeModel *model,
   GtkRBTree *tree;
   GtkRBNode *node;
   GList *list;
-
+  
   g_return_if_fail (path != NULL);
 
   if (_gtk_tree_view_find_node (tree_view, path, &tree, &node))
     return;
 
+  if (tree == NULL)
+    return;
+  
   /* next, update the selection */
   if (tree_view->priv->anchor)
     {
@@ -2633,11 +2709,20 @@ gtk_tree_view_deleted (GtkTreeModel *model,
        ((GtkTreeViewColumn *)list->data)->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
       ((GtkTreeViewColumn *)list->data)->dirty = TRUE;
 
+  /* Ensure we don't have a dangling pointer to a dead node */
+  ensure_unprelighted (tree_view);
+
+  g_assert (tree_view->priv->prelight_node == NULL);
+  
   if (tree->root->count == 1)
-    _gtk_rbtree_remove (tree);
+    {
+      _gtk_rbtree_remove (tree);
+    }
   else
-    _gtk_rbtree_remove_node (tree, node);
-
+    {      
+      _gtk_rbtree_remove_node (tree, node);
+    }
+  
   _gtk_tree_view_set_size (GTK_TREE_VIEW (data), -1, -1);
 }
 
@@ -2905,6 +2990,10 @@ gtk_tree_view_check_dirty (GtkTreeView *tree_view)
   GtkTreeViewColumn *column;
   GtkTreeIter iter;
   
+  if (!GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_MODEL_SETUP) &&
+      tree_view->priv->model)
+    gtk_tree_view_setup_model (tree_view);
+  
   for (list = tree_view->priv->columns; list; list = list->next)
     {
       column = list->data;
@@ -2913,13 +3002,22 @@ gtk_tree_view_check_dirty (GtkTreeView *tree_view)
          dirty = TRUE;
          if (column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
            {
-              gtk_tree_view_column_set_width (column, MAX (column->button->requisition.width, 1));
+              gint w = 1;
+
+              if (column->button)
+                w = MAX (w, column->button->requisition.width);
+              
+              gtk_tree_view_column_set_width (column, w);
            }
        }
     }
+
   if (dirty == FALSE)
     return;
 
+  if (tree_view->priv->model == NULL)
+    return;
+  
   path = gtk_tree_path_new_root ();
   if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, path))
     {
@@ -2948,8 +3046,8 @@ gtk_tree_view_create_button (GtkTreeView *tree_view,
   button = column->button = gtk_button_new ();
   gtk_widget_pop_composite_child ();
 
-  gtk_widget_set_parent (button, GTK_WIDGET (tree_view));
-
+  gtk_widget_set_parent (button, GTK_WIDGET (tree_view));\
+  
   gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) gtk_tree_view_button_clicked,
                      (gpointer) tree_view);
@@ -2965,7 +3063,13 @@ gtk_tree_view_create_buttons (GtkTreeView *tree_view)
   GList *list;
   GtkTreeViewColumn *column;
   gint i;
+  GtkWidget *hbox;
+  GtkWidget *arrow;
 
+  /* FIXME this has to be merged with update_button_contents() in
+   * gtktreeviewcolumn.c
+   */
+  
   for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++)
     {
       column = list->data;
@@ -2974,23 +3078,14 @@ gtk_tree_view_create_buttons (GtkTreeView *tree_view)
        continue;
 
       gtk_tree_view_create_button (tree_view, i);
-      switch (column->justification)
-       {
-       case GTK_JUSTIFY_LEFT:
-         alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
-         break;
-       case GTK_JUSTIFY_RIGHT:
-         alignment = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
-         break;
-       case GTK_JUSTIFY_CENTER:
-         alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-         break;
-       case GTK_JUSTIFY_FILL:
-       default:
-         alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-         break;
-       }
+      alignment = gtk_alignment_new (column->xalign, 0.5, 0.0, 0.0);
 
+      hbox = gtk_hbox_new (FALSE, 2);
+      arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
+
+      column->arrow = arrow;
+      column->alignment = alignment;
+      
       if (column->child)
         label = column->child;
       else
@@ -2999,10 +3094,19 @@ gtk_tree_view_create_buttons (GtkTreeView *tree_view)
           gtk_widget_show (label);
         }
 
-      gtk_container_add (GTK_CONTAINER (alignment), label);
-      gtk_container_add (GTK_CONTAINER (column->button), alignment);
+      if (column->xalign <= 0.5)
+        gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+      else
+        gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
       
+      gtk_box_pack_start (GTK_BOX (hbox), alignment, TRUE, TRUE, 0);
+        
+      gtk_container_add (GTK_CONTAINER (alignment), label);
+      gtk_container_add (GTK_CONTAINER (column->button), hbox);
+
+      gtk_widget_show (hbox);
       gtk_widget_show (alignment);
+      /* don't show the arrow yet */
     }
 
   gtk_tree_view_size_request_buttons (tree_view);
@@ -3104,7 +3208,10 @@ _gtk_tree_view_find_path (GtkTreeView *tree_view,
   return path;
 }
 
-/* Returns whether or not it's a parent, or not */
+/* Returns TRUE if we ran out of tree before finding the node,
+ * so the returned node is the last node we saw and the returned
+ * tree is NULL
+ */
 gboolean
 _gtk_tree_view_find_node (GtkTreeView  *tree_view,
                          GtkTreePath  *path,
@@ -3129,7 +3236,8 @@ _gtk_tree_view_find_node (GtkTreeView  *tree_view,
          return TRUE;
        }
       tmpnode = _gtk_rbtree_find_count (tmptree, indices[i] + 1);
-      if (++i >= depth)
+      ++i;
+      if (i >= depth)
        {
          *node = tmpnode;
          *tree = tmptree;
@@ -3269,6 +3377,7 @@ _gtk_tree_view_set_size (GtkTreeView     *tree_view,
          width += TREE_VIEW_COLUMN_WIDTH (column);
        }
     }
+
   if (height == -1)
     height = tree_view->priv->tree->root->offset + TREE_VIEW_VERTICAL_SEPARATOR;
 
@@ -3292,6 +3401,7 @@ _gtk_tree_view_set_size (GtkTreeView     *tree_view,
       gdk_window_resize (tree_view->priv->bin_window, MAX (width, GTK_WIDGET (tree_view)->allocation.width), height + TREE_VIEW_HEADER_HEIGHT (tree_view));
       gdk_window_resize (tree_view->priv->header_window, MAX (width, GTK_WIDGET (tree_view)->allocation.width), tree_view->priv->header_height);
     }
+  
   gtk_widget_queue_resize (GTK_WIDGET (tree_view));
 }
 
@@ -4557,6 +4667,10 @@ gtk_tree_view_collapse_all_helper (GtkRBTree  *tree,
                                    node->children,
                                    &iter,
                                    gtk_tree_path_get_depth (path));
+
+      /* Ensure we don't have a dangling pointer to a dead node */
+      ensure_unprelighted (GTK_TREE_VIEW (data));
+      
       _gtk_rbtree_remove (node->children);
       gtk_tree_path_free (path);
     }
@@ -4620,7 +4734,7 @@ gtk_tree_view_expand_row (GtkTreeView *tree_view,
                                &tree,
                                &node))
     return FALSE;
-
+  
   if (node->children)
     return TRUE;
   
@@ -4682,6 +4796,12 @@ gtk_tree_view_collapse_row (GtkTreeView *tree_view,
                                node->children,
                                &iter,
                                gtk_tree_path_get_depth (path));
+
+  /* Ensure we don't have a dangling pointer to a dead node */
+  ensure_unprelighted (tree_view);
+  
+  g_assert (tree_view->priv->prelight_node == NULL);
+  
   _gtk_rbtree_remove (node->children);
 
   if (GTK_WIDGET_MAPPED (tree_view))
@@ -4785,6 +4905,56 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
     }
 }
 
+/**
+ * gtk_tree_view_set_rules_hint
+ * @tree_view: a #GtkTreeView
+ * @setting: %TRUE if the tree requires reading across rows
+ * 
+ * This function tells GTK+ that the user interface for your
+ * application requires users to read across tree rows and associate
+ * cells with one another. By default, GTK+ will then render the tree
+ * with alternating row colors. <emphasis>DO NOT</emphasis> use it
+ * just because you prefer the appearance of the ruled tree; that's a
+ * question for the theme. Some themes will draw tree rows in
+ * alternating colors even when rules are turned off, and users who
+ * prefer that appearance all the time can choose those themes. You
+ * should call this function only as a <emphasis>semantic</emphasis>
+ * hint to the theme engine that your tree makes alternating colors
+ * useful from a functional standpoint (since it has lots of columns,
+ * generally).
+ * 
+ **/
+void
+gtk_tree_view_set_rules_hint (GtkTreeView  *tree_view,
+                              gboolean      setting)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  
+  setting = setting != FALSE;
+
+  if (tree_view->priv->has_rules != setting)
+    {
+      tree_view->priv->has_rules = setting;
+      gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+    }
+}
+
+/**
+ * gtk_tree_view_get_rules_hint
+ * @tree_view: a #GtkTreeView
+ * 
+ * Gets the setting set by gtk_tree_view_set_rules_hint().
+ * 
+ * Return value: %TRUE if rules are useful for the user of this tree
+ **/
+gboolean
+gtk_tree_view_get_rules_hint (GtkTreeView  *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
+  
+  return tree_view->priv->has_rules;
+}
+
 /* Drag-and-drop */
 
 static void
@@ -5447,8 +5617,6 @@ gtk_tree_view_drag_data_delete (GtkWidget      *widget,
   
   tree_view = GTK_TREE_VIEW (widget);
   model = gtk_tree_view_get_model (tree_view);
-
-  g_print ("data_delete\n");
   
   if (!check_model_dnd (model, GTK_TYPE_TREE_DRAG_SOURCE, "drag_data_delete"))
     return;
@@ -5491,7 +5659,6 @@ 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);
@@ -5561,7 +5728,6 @@ set_destination_row (GtkTreeView    *tree_view,
        * 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);
@@ -5575,7 +5741,6 @@ set_destination_row (GtkTreeView    *tree_view,
   *target = gtk_drag_dest_find_target (widget, context, di->dest_target_list);
   if (*target == GDK_NONE)
     {
-      g_print ("bad target, not accepting\n");
       return FALSE;
     }
   
@@ -5587,7 +5752,6 @@ set_destination_row (GtkTreeView    *tree_view,
       /* can't drop here */
       remove_open_timeout (tree_view);
 
-      g_print ("no drag row here\n");
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                        NULL,
                                        GTK_TREE_VIEW_DROP_BEFORE);
@@ -5631,7 +5795,6 @@ set_destination_row (GtkTreeView    *tree_view,
             *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);
     }
@@ -5640,7 +5803,6 @@ set_destination_row (GtkTreeView    *tree_view,
       /* can't drop here */
       remove_open_timeout (tree_view);
       
-      g_print ("droppable predicate false\n");
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget),
                                        NULL,
                                        GTK_TREE_VIEW_DROP_BEFORE);
@@ -5664,8 +5826,6 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
   
   tree_view = GTK_TREE_VIEW (widget);
   
-  g_print ("motion\n");
-
   if (!set_destination_row (tree_view, context, x, y, &suggested_action, &target))
     return FALSE;
 
@@ -5676,7 +5836,6 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
   if (path == NULL)
     {
       /* Can't drop here. */
-      g_print ("not over a dest row\n");
       gdk_drag_status (context, 0, time);
     }
   else
@@ -5695,13 +5854,11 @@ gtk_tree_view_drag_motion (GtkWidget        *widget,
            * determining whether to accept the drop
            */
           set_status_pending (context, suggested_action);
-          g_print ("motion requesting the drop data\n");          
           gtk_drag_get_data (widget, context, target, time);
         }
       else
         {
           set_status_pending (context, 0);
-          g_print ("motion sending positive status\n");          
           gdk_drag_status (context, suggested_action, time);
         }
     }
@@ -5760,8 +5917,6 @@ gtk_tree_view_drag_drop (GtkWidget        *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));
   
@@ -5780,8 +5935,6 @@ gtk_tree_view_drag_drop (GtkWidget        *widget,
 
   if (target != GDK_NONE && path != NULL)
     {
-      g_print ("have target\n");
-      
       /* in case a motion had requested drag data, change things so we
        * treat drag data receives as a drop.
        */
@@ -5800,7 +5953,6 @@ gtk_tree_view_drag_drop (GtkWidget        *widget,
   
   if (target != GDK_NONE)
     {
-      g_print ("getting data\n");
       gtk_drag_get_data (widget, context, target, time);
       return TRUE;
     }
@@ -5831,8 +5983,6 @@ gtk_tree_view_drag_data_received (GtkWidget        *widget,
 
   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);
 
@@ -5874,8 +6024,6 @@ gtk_tree_view_drag_data_received (GtkWidget        *widget,
               gtk_tree_path_free (src_path);
             }
         }
-
-      g_print ("suggested action %d in drag_data_received\n", suggested_action);
       
       gdk_drag_status (context, suggested_action, time);
 
@@ -5903,8 +6051,6 @@ gtk_tree_view_drag_data_received (GtkWidget        *widget,
                                                  selection_data))
         accepted = TRUE;
     }
-
-  g_print ("accepted: %d\n", accepted);
   
   gtk_drag_finish (context, 
                    accepted,
index fd36f4d0a68e97cd64ae87a06da0ff1c0cc6ad9b..cb23a4e906c0173d4e6c0ab8a398caa99153f580 100644 (file)
@@ -155,6 +155,9 @@ void gtk_tree_view_tree_to_widget_coords (GtkTreeView  *tree_view,
                                           gint         *wx,
                                           gint         *wy);
 
+void     gtk_tree_view_set_rules_hint     (GtkTreeView  *tree_view,
+                                           gboolean      setting);
+gboolean gtk_tree_view_get_rules_hint     (GtkTreeView  *tree_view);
 
 
 /* Drag-and-Drop support */
index 1d7dab0eee279e0defbb16242558359675b7f9c7..7515327c4a813f4999c7cf552959780032e31bca 100644 (file)
@@ -23,6 +23,8 @@
 #include "gtkbutton.h"
 #include "gtkalignment.h"
 #include "gtklabel.h"
+#include "gtkhbox.h"
+#include "gtkarrow.h"
 #include "gtkintl.h"
 
 enum
@@ -38,7 +40,9 @@ enum
   PROP_TITLE,
   PROP_CLICKABLE,
   PROP_WIDGET,
-  PROP_JUSTIFICATION
+  PROP_ALIGNMENT,
+  PROP_SORT_INDICATOR,
+  PROP_SORT_ORDER
 };
 
 enum
@@ -200,13 +204,32 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
 
   g_object_class_install_property (object_class,
-                                   PROP_JUSTIFICATION,
-                                   g_param_spec_enum ("justification",
-                                                      _("Justification"),
-                                                      _("Justification of the column"),
-                                                      GTK_TYPE_JUSTIFICATION,
-                                                      GTK_JUSTIFY_LEFT,
+                                   PROP_ALIGNMENT,
+                                   g_param_spec_float ("alignment",
+                                                       _("Alignment"),
+                                                       _("Alignment of the column header text or widget"),
+                                                       0.0,
+                                                       1.0,
+                                                       0.5,
+                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_SORT_INDICATOR,
+                                   g_param_spec_boolean ("sort_indicator",
+                                                        _("Sort indicator"),
+                                                        _("Whether to show a sort indicator"),
+                                                         FALSE,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (object_class,
+                                   PROP_SORT_ORDER,
+                                   g_param_spec_enum ("sort_order",
+                                                      _("Sort order"),
+                                                      _("Sort direction the sort indicator should indicate"),
+                                                      GTK_TYPE_TREE_SORT_ORDER,
+                                                      GTK_TREE_SORT_ASCENDING,
                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
+  
 }
 
 static void
@@ -217,7 +240,7 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
   gtk_object_sink (GTK_OBJECT (tree_column));
   
   tree_column->button = NULL;
-  tree_column->justification = GTK_JUSTIFY_LEFT;
+  tree_column->xalign = 0.0;
   tree_column->width = 1;
   tree_column->min_width = -1;
   tree_column->max_width = -1;
@@ -227,6 +250,8 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
   tree_column->visible = TRUE;
   tree_column->button_active = FALSE;
   tree_column->dirty = TRUE;
+  tree_column->sort_order = GTK_TREE_SORT_ASCENDING;
+  tree_column->show_sort_indicator = FALSE;
 }
 
 static void
@@ -288,11 +313,21 @@ gtk_tree_view_column_set_property (GObject         *object,
                                        (GtkWidget*) g_value_get_object (value));
       break;
 
-    case PROP_JUSTIFICATION:
-      gtk_tree_view_column_set_justification (tree_column,
-                                              g_value_get_enum (value));
+    case PROP_ALIGNMENT:
+      gtk_tree_view_column_set_alignment (tree_column,
+                                          g_value_get_float (value));
+      break;
+
+    case PROP_SORT_INDICATOR:
+      gtk_tree_view_column_set_sort_indicator (tree_column,
+                                               g_value_get_boolean (value));
       break;
 
+    case PROP_SORT_ORDER:
+      gtk_tree_view_column_set_sort_order (tree_column,
+                                           g_value_get_enum (value));
+      break;
+      
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -313,50 +348,69 @@ gtk_tree_view_column_get_property (GObject         *object,
   switch (prop_id)
     {
     case PROP_CELL_RENDERER:
-      g_value_set_object (value, (GObject*) tree_column->cell);
+      g_value_set_object (value,
+                          (GObject*) gtk_tree_view_column_get_cell_renderer (tree_column));
       break;
 
     case PROP_VISIBLE:
-      g_value_set_boolean (value, tree_column->visible);
+      g_value_set_boolean (value,
+                           gtk_tree_view_column_get_visible (tree_column));
       break;
 
     case PROP_SIZING:
-      g_value_set_enum (value, tree_column->column_type);
+      g_value_set_enum (value,
+                        gtk_tree_view_column_get_sizing (tree_column));
       break;
 
     case PROP_WIDTH:
-      g_value_set_int (value, tree_column->width);
+      g_value_set_int (value,
+                       gtk_tree_view_column_get_width (tree_column));
       break;
 
     case PROP_MIN_WIDTH:
-      g_value_set_int (value, tree_column->min_width);
+      g_value_set_int (value,
+                       gtk_tree_view_column_get_min_width (tree_column));
       break;
 
     case PROP_MAX_WIDTH:
-      g_value_set_int (value, tree_column->max_width);
+      g_value_set_int (value,
+                       gtk_tree_view_column_get_max_width (tree_column));
       break;
 
     case PROP_TITLE:
-      g_value_set_string (value, tree_column->title);
+      g_value_set_string (value,
+                          gtk_tree_view_column_get_title (tree_column));
       break;
 
     case PROP_CLICKABLE:
-      g_value_set_boolean (value, tree_column->button_active);
+      g_value_set_boolean (value,
+                           gtk_tree_view_column_get_clickable (tree_column));
       break;
 
     case PROP_WIDGET:
-      g_warning ("FIXME");
+      g_value_set_object (value,
+                          (GObject*) gtk_tree_view_column_get_widget (tree_column));
       break;
 
-    case PROP_JUSTIFICATION:
-      g_value_set_enum (value, tree_column->justification);
+    case PROP_ALIGNMENT:
+      g_value_set_float (value,
+                         gtk_tree_view_column_get_alignment (tree_column));
       break;
 
+    case PROP_SORT_INDICATOR:
+      g_value_set_boolean (value,
+                           gtk_tree_view_column_get_sort_indicator (tree_column));
+      break;
+
+    case PROP_SORT_ORDER:
+      g_value_set_enum (value,
+                        gtk_tree_view_column_get_sort_order (tree_column));
+      break;
+      
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
-
 }
 
 /* used to make the buttons 'unclickable' */
@@ -455,8 +509,8 @@ void
 gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
                                        GtkCellRenderer   *cell)
 {
-  g_return_if_fail (tree_column != NULL);
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+
   if (cell)
     g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
 
@@ -471,6 +525,22 @@ gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
   g_object_notify (G_OBJECT (tree_column), "cell_renderer");
 }
 
+/**
+ * gtk_tree_view_column_get_cell_renderer:
+ * @tree_column: a #GtkTreeViewColumn
+ * 
+ * Gets the value set with gtk_tree_view_column_set_cell_renderer().
+ * 
+ * Return value: cell renderer for the column, or %NULL if unset
+ **/
+GtkCellRenderer*
+gtk_tree_view_column_get_cell_renderer (GtkTreeViewColumn *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
+  
+  return tree_column->cell;
+}
+
 /**
  * gtk_tree_view_column_add_attribute:
  * @tree_column: A #GtkTreeViewColumn.
@@ -787,6 +857,22 @@ gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
   g_object_notify (G_OBJECT (tree_column), "width");
 }
 
+/**
+ * gtk_tree_view_column_get_width:
+ * @tree_column: a #GtkTreeViewColumn
+ * 
+ * Gets the value set by gtk_tree_view_column_set_width().
+ * 
+ * Return value: the width of the column
+ **/
+gint
+gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
+
+  return tree_column->width;
+}
+
 /**
  * gtk_tree_view_column_set_min_width:
  * @tree_column: A #GtkTreeViewColumn.
@@ -923,8 +1009,13 @@ update_button_contents (GtkTreeViewColumn *tree_column)
 {
   if (tree_column->button)
     {
-      GtkWidget *alignment = GTK_BIN (tree_column->button)->child;
+      GtkWidget *hbox = GTK_BIN (tree_column->button)->child;
+      GtkWidget *alignment = tree_column->alignment;
+      GtkWidget *arrow = tree_column->arrow;
       GtkWidget *current_child = GTK_BIN (alignment)->child;
+
+      gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
+                         0.5, 0.0, 0.0);
       
       if (tree_column->child)
         {
@@ -958,6 +1049,50 @@ update_button_contents (GtkTreeViewColumn *tree_column)
             gtk_label_set_text (GTK_LABEL (current_child),
                                 "");
         }
+
+      switch (tree_column->sort_order)
+        {
+        case GTK_TREE_SORT_ASCENDING:
+          gtk_arrow_set (GTK_ARROW (arrow),
+                         GTK_ARROW_DOWN,
+                         GTK_SHADOW_IN);
+          break;
+
+        case GTK_TREE_SORT_DESCENDING:
+          gtk_arrow_set (GTK_ARROW (arrow),
+                         GTK_ARROW_UP,
+                         GTK_SHADOW_IN);
+          break;
+          
+        default:
+          g_warning (G_STRLOC": bad sort order");
+          break;
+        }
+
+      /* Put arrow on the right if the text is left-or-center justified,
+       * and on the left otherwise; do this by packing boxes, so flipping
+       * text direction will reverse things
+       */
+      gtk_widget_ref (arrow);
+      gtk_container_remove (GTK_CONTAINER (hbox), arrow);
+
+      if (tree_column->xalign <= 0.5)
+        {
+          gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+        }
+      else
+        {
+          gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+          /* move it to the front */
+          gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
+        }
+
+      gtk_widget_unref (arrow);
+
+      if (tree_column->show_sort_indicator)
+        gtk_widget_show (arrow);
+      else
+        gtk_widget_hide (arrow);
     }
 }
 
@@ -995,7 +1130,7 @@ gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
  * 
  * Return value: the title of the column.
  **/
-gchar *
+G_CONST_RETURN gchar *
 gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column)
 {
   g_return_val_if_fail (tree_column != NULL, NULL);
@@ -1120,54 +1255,126 @@ gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column)
 }
 
 /**
- * gtk_tree_view_column_set_justification:
+ * gtk_tree_view_column_set_alignment:
  * @tree_column: A #GtkTreeViewColumn.
- * @justification: The justification of the title.
+ * @xalign: alignment (0.0 for left, 0.5 for center, 1.0 for right)
  * 
- * Sets the justification of the title inside the column header.  If a custom
- * widget has been set, then this value is discarded.
+ * Sets the alignment of the title or custom widget inside the column header.
  **/
 void
-gtk_tree_view_column_set_justification (GtkTreeViewColumn *tree_column,
-                                       GtkJustification   justification)
+gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
+                                    gfloat             xalign)
 {
-  GtkWidget *alignment;
-
   g_return_if_fail (tree_column != NULL);
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
 
-  if (tree_column->justification == justification)
+  if (tree_column->xalign == xalign)
     return;
 
-  tree_column->justification = justification;
+  tree_column->xalign = xalign;
+
+  update_button_contents (tree_column);
+
+  g_object_notify (G_OBJECT (tree_column), "alignment");
+}
 
-  alignment = GTK_BIN (tree_column->button)->child;
+gfloat
+gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0.5);
 
-  if (GTK_IS_ALIGNMENT (alignment))
+  return tree_column->xalign;
+}
+
+/**
+ * gtk_tree_view_column_set_sort_indicator:
+ * @tree_column: a #GtkTreeViewColumn
+ * @setting: %TRUE to display an indicator that the column is sorted
+ *
+ * Call this function with a @setting of %TRUE to display an arrow in
+ * the header button indicating the column is sorted. Call
+ * gtk_tree_view_column_set_sort_order() to change the direction of
+ * the arrow.
+ * 
+ **/
+void
+gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn     *tree_column,
+                                         gboolean               setting)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+
+  setting = setting != FALSE;
+
+  if (setting != tree_column->show_sort_indicator)
     {
-      switch (tree_column->justification)
-       {
-       case GTK_JUSTIFY_LEFT:
-         gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.0, 0.5, 0.0, 0.0);
-         break;
-
-       case GTK_JUSTIFY_RIGHT:
-         gtk_alignment_set (GTK_ALIGNMENT (alignment), 1.0, 0.5, 0.0, 0.0);
-         break;
-
-       case GTK_JUSTIFY_CENTER:
-         gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.5, 0.5, 0.0, 0.0);
-         break;
-
-       case GTK_JUSTIFY_FILL:
-         gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.5, 0.5, 0.0, 0.0);
-         break;
-
-       default:
-         break;
-       }
+      tree_column->show_sort_indicator = setting;
+
+      update_button_contents (tree_column);
+      
+      g_object_notify (G_OBJECT (tree_column), "sort_indicator");
     }
+}
+
+/**
+ * gtk_tree_view_column_get_sort_indicator:
+ * @tree_column: a #GtkTreeViewColumn
+ * 
+ * Gets the value set by gtk_tree_view_column_set_sort_indicator().
+ * 
+ * Return value: whether the sort indicator arrow is displayed
+ **/
+gboolean
+gtk_tree_view_column_get_sort_indicator  (GtkTreeViewColumn     *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
+
+  return tree_column->show_sort_indicator;
+}
+
+/**
+ * gtk_tree_view_column_set_sort_order:
+ * @tree_column: a #GtkTreeViewColumn
+ * @order: sort order that the sort indicator should indicate
+ *
+ * Changes the appearance of the sort indicator. (This <emphasis>does
+ * not</emphasis> actually sort the model - for the models shipped
+ * with GTK+, use at gtk_tree_sortable_set_sort_column() to do
+ * that. For custom models, the mechanism will vary.) The sort
+ * indicator changes direction to indicate normal sort or reverse
+ * sort. Note that you must have the sort indicator enabled to see
+ * anything when calling this function; see
+ * gtk_tree_view_column_set_sort_indicator().
+ * 
+ **/
+void
+gtk_tree_view_column_set_sort_order      (GtkTreeViewColumn     *tree_column,
+                                          GtkTreeSortOrder       order)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+
+  if (order != tree_column->sort_order)
+    {
+      tree_column->sort_order = order;
+
+      update_button_contents (tree_column);
+      
+      g_object_notify (G_OBJECT (tree_column), "sort_order");
+    }
+}
+
+/**
+ * gtk_tree_view_column_get_sort_order:
+ * @tree_column: a #GtkTreeViewColumn
+ * 
+ * Gets the value set by gtk_tree_view_column_set_sort_order().
+ * 
+ * Return value: the sort order the sort indicator is indicating
+ **/
+GtkTreeSortOrder
+gtk_tree_view_column_get_sort_order      (GtkTreeViewColumn     *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
 
-  g_object_notify (G_OBJECT (tree_column), "justification");
+  return tree_column->sort_order;
 }
 
index ea13946c4bb28695486450583eebe9688e53bbe1..3dbc471afdada1e40ad2f1d8aba47fcb859af850 100644 (file)
@@ -23,6 +23,7 @@
 #include <gtk/gtkobject.h>
 #include <gtk/gtkcellrenderer.h>
 #include <gtk/gtktreemodel.h>
+#include <gtk/gtktreesortable.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -55,9 +56,11 @@ struct _GtkTreeViewColumn
 
   GtkWidget *tree_view;
   GtkWidget *button;
-  GtkWidget *child;
+  GtkWidget *child;  
+  GtkWidget *arrow;
+  GtkWidget *alignment;
   GdkWindow *window;
-  GtkJustification justification;
+  gfloat xalign;
 
   gint id;
 
@@ -71,9 +74,11 @@ struct _GtkTreeViewColumn
   GtkCellRenderer *cell;
   GSList *attributes;
   GtkTreeViewColumnSizing column_type;
+  GtkTreeSortOrder sort_order;
   guint visible       : 1;
   guint button_active : 1;
   guint dirty         : 1;
+  guint show_sort_indicator : 1;
 };
 
 struct _GtkTreeViewColumnClass
@@ -91,6 +96,7 @@ GtkTreeViewColumn *gtk_tree_view_column_new_with_attributes (gchar
                                                             ...);
 void               gtk_tree_view_column_set_cell_renderer   (GtkTreeViewColumn     *tree_column,
                                                             GtkCellRenderer       *cell);
+GtkCellRenderer   *gtk_tree_view_column_get_cell_renderer   (GtkTreeViewColumn     *tree_column);
 void               gtk_tree_view_column_add_attribute       (GtkTreeViewColumn     *tree_column,
                                                             gchar                 *attribute,
                                                             gint                   column);
@@ -121,18 +127,26 @@ void               gtk_tree_view_column_clicked             (GtkTreeViewColumn
 
 /* Options for manipulating the column headers
  */
-void               gtk_tree_view_column_set_title           (GtkTreeViewColumn     *tree_column,
-                                                            gchar                 *title);
-gchar             *gtk_tree_view_column_get_title           (GtkTreeViewColumn     *tree_column);
-void               gtk_tree_view_column_set_clickable       (GtkTreeViewColumn     *tree_column,
-                                                             gboolean               active);
-gboolean           gtk_tree_view_column_get_clickable       (GtkTreeViewColumn     *tree_column);
-void               gtk_tree_view_column_set_widget          (GtkTreeViewColumn     *tree_column,
-                                                            GtkWidget             *widget);
-GtkWidget         *gtk_tree_view_column_get_widget          (GtkTreeViewColumn     *tree_column);
-void               gtk_tree_view_column_set_justification   (GtkTreeViewColumn     *tree_column,
-                                                            GtkJustification       justification);
-GtkJustification   gtk_tree_view_column_get_justification   (GtkTreeViewColumn     *tree_column);
+void                  gtk_tree_view_column_set_title          (GtkTreeViewColumn *tree_column,
+                                                               gchar             *title);
+G_CONST_RETURN gchar *gtk_tree_view_column_get_title          (GtkTreeViewColumn *tree_column);
+void                  gtk_tree_view_column_set_clickable      (GtkTreeViewColumn *tree_column,
+                                                               gboolean           active);
+gboolean              gtk_tree_view_column_get_clickable      (GtkTreeViewColumn *tree_column);
+void                  gtk_tree_view_column_set_widget         (GtkTreeViewColumn *tree_column,
+                                                               GtkWidget         *widget);
+GtkWidget         *   gtk_tree_view_column_get_widget         (GtkTreeViewColumn *tree_column);
+void                  gtk_tree_view_column_set_alignment      (GtkTreeViewColumn *tree_column,
+                                                               gfloat             xalign);
+gfloat                gtk_tree_view_column_get_alignment      (GtkTreeViewColumn *tree_column);
+void                  gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn *tree_column,
+                                                               gboolean           setting);
+gboolean              gtk_tree_view_column_get_sort_indicator (GtkTreeViewColumn *tree_column);
+void                  gtk_tree_view_column_set_sort_order     (GtkTreeViewColumn *tree_column,
+                                                               GtkTreeSortOrder   order);
+GtkTreeSortOrder      gtk_tree_view_column_get_sort_order     (GtkTreeViewColumn *tree_column);
+
+
 
 
 
index 5ffcecb2553e93694e39c760935ce0f8e5717908..226d9017ab1b2718234a5df8948ca8dd708c0405 100644 (file)
@@ -261,12 +261,17 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type)
       col = gtk_tree_view_get_column (tree_view, 0);
     }
 
+  gtk_tree_view_set_rules_hint (tree_view, FALSE);
+  
   switch (type)
     {
     case COLUMNS_NONE:
       break;
 
-    case COLUMNS_LOTS:      
+    case COLUMNS_LOTS:
+      /* with lots of columns we need to turn on rules */
+      gtk_tree_view_set_rules_hint (tree_view, TRUE);
+      
       rend = gtk_cell_renderer_text_new ();
       
       col = gtk_tree_view_column_new_with_attributes ("Column 1",
@@ -691,7 +696,7 @@ main (int    argc,
   gtk_container_add (GTK_CONTAINER (window), table);
 
   tv = gtk_tree_view_new_with_model (models[0]);
-
+  
   gtk_tree_view_set_rows_drag_source (GTK_TREE_VIEW (tv),
                                       GDK_BUTTON1_MASK,
                                       row_targets,
@@ -1374,6 +1379,28 @@ int_changed (GObject *object, GParamSpec *pspec, gpointer data)
   g_value_unset (&val);
 }
 
+static void
+float_modified (GtkAdjustment *adj, gpointer data)
+{
+  ObjectProperty *p = data;
+
+  g_object_set (p->obj, p->prop, (float) adj->value, NULL);
+}
+
+static void
+float_changed (GObject *object, GParamSpec *pspec, gpointer data)
+{
+  GtkAdjustment *adj = GTK_ADJUSTMENT (data);
+  GValue val = { 0, };  
+
+  g_value_init (&val, G_TYPE_FLOAT);
+  g_object_get_property (object, pspec->name, &val);
+
+  if (g_value_get_float (&val) != (float) adj->value)
+    gtk_adjustment_set_value (adj, g_value_get_float (&val));
+
+  g_value_unset (&val);
+}
 
 static void
 string_modified (GtkEntry *entry, gpointer data)
@@ -1559,6 +1586,34 @@ create_prop_editor (GObject *object)
                                 object, spec->name, (GtkSignalFunc) int_modified);
           break;
 
+        case G_TYPE_FLOAT:
+          hbox = gtk_hbox_new (FALSE, 10);
+          label = gtk_label_new (spec->nick);
+          gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+          gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+          adj = GTK_ADJUSTMENT (gtk_adjustment_new (G_PARAM_SPEC_FLOAT (spec)->default_value,
+                                                    G_PARAM_SPEC_FLOAT (spec)->minimum,
+                                                    G_PARAM_SPEC_FLOAT (spec)->maximum,
+                                                    0.1,
+                                                    MAX ((G_PARAM_SPEC_FLOAT (spec)->maximum -
+                                                          G_PARAM_SPEC_FLOAT (spec)->minimum) / 10, 0.1),
+                                                    0.0));
+
+          prop_edit = gtk_spin_button_new (adj, 0.1, 2);
+          
+          gtk_box_pack_end (GTK_BOX (hbox), prop_edit, FALSE, FALSE, 0);
+          
+          gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 
+
+          g_object_connect_property (object, spec->name,
+                                     GTK_SIGNAL_FUNC (float_changed),
+                                     adj, G_OBJECT (adj));
+
+          if (can_modify)
+            connect_controller (G_OBJECT (adj), "value_changed",
+                                object, spec->name, (GtkSignalFunc) float_modified);
+          break;
+          
         case G_TYPE_STRING:
           hbox = gtk_hbox_new (FALSE, 10);
           label = gtk_label_new (spec->nick);