]> Pileus Git - ~andy/gtk/commitdiff
Few fixes for column resize. Store resize column in clist->drag_pos.
authorLars Hamann <lars@gtk.org>
Fri, 31 Jul 1998 20:48:06 +0000 (20:48 +0000)
committerLars Hamann <lars@src.gnome.org>
Fri, 31 Jul 1998 20:48:06 +0000 (20:48 +0000)
Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>

        * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
        (gtk_clist_button_release) (new_column_width): Few fixes for
        column resize. Store resize column in clist->drag_pos.

Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>

        * gtk/gtkctree.h
        * gtk/gtkctree.c
        * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
        to GtkCTreeNode *node.

        * gtk/gtklist.h : added extended selection mode and auto scrolling.
        (struct _GtkList): removed unneeded variables timer, button,
        selection_start_pos, selection_end_pos, scroll_direction, have_grab.
        Added new variables undo_selection, undo_unselection, last_focus_child,
        undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
        drag_selection, add_mode.

        New functions :
        (gtk_list_extend_selection), (gtk_list_start_selection),
        (gtk_list_end_selection), (gtk_list_select_all),
        (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
        (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
        (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
        (gtk_list_undo_selection), (gtk_list_end_drag_selection)

        * gtk/gtklist.c :
        (gtk_list_enter_notify): removed, because auto scrolling now works
        with gtk_list_motion_notify

        New functions, needed for auto scrolling :
        (gtk_list_motion_notify) (gtk_list_move_focus_child)

        New functions for extended selection support :
        (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
        (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
        (gtk_list_focus_lost)

        (gtk_list_set_focus_child): modified gtk_container_set_focus_child
        function to support auto scrolling, and avoid out-of-sync errors in
        case auf GTK_SELECTION_BROWSE
        (gtk_list_focus): modified gtk_container_focus function to avoid out
        off sync errors in case auf GTK_SELECTION_EXTENDED

        * gtk/gtklistitem.h
        * gtk/gtklistitem.c :
        New signal functions for key binding support :
        (toggle_focus_row), (select_all), (list_item), (unselect_all)
        (list_item), (undo_selection), (start_selection), (end_selection)
        (extend_selection), (scroll_horizontal), (scroll_vertical),
        (toggle_add_mode)
        (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
        GDK_KEY_RELEASE_MASK
        (gtk_list_item_draw_focus): modify gc if parent has add_mode set.

        * gtk/gtkcombo.c :
        (gtk_combo_popup_button_press):  grab pointer for combo->list
        (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
        (gtk_combo_list_key_press): take care of which child HAS_GRAB
        (gtk_comb_init): don't connect combo->button with button_release_event

17 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
gtk/gtkclist.c
gtk/gtkcombo.c
gtk/gtkctree.c
gtk/gtkctree.h
gtk/gtklist.c
gtk/gtklist.h
gtk/gtklistitem.c
gtk/gtklistitem.h
gtk/testgtk.c
tests/testgtk.c

index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index 527dc7f5a06b06b06162f06449ccb6a9d91398f9..3662c1eb033f7e66c39f62b14b62a228a31e2eeb 100644 (file)
@@ -1,3 +1,66 @@
+Fri Jul 31 20:45:07 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkclist.c (gtk_clist_button_press) (gtk_clist_motion)
+       (gtk_clist_button_release) (new_column_width): Few fixes for
+       column resize. Store resize column in clist->drag_pos.
+
+Thu Jul 31 15:18:36 1998  Lars Hamann  <lars@gtk.org>
+
+       * gtk/gtkctree.h 
+       * gtk/gtkctree.c 
+       * gtk/testgtk.c : New typedef GtkCTreeNode, changed all GList *node
+       to GtkCTreeNode *node.
+
+       * gtk/gtklist.h : added extended selection mode and auto scrolling.
+       (struct _GtkList): removed unneeded variables timer, button,
+       selection_start_pos, selection_end_pos, scroll_direction, have_grab.
+       Added new variables undo_selection, undo_unselection, last_focus_child,
+       undo_focus_child, htimer, vtimer, anchor, drag_pos, anchor_state,
+       drag_selection, add_mode.
+       New functions :
+       (gtk_list_extend_selection), (gtk_list_start_selection),
+       (gtk_list_end_selection), (gtk_list_select_all),
+       (gtk_list_unselect_all), (gtk_list_scroll_horizontal),
+       (gtk_list_scroll_vertical), (gtk_list_toggle_add_mode),
+       (gtk_list_toggle_focus_row), (gtk_list_toggle_row),
+       (gtk_list_undo_selection), (gtk_list_end_drag_selection)
+        
+       * gtk/gtklist.c : 
+       (gtk_list_enter_notify): removed, because auto scrolling now works
+       with gtk_list_motion_notify
+       New functions, needed for auto scrolling :
+       (gtk_list_motion_notify) (gtk_list_move_focus_child)
+       New functions for extended selection support :
+       (gtk_list_set_anchor), (gtk_list_fake_unselect_all),
+       (gtk_list_fake_toggle_row), (gtk_list_update_extended_selection),
+       (gtk_list_focus_lost)
+       
+       (gtk_list_set_focus_child): modified gtk_container_set_focus_child
+       function to support auto scrolling, and avoid out-of-sync errors in
+       case auf GTK_SELECTION_BROWSE
+       (gtk_list_focus): modified gtk_container_focus function to avoid out
+       off sync errors in case auf GTK_SELECTION_EXTENDED
+
+       * gtk/gtklistitem.h 
+       * gtk/gtklistitem.c :
+       New signal functions for key binding support :
+       (toggle_focus_row), (select_all), (list_item), (unselect_all)
+       (list_item), (undo_selection), (start_selection), (end_selection)
+       (extend_selection), (scroll_horizontal), (scroll_vertical),
+       (toggle_add_mode)
+       (gtk_list_item_realize): added  GDK_KEY_PRESS_MASK |
+       GDK_KEY_RELEASE_MASK
+       (gtk_list_item_draw_focus): modify gc if parent has add_mode set.
+       * gtk/gtkcombo.c :
+       (gtk_combo_popup_button_press):  grab pointer for combo->list
+       (gtk_combo_button_release): ungrab only if combo->popwin HAS_GRAB
+       (gtk_combo_list_key_press): take care of which child HAS_GRAB
+       (gtk_comb_init): don't connect combo->button with button_release_event
+
 Thu Jul 30 12:39:36 1998  Lars Hamann  <lars@gtk.org>
 
        * gtk/gtkclist.c (gtk_clist_motion): removed a few unneeded lines
@@ -18,12 +81,6 @@ Tue Jul 28 00:03:20 1998  Lars Hamann  <lars@gtk.org>
        * gtk/gtknotebook.c (gtk_notebook_paint): small fix for border drawing
        bug
 
-Tue Jul 28 00:15:28 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
-
-       * docs/gdk.sgml: new format for GDK documentation.  Eventually
-         plan to remove gdk.texi, but not quite yet.  Just getting 
-         started.
-
 Mon Jul 27 09:18:13 BST 1998  Tony Gale  <gale@gtk.org>
 
        * docs/gtk_tut.sgml: GtkTree section from
@@ -102,7 +159,7 @@ Sat Jul 25 02:25:03 1998  Lars Hamann  <lars@gtk.org>
 
 Fri Jul 24 18:15:49 1998  Lars Hamann  <lars@gtk.org>
 
-        * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
+       * gtk/gtkclist.c (toggle_focus_row): mini code cleanup
 
 Fri, 24 Jul 1998 10:56:22 +0200 Paolo Molaro <lupus@debian.org>
 
index b7c8786bd26ad0d6fa2e6ea551d68029dda1a066..cbe95622e19684fc18cba5f04aa6dce064e6403b 100644 (file)
@@ -2758,6 +2758,7 @@ gtk_clist_button_press (GtkWidget * widget,
          gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0);
 
        draw_xor_line (clist);
+       clist->drag_pos = i;
        return FALSE;
       }
 
@@ -2768,7 +2769,6 @@ static gint
 gtk_clist_button_release (GtkWidget * widget,
                          GdkEventButton * event)
 {
-  gint i, x, width, visible;
   GtkCList *clist;
 
   g_return_val_if_fail (widget != NULL, FALSE);
@@ -2783,30 +2783,32 @@ gtk_clist_button_release (GtkWidget * widget,
 
   /* release on resize windows */
   if (GTK_CLIST_IN_DRAG (clist))
-    for (i = 0; i < clist->columns; i++)
-      if (clist->column[i].window && event->window == clist->column[i].window)
-       {
-         GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
-         gtk_widget_get_pointer (widget, &x, NULL);
-         width = new_column_width (clist, i, &x, &visible);
+    {
+      gint i, x, width, visible;
 
-         gtk_grab_remove (widget);
-         gdk_pointer_ungrab (event->time);
+      i = clist->drag_pos;
+      clist->drag_pos = -1;
+      GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
+      gtk_widget_get_pointer (widget, &x, NULL);
 
-         if (visible)
-           draw_xor_line (clist);
+      width = new_column_width (clist, i, &x, &visible);
+      gtk_grab_remove (widget);
+      gdk_pointer_ungrab (event->time);
 
-         if (GTK_CLIST_ADD_MODE (clist))
-           {
-             gdk_gc_set_line_attributes (clist->xor_gc, 1, 
-                                         GDK_LINE_ON_OFF_DASH, 0, 0);
-             gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
-           }
+      if (visible)
+       draw_xor_line (clist);
 
-         resize_column (clist, i, width);
-         return FALSE;
+      if (GTK_CLIST_ADD_MODE (clist))
+       {
+         gdk_gc_set_line_attributes (clist->xor_gc, 1,
+                                     GDK_LINE_ON_OFF_DASH, 0, 0);
+         gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
        }
 
+      resize_column (clist, i, width);
+      return FALSE;
+    }
+
   if (GTK_CLIST_DRAG_SELECTION (clist))
     {
       gint row;
@@ -2943,44 +2945,52 @@ gtk_clist_motion (GtkWidget * widget,
                  GdkEventMotion * event)
 {
   GtkCList *clist;
-  gint i, x, y, visible;
+  gint x, y, visible;
   gint row;
+  gint new_width;
+  static gint cc =0;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
 
   clist = GTK_CLIST (widget);
-
+  cc++;
   if (!(gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)))
     return FALSE;
 
   if (GTK_CLIST_IN_DRAG (clist))
-    for (i = 0; i < clist->columns; i++)
-      if (clist->column[i].window && event->window == clist->column[i].window)
+    {
+      if (event->is_hint || event->window != widget->window)
+       gtk_widget_get_pointer (widget, &x, NULL);
+      else
+       x = event->x;
+
+      new_width = new_column_width (clist, clist->drag_pos, &x, &visible);
+      /* Welcome to my hack! I'm going to use a value of x_drag = -99999
+       * to indicate that the xor line is already invisible */
+      
+      if (!visible && clist->x_drag != -99999)
        {
-         if (event->is_hint || event->window != widget->window)
-           gtk_widget_get_pointer (widget, &x, NULL);
-         else
-           x = event->x;
+         draw_xor_line (clist);
+         clist->x_drag = -99999;
+       }
 
-         new_column_width (clist, i, &x, &visible);
-         /* Welcome to my hack! I'm going to use a value of x_drag = -99999
-          * to indicate that the xor line is already invisible */
-         if (!visible && clist->x_drag != -99999)
-           {
-             draw_xor_line (clist);
-             clist->x_drag = -99999;
-           }
+      if (x != clist->x_drag && visible)
+       {
+         if (clist->x_drag != -99999)
+           draw_xor_line (clist);
 
-         if (x != clist->x_drag && visible)
-           {
-             if (clist->x_drag != -99999)
-               draw_xor_line (clist);
+         clist->x_drag = x;
+         draw_xor_line (clist);
+       }
 
-             clist->x_drag = x;
-             draw_xor_line (clist);
-           }
+      if (new_width <= COLUMN_MIN_WIDTH + 1)
+       {
+         if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) && x < 0)
+           gtk_clist_moveto (clist, -1, clist->drag_pos, 0, 0);
+         return FALSE;
        }
+    }
 
       
   if (event->is_hint || event->window != clist->clist_window)
@@ -4112,7 +4122,7 @@ new_column_width (GtkCList * clist,
       rx = cx - clist->hoffset;
     }
 
-  if (cx > clist->clist_window_width)
+  if (cx < 0 || cx > clist->clist_window_width)
     *visible = 0;
   else
     *visible = 1;
index 165bed40f110777e7a627c6ee2268ed9111398ae..03b24e1ecc4a7d7034483c0a244a20b95bad4a37 100644 (file)
@@ -383,6 +383,7 @@ gtk_combo_activate (GtkWidget        *widget,
 
   if (!GTK_WIDGET_HAS_FOCUS (combo->entry))
     gtk_widget_grab_focus (combo->entry);
+
   gtk_grab_add (combo->popwin);
   gdk_pointer_grab (combo->popwin->window, TRUE,
                    GDK_BUTTON_PRESS_MASK | 
@@ -402,6 +403,14 @@ gtk_combo_popup_button_press (GtkWidget        *button,
     gtk_combo_popup_list (combo);
 
   combo->current_button = event->button;
+  
+  GTK_LIST (combo->list)->drag_selection = TRUE;
+  gdk_pointer_grab (combo->list->window, TRUE,
+                   GDK_POINTER_MOTION_HINT_MASK |
+                   GDK_BUTTON1_MOTION_MASK |
+                   GDK_BUTTON_RELEASE_MASK,
+                   NULL, NULL, event->time);
+  gtk_grab_add (combo->list);
 }
 
 static void         
@@ -527,8 +536,11 @@ gtk_combo_button_release (GtkWidget * widget, GdkEvent * event, GtkCombo * combo
     {
       /* The user has clicked inside the popwin and released */
 
-      gtk_grab_remove (combo->popwin);
-      gdk_pointer_ungrab (event->button.time);
+      if (GTK_WIDGET_HAS_GRAB (combo->popwin))
+       {
+         gtk_grab_remove (combo->popwin);
+         gdk_pointer_ungrab (event->button.time);
+       }
     }
   
   gtk_widget_hide (combo->popwin);
@@ -583,9 +595,21 @@ gtk_combo_list_key_press (GtkWidget * widget, GdkEventKey * event, GtkCombo * co
 {
   if (event->keyval == GDK_Escape)
     {
+      if (GTK_WIDGET_HAS_GRAB (combo->popwin))
+       {
+         gtk_grab_remove (combo->popwin);
+         gdk_pointer_ungrab (GDK_CURRENT_TIME);
+       }
+      else if (GTK_WIDGET_HAS_GRAB (combo->list))
+       gtk_list_end_drag_selection (GTK_LIST (combo->list));
       gtk_widget_hide (combo->popwin);
-      gtk_grab_remove (combo->popwin);
-      gdk_pointer_ungrab (GDK_CURRENT_TIME);
+      if (GTK_WIDGET_HAS_GRAB (combo->button))
+       {
+         combo->current_button = 0;
+         GTK_BUTTON (combo->button)->in_button = FALSE;
+         gtk_button_released (combo->button);
+         gtk_grab_remove (combo->button);
+       }
       return TRUE;
     }
   return FALSE;
@@ -625,8 +649,8 @@ gtk_combo_init (GtkCombo * combo)
                      (GtkSignalFunc) gtk_combo_activate, combo);
   gtk_signal_connect_after (GTK_OBJECT (combo->button), "button_press_event",
                            (GtkSignalFunc) gtk_combo_popup_button_press, combo);
-  gtk_signal_connect_after (GTK_OBJECT (combo->button), "button_release_event",
-                           (GtkSignalFunc) gtk_combo_button_release, combo);
+  /*gtk_signal_connect_after (GTK_OBJECT (combo->button), "button_release_event",
+    (GtkSignalFunc) gtk_combo_button_release, combo);*/
   gtk_signal_connect (GTK_OBJECT (combo->button), "leave_notify_event",
                      (GtkSignalFunc) gtk_combo_popup_button_leave, combo);
   /*gtk_signal_connect(GTK_OBJECT(combo->button), "clicked",
@@ -670,6 +694,8 @@ gtk_combo_init (GtkCombo * combo)
   gtk_container_add (GTK_CONTAINER (combo->popup), combo->list);
   gtk_container_set_focus_vadjustment (GTK_CONTAINER (combo->list),
                                       gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (combo->popup)));
+  gtk_container_set_focus_hadjustment (GTK_CONTAINER (combo->list),
+                                      gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (combo->popup)));
   gtk_widget_show (combo->list);
 
   combo->list_change_id = gtk_signal_connect (GTK_OBJECT (combo->list), "selection_changed",
@@ -679,8 +705,8 @@ gtk_combo_init (GtkCombo * combo)
   gtk_signal_connect (GTK_OBJECT (combo->popwin), "button_press_event",
                      GTK_SIGNAL_FUNC (gtk_combo_button_press), combo);
 
-  gtk_signal_connect (GTK_OBJECT (combo->list), "button_release_event",
-                     GTK_SIGNAL_FUNC (gtk_combo_button_release), combo);
+  gtk_signal_connect_after (GTK_OBJECT (combo->list), "button_release_event",
+                           GTK_SIGNAL_FUNC (gtk_combo_button_release), combo);
   /* We connect here on the button, because we'll have a grab on it
    * when the event occurs. But we are actually interested in enters
    * for the combo->list.
index 0010bf43d721c026b268c584c94130107b8ee861..9cee1fd402ac095fc932830a57859e9e8cd95f8f 100644 (file)
@@ -68,8 +68,8 @@ static void draw_xor_line               (GtkCTree       *ctree);
 static void draw_xor_rect               (GtkCTree       *ctree);
 static void create_drag_icon            (GtkCTree       *ctree,
                                         GtkCTreeRow    *row);
-static void tree_draw_row               (GtkCTree      *ctree,
-                                        GList         *row);
+static void tree_draw_node              (GtkCTree      *ctree,
+                                        GtkCTreeNode  *node);
 static void cell_empty                  (GtkCList      *clist,
                                         GtkCListRow   *clist_row,
                                         gint           column);
@@ -90,7 +90,7 @@ static void cell_set_pixtext            (GtkCList      *clist,
                                         GdkPixmap     *pixmap,
                                         GdkBitmap     *mask);
 static void set_node_info               (GtkCTree      *ctree,
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gchar         *text,
                                         guint8         spacing,
                                         GdkPixmap     *pixmap_closed,
@@ -103,34 +103,34 @@ static GtkCTreeRow *row_new             (GtkCTree      *ctree);
 static void row_delete                  (GtkCTree      *ctree,
                                         GtkCTreeRow   *ctree_row);
 static void tree_delete                 (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 static void tree_delete_row             (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 static void real_clear                  (GtkCList      *clist);
 static void tree_update_level           (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 static void tree_select                 (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 static void tree_unselect               (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 static void real_select_all             (GtkCList      *clist);
 static void real_unselect_all           (GtkCList      *clist);
 static void tree_expand                 (GtkCTree      *ctree, 
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gpointer       data);
 static void tree_collapse               (GtkCTree      *ctree, 
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gpointer       data);
 static void tree_collapse_to_depth      (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gint           depth);
 static void tree_toggle_expansion       (GtkCTree      *ctree,
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gpointer       data);
 static void change_focus_row_expansion  (GtkCTree      *ctree,
                                         GtkCTreeExpansionType expansion);
@@ -143,56 +143,56 @@ static void real_unselect_row           (GtkCList      *clist,
                                         gint           column,
                                         GdkEvent      *event);
 static void real_tree_select            (GtkCTree      *ctree,
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gint           column);
 static void real_tree_unselect          (GtkCTree      *ctree,
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gint           column);
 static void tree_toggle_selection       (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gint           column);
 static void real_tree_expand            (GtkCTree      *ctree,
-                                        GList         *node);
+                                        GtkCTreeNode  *node);
 static void real_tree_collapse          (GtkCTree      *ctree,
-                                        GList         *node);
+                                        GtkCTreeNode  *node);
 static void real_tree_move              (GtkCTree      *ctree,
-                                        GList         *node,
-                                        GList         *new_parent, 
-                                        GList         *new_sibling);
+                                        GtkCTreeNode  *node,
+                                        GtkCTreeNode  *new_parent, 
+                                        GtkCTreeNode  *new_sibling);
 static void gtk_ctree_link              (GtkCTree      *ctree,
-                                        GList         *node,
-                                        GList         *parent,
-                                        GList         *sibling,
+                                        GtkCTreeNode  *node,
+                                        GtkCTreeNode  *parent,
+                                        GtkCTreeNode  *sibling,
                                         gboolean       update_focus_row);
 static void gtk_ctree_unlink            (GtkCTree      *ctree, 
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gboolean       update_focus_row);
-static GList * gtk_ctree_last_visible    (GtkCTree     *ctree,
-                                         GList        *node);
+static GtkCTreeNode * gtk_ctree_last_visible (GtkCTree     *ctree,
+                                             GtkCTreeNode *node);
 static gboolean ctree_is_hot_spot       (GtkCTree      *ctree, 
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gint           row, 
                                         gint           x, 
                                         gint           y);
 static void tree_sort                   (GtkCTree      *ctree,
-                                        GList         *node,
+                                        GtkCTreeNode  *node,
                                         gpointer       data);
-static gint default_compare             (GtkCTree      *ctree,
-                                        const GList   *node1,
-                                        const GList   *node2);
+static gint default_compare             (GtkCTree           *ctree,
+                                        const GtkCTreeNode *node1,
+                                        const GtkCTreeNode *node2);
 
 
 
 static void fake_unselect_all           (GtkCList      *clist,
                                         gint           row);
-static GList selection_find           (GtkCList      *clist,
+static GList * selection_find           (GtkCList      *clist,
                                         gint           row_number,
                                         GList         *row_list_element);
 static void resync_selection            (GtkCList      *clist,
                                         GdkEvent      *event);
 static void real_undo_selection         (GtkCList      *clist);
 static void select_row_recursive        (GtkCTree      *ctree, 
-                                        GList         *node, 
+                                        GtkCTreeNode  *node, 
                                         gpointer       data);
 
 
@@ -209,20 +209,20 @@ enum
   LAST_SIGNAL
 };
 
-typedef void (*GtkCTreeSignal1) (GtkObject *object,
-                                GList     *arg1,
-                                gint       arg2,
-                                gpointer   data);
+typedef void (*GtkCTreeSignal1) (GtkObject    *object,
+                                GtkCTreeNode *arg1,
+                                gint          arg2,
+                                gpointer      data);
 
-typedef void (*GtkCTreeSignal2) (GtkObject *object,
-                                GList     *arg1,
-                                GList     *arg2,
-                                GList     *arg3,
-                                gpointer   data);
+typedef void (*GtkCTreeSignal2) (GtkObject    *object,
+                                GtkCTreeNode *arg1,
+                                GtkCTreeNode *arg2,
+                                GtkCTreeNode *arg3,
+                                gpointer      data);
 
-typedef void (*GtkCTreeSignal3) (GtkObject *object,
-                                GList     *arg1,
-                                gpointer   data);
+typedef void (*GtkCTreeSignal3) (GtkObject    *object,
+                                GtkCTreeNode *arg1,
+                                gpointer      data);
 
 typedef void (*GtkCTreeSignal4) (GtkObject         *object,
                                 GtkCTreeExpansionType arg1,
@@ -522,7 +522,7 @@ gtk_ctree_button_press (GtkWidget      *widget,
   if (event->window == clist->clist_window)
     {
       gboolean collapse_expand = FALSE;
-      GList *work;
+      GtkCTreeNode *work;
       gint x;
       gint y;
       gint row;
@@ -537,7 +537,7 @@ gtk_ctree_button_press (GtkWidget      *widget,
       if (event->button == 2)
        ctree->drag_row = - 1 - ROW_FROM_YPIXEL (clist, y);
 
-      work = g_list_nth (clist->row_list, row);
+      work = GTK_CTREE_NODE (g_list_nth (clist->row_list, row));
          
       if (ctree->reorderable && event->button == 2 && !ctree->in_drag &&
          clist->anchor == -1)
@@ -711,7 +711,7 @@ gtk_ctree_button_motion (GtkWidget      *widget,
 
       /* re-calculate target (mouse left the window) */
       if (ctree->drag_target && ctree->drag_row == -1)
-       ctree->drag_target = g_list_nth (clist->row_list, row);
+       ctree->drag_target = GTK_CTREE_NODE (g_list_nth (clist->row_list,row));
       
       if (y < 0 || y > clist->clist_window_height || 
          ROW_TOP_YPIXEL (clist, row + 1) > clist->clist_window_height
@@ -741,7 +741,8 @@ gtk_ctree_button_motion (GtkWidget      *widget,
                    draw_xor_line (ctree);
                }
              ctree->insert_pos = insert_pos;
-             ctree->drag_target = g_list_nth (clist->row_list, row);
+             ctree->drag_target =
+               GTK_CTREE_NODE (g_list_nth (clist->row_list, row));
              ctree->drag_row = row;
              draw_xor_line (ctree);
            }
@@ -757,7 +758,8 @@ gtk_ctree_button_motion (GtkWidget      *widget,
                }
              ctree->drag_rect = TRUE;
              ctree->insert_pos = insert_pos;
-             ctree->drag_target = g_list_nth (clist->row_list, row);
+             ctree->drag_target =
+               GTK_CTREE_NODE (g_list_nth (clist->row_list, row));
              ctree->drag_row = row;
              draw_xor_rect (ctree);
            }
@@ -858,13 +860,13 @@ gtk_ctree_button_release (GtkWidget      *widget,
     {
       gint row;
       gint column;
-      GList *work;
+      GtkCTreeNode *work;
 
       if (gtk_clist_get_selection_info
          (clist, event->x, event->y, &row, &column))
        {
          if (clist->anchor == clist->focus_row &&
-             (work = g_list_nth (clist->row_list, row)))
+             (work = GTK_CTREE_NODE (g_list_nth (clist->row_list, row))))
            tree_toggle_selection (ctree, work, column);
        }
       clist->anchor = -1;
@@ -1469,8 +1471,8 @@ draw_row (GtkCList     *clist,
          GdkGC *cgc;
          GdkGC *tgc;
          GdkGC *mbg_gc;
-         GList *work;
-         GList *work2;
+         GtkCTreeNode *work;
+         GtkCTreeNode *work2;
          gint xoffset;
          gint yoffset;
          gint xcenter;
@@ -1536,8 +1538,9 @@ draw_row (GtkCList     *clist,
                      work2 = gtk_ctree_find_glist_ptr
                        (ctree, (GtkCTreeRow *) clist_row);
 
-                     if (work2->next)
-                       next_level = GTK_CTREE_ROW (work2->next)->level;
+                     if (GTK_CTREE_NODE_NEXT (work2))
+                       next_level =
+                         GTK_CTREE_ROW (GTK_CTREE_NODE_NEXT (work2))->level;
                      else
                        next_level = 0;
                    }
@@ -1576,12 +1579,13 @@ draw_row (GtkCList     *clist,
 
                          if (clist_row->state != GTK_STATE_SELECTED)
                            {
-                             if ((work2 = GTK_CTREE_ROW (work)->parent) &&
-                                 GTK_CTREE_ROW(work2)->row.bg_set)
+                             work2 = GTK_CTREE_ROW (work)->parent;
+
+                             if (work2 && GTK_CTREE_ROW (work2)->row.bg_set)
                                {
                                  gdk_gc_set_foreground
                                    (clist->bg_gc,
-                                    &(GTK_CTREE_ROW(work2)->row.background));
+                                    &(GTK_CTREE_ROW (work2)->row.background));
                                  
                                  gdk_draw_rectangle 
                                    (clist->clist_window, clist->bg_gc, TRUE,
@@ -1590,10 +1594,10 @@ draw_row (GtkCList     *clist,
                                     in / 2 + in % 2,
                                     row_rectangle.height / 2 + 1);
 
-                                 if (GTK_CTREE_ROW(work)->row.bg_set)
+                                 if (GTK_CTREE_ROW (work)->row.bg_set)
                                    gdk_gc_set_foreground
                                      (clist->bg_gc,
-                                      &(GTK_CTREE_ROW(work)->row.background));
+                                      &(GTK_CTREE_ROW (work)->row.background));
                                }
                              else 
                                gdk_draw_rectangle 
@@ -1861,11 +1865,12 @@ draw_row (GtkCList     *clist,
                        (((GtkCTreeRow *)clist_row)->children &&
                         ((GtkCTreeRow *)clist_row)->expanded)))
                    {
-                     work2 = gtk_ctree_find_glist_ptr 
+                     work2 = gtk_ctree_find_glist_ptr
                        (ctree, (GtkCTreeRow *) clist_row);
 
-                     if (work2->next)
-                       next_level = GTK_CTREE_ROW (work2->next)->level;
+                     if (GTK_CTREE_NODE_NEXT (work2))
+                       next_level =
+                         GTK_CTREE_ROW (GTK_CTREE_NODE_NEXT (work2))->level;
                      else
                        next_level = 0;
                    }
@@ -1878,7 +1883,7 @@ draw_row (GtkCList     *clist,
                        {
                          gdk_gc_set_foreground
                            (clist->bg_gc,
-                            &(GTK_CTREE_ROW(work)->row.background));
+                            &(GTK_CTREE_ROW (work)->row.background));
                          mbg_gc = clist->bg_gc;
                        }
                      else
@@ -1907,12 +1912,13 @@ draw_row (GtkCList     *clist,
 
                          if (clist_row->state != GTK_STATE_SELECTED)
                            {
-                             if ((work2 = GTK_CTREE_ROW (work)->parent) &&
-                                 GTK_CTREE_ROW(work2)->row.bg_set)
+                             work2 = GTK_CTREE_ROW (work)->parent;
+
+                             if (work2 && GTK_CTREE_ROW (work2)->row.bg_set)
                                {
                                  gdk_gc_set_foreground
                                    (clist->bg_gc,
-                                    &(GTK_CTREE_ROW(work2)->row.background));
+                                    &(GTK_CTREE_ROW (work2)->row.background));
                                  
                                  gdk_draw_rectangle 
                                    (clist->clist_window, clist->bg_gc, TRUE,
@@ -1921,7 +1927,7 @@ draw_row (GtkCList     *clist,
                                     in / 2 + in % 2,
                                     row_rectangle.height / 2 + 1);
 
-                                 if (GTK_CTREE_ROW(work)->row.bg_set)
+                                 if (GTK_CTREE_ROW (work)->row.bg_set)
                                    gdk_gc_set_foreground
                                      (clist->bg_gc,
                                       &(GTK_CTREE_ROW(work)->row.background));
@@ -2038,7 +2044,7 @@ draw_row (GtkCList     *clist,
                  while (work)
                    {
                      xcenter += ctree->tree_indent;
-                     if (GTK_CTREE_ROW(work)->sibling)
+                     if (GTK_CTREE_ROW (work)->sibling)
                        gdk_draw_line (clist->clist_window, ctree->lines_gc,
                                       xcenter, clip_rectangle.y - offset_y,
                                       xcenter, rect->y + rect->height);
@@ -2391,35 +2397,35 @@ draw_row (GtkCList     *clist,
 }
 
 static void
-tree_draw_row (GtkCTree *ctree, 
-              GList    *row)
+tree_draw_node (GtkCTree     *ctree, 
+               GtkCTreeNode *node)
 {
   GtkCList *clist;
   
   clist = GTK_CLIST (ctree);
 
-  if (!GTK_CLIST_FROZEN (clist) && gtk_ctree_is_visible (ctree, row))
+  if (!GTK_CLIST_FROZEN (clist) && gtk_ctree_is_visible (ctree, node))
     {
-      GList *work;
+      GtkCTreeNode *work;
       gint num = 0;
       
-      work = clist->row_list;
-      while (work != row)
+      work = GTK_CTREE_NODE (clist->row_list);
+      while (work != node)
        {
-         work = work->next;
+         work = GTK_CTREE_NODE_NEXT (work);
          num++;
        }
       if (gtk_clist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, num,
-                                             GTK_CLIST_ROW (row));
+       GTK_CLIST_CLASS_FW (clist)->draw_row
+         (clist, NULL, num, GTK_CLIST_ROW ((GList *) node));
     }
 }
 
-static GList *
-gtk_ctree_last_visible (GtkCTree *ctree,
-                       GList    *node)
+static GtkCTreeNode *
+gtk_ctree_last_visible (GtkCTree     *ctree,
+                       GtkCTreeNode *node)
 {
-  GList *work;
+  GtkCTreeNode *work;
   
   if (!node)
     return NULL;
@@ -2436,14 +2442,14 @@ gtk_ctree_last_visible (GtkCTree *ctree,
 }
 
 static void
-gtk_ctree_link (GtkCTree *ctree,
-               GList    *node,
-               GList    *parent,
-               GList    *sibling,
-               gboolean  update_focus_row)
+gtk_ctree_link (GtkCTree     *ctree,
+               GtkCTreeNode *node,
+               GtkCTreeNode *parent,
+               GtkCTreeNode *sibling,
+               gboolean      update_focus_row)
 {
   GtkCList *clist;
-  GList *list_end;
+  GtkCTreeNode *list_end;
   gboolean visible = FALSE;
   gint rows = 0;
   
@@ -2465,7 +2471,8 @@ gtk_ctree_link (GtkCTree *ctree,
       clist->undo_unselection = NULL;
     }
 
-  for (rows = 1, list_end = node; list_end->next; list_end = list_end->next)
+  for (rows = 1, list_end = node; GTK_CTREE_NODE_NEXT (list_end);
+       list_end = GTK_CTREE_NODE_NEXT (list_end))
     rows++;
 
   GTK_CTREE_ROW (node)->parent = parent;
@@ -2481,12 +2488,12 @@ gtk_ctree_link (GtkCTree *ctree,
 
   if (sibling)
     {
-      GList *work;
+      GtkCTreeNode *work;
 
       if (parent)
        work = GTK_CTREE_ROW (parent)->children;
       else
-       work = clist->row_list;
+       work = GTK_CTREE_NODE (clist->row_list);
       if (work != sibling)
        {
          while (GTK_CTREE_ROW (work)->sibling != sibling)
@@ -2494,25 +2501,26 @@ gtk_ctree_link (GtkCTree *ctree,
          GTK_CTREE_ROW (work)->sibling = node;
        }
 
-      if (sibling == clist->row_list)
-       clist->row_list = node;
-      if (sibling->prev && sibling->prev->next == sibling)
-       sibling->prev->next = node;
+      if (sibling == GTK_CTREE_NODE (clist->row_list))
+       GTK_CTREE_NODE (clist->row_list) = node;
+      if (GTK_CTREE_NODE_PREV (sibling) &&
+         GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (sibling)) == sibling)
+       GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (sibling)) = node;
       
-      node->prev = sibling->prev;
-      list_end->next = sibling;
-      sibling->prev = list_end;
+      GTK_CTREE_NODE_PREV (node) = GTK_CTREE_NODE_PREV (sibling);
+      GTK_CTREE_NODE_NEXT (list_end) = sibling;
+      GTK_CTREE_NODE_PREV (sibling) = list_end;
       if (parent && GTK_CTREE_ROW (parent)->children == sibling)
        GTK_CTREE_ROW (parent)->children = node;
     }
   else
     {
-      GList *work;
+      GtkCTreeNode *work;
 
       if (parent)
        work = GTK_CTREE_ROW (parent)->children;
       else
-       work = clist->row_list;
+       work = GTK_CTREE_NODE (clist->row_list);
 
       if (work)
        {
@@ -2524,47 +2532,49 @@ gtk_ctree_link (GtkCTree *ctree,
          /* find last visible child of sibling */
          work = gtk_ctree_last_visible (ctree, work);
          
-         list_end->next = work->next;
-         if (work->next)
-           work->next->prev = list_end;
-         work->next = node;
-         node->prev = work;
+         GTK_CTREE_NODE_NEXT (list_end) = GTK_CTREE_NODE_NEXT (work);
+         if (GTK_CTREE_NODE_NEXT (work))
+           GTK_CTREE_NODE_PREV (GTK_CTREE_NODE_NEXT (work)) = list_end;
+         GTK_CTREE_NODE_NEXT (work) = node;
+         GTK_CTREE_NODE_PREV (node) = work;
        }
       else
        {
          if (parent)
            {
              GTK_CTREE_ROW (parent)->children = node;
-             node->prev = parent;
+             GTK_CTREE_NODE_PREV (node) = parent;
              if (GTK_CTREE_ROW (parent)->expanded)
                {
-                 list_end->next = parent->next;
-                 if (parent->next)
-                   parent->next->prev = list_end;
-                 parent->next = node;
+                 GTK_CTREE_NODE_NEXT (list_end)= GTK_CTREE_NODE_NEXT (parent);
+                 if (GTK_CTREE_NODE_NEXT(parent))
+                   GTK_CTREE_NODE_PREV (GTK_CTREE_NODE_NEXT (parent)) =
+                     list_end;
+                 GTK_CTREE_NODE_NEXT (parent) = node;
                }
              else
-               list_end->next = NULL;
+               GTK_CTREE_NODE_NEXT (list_end) = NULL;
            }
          else
            {
-             clist->row_list = node;
-             node->prev = NULL;
-             list_end->next = NULL;
+             GTK_CTREE_NODE (clist->row_list) = node;
+             GTK_CTREE_NODE_PREV (node) = NULL;
+             GTK_CTREE_NODE_NEXT (list_end) = NULL;
            }
        }
     }
 
   gtk_ctree_pre_recursive (ctree, node, tree_update_level, NULL); 
 
-  if (clist->row_list_end == NULL || clist->row_list_end->next == node)
-    clist->row_list_end = list_end;
+  if (clist->row_list_end == NULL ||
+      GTK_CTREE_NODE (clist->row_list_end->next) == node)
+    GTK_CTREE_NODE (clist->row_list_end) = list_end;
 
   if (visible && update_focus_row)
     {
       gint pos;
          
-      pos = g_list_position (clist->row_list, node);
+      pos = g_list_position (clist->row_list, (GList *)node);
   
       if (pos <= clist->focus_row)
        {
@@ -2575,16 +2585,16 @@ gtk_ctree_link (GtkCTree *ctree,
 }
 
 static void
-gtk_ctree_unlink (GtkCTree *ctree, 
-                 GList    *node,
-                  gboolean  update_focus_row)
+gtk_ctree_unlink (GtkCTree     *ctree, 
+                 GtkCTreeNode *node,
+                  gboolean      update_focus_row)
 {
   GtkCList *clist;
   gint rows;
   gint level;
   gint visible;
-  GList *work;
-  GList *parent;
+  GtkCTreeNode *work;
+  GtkCTreeNode *parent;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -2606,18 +2616,20 @@ gtk_ctree_unlink (GtkCTree *ctree,
   visible = gtk_ctree_is_visible (ctree, node);
 
   /* clist->row_list_end unlinked ? */
-  if (visible && (node->next == NULL ||
-                 (GTK_CTREE_ROW (node)->children &&
-                  gtk_ctree_is_ancestor (ctree, node, clist->row_list_end))))
-    clist->row_list_end = node->prev;
+  if (visible &&
+      (GTK_CTREE_NODE_NEXT (node) == NULL ||
+       (GTK_CTREE_ROW (node)->children &&
+       gtk_ctree_is_ancestor (ctree, node,
+                              GTK_CTREE_NODE (clist->row_list_end)))))
+    GTK_CTREE_NODE (clist->row_list_end) = GTK_CTREE_NODE_PREV (node);
 
   /* update list */
   rows = 0;
   level = GTK_CTREE_ROW (node)->level;
-  work = node->next;
+  work = GTK_CTREE_NODE_NEXT (node);
   while (work && GTK_CTREE_ROW (work)->level > level)
     {
-      work = work->next;
+      work = GTK_CTREE_NODE_NEXT (work);
       rows++;
     }
 
@@ -2629,7 +2641,7 @@ gtk_ctree_unlink (GtkCTree *ctree,
        {
          gint pos;
          
-         pos = g_list_position (clist->row_list, node);
+         pos = g_list_position (clist->row_list, (GList *)node);
          if (pos + rows + 1 < clist->focus_row)
            clist->focus_row -= (rows + 1);
          else if (pos <= clist->focus_row)
@@ -2640,12 +2652,13 @@ gtk_ctree_unlink (GtkCTree *ctree,
 
   if (work)
     {
-      work->prev->next = NULL;
-      work->prev = node->prev;
+      GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (work)) = NULL;
+      GTK_CTREE_NODE_PREV (work) = GTK_CTREE_NODE_PREV (node);
     }
 
-  if (node->prev && node->prev->next == node)
-    node->prev->next = work;
+  if (GTK_CTREE_NODE_PREV (node) &&
+      GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (node)) == node)
+    GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (node)) = work;
 
   /* update tree */
   parent = GTK_CTREE_ROW (node)->parent;
@@ -2668,7 +2681,7 @@ gtk_ctree_unlink (GtkCTree *ctree,
        }
       else
        {
-         GList *sibling;
+         GtkCTreeNode *sibling;
 
          sibling = GTK_CTREE_ROW (parent)->children;
          while (GTK_CTREE_ROW (sibling)->sibling != node)
@@ -2678,13 +2691,13 @@ gtk_ctree_unlink (GtkCTree *ctree,
     }
   else
     {
-      if (clist->row_list == node)
-       clist->row_list = GTK_CTREE_ROW (node)->sibling;
+      if (GTK_CTREE_NODE (clist->row_list) == node)
+       GTK_CTREE_NODE (clist->row_list) = GTK_CTREE_ROW (node)->sibling;
       else
        {
-         GList *sibling;
-         
-         sibling = clist->row_list;
+         GtkCTreeNode *sibling;
+
+         sibling = GTK_CTREE_NODE (clist->row_list);
          while (GTK_CTREE_ROW (sibling)->sibling != node)
            sibling = GTK_CTREE_ROW (sibling)->sibling;
          GTK_CTREE_ROW (sibling)->sibling = GTK_CTREE_ROW (node)->sibling;
@@ -2693,13 +2706,13 @@ gtk_ctree_unlink (GtkCTree *ctree,
 }
 
 static void
-real_tree_move (GtkCTree *ctree,
-               GList    *node,
-               GList    *new_parent, 
-               GList    *new_sibling)
+real_tree_move (GtkCTree     *ctree,
+               GtkCTreeNode *node,
+               GtkCTreeNode *new_parent, 
+               GtkCTreeNode *new_sibling)
 {
   GtkCList *clist;
-  GList *work;
+  GtkCTreeNode *work;
   gboolean thaw = FALSE;
 
   g_return_if_fail (ctree != NULL);
@@ -2736,7 +2749,7 @@ real_tree_move (GtkCTree *ctree,
       if (new_parent)
        new_sibling = GTK_CTREE_ROW (new_parent)->children;
       else
-       new_sibling = clist->row_list;
+       new_sibling = GTK_CTREE_NODE (clist->row_list);
 
       while (new_sibling && ctree->node_compare (ctree, node, new_sibling) > 0)
        new_sibling = GTK_CTREE_ROW (new_sibling)->sibling;
@@ -2755,7 +2768,7 @@ real_tree_move (GtkCTree *ctree,
   work = NULL;
   if (gtk_ctree_is_visible (ctree, node) ||
       gtk_ctree_is_visible (ctree, new_sibling))
-    work = g_list_nth (clist->row_list, clist->focus_row);
+    work = GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row));
       
   gtk_ctree_unlink (ctree, node, FALSE);
   gtk_ctree_link (ctree, node, new_parent, new_sibling, FALSE);
@@ -2764,7 +2777,7 @@ real_tree_move (GtkCTree *ctree,
     {
       while (work &&  !gtk_ctree_is_visible (ctree, work))
        work = GTK_CTREE_ROW (work)->parent;
-      clist->focus_row = g_list_position (clist->row_list, work);
+      clist->focus_row = g_list_position (clist->row_list, (GList *)work);
       clist->undo_anchor = clist->focus_row;
     }
 
@@ -2777,7 +2790,7 @@ change_focus_row_expansion (GtkCTree          *ctree,
                            GtkCTreeExpansionType action)
 {
   GtkCList *clist;
-  GList *node;
+  GtkCTreeNode *node;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -2787,7 +2800,8 @@ change_focus_row_expansion (GtkCTree          *ctree,
   if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (ctree))
     return;
   
-  if (!(node = g_list_nth (clist->row_list, clist->focus_row)) ||
+  if (!(node =
+       GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row))) ||
       GTK_CTREE_ROW (node)->is_leaf || !(GTK_CTREE_ROW (node)->children))
     return;
 
@@ -2815,11 +2829,11 @@ change_focus_row_expansion (GtkCTree          *ctree,
 }
 
 static void 
-real_tree_expand (GtkCTree *ctree,
-                 GList    *node)
+real_tree_expand (GtkCTree     *ctree,
+                 GtkCTreeNode *node)
 {
   GtkCList *clist;
-  GList *work;
+  GtkCTreeNode *work;
   gint level;
 
   g_return_if_fail (ctree != NULL);
@@ -2855,24 +2869,24 @@ real_tree_expand (GtkCTree *ctree,
 
       clist = GTK_CLIST (ctree);
 
-      while (work->next)
+      while (GTK_CTREE_NODE_NEXT (work))
        {
-         work = work->next;
+         work = GTK_CTREE_NODE_NEXT (work);
          tmp++;
        }
 
-      work->next = node->next;
+      GTK_CTREE_NODE_NEXT (work) = GTK_CTREE_NODE_NEXT (node);
 
-      if (node->next)
-       node->next->prev = work;
+      if (GTK_CTREE_NODE_NEXT (node))
+       GTK_CTREE_NODE_PREV (GTK_CTREE_NODE_NEXT (node)) = work;
       else
-       clist->row_list_end = work;
+       GTK_CTREE_NODE (clist->row_list_end) = work;
 
-      node->next = GTK_CTREE_ROW (node)->children;
+      GTK_CTREE_NODE_NEXT (node) = GTK_CTREE_ROW (node)->children;
       
       if (gtk_ctree_is_visible (ctree, node))
        {
-         row = g_list_position (clist->row_list, node);
+         row = g_list_position (clist->row_list, (GList *)node);
          if (row < clist->focus_row)
            clist->focus_row += tmp + 1;
          clist->rows += tmp + 1;
@@ -2883,11 +2897,11 @@ real_tree_expand (GtkCTree *ctree,
 }
 
 static void 
-real_tree_collapse (GtkCTree *ctree,
-                   GList    *node)
+real_tree_collapse (GtkCTree     *ctree,
+                   GtkCTreeNode *node)
 {
   GtkCList *clist;
-  GList *work;
+  GtkCTreeNode *work;
   gint level;
 
   g_return_if_fail (ctree != NULL);
@@ -2925,25 +2939,25 @@ real_tree_collapse (GtkCTree *ctree,
 
       while (work && GTK_CTREE_ROW (work)->level > level)
        {
-         work = work->next;
+         work = GTK_CTREE_NODE_NEXT (work);
          tmp++;
        }
 
       if (work)
        {
-         node->next = work;
-         work->prev->next = NULL;
-         work->prev = node;
+         GTK_CTREE_NODE_NEXT (node) = work;
+         GTK_CTREE_NODE_NEXT (GTK_CTREE_NODE_PREV (work)) = NULL;
+         GTK_CTREE_NODE_PREV (work) = node;
        }
       else
        {
-         node->next = NULL;
-         clist->row_list_end = node;
+         GTK_CTREE_NODE_NEXT (node) = NULL;
+         GTK_CTREE_NODE (clist->row_list_end) = node;
        }
 
       if (gtk_ctree_is_visible (ctree, node))
        {
-         row = g_list_position (clist->row_list, node);
+         row = g_list_position (clist->row_list, (GList *)node);
          if (row < clist->focus_row)
            clist->focus_row -= tmp;
          clist->rows -= tmp;
@@ -3007,16 +3021,16 @@ cell_set_pixtext (GtkCList    *clist,
 }
 
 static void 
-set_node_info (GtkCTree  *ctree,
-              GList     *node,
-              gchar     *text,
-              guint8     spacing,
-              GdkPixmap *pixmap_closed,
-              GdkBitmap *mask_closed,
-              GdkPixmap *pixmap_opened,
-              GdkBitmap *mask_opened,
-              gboolean   is_leaf,
-              gboolean   expanded)
+set_node_info (GtkCTree     *ctree,
+              GtkCTreeNode *node,
+              gchar        *text,
+              guint8        spacing,
+              GdkPixmap    *pixmap_closed,
+              GdkBitmap    *mask_closed,
+              GdkPixmap    *pixmap_opened,
+              GdkBitmap    *mask_opened,
+              gboolean      is_leaf,
+              gboolean      expanded)
 {
   GtkCellPixText *tree_cell;
 
@@ -3078,9 +3092,9 @@ set_node_info (GtkCTree  *ctree,
 }
 
 static void
-tree_delete (GtkCTree *ctree, 
-            GList    *node, 
-            gpointer  data)
+tree_delete (GtkCTree     *ctree, 
+            GtkCTreeNode *node, 
+            gpointer      data)
 {
   GtkCList *clist;
   
@@ -3100,22 +3114,22 @@ tree_delete (GtkCTree *ctree,
     }
 
   row_delete (ctree, GTK_CTREE_ROW (node));
-  g_list_free_1 (node);
+  g_list_free_1 ((GList *)node);
 }
 
 static void
-tree_delete_row (GtkCTree *ctree, 
-                GList    *node, 
-                gpointer  data)
+tree_delete_row (GtkCTree     *ctree, 
+                GtkCTreeNode *node, 
+                gpointer      data)
 {
   row_delete (ctree, GTK_CTREE_ROW (node));
-  g_list_free_1 (node);
+  g_list_free_1 ((GList *)node);
 }
 
 static void
-tree_update_level (GtkCTree *ctree, 
-                  GList    *node, 
-                  gpointer  data)
+tree_update_level (GtkCTree     *ctree, 
+                  GtkCTreeNode *node, 
+                  gpointer      data)
 {
   if (!node)
     return;
@@ -3128,9 +3142,9 @@ tree_update_level (GtkCTree *ctree,
 }
 
 static void
-tree_select (GtkCTree *ctree, 
-            GList    *node, 
-            gpointer  data)
+tree_select (GtkCTree     *ctree, 
+            GtkCTreeNode *node, 
+            gpointer      data)
 {
   if (node && GTK_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED)
     gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_SELECT_ROW],
@@ -3138,9 +3152,9 @@ tree_select (GtkCTree *ctree,
 }
 
 static void
-tree_unselect (GtkCTree *ctree, 
-              GList    *node, 
-              gpointer  data)
+tree_unselect (GtkCTree     *ctree, 
+              GtkCTreeNode *node, 
+              gpointer      data)
 {
   if (node && GTK_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED)
     gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_UNSELECT_ROW], 
@@ -3148,36 +3162,36 @@ tree_unselect (GtkCTree *ctree,
 }
 
 static void
-tree_expand (GtkCTree *ctree, 
-            GList    *node, 
-            gpointer  data)
+tree_expand (GtkCTree     *ctree, 
+            GtkCTreeNode *node, 
+            gpointer      data)
 {
   if (node && !GTK_CTREE_ROW (node)->expanded)
     gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node);
 }
 
 static void
-tree_collapse (GtkCTree *ctree, 
-              GList    *node, 
-              gpointer  data)
+tree_collapse (GtkCTree     *ctree, 
+              GtkCTreeNode *node, 
+              gpointer      data)
 {
   if (node && GTK_CTREE_ROW (node)->expanded)
     gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node);
 }
 
 static void
-tree_collapse_to_depth (GtkCTree *ctree, 
-                       GList    *node, 
-                       gint      depth)
+tree_collapse_to_depth (GtkCTree     *ctree, 
+                       GtkCTreeNode *node, 
+                       gint          depth)
 {
   if (node && GTK_CTREE_ROW (node)->level == depth)
     gtk_ctree_collapse_recursive (ctree, node);
 }
 
 static void
-tree_toggle_expansion (GtkCTree *ctree,
-                      GList    *node,
-                      gpointer  data)
+tree_toggle_expansion (GtkCTree     *ctree,
+                      GtkCTreeNode *node,
+                      gpointer      data)
 {
   if (!node)
     return;
@@ -3337,13 +3351,13 @@ real_unselect_row (GtkCList *clist,
 }
 
 static void
-real_tree_select (GtkCTree *ctree,
-                 GList    *node,
-                 gint      column)
+real_tree_select (GtkCTree     *ctree,
+                 GtkCTreeNode *node,
+                 gint          column)
 {
   GtkCList *clist;
   GList *list;
-  GList *sel_row;
+  GtkCTreeNode *sel_row;
   gboolean node_selected;
 
   g_return_if_fail (ctree != NULL);
@@ -3391,13 +3405,13 @@ real_tree_select (GtkCTree *ctree,
   else
     clist->selection_end = g_list_append (clist->selection_end, node)->next;
 
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 static void
-real_tree_unselect (GtkCTree *ctree,
-                   GList    *node,
-                   gint      column)
+real_tree_unselect (GtkCTree     *ctree,
+                   GtkCTreeNode *node,
+                   gint          column)
 {
   GtkCList *clist;
 
@@ -3416,13 +3430,13 @@ real_tree_unselect (GtkCTree *ctree,
   
   GTK_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL;
 
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 static void
-tree_toggle_selection (GtkCTree *ctree,
-                      GList    *node,
-                      gint      column)
+tree_toggle_selection (GtkCTree     *ctree,
+                      GtkCTreeNode *node,
+                      gint          column)
 {
   GtkCList *clist;
   
@@ -3455,9 +3469,9 @@ tree_toggle_selection (GtkCTree *ctree,
 }
 
 static void
-select_row_recursive (GtkCTree *ctree, 
-                     GList    *node, 
-                     gpointer  data)
+select_row_recursive (GtkCTree     *ctree, 
+                     GtkCTreeNode *node, 
+                     gpointer      data)
 {
   if (!node || GTK_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED)
     return;
@@ -3471,7 +3485,7 @@ static void
 real_select_all (GtkCList *clist)
 {
   GtkCTree *ctree;
-  GList *node;
+  GtkCTreeNode *node;
   gboolean thaw = FALSE;
   
   g_return_if_fail (clist != NULL);
@@ -3503,7 +3517,8 @@ real_select_all (GtkCList *clist)
       clist->drag_pos = -1;
       clist->undo_anchor = clist->focus_row;
 
-      for (node = clist->row_list; node; node = node->next)
+      for (node = GTK_CTREE_NODE (clist->row_list); node;
+          node = GTK_CTREE_NODE_NEXT (node))
        gtk_ctree_pre_recursive (ctree, node, select_row_recursive, NULL);
 
       if (thaw)
@@ -3520,8 +3535,8 @@ static void
 real_unselect_all (GtkCList *clist)
 {
   GtkCTree *ctree;
+  GtkCTreeNode *node;
   GList *list;
-  GList *node;
  
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CTREE (clist));
@@ -3534,7 +3549,8 @@ real_unselect_all (GtkCList *clist)
       if (clist->focus_row >= 0)
        {
          gtk_ctree_select
-           (ctree, g_list_nth (clist->row_list, clist->focus_row));
+           (ctree,
+            GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row)));
          return;
        }
       break;
@@ -3565,11 +3581,11 @@ real_unselect_all (GtkCList *clist)
 }
 
 static gboolean
-ctree_is_hot_spot (GtkCTree *ctree, 
-                  GList    *node,
-                  gint      row, 
-                  gint      x, 
-                  gint      y)
+ctree_is_hot_spot (GtkCTree     *ctree, 
+                  GtkCTreeNode *node,
+                  gint          row, 
+                  gint          x, 
+                  gint          y)
 {
   GtkCTreeRow *tree_row;
   GtkCList *clist;
@@ -3609,8 +3625,8 @@ ctree_is_hot_spot (GtkCTree *ctree,
 
 static gint
 default_compare (GtkCTree    *ctree,
-                const GList *node1,
-                const GList *node2)
+                const GtkCTreeNode *node1,
+                const GtkCTreeNode *node2)
 {
   char *text1;
   char *text2;
@@ -3687,10 +3703,10 @@ gtk_ctree_new (gint columns,
   return gtk_ctree_new_with_titles (columns, tree_column, NULL);
 }
 
-GList * 
-gtk_ctree_insert (GtkCTree  *ctree,
-                 GList     *parent, 
-                 GList     *sibling,
+GtkCTreeNode * 
+gtk_ctree_insert (GtkCTree     *ctree,
+                 GtkCTreeNode *parent, 
+                 GtkCTreeNode *sibling,
                  gchar     *text[],
                  guint8     spacing,
                  GdkPixmap *pixmap_closed,
@@ -3702,7 +3718,7 @@ gtk_ctree_insert (GtkCTree  *ctree,
 {
   GtkCList *clist;
   GtkCTreeRow *new_row;
-  GList *node;
+  GtkCTreeNode *node;
   gint i;
 
   g_return_val_if_fail (ctree != NULL, NULL);
@@ -3716,8 +3732,8 @@ gtk_ctree_insert (GtkCTree  *ctree,
 
   /* create the row */
   new_row = row_new (ctree);
-  node = g_list_alloc ();
-  node->data = new_row;
+  node = GTK_CTREE_NODE (g_list_alloc ());
+  GTK_CTREE_ROW (node) = new_row;
 
   if (text)
     for (i = 0; i < clist->columns; i++)
@@ -3733,7 +3749,7 @@ gtk_ctree_insert (GtkCTree  *ctree,
       if (parent)
        sibling = GTK_CTREE_ROW (parent)->children;
       else
-       sibling = clist->row_list;
+       sibling = GTK_CTREE_NODE (clist->row_list);
 
       while (sibling && ctree->node_compare (ctree, node, sibling) > 0)
        sibling = GTK_CTREE_ROW (sibling)->sibling;
@@ -3748,8 +3764,8 @@ gtk_ctree_insert (GtkCTree  *ctree,
 }
 
 void
-gtk_ctree_remove (GtkCTree *ctree, 
-                 GList    *node)
+gtk_ctree_remove (GtkCTree     *ctree, 
+                 GtkCTreeNode *node)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -3782,8 +3798,8 @@ static void
 real_clear (GtkCList *clist)
 {
   GtkCTree *ctree;
-  GList *work;
-  GList *ptr;
+  GtkCTreeNode *work;
+  GtkCTreeNode *ptr;
 
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CTREE (clist));
@@ -3798,7 +3814,7 @@ real_clear (GtkCList *clist)
   ctree->drag_icon      = NULL;
 
   /* remove all the rows */
-  work = clist->row_list;
+  work = GTK_CTREE_NODE (clist->row_list);
   clist->row_list = NULL;
   clist->row_list_end = NULL;
 
@@ -3822,12 +3838,12 @@ real_clear (GtkCList *clist)
 
 void
 gtk_ctree_post_recursive (GtkCTree     *ctree, 
-                         GList        *node,
+                         GtkCTreeNode *node,
                          GtkCTreeFunc  func,
                          gpointer      data)
 {
-  GList *work;
-  GList *tmp;
+  GtkCTreeNode *work;
+  GtkCTreeNode *tmp;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -3835,7 +3851,7 @@ gtk_ctree_post_recursive (GtkCTree     *ctree,
   if (node)
     work = GTK_CTREE_ROW (node)->children;
   else
-    work = GTK_CLIST (ctree)->row_list;
+    work = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
   while (work)
     {
@@ -3850,13 +3866,13 @@ gtk_ctree_post_recursive (GtkCTree     *ctree,
 
 void
 gtk_ctree_post_recursive_to_depth (GtkCTree     *ctree, 
-                                  GList        *node,
+                                  GtkCTreeNode *node,
                                   gint          depth,
                                   GtkCTreeFunc  func,
                                   gpointer      data)
 {
-  GList *work;
-  GList *tmp;
+  GtkCTreeNode *work;
+  GtkCTreeNode *tmp;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -3870,7 +3886,7 @@ gtk_ctree_post_recursive_to_depth (GtkCTree     *ctree,
   if (node)
     work = GTK_CTREE_ROW (node)->children;
   else
-    work = GTK_CLIST (ctree)->row_list;
+    work = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
   if (work && GTK_CTREE_ROW (work)->level <= depth)
     {
@@ -3888,12 +3904,12 @@ gtk_ctree_post_recursive_to_depth (GtkCTree     *ctree,
 
 void
 gtk_ctree_pre_recursive (GtkCTree     *ctree, 
-                        GList        *node,
+                        GtkCTreeNode *node,
                         GtkCTreeFunc  func,
                         gpointer      data)
 {
-  GList *work;
-  GList *tmp;
+  GtkCTreeNode *work;
+  GtkCTreeNode *tmp;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -3904,7 +3920,7 @@ gtk_ctree_pre_recursive (GtkCTree     *ctree,
       func (ctree, node, data);
     }
   else
-    work = GTK_CLIST (ctree)->row_list;
+    work = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
   while (work)
     {
@@ -3916,13 +3932,13 @@ gtk_ctree_pre_recursive (GtkCTree     *ctree,
 
 void
 gtk_ctree_pre_recursive_to_depth (GtkCTree     *ctree, 
-                                 GList        *node,
+                                 GtkCTreeNode *node,
                                  gint          depth, 
                                  GtkCTreeFunc  func,
                                  gpointer      data)
 {
-  GList *work;
-  GList *tmp;
+  GtkCTreeNode *work;
+  GtkCTreeNode *tmp;
 
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -3940,7 +3956,7 @@ gtk_ctree_pre_recursive_to_depth (GtkCTree     *ctree,
        func (ctree, node, data);
     }
   else
-    work = GTK_CLIST (ctree)->row_list;
+    work = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
   if (work && GTK_CTREE_ROW (work)->level <= depth)
     {
@@ -3954,8 +3970,8 @@ gtk_ctree_pre_recursive_to_depth (GtkCTree     *ctree,
 }
 
 gboolean
-gtk_ctree_is_visible (GtkCTree *ctree, 
-                     GList    *node)
+gtk_ctree_is_visible (GtkCTree     *ctree, 
+                     GtkCTreeNode *node)
 { 
   GtkCTreeRow *work;
 
@@ -3974,9 +3990,9 @@ gtk_ctree_is_visible (GtkCTree *ctree,
   return FALSE;
 }
 
-GList * 
-gtk_ctree_last (GtkCTree *ctree,
-               GList    *node)
+GtkCTreeNode * 
+gtk_ctree_last (GtkCTree     *ctree,
+               GtkCTreeNode *node)
 {
   g_return_val_if_fail (ctree != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), NULL);
@@ -3993,11 +4009,11 @@ gtk_ctree_last (GtkCTree *ctree,
   return node;
 }
 
-GList *
+GtkCTreeNode *
 gtk_ctree_find_glist_ptr (GtkCTree    *ctree,
                          GtkCTreeRow *ctree_row)
 {
-  GList *node;
+  GtkCTreeNode *node;
   
   g_return_val_if_fail (ctree != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), FALSE);
@@ -4006,18 +4022,18 @@ gtk_ctree_find_glist_ptr (GtkCTree    *ctree,
   if (ctree_row->parent)
     node = GTK_CTREE_ROW(ctree_row->parent)->children;
   else
-    node = GTK_CLIST (ctree)->row_list;
+    node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
-  while (node->data != ctree_row)
+  while (GTK_CTREE_ROW (node) != ctree_row)
     node = GTK_CTREE_ROW (node)->sibling;
   
   return node;
 }
 
 gint
-gtk_ctree_find (GtkCTree *ctree,
-               GList    *node,
-               GList    *child)
+gtk_ctree_find (GtkCTree     *ctree,
+               GtkCTreeNode *node,
+               GtkCTreeNode *child)
 {
   while (node)
     {
@@ -4034,19 +4050,19 @@ gtk_ctree_find (GtkCTree *ctree,
 }
 
 gboolean
-gtk_ctree_is_ancestor (GtkCTree *ctree,
-                      GList    *node,
-                      GList    *child)
+gtk_ctree_is_ancestor (GtkCTree     *ctree,
+                      GtkCTreeNode *node,
+                      GtkCTreeNode *child)
 {
   return gtk_ctree_find (ctree, GTK_CTREE_ROW (node)->children, child);
 }
 
-GList *
-gtk_ctree_find_by_row_data (GtkCTree    *ctree,
-                           GList       *node,
-                           gpointer     data)
+GtkCTreeNode *
+gtk_ctree_find_by_row_data (GtkCTree     *ctree,
+                           GtkCTreeNode *node,
+                           gpointer      data)
 {
-  GList *work;
+  GtkCTreeNode *work;
   
   while (node)
     {
@@ -4066,15 +4082,15 @@ gtk_ctree_is_hot_spot (GtkCTree *ctree,
                       gint      x, 
                       gint      y)
 {
-  GList *node;
-  gint row;
+  GtkCTreeNode *node;
   gint column;
+  gint row;
   
   g_return_val_if_fail (ctree != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), FALSE);
 
   if (gtk_clist_get_selection_info (GTK_CLIST (ctree), x, y, &row, &column))
-    if ((node = g_list_nth (GTK_CLIST (ctree)->row_list, row)))
+    if ((node = GTK_CTREE_NODE(g_list_nth (GTK_CLIST (ctree)->row_list, row))))
       return ctree_is_hot_spot (ctree, node, row, x, y);
 
   return FALSE;
@@ -4087,10 +4103,10 @@ gtk_ctree_is_hot_spot (GtkCTree *ctree,
 
 
 void
-gtk_ctree_move (GtkCTree *ctree,
-               GList    *node,
-               GList    *new_parent, 
-               GList    *new_sibling)
+gtk_ctree_move (GtkCTree     *ctree,
+               GtkCTreeNode *node,
+               GtkCTreeNode *new_parent, 
+               GtkCTreeNode *new_sibling)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4101,8 +4117,8 @@ gtk_ctree_move (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_expand (GtkCTree *ctree,
-                 GList    *node)
+gtk_ctree_expand (GtkCTree     *ctree,
+                 GtkCTreeNode *node)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4115,8 +4131,8 @@ gtk_ctree_expand (GtkCTree *ctree,
 }
 
 void 
-gtk_ctree_expand_recursive (GtkCTree *ctree,
-                           GList    *node)
+gtk_ctree_expand_recursive (GtkCTree     *ctree,
+                           GtkCTreeNode *node)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4143,9 +4159,9 @@ gtk_ctree_expand_recursive (GtkCTree *ctree,
 }
 
 void 
-gtk_ctree_expand_to_depth (GtkCTree *ctree,
-                          GList    *node,
-                          gint      depth)
+gtk_ctree_expand_to_depth (GtkCTree     *ctree,
+                          GtkCTreeNode *node,
+                          gint          depth)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4173,8 +4189,8 @@ gtk_ctree_expand_to_depth (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_collapse (GtkCTree *ctree,
-                   GList    *node)
+gtk_ctree_collapse (GtkCTree     *ctree,
+                   GtkCTreeNode *node)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4187,8 +4203,8 @@ gtk_ctree_collapse (GtkCTree *ctree,
 }
 
 void 
-gtk_ctree_collapse_recursive (GtkCTree *ctree,
-                             GList    *node)
+gtk_ctree_collapse_recursive (GtkCTree     *ctree,
+                             GtkCTreeNode *node)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4215,9 +4231,9 @@ gtk_ctree_collapse_recursive (GtkCTree *ctree,
 }
 
 void 
-gtk_ctree_collapse_to_depth (GtkCTree *ctree,
-                            GList    *node,
-                            gint      depth)
+gtk_ctree_collapse_to_depth (GtkCTree     *ctree,
+                            GtkCTreeNode *node,
+                            gint          depth)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4246,8 +4262,8 @@ gtk_ctree_collapse_to_depth (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_toggle_expansion (GtkCTree *ctree,
-                           GList    *node)
+gtk_ctree_toggle_expansion (GtkCTree     *ctree,
+                           GtkCTreeNode *node)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4260,8 +4276,8 @@ gtk_ctree_toggle_expansion (GtkCTree *ctree,
 }
 
 void 
-gtk_ctree_toggle_expansion_recursive (GtkCTree *ctree,
-                                     GList    *node)
+gtk_ctree_toggle_expansion_recursive (GtkCTree     *ctree,
+                                     GtkCTreeNode *node)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4289,8 +4305,8 @@ gtk_ctree_toggle_expansion_recursive (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_select (GtkCTree *ctree, 
-                 GList    *node)
+gtk_ctree_select (GtkCTree     *ctree, 
+                 GtkCTreeNode *node)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4301,8 +4317,8 @@ gtk_ctree_select (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_unselect (GtkCTree *ctree, 
-                   GList    *node)
+gtk_ctree_unselect (GtkCTree     *ctree, 
+                   GtkCTreeNode *node)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4313,23 +4329,23 @@ gtk_ctree_unselect (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_select_recursive (GtkCTree *ctree, 
-                           GList    *node)
+gtk_ctree_select_recursive (GtkCTree     *ctree, 
+                           GtkCTreeNode *node)
 {
   gtk_ctree_real_select_recursive (ctree, node, TRUE);
 }
 
 void
-gtk_ctree_unselect_recursive (GtkCTree *ctree, 
-                             GList    *node)
+gtk_ctree_unselect_recursive (GtkCTree     *ctree, 
+                             GtkCTreeNode *node)
 {
   gtk_ctree_real_select_recursive (ctree, node, FALSE);
 }
 
 void
-gtk_ctree_real_select_recursive (GtkCTree *ctree, 
-                                GList    *node, 
-                                gint      state)
+gtk_ctree_real_select_recursive (GtkCTree     *ctree, 
+                                GtkCTreeNode *node, 
+                                gint          state)
 {
   GtkCList *clist;
   gboolean thaw = FALSE;
@@ -4370,10 +4386,10 @@ gtk_ctree_real_select_recursive (GtkCTree *ctree,
 
 
 void 
-gtk_ctree_set_text (GtkCTree *ctree,
-                   GList    *node,
-                   gint      column,
-                   gchar    *text)
+gtk_ctree_set_text (GtkCTree     *ctree,
+                   GtkCTreeNode *node,
+                   gint          column,
+                   gchar        *text)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4384,15 +4400,15 @@ gtk_ctree_set_text (GtkCTree *ctree,
     return;
 
   cell_set_text (GTK_CLIST (ctree), &(GTK_CTREE_ROW(node)->row), column, text);
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void 
-gtk_ctree_set_pixmap (GtkCTree  *ctree,
-                     GList     *node,
-                     gint       column,
-                     GdkPixmap *pixmap,
-                     GdkBitmap *mask)
+gtk_ctree_set_pixmap (GtkCTree     *ctree,
+                     GtkCTreeNode *node,
+                     gint          column,
+                     GdkPixmap    *pixmap,
+                     GdkBitmap    *mask)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4409,17 +4425,17 @@ gtk_ctree_set_pixmap (GtkCTree  *ctree,
 
   cell_set_pixmap (GTK_CLIST (ctree), &(GTK_CTREE_ROW (node)->row), column, 
                   pixmap, mask);
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void 
-gtk_ctree_set_pixtext (GtkCTree  *ctree,
-                      GList     *node,
-                      gint       column,
-                      gchar     *text,
-                      guint8     spacing,
-                      GdkPixmap *pixmap,
-                      GdkBitmap *mask)
+gtk_ctree_set_pixtext (GtkCTree     *ctree,
+                      GtkCTreeNode *node,
+                      gint          column,
+                      gchar        *text,
+                      guint8        spacing,
+                      GdkPixmap    *pixmap,
+                      GdkBitmap    *mask)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4436,20 +4452,20 @@ gtk_ctree_set_pixtext (GtkCTree  *ctree,
 
   cell_set_pixtext (GTK_CLIST (ctree), &(GTK_CTREE_ROW (node)->row), column,
                    text, spacing, pixmap, mask);
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void 
-gtk_ctree_set_node_info (GtkCTree  *ctree,
-                        GList     *node,
-                        gchar     *text,
-                        guint8     spacing,
-                        GdkPixmap *pixmap_closed,
-                        GdkBitmap *mask_closed,
-                        GdkPixmap *pixmap_opened,
-                        GdkBitmap *mask_opened,
-                        gboolean   is_leaf,
-                        gboolean   expanded)
+gtk_ctree_set_node_info (GtkCTree     *ctree,
+                        GtkCTreeNode *node,
+                        gchar        *text,
+                        guint8        spacing,
+                        GdkPixmap    *pixmap_closed,
+                        GdkBitmap    *mask_closed,
+                        GdkPixmap    *pixmap_opened,
+                        GdkBitmap    *mask_opened,
+                        gboolean      is_leaf,
+                        gboolean      expanded)
 {
   gboolean old_leaf;
   gboolean old_expanded;
@@ -4463,8 +4479,8 @@ gtk_ctree_set_node_info (GtkCTree  *ctree,
 
   if (is_leaf && GTK_CTREE_ROW (node)->children)
     {
-      GList *work;
-      GList *ptr;
+      GtkCTreeNode *work;
+      GtkCTreeNode *ptr;
       
       work = GTK_CTREE_ROW (node)->children;
       while (work)
@@ -4488,15 +4504,15 @@ gtk_ctree_set_node_info (GtkCTree  *ctree,
 
   GTK_CTREE_ROW (node)->expanded = expanded;
   
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void
-gtk_ctree_set_shift (GtkCTree *ctree,
-                    GList    *node,
-                     gint      column,
-                     gint      vertical,
-                     gint      horizontal)
+gtk_ctree_set_shift (GtkCTree     *ctree,
+                    GtkCTreeNode *node,
+                     gint          column,
+                     gint          vertical,
+                     gint          horizontal)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4508,13 +4524,13 @@ gtk_ctree_set_shift (GtkCTree *ctree,
   GTK_CTREE_ROW (node)->row.cell[column].vertical   = vertical;
   GTK_CTREE_ROW (node)->row.cell[column].horizontal = horizontal;
 
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 GtkCellType 
-gtk_ctree_get_cell_type (GtkCTree *ctree,
-                        GList    *node,
-                        gint      column)
+gtk_ctree_get_cell_type (GtkCTree     *ctree,
+                        GtkCTreeNode *node,
+                        gint          column)
 {
   g_return_val_if_fail (ctree != NULL, -1);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), -1);
@@ -4527,10 +4543,10 @@ gtk_ctree_get_cell_type (GtkCTree *ctree,
 }
 
 gint
-gtk_ctree_get_text (GtkCTree  *ctree,
-                    GList     *node,
-                   gint       column,
-                    gchar    **text)
+gtk_ctree_get_text (GtkCTree      *ctree,
+                    GtkCTreeNode  *node,
+                   gint           column,
+                    gchar        **text)
 {
   g_return_val_if_fail (ctree != NULL, 0);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), 0);
@@ -4549,11 +4565,11 @@ gtk_ctree_get_text (GtkCTree  *ctree,
 }
 
 gint
-gtk_ctree_get_pixmap (GtkCTree   *ctree,
-                     GList      *node,
-                      gint        column,
-                      GdkPixmap **pixmap,
-                      GdkBitmap **mask)
+gtk_ctree_get_pixmap (GtkCTree     *ctree,
+                     GtkCTreeNode *node,
+                      gint          column,
+                      GdkPixmap   **pixmap,
+                      GdkBitmap   **mask)
 {
   g_return_val_if_fail (ctree != NULL, 0);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), 0);
@@ -4574,13 +4590,13 @@ gtk_ctree_get_pixmap (GtkCTree   *ctree,
 }
 
 gint
-gtk_ctree_get_pixtext (GtkCTree   *ctree,
-                      GList      *node,
-                       gint        column,
-                       gchar     **text,
-                       guint8     *spacing,
-                       GdkPixmap **pixmap,
-                       GdkBitmap **mask)
+gtk_ctree_get_pixtext (GtkCTree      *ctree,
+                      GtkCTreeNode  *node,
+                       gint           column,
+                       gchar        **text,
+                       guint8        *spacing,
+                       GdkPixmap    **pixmap,
+                       GdkBitmap    **mask)
 {
   g_return_val_if_fail (ctree != NULL, 0);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), 0);
@@ -4607,16 +4623,16 @@ gtk_ctree_get_pixtext (GtkCTree   *ctree,
 }
 
 gint
-gtk_ctree_get_node_info (GtkCTree     *ctree,
-                        GList        *node,
-                        gchar       **text,
-                        guint8       *spacing,
-                        GdkPixmap   **pixmap_closed,
-                        GdkBitmap   **mask_closed,
-                        GdkPixmap   **pixmap_opened,
-                        GdkBitmap   **mask_opened,
-                        gboolean     *is_leaf,
-                        gboolean     *expanded)
+gtk_ctree_get_node_info (GtkCTree      *ctree,
+                        GtkCTreeNode  *node,
+                        gchar        **text,
+                        guint8        *spacing,
+                        GdkPixmap    **pixmap_closed,
+                        GdkBitmap    **mask_closed,
+                        GdkPixmap    **pixmap_opened,
+                        GdkBitmap    **mask_opened,
+                        gboolean      *is_leaf,
+                        gboolean      *expanded)
 {
   g_return_val_if_fail (ctree != NULL, 0);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), 0);
@@ -4645,9 +4661,9 @@ gtk_ctree_get_node_info (GtkCTree     *ctree,
 }
 
 void
-gtk_ctree_set_foreground (GtkCTree   *ctree,
-                         GList      *node,
-                          GdkColor   *color)
+gtk_ctree_set_foreground (GtkCTree     *ctree,
+                         GtkCTreeNode *node,
+                          GdkColor     *color)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4661,13 +4677,13 @@ gtk_ctree_set_foreground (GtkCTree   *ctree,
   else
     GTK_CTREE_ROW (node)->row.fg_set = FALSE;
 
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void
-gtk_ctree_set_background (GtkCTree   *ctree,
-                         GList      *node,
-                          GdkColor   *color)
+gtk_ctree_set_background (GtkCTree     *ctree,
+                         GtkCTreeNode *node,
+                          GdkColor     *color)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4681,22 +4697,22 @@ gtk_ctree_set_background (GtkCTree   *ctree,
   else
     GTK_CTREE_ROW (node)->row.bg_set = FALSE;
 
-  tree_draw_row (ctree, node);
+  tree_draw_node (ctree, node);
 }
 
 void
-gtk_ctree_set_row_data (GtkCTree *ctree,
-                        GList    *node,
-                        gpointer  data)
+gtk_ctree_set_row_data (GtkCTree     *ctree,
+                        GtkCTreeNode *node,
+                        gpointer      data)
 {
   gtk_ctree_set_row_data_full (ctree, node, data, NULL);
 }
 
 void
-gtk_ctree_set_row_data_full (GtkCTree        *ctree,
-                             GList           *node,
-                             gpointer         data,
-                             GtkDestroyNotify destroy)
+gtk_ctree_set_row_data_full (GtkCTree         *ctree,
+                             GtkCTreeNode     *node,
+                             gpointer          data,
+                             GtkDestroyNotify  destroy)
 {
   g_return_if_fail (ctree != NULL);
   g_return_if_fail (GTK_IS_CTREE (ctree));
@@ -4706,8 +4722,8 @@ gtk_ctree_set_row_data_full (GtkCTree        *ctree,
 }
 
 gpointer
-gtk_ctree_get_row_data (GtkCTree *ctree,
-                        GList    *node)
+gtk_ctree_get_row_data (GtkCTree     *ctree,
+                        GtkCTreeNode *node)
 {
   g_return_val_if_fail (ctree != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CTREE (ctree), NULL);
@@ -4716,11 +4732,11 @@ gtk_ctree_get_row_data (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_moveto (GtkCTree *ctree,
-                 GList    *node,
-                 gint      column,
-                 gfloat    row_align,
-                 gfloat    col_align)
+gtk_ctree_moveto (GtkCTree     *ctree,
+                 GtkCTreeNode *node,
+                 gint          column,
+                 gfloat        row_align,
+                 gfloat        col_align)
 {
   gint row = -1;
   GtkCList *clist;
@@ -4734,7 +4750,7 @@ gtk_ctree_moveto (GtkCTree *ctree,
     node = GTK_CTREE_ROW (node)->parent;
 
   if (node)
-    row = g_list_position (clist->row_list, node);
+    row = g_list_position (clist->row_list, (GList *)node);
   
   gtk_clist_moveto (clist, row, column, row_align, col_align);
 }
@@ -4873,18 +4889,18 @@ gtk_ctree_set_compare_func (GtkCTree            *ctree,
 }
 
 static void
-tree_sort (GtkCTree *ctree,
-          GList    *node,
-          gpointer  data)
+tree_sort (GtkCTree     *ctree,
+          GtkCTreeNode *node,
+          gpointer      data)
 {
-  GList *list_start;
-  GList *max;
-  GList *work;
+  GtkCTreeNode *list_start;
+  GtkCTreeNode *max;
+  GtkCTreeNode *work;
 
   if (node)
     list_start = GTK_CTREE_ROW (node)->children;
   else
-    list_start = GTK_CLIST (ctree)->row_list;
+    list_start = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
 
   while (list_start)
     {
@@ -4907,11 +4923,11 @@ tree_sort (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_sort_recursive (GtkCTree *ctree, 
-                         GList    *node)
+gtk_ctree_sort_recursive (GtkCTree     *ctree, 
+                         GtkCTreeNode *node)
 {
   GtkCList *clist;
-  GList *focus_node = NULL;
+  GtkCTreeNode *focus_node = NULL;
   gboolean thaw = FALSE;
 
   g_return_if_fail (ctree != NULL);
@@ -4937,13 +4953,14 @@ gtk_ctree_sort_recursive (GtkCTree *ctree,
     }
 
   if (node && gtk_ctree_is_visible (ctree, node))
-    focus_node = g_list_nth (clist->row_list, clist->focus_row);
+    focus_node =
+      GTK_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row));
       
   gtk_ctree_post_recursive (ctree, node, GTK_CTREE_FUNC (tree_sort), NULL);
 
   if (focus_node)
     {
-      clist->focus_row = g_list_position (clist->row_list, focus_node);
+      clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node);
       clist->undo_anchor = clist->focus_row;
     }
 
@@ -4952,11 +4969,11 @@ gtk_ctree_sort_recursive (GtkCTree *ctree,
 }
 
 void
-gtk_ctree_sort (GtkCTree *ctree, 
-               GList    *node)
+gtk_ctree_sort (GtkCTree     *ctree, 
+               GtkCTreeNode *node)
 {
   GtkCList *clist;
-  GList *focus_node = NULL;
+  GtkCTreeNode *focus_node = NULL;
   gboolean thaw = FALSE;
 
   g_return_if_fail (ctree != NULL);
@@ -4982,13 +4999,14 @@ gtk_ctree_sort (GtkCTree *ctree,
     }
 
   if (node && gtk_ctree_is_visible (ctree, node))
-    focus_node = g_list_nth (clist->row_list, clist->focus_row);
+    focus_node = GTK_CTREE_NODE
+      (g_list_nth (clist->row_list, clist->focus_row));
 
   tree_sort (ctree, node, NULL);
 
   if (focus_node)
     {
-      clist->focus_row = g_list_position (clist->row_list, focus_node);
+      clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node);
       clist->undo_anchor = clist->focus_row;
     }
 
@@ -5028,7 +5046,7 @@ fake_unselect_all (GtkCList *clist,
        continue;
 
       GTK_CTREE_ROW ((GList *)(list->data))->row.state = GTK_STATE_NORMAL;
-      tree_draw_row (GTK_CTREE (clist), (GList *)(list->data));
+      tree_draw_node (GTK_CTREE (clist), GTK_CTREE_NODE (list->data));
     }
 }
 
@@ -5045,7 +5063,7 @@ resync_selection (GtkCList *clist, GdkEvent *event)
 {
   GtkCTree *ctree;
   GList *list;
-  GList *node;
+  GtkCTreeNode *node;
   gint i;
   gint e;
   gint row;
@@ -5086,7 +5104,7 @@ resync_selection (GtkCList *clist, GdkEvent *event)
 
          if (gtk_ctree_is_visible (ctree, node))
            {
-             row = g_list_position (clist->row_list, node);
+             row = g_list_position (clist->row_list, (GList *)node);
              if (row >= i && row <= e)
                unselect = FALSE;
            }
@@ -5101,7 +5119,8 @@ resync_selection (GtkCList *clist, GdkEvent *event)
     }    
 
 
-  for (node = g_list_nth (clist->row_list, i); i <= e; i++, node = node->next)
+  for (node = GTK_CTREE_NODE (g_list_nth (clist->row_list, i)); i <= e;
+       i++, node = GTK_CTREE_NODE_NEXT (node))
     if (g_list_find (clist->selection, node))
       {
        if (GTK_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL)
@@ -5150,10 +5169,10 @@ real_undo_selection (GtkCList *clist)
   ctree = GTK_CTREE (clist);
 
   for (work = clist->undo_selection; work; work = work->next)
-    gtk_ctree_select (ctree, (GList *) work->data);
+    gtk_ctree_select (ctree, GTK_CTREE_NODE (work->data));
 
   for (work = clist->undo_unselection; work; work = work->next)
-    gtk_ctree_unselect (ctree, (GList *) work->data);
+    gtk_ctree_unselect (ctree, GTK_CTREE_NODE (work->data));
 
   if (GTK_WIDGET_HAS_FOCUS (clist) && clist->focus_row != clist->undo_anchor)
     {
index e430a19dd5f2cce2ef49960124db1cc461a4a33b..b48e2aad369f88a9b92056232ef0d611f5a04205 100644 (file)
@@ -37,7 +37,10 @@ extern "C"
 #define GTK_IS_CTREE(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_CTREE))
 #define GTK_IS_CTREE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CTREE))
 
-#define GTK_CTREE_ROW(_glist_) ((GtkCTreeRow *)((_glist_)->data))
+#define GTK_CTREE_ROW(_node_) ((GtkCTreeRow *)(((GList *)(_node_))->data))
+#define GTK_CTREE_NODE(_node_) ((GtkCTreeNode *)((_node_)))
+#define GTK_CTREE_NODE_NEXT(_nnode_) ((GtkCTreeNode *)(((GList *)(_nnode_))->next))
+#define GTK_CTREE_NODE_PREV(_pnode_) ((GtkCTreeNode *)(((GList *)(_pnode_))->prev))
 #define GTK_CTREE_TREE(_ctree_, _glist_) \
   ((GtkCellTree *) &(((GtkCTreeRow *)((_glist_)->data))->cell[(_ctree_)->tree_col]))
 
@@ -71,14 +74,15 @@ typedef enum
 typedef struct _GtkCTree      GtkCTree;
 typedef struct _GtkCTreeClass GtkCTreeClass;
 typedef struct _GtkCTreeRow   GtkCTreeRow;
+typedef struct _GtkCTreeNode  GtkCTreeNode;
 
-typedef void (*GtkCTreeFunc) (GtkCTree *ctree,
-                             GList    *node,
-                             gpointer  data);
+typedef void (*GtkCTreeFunc) (GtkCTree     *ctree,
+                             GtkCTreeNode *node,
+                             gpointer      data);
 
 typedef gint (*GtkCTreeCompareFunc) (GtkCTree    *ctree,
-                                    const GList *node1,
-                                    const GList *node2);
+                                    const GtkCTreeNode *node1,
+                                    const GtkCTreeNode *node2);
 
 struct _GtkCTree
 {
@@ -93,8 +97,8 @@ struct _GtkCTree
   gint tree_indent;
   gint tree_column;
   gint drag_row;
-  GList *drag_source;
-  GList *drag_target;
+  GtkCTreeNode *drag_source;
+  GtkCTreeNode *drag_target;
   gint insert_pos;
   GtkCTreeCompareFunc node_compare;
 
@@ -110,20 +114,20 @@ struct _GtkCTreeClass
 {
   GtkCListClass parent_class;
 
-  void (*tree_select_row)   (GtkCTree *ctree,
-                            GList    *row,
-                            gint      column);
-  void (*tree_unselect_row) (GtkCTree *ctree,
-                            GList    *row,
-                            gint      column);
-  void (*tree_expand)       (GtkCTree *ctree,
-                            GList    *node);
-  void (*tree_collapse)     (GtkCTree *ctree,
-                            GList    *node);
-  void (*tree_move)         (GtkCTree *ctree,
-                            GList    *node,
-                            GList    *new_parent,
-                            GList    *new_sibling);
+  void (*tree_select_row)   (GtkCTree     *ctree,
+                            GtkCTreeNode *row,
+                            gint          column);
+  void (*tree_unselect_row) (GtkCTree     *ctree,
+                            GtkCTreeNode *row,
+                            gint          column);
+  void (*tree_expand)       (GtkCTree     *ctree,
+                            GtkCTreeNode *node);
+  void (*tree_collapse)     (GtkCTree     *ctree,
+                            GtkCTreeNode *node);
+  void (*tree_move)         (GtkCTree     *ctree,
+                            GtkCTreeNode *node,
+                            GtkCTreeNode *new_parent,
+                            GtkCTreeNode *new_sibling);
   void (*change_focus_row_expansion) (GtkCTree *ctree,
                                      GtkCTreeExpansionType action);
 };
@@ -132,9 +136,9 @@ struct _GtkCTreeRow
 {
   GtkCListRow row;
 
-  GList *parent;
-  GList *sibling;
-  GList *children;
+  GtkCTreeNode *parent;
+  GtkCTreeNode *sibling;
+  GtkCTreeNode *children;
 
   GdkPixmap *pixmap_closed;
   GdkBitmap *mask_closed;
@@ -147,6 +151,10 @@ struct _GtkCTreeRow
   guint expanded : 1;
 };
 
+struct _GtkCTreeNode {
+  GList list;
+};
+
 
 /***********************************************************
  *           Creation, insertion, deletion                 *
@@ -162,9 +170,9 @@ GtkWidget * gtk_ctree_new_with_titles       (gint          columns,
                                             gchar        *titles[]);
 GtkWidget * gtk_ctree_new                   (gint          columns, 
                                             gint          tree_column);
-GList *     gtk_ctree_insert                (GtkCTree     *ctree,
-                                            GList        *parent, 
-                                            GList        *sibling,
+GtkCTreeNode * gtk_ctree_insert             (GtkCTree     *ctree,
+                                            GtkCTreeNode *parent, 
+                                            GtkCTreeNode *sibling,
                                             gchar        *text[],
                                             guint8        spacing,
                                             GdkPixmap    *pixmap_closed,
@@ -174,7 +182,7 @@ GList *     gtk_ctree_insert                (GtkCTree     *ctree,
                                             gboolean      is_leaf,
                                             gboolean      expanded);
 void       gtk_ctree_remove                 (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 
 /***********************************************************
  *  Generic recursive functions, querying / finding tree   *
@@ -182,37 +190,37 @@ void       gtk_ctree_remove                 (GtkCTree     *ctree,
  ***********************************************************/
 
 void       gtk_ctree_post_recursive          (GtkCTree     *ctree, 
-                                             GList        *node,
+                                             GtkCTreeNode *node,
                                              GtkCTreeFunc  func,
                                              gpointer      data);
 void       gtk_ctree_post_recursive_to_depth (GtkCTree     *ctree, 
-                                             GList        *node,
+                                             GtkCTreeNode *node,
                                              gint          depth,
                                              GtkCTreeFunc  func,
                                              gpointer      data);
 void       gtk_ctree_pre_recursive           (GtkCTree     *ctree, 
-                                             GList        *node,
+                                             GtkCTreeNode *node,
                                              GtkCTreeFunc  func,
                                              gpointer      data);
 void       gtk_ctree_pre_recursive_to_depth  (GtkCTree     *ctree, 
-                                             GList        *node,
+                                             GtkCTreeNode *node,
                                              gint          depth,
                                              GtkCTreeFunc  func,
                                              gpointer      data);
 gboolean   gtk_ctree_is_visible              (GtkCTree     *ctree, 
-                                             GList        *node);
-GList *    gtk_ctree_last                    (GtkCTree     *ctree,
-                                             GList        *node);
-GList *    gtk_ctree_find_glist_ptr          (GtkCTree     *ctree,
+                                             GtkCTreeNode *node);
+GtkCTreeNode * gtk_ctree_last                (GtkCTree     *ctree,
+                                             GtkCTreeNode *node);
+GtkCTreeNode * gtk_ctree_find_glist_ptr      (GtkCTree     *ctree,
                                              GtkCTreeRow  *ctree_row);
 gint       gtk_ctree_find                    (GtkCTree     *ctree,
-                                             GList        *node,
-                                             GList        *child);
+                                             GtkCTreeNode *node,
+                                             GtkCTreeNode *child);
 gboolean   gtk_ctree_is_ancestor             (GtkCTree     *ctree,
-                                             GList        *node,
-                                             GList        *child);
-GList *    gtk_ctree_find_by_row_data        (GtkCTree     *ctree,
-                                             GList        *node,
+                                             GtkCTreeNode *node,
+                                             GtkCTreeNode *child);
+GtkCTreeNode * gtk_ctree_find_by_row_data    (GtkCTree     *ctree,
+                                             GtkCTreeNode *node,
                                              gpointer      data);
 gboolean   gtk_ctree_is_hot_spot             (GtkCTree     *ctree,
                                              gint          x,
@@ -223,37 +231,37 @@ gboolean   gtk_ctree_is_hot_spot             (GtkCTree     *ctree,
  ***********************************************************/
 
 void       gtk_ctree_move                   (GtkCTree     *ctree,
-                                            GList        *node,
-                                            GList        *new_parent, 
-                                            GList        *new_sibling);
+                                            GtkCTreeNode *node,
+                                            GtkCTreeNode *new_parent, 
+                                            GtkCTreeNode *new_sibling);
 void       gtk_ctree_expand                 (GtkCTree     *ctree,
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_expand_recursive       (GtkCTree     *ctree,
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_expand_to_depth        (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          depth);
 void       gtk_ctree_collapse               (GtkCTree     *ctree,
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_collapse_recursive     (GtkCTree     *ctree,
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_collapse_to_depth      (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          depth);
 void       gtk_ctree_toggle_expansion       (GtkCTree     *ctree,
-                                            GList        *node);
-void       gtk_ctree_toggle_expansion_recursive (GtkCTree *ctree,
-                                                GList    *node);
+                                            GtkCTreeNode *node);
+void       gtk_ctree_toggle_expansion_recursive (GtkCTree     *ctree,
+                                                GtkCTreeNode *node);
 void       gtk_ctree_select                 (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_select_recursive       (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_unselect               (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_unselect_recursive     (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_real_select_recursive  (GtkCTree     *ctree, 
-                                            GList        *node, 
+                                            GtkCTreeNode *node, 
                                             gint          state);
 
 /***********************************************************
@@ -261,23 +269,23 @@ void       gtk_ctree_real_select_recursive  (GtkCTree     *ctree,
  ***********************************************************/
 
 void       gtk_ctree_set_text               (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gchar        *text);
 void       gtk_ctree_set_pixmap             (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             GdkPixmap    *pixmap,
                                             GdkBitmap    *mask);
 void       gtk_ctree_set_pixtext            (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gchar        *text,
                                             guint8        spacing,
                                             GdkPixmap    *pixmap,
                                             GdkBitmap    *mask);
 void       gtk_ctree_set_node_info          (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gchar        *text,
                                             guint8        spacing,
                                             GdkPixmap    *pixmap_closed,
@@ -287,31 +295,31 @@ void       gtk_ctree_set_node_info          (GtkCTree     *ctree,
                                             gboolean      is_leaf,
                                             gboolean      expanded);
 void       gtk_ctree_set_shift              (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gint          vertical,
                                             gint          horizontal);
 GtkCellType gtk_ctree_get_cell_type         (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column);
 gint       gtk_ctree_get_text               (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gchar       **text);
 gint       gtk_ctree_get_pixmap             (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             GdkPixmap   **pixmap,
                                             GdkBitmap   **mask);
 gint       gtk_ctree_get_pixtext            (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gchar       **text,
                                             guint8       *spacing,
                                             GdkPixmap   **pixmap,
                                             GdkBitmap   **mask);
 gint       gtk_ctree_get_node_info          (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gchar       **text,
                                             guint8       *spacing,
                                             GdkPixmap   **pixmap_closed,
@@ -321,22 +329,22 @@ gint       gtk_ctree_get_node_info          (GtkCTree     *ctree,
                                             gboolean     *is_leaf,
                                             gboolean     *expanded);
 void       gtk_ctree_set_foreground         (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             GdkColor     *color);
 void       gtk_ctree_set_background         (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             GdkColor     *color);
 void       gtk_ctree_set_row_data           (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gpointer      data);
 void       gtk_ctree_set_row_data_full      (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gpointer      data,
                                             GtkDestroyNotify destroy);
 gpointer   gtk_ctree_get_row_data           (GtkCTree     *ctree,
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_moveto                 (GtkCTree     *ctree,
-                                            GList        *node,
+                                            GtkCTreeNode *node,
                                             gint          column,
                                             gfloat        row_align,
                                             gfloat        col_align);
@@ -363,9 +371,9 @@ void       gtk_ctree_set_auto_sort          (GtkCTree     *ctree,
 void       gtk_ctree_set_compare_func       (GtkCTree     *ctree,
                                             GtkCTreeCompareFunc cmp_func);
 void       gtk_ctree_sort                   (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 void       gtk_ctree_sort_recursive         (GtkCTree     *ctree, 
-                                            GList        *node);
+                                            GtkCTreeNode *node);
 
 #ifdef __cplusplus
 }
index 09a5a1a8f9f0449c8691f91daef5f6a97ab77195..3e4b432f22585bb912ff60e33d7fbc7f26b770e2 100644 (file)
@@ -20,7 +20,7 @@
 #include "gtklistitem.h"
 #include "gtkmain.h"
 #include "gtksignal.h"
-
+#include "gtklabel.h"
 
 enum {
   SELECTION_CHANGED,
@@ -29,6 +29,8 @@ enum {
   LAST_SIGNAL
 };
 
+#define SCROLL_TIME  100
+
 static void gtk_list_class_init             (GtkListClass   *klass);
 static void gtk_list_init           (GtkList        *list);
 static void gtk_list_shutdown       (GtkObject      *object);
@@ -40,8 +42,8 @@ static void gtk_list_draw          (GtkWidget      *widget,
                                      GdkRectangle   *area);
 static gint gtk_list_expose         (GtkWidget      *widget,
                                      GdkEventExpose *event);
-static gint gtk_list_enter_notify    (GtkWidget        *widget,
-                                     GdkEventCrossing *event);
+static gint gtk_list_motion_notify   (GtkWidget      *widget,
+                                     GdkEventMotion *event);
 static gint gtk_list_button_press    (GtkWidget      *widget,
                                      GdkEventButton *event);
 static gint gtk_list_button_release  (GtkWidget             *widget,
@@ -63,12 +65,39 @@ static void gtk_real_list_select_child       (GtkList       *list,
 static void gtk_real_list_unselect_child (GtkList      *list,
                                          GtkWidget     *child);
 
+
+static void gtk_list_set_anchor          (GtkList       *list,
+                                         gboolean       add_mode,
+                                         gint           anchor,
+                                         GtkWidget     *undo_focus_child);
+static void gtk_list_fake_unselect_all   (GtkList       *list,
+                                         GtkWidget     *item);
+static void gtk_list_fake_toggle_row     (GtkList       *list,
+                                         GtkWidget     *item);
+static void gtk_list_move_focus_child    (GtkList       *list,
+                                         GtkScrollType  scroll_type,
+                                         gfloat         position);
+static void gtk_list_update_extended_selection (GtkList *list,
+                                               gint     row);
+static void gtk_list_focus_lost          (GtkWidget     *item,
+                                         GdkEventKey   *event,
+                                         GtkList       *list);
+static void gtk_list_set_focus_child     (GtkContainer  *container,
+                                         GtkWidget     *widget);
+static gint gtk_list_focus               (GtkContainer     *container,
+                                         GtkDirectionType  direction);
+
+
 static GtkType gtk_list_child_type  (GtkContainer   *container);
 
 
 static GtkContainerClass *parent_class = NULL;
 static guint list_signals[LAST_SIGNAL] = { 0 };
 
+static const gchar *vadjustment_key = "gtk-vadjustment";
+static guint        vadjustment_key_id = 0;
+static const gchar *hadjustment_key = "gtk-hadjustment";
+static guint        hadjustment_key_id = 0;
 
 GtkType
 gtk_list_get_type (void)
@@ -108,6 +137,9 @@ gtk_list_class_init (GtkListClass *class)
 
   parent_class = gtk_type_class (gtk_container_get_type ());
 
+  vadjustment_key_id = g_quark_from_static_string (vadjustment_key);
+  hadjustment_key_id = g_quark_from_static_string (hadjustment_key);
+
   list_signals[SELECTION_CHANGED] =
     gtk_signal_new ("selection_changed",
                    GTK_RUN_FIRST,
@@ -144,7 +176,7 @@ gtk_list_class_init (GtkListClass *class)
   widget_class->expose_event = gtk_list_expose;
   widget_class->button_press_event = gtk_list_button_press;
   widget_class->button_release_event = gtk_list_button_release;
-  widget_class->enter_notify_event = gtk_list_enter_notify;
+  widget_class->motion_notify_event = gtk_list_motion_notify;
   widget_class->size_request = gtk_list_size_request;
   widget_class->size_allocate = gtk_list_size_allocate;
 
@@ -152,6 +184,8 @@ gtk_list_class_init (GtkListClass *class)
   container_class->remove = gtk_list_remove;
   container_class->foreach = gtk_list_foreach;
   container_class->child_type = gtk_list_child_type;
+  container_class->set_focus_child = gtk_list_set_focus_child;
+  container_class->focus = gtk_list_focus;
 
   class->selection_changed = NULL;
   class->select_child = gtk_real_list_select_child;
@@ -169,12 +203,23 @@ gtk_list_init (GtkList *list)
 {
   list->children = NULL;
   list->selection = NULL;
-  list->timer = 0;
-  list->selection_start_pos = 0;
-  list->selection_end_pos = 0;
+
+  list->undo_selection = NULL;
+  list->undo_unselection = NULL;
+
+  list->last_focus_child = NULL;
+  list->undo_focus_child = NULL;
+
+  list->htimer = 0;
+  list->vtimer = 0;
+
+  list->anchor = -1;
+  list->drag_pos = -1;
+  list->anchor_state = GTK_STATE_SELECTED;
+
   list->selection_mode = GTK_SELECTION_SINGLE;
-  list->scroll_direction = 0;
-  list->button = 0;
+  list->drag_selection = FALSE;
+  list->add_mode = FALSE;
 }
 
 GtkWidget*
@@ -225,18 +270,28 @@ gtk_list_destroy (GtkObject *object)
     (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
-static void
-gtk_list_ungrab (GtkList *list)
+void
+gtk_list_end_drag_selection (GtkList *list)
 {
   g_return_if_fail (list != NULL);
   g_return_if_fail (GTK_IS_LIST (list));
 
-  if (list->button)
+  list->drag_selection = FALSE;
+  if (GTK_WIDGET_HAS_GRAB (list))
     {
-      list->button = 0;
       gtk_grab_remove (GTK_WIDGET (list));
       gdk_pointer_ungrab (GDK_CURRENT_TIME);
     }
+  if (list->htimer)
+    {
+      gtk_timeout_remove (list->htimer);
+      list->htimer = 0;
+    }
+  if (list->vtimer)
+    {
+      gtk_timeout_remove (list->vtimer);
+      list->vtimer = 0;
+    }
 }
 
 void
@@ -255,7 +310,9 @@ gtk_list_insert_items (GtkList *list,
   if (!items)
     return;
 
-  gtk_list_ungrab (list);
+  gtk_list_end_drag_selection (list);
+  if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+    gtk_list_end_selection (list);
 
   tmp_list = items;
   while (tmp_list)
@@ -264,6 +321,8 @@ gtk_list_insert_items (GtkList *list,
       tmp_list = tmp_list->next;
 
       gtk_widget_set_parent (widget, GTK_WIDGET (list));
+      gtk_signal_connect (GTK_OBJECT (widget), "focus_out_event",
+                         GTK_SIGNAL_FUNC (gtk_list_focus_lost), list);
 
       if (GTK_WIDGET_VISIBLE (widget->parent))
        {
@@ -346,28 +405,62 @@ gtk_list_remove_items_internal (GtkList    *list,
                                gboolean no_unref)
 {
   GtkWidget *widget;
+  GtkWidget *new_focus_child;
+  GtkWidget *old_focus_child;
+  GtkContainer *container;
   GList *selected_widgets;
   GList *tmp_list;
+  GList *work;
+  gboolean grab_focus = FALSE;
   
   g_return_if_fail (list != NULL);
   g_return_if_fail (GTK_IS_LIST (list));
 
   if (!items)
     return;
+  
+  container = GTK_CONTAINER (list);
+
+  gtk_list_end_drag_selection (list);
+  if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+    gtk_list_end_selection (list);
 
-  gtk_list_ungrab (list);
   
   tmp_list = items;
   selected_widgets = NULL;
   widget = NULL;
-  
+  old_focus_child = new_focus_child = container->focus_child;
+
   while (tmp_list)
     {
       widget = tmp_list->data;
+
       tmp_list = tmp_list->next;
       
       if (no_unref)
        gtk_widget_ref (widget);
+      
+      gtk_signal_disconnect_by_func
+       (GTK_OBJECT (widget), GTK_SIGNAL_FUNC (gtk_list_focus_lost), list);
+
+
+      if (widget == new_focus_child) 
+       {
+         work = g_list_find (list->children, widget);
+
+         if (work)
+           {
+             if (work->next)
+               new_focus_child = work->next->data;
+             else if (list->children != work && work->prev)
+               new_focus_child = work->prev->data;
+             else
+               new_focus_child = NULL;
+             
+             if (GTK_WIDGET_HAS_FOCUS (widget))
+               grab_focus = TRUE;
+           }
+       }
 
       list->children = g_list_remove (list->children, widget);
 
@@ -395,11 +488,12 @@ gtk_list_remove_items_internal (GtkList    *list,
   
   g_list_free (selected_widgets);
   
-  if (list->children && !list->selection &&
-      (list->selection_mode == GTK_SELECTION_BROWSE))
+  if (new_focus_child && new_focus_child != old_focus_child)
     {
-      widget = list->children->data;
-      gtk_list_select_child (list, widget);
+      if (grab_focus)
+       gtk_widget_grab_focus (new_focus_child);
+      else
+       gtk_container_set_focus_child (container, new_focus_child);
     }
   
   if (GTK_WIDGET_VISIBLE (list))
@@ -449,7 +543,9 @@ gtk_list_clear_items (GtkList *list,
       start_list = g_list_nth (list->children, start);
       end_list = g_list_nth (list->children, end);
 
-      gtk_list_ungrab (list);
+      gtk_list_end_drag_selection (list);
+      if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+       gtk_list_end_selection (list);
 
       if (start_list->prev)
        start_list->prev->next = end_list;
@@ -568,7 +664,21 @@ gtk_list_set_selection_mode (GtkList             *list,
   g_return_if_fail (list != NULL);
   g_return_if_fail (GTK_IS_LIST (list));
 
+  if (list->selection_mode == mode)
+    return;
+
   list->selection_mode = mode;
+
+  switch (mode)
+    {
+    case GTK_SELECTION_SINGLE:
+    case GTK_SELECTION_BROWSE:
+      gtk_list_unselect_all (list);
+      break;
+
+    default:
+      break;
+    }
 }
 
 
@@ -703,32 +813,165 @@ gtk_list_expose (GtkWidget       *widget,
   return FALSE;
 }
 
+static void
+move_horizontal (GtkList       *list,
+                GtkAdjustment *adj,
+                gint           diff)
+{
+  gfloat upper;
+
+  adj->value += diff;
+
+  upper = adj->upper - adj->page_size;
+  adj->value = MIN (adj->value, upper);
+  adj->value = MAX (adj->value, 0.0);
+
+  gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+}
+
+static gint
+horizontal_timeout (GtkWidget *list)
+{
+  gint x, y;
+  GdkEventMotion event;
+  GdkModifierType mask;
+
+  g_return_val_if_fail (GTK_IS_LIST (list), FALSE);
+
+  GTK_LIST (list)->htimer = 0;
+  gdk_window_get_pointer (list->window, &x, &y, &mask);
+
+  event.is_hint = 0;
+  event.x = x;
+  event.y = y;
+  event.state = mask;
+
+  gtk_list_motion_notify (list, &event);
+
+  return FALSE;
+}
+
+static gint
+vertical_timeout (GtkWidget *list)
+{
+  gint x;
+  gint y;
+  GdkEventMotion event;
+  GdkModifierType mask;
+
+  g_return_val_if_fail (GTK_IS_LIST (list), FALSE);
+
+  GTK_LIST (list)->vtimer = 0;
+  gdk_window_get_pointer (list->window, &x, &y, &mask);
+
+  event.is_hint = 0;
+  event.x = x;
+  event.y = y;
+  event.state = mask;
+
+  gtk_list_motion_notify (list, &event);
+
+  return FALSE;
+}
+
 static gint
-gtk_list_enter_notify (GtkWidget        *widget,
-                      GdkEventCrossing *event)
+gtk_list_motion_notify (GtkWidget      *widget,
+                       GdkEventMotion *event)
 {
   GtkList *list;
-  GtkWidget *item;
+  GtkWidget *item = NULL;
+  GtkAdjustment *adj;
+  GtkContainer *container;
+  GList *work;
+  gint x;
+  gint y;
+  gint row = -1;
+  gint focus_row = 0;
+  gint length = 0;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
   list = GTK_LIST (widget);
-  item = gtk_get_event_widget ((GdkEvent*) event);
 
-  if (!list->button)
+  if (!list->drag_selection || !list->children)
     return FALSE;
+
+  container = GTK_CONTAINER (widget);
+
+  if (event->is_hint || event->window != widget->window)
+    gdk_window_get_pointer (widget->window, &x, &y, NULL);
+
+  adj = gtk_object_get_data_by_id (GTK_OBJECT (list), hadjustment_key_id);
+
+  /* horizontal autoscrolling */
+  if (adj && widget->allocation.width > adj->page_size &&
+      (x < adj->value || x >= adj->value + adj->page_size))
+    {
+      if (list->htimer == 0)
+       {
+         list->htimer = gtk_timeout_add
+           (SCROLL_TIME, (GtkFunction) horizontal_timeout, widget);
+         
+         if (!((x < adj->value && adj->value <= 0) ||
+               (x > adj->value + adj->page_size &&
+                adj->value >= adj->upper - adj->page_size)))
+           {
+             if (x < adj->value)
+               move_horizontal (list, adj, - 1 + (x - adj->value) / 2 );
+             else
+               move_horizontal (list, adj,
+                                1 + (x - adj->value - adj->page_size) / 2);
+           }
+       }
+      else
+       return FALSE;
+    }
+
   
-  while (item && !GTK_IS_LIST_ITEM (item))
-    item = item->parent;
+  /* vertical autoscrolling */
+  for (work = list->children; work; length++, work = work->next)
+    {
+      if (row < 0)
+       {
+         item = GTK_WIDGET (work->data);
+         if (item->allocation.y > y || 
+             (item->allocation.y <= y &&
+              item->allocation.y + item->allocation.height > y))
+           row = length;
+       }
 
-  if (item && (item->parent == widget))
+      if (work->data == container->focus_child)
+       focus_row = length;
+    }
+  
+  if (row < 0)
+    row = length - 1;
+
+  if (list->vtimer != 0)
+    return FALSE;
+
+  if (!((y < 0 && focus_row == 0) ||
+       (y > widget->allocation.height && focus_row >= length - 1)))
+    list->vtimer = gtk_timeout_add (SCROLL_TIME,
+                                   (GtkFunction) vertical_timeout, list);
+         
+  if (row != focus_row)
+    gtk_widget_grab_focus (item);
+         
+  switch (list->selection_mode)
     {
+    case GTK_SELECTION_BROWSE:
       gtk_list_select_child (list, item);
+      break;
+      
+    case GTK_SELECTION_EXTENDED:
+      gtk_list_update_extended_selection (list, row);
+      break;
 
-      if (!GTK_WIDGET_HAS_FOCUS (item))
-       gtk_widget_grab_focus (item);
+    default:
+      break;
     }
 
   return FALSE;
@@ -745,27 +988,126 @@ gtk_list_button_press (GtkWidget      *widget,
   g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
+  if (event->button != 1)
+    return FALSE;
+
   list = GTK_LIST (widget);
   item = gtk_get_event_widget ((GdkEvent*) event);
 
-  if ((event->button != 1) || (list->button))
-    return FALSE;
-  
   while (item && !GTK_IS_LIST_ITEM (item))
     item = item->parent;
 
-  list->button = event->button;
-  gdk_pointer_grab (widget->window, TRUE,
-                   GDK_BUTTON_PRESS_MASK | 
-                   GDK_BUTTON_RELEASE_MASK,
-                   NULL, NULL, event->time);
-  gtk_grab_add (widget);
-
-  /* note: gtk_list_select_child() may cause the grab to be removed again!
-   */
   if (item && (item->parent == widget))
-    gtk_list_select_child (list, item);
-  
+    {
+      gint last_focus_row;
+      gint focus_row;
+
+      if (event->type == GDK_BUTTON_PRESS)
+       {
+         list->drag_selection = TRUE;
+         gdk_pointer_grab (widget->window, TRUE,
+                           GDK_POINTER_MOTION_HINT_MASK |
+                           GDK_BUTTON1_MOTION_MASK |
+                           GDK_BUTTON_RELEASE_MASK,
+                           NULL, NULL, event->time);
+         gtk_grab_add (widget);
+       }
+      else if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+       gtk_list_end_drag_selection (list);
+         
+      if (!GTK_WIDGET_HAS_FOCUS(item))
+       gtk_widget_grab_focus (item);
+
+      if (list->add_mode)
+       {
+         list->add_mode = FALSE;
+         gtk_widget_queue_draw (item);
+       }
+      
+      switch (list->selection_mode)
+       {
+       case GTK_SELECTION_SINGLE:
+       case GTK_SELECTION_MULTIPLE:
+         if (event->type != GDK_BUTTON_PRESS)
+           gtk_list_select_child (list, item);
+         else
+           list->undo_focus_child = item;
+         break;
+         
+       case GTK_SELECTION_BROWSE:
+         break;
+
+       case GTK_SELECTION_EXTENDED:
+         focus_row = g_list_index (list->children, item);
+
+         if (list->last_focus_child)
+           last_focus_row = g_list_index (list->children,
+                                          list->last_focus_child);
+         else
+           {
+             last_focus_row = focus_row;
+             list->last_focus_child = item;
+           }
+
+         if (event->type != GDK_BUTTON_PRESS)
+           {
+             if (list->anchor >= 0)
+               {
+                 gtk_list_update_extended_selection (list, focus_row);
+                 gtk_list_end_selection (list);
+               }
+             gtk_list_select_child (list, item);
+             break;
+           }
+             
+         if (event->state & GDK_CONTROL_MASK)
+           {
+             if (event->state & GDK_SHIFT_MASK)
+               {
+                 if (list->anchor < 0)
+                   {
+                     g_list_free (list->undo_selection);
+                     g_list_free (list->undo_unselection);
+                     list->undo_selection = NULL;
+                     list->undo_unselection = NULL;
+
+                     list->anchor = last_focus_row;
+                     list->drag_pos = last_focus_row;
+                     list->undo_focus_child = list->last_focus_child;
+                   }
+                 gtk_list_update_extended_selection (list, focus_row);
+               }
+             else
+               {
+                 if (list->anchor < 0)
+                   gtk_list_set_anchor (list, TRUE,
+                                        focus_row, list->last_focus_child);
+                 else
+                   gtk_list_update_extended_selection (list, focus_row);
+               }
+             break;
+           }
+
+         if (event->state & GDK_SHIFT_MASK)
+           {
+             gtk_list_set_anchor (list, FALSE,
+                                  last_focus_row, list->last_focus_child);
+             gtk_list_update_extended_selection (list, focus_row);
+             break;
+           }
+
+         if (list->anchor < 0)
+           gtk_list_set_anchor (list, FALSE, focus_row,
+                                list->last_focus_child);
+         else
+           gtk_list_update_extended_selection (list, focus_row);
+         break;
+         
+       default:
+         break;
+       }
+    }
+
   return FALSE;
 }
 
@@ -781,11 +1123,43 @@ gtk_list_button_release (GtkWidget       *widget,
   g_return_val_if_fail (event != NULL, FALSE);
 
   list = GTK_LIST (widget);
-  item = gtk_get_event_widget ((GdkEvent*) event);
 
-  if (list->button == event->button)
-    gtk_list_ungrab (list);
+  /* we don't handle button 2 and 3 */
+  if (event->button != 1)
+    return FALSE;
+
+  if (list->drag_selection)
+    {
+      gtk_list_end_drag_selection (list);
+
+      switch (list->selection_mode)
+       {
+       case GTK_SELECTION_EXTENDED:
+         if (!(event->state & GDK_SHIFT_MASK))
+           gtk_list_end_selection (list);
+         break;
+
+       case GTK_SELECTION_SINGLE:
+       case GTK_SELECTION_MULTIPLE:
+
+         item = gtk_get_event_widget ((GdkEvent*) event);
+  
+         while (item && !GTK_IS_LIST_ITEM (item))
+           item = item->parent;
+         
+         if (item && item->parent == widget)
+           {
+             if (list->undo_focus_child == item)
+               gtk_list_toggle_row (list, item);
+           }
+         list->undo_focus_child = NULL;
+         break;
 
+       default:
+         break;
+       }
+    }
+  
   return FALSE;
 }
 
@@ -935,7 +1309,6 @@ gtk_list_foreach (GtkContainer *container,
     }
 }
 
-
 static void
 gtk_real_list_select_child (GtkList   *list,
                            GtkWidget *child)
@@ -952,6 +1325,7 @@ gtk_real_list_select_child (GtkList   *list,
   switch (list->selection_mode)
     {
     case GTK_SELECTION_SINGLE:
+    case GTK_SELECTION_BROWSE:
       selection = list->selection;
 
       while (selection)
@@ -979,46 +1353,12 @@ gtk_real_list_select_child (GtkList   *list,
          gtk_widget_ref (child);
          gtk_list_item_select (GTK_LIST_ITEM (child));
        }
-      else if (child->state == GTK_STATE_SELECTED)
-       {
-         list->selection = g_list_remove (list->selection, child);
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
-         gtk_widget_unref (child);
-       }
-
       gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
       break;
 
-    case GTK_SELECTION_BROWSE:
-      selection = list->selection;
-
-      while (selection)
-       {
-         tmp_item = selection->data;
-
-         if (tmp_item != child)
-           {
-             tmp_list = selection;
-             selection = selection->next;
-
-             list->selection = g_list_remove_link (list->selection, tmp_list);
-             g_list_free (tmp_list);
-
-             gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
-             gtk_widget_unref (GTK_WIDGET (tmp_item));
-           }
-         else
-           selection = selection->next;
-       }
-
-      if (child->state == GTK_STATE_NORMAL)
-       {
-         list->selection = g_list_prepend (list->selection, child);
-         gtk_widget_ref (child);
-         gtk_list_item_select (GTK_LIST_ITEM (child));
-         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
-       }
-      break;
+    case GTK_SELECTION_EXTENDED:
+      if (list->anchor >= 0)
+       return;
 
     case GTK_SELECTION_MULTIPLE:
       if (child->state == GTK_STATE_NORMAL)
@@ -1028,16 +1368,6 @@ gtk_real_list_select_child (GtkList   *list,
          gtk_list_item_select (GTK_LIST_ITEM (child));
          gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
        }
-      else if (child->state == GTK_STATE_SELECTED)
-       {
-         list->selection = g_list_remove (list->selection, child);
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
-         gtk_widget_unref (child);
-         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
-       }
-      break;
-
-    case GTK_SELECTION_EXTENDED:
       break;
     }
 }
@@ -1051,21 +1381,891 @@ gtk_real_list_unselect_child (GtkList  *list,
   g_return_if_fail (child != NULL);
   g_return_if_fail (GTK_IS_LIST_ITEM (child));
 
-  switch (list->selection_mode)
+  if (child->state == GTK_STATE_SELECTED)
     {
-    case GTK_SELECTION_SINGLE:
-    case GTK_SELECTION_MULTIPLE:
-    case GTK_SELECTION_BROWSE:
-      if (child->state == GTK_STATE_SELECTED)
+      list->selection = g_list_remove (list->selection, child);
+      gtk_list_item_deselect (GTK_LIST_ITEM (child));
+      gtk_widget_unref (child);
+      gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+    }
+}
+
+
+/***************************************************************************/
+
+static void
+gtk_list_set_anchor (GtkList   *list,
+                    gboolean   add_mode,
+                    gint       anchor,
+                    GtkWidget *undo_focus_child)
+{
+  GList *work;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+  
+  if (list->selection_mode != GTK_SELECTION_EXTENDED || list->anchor >= 0)
+    return;
+
+  g_list_free (list->undo_selection);
+  g_list_free (list->undo_unselection);
+  list->undo_selection = NULL;
+  list->undo_unselection = NULL;
+
+  if ((work = g_list_nth (list->children, anchor)))
+    {
+      if (add_mode)
+       gtk_list_fake_toggle_row (list, GTK_WIDGET (work->data));
+      else
        {
-         list->selection = g_list_remove (list->selection, child);
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
-         gtk_widget_unref (child);
-         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+         gtk_list_fake_unselect_all (list, GTK_WIDGET (work->data));
+         list->anchor_state = GTK_STATE_SELECTED;
        }
-      break;
+    }
 
-    case GTK_SELECTION_EXTENDED:
-      break;
+  list->anchor = anchor;
+  list->drag_pos = anchor;
+  list->undo_focus_child = undo_focus_child;
+}
+
+static void
+gtk_list_fake_unselect_all (GtkList   *list,
+                           GtkWidget *item)
+{
+  GList *work;
+
+  if (item && item->state == GTK_STATE_NORMAL)
+    gtk_widget_set_state (item, GTK_STATE_SELECTED);
+
+  list->undo_selection = list->selection;
+  list->selection = NULL;
+  
+  for (work = list->undo_selection; work; work = work->next)
+    if (work->data != item)
+      gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL);
+}
+
+static void
+gtk_list_fake_toggle_row (GtkList   *list,
+                         GtkWidget *item)
+{
+  if (!item)
+    return;
+  
+  if (item->state == GTK_STATE_NORMAL)
+    {
+      list->anchor_state = GTK_STATE_SELECTED;
+      gtk_widget_set_state (item, GTK_STATE_SELECTED);
+    }
+  else
+    {
+      list->anchor_state = GTK_STATE_NORMAL;
+      gtk_widget_set_state (item, GTK_STATE_NORMAL);
     }
 }
+
+void
+gtk_list_scroll_horizontal (GtkList       *list,
+                           GtkScrollType  scroll_type,
+                           gfloat         position)
+{
+  GtkAdjustment *adj;
+
+  g_return_if_fail (list != 0);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+    return;
+
+  if (!(adj =
+       gtk_object_get_data_by_id (GTK_OBJECT (list), hadjustment_key_id)))
+    return;
+
+  switch (scroll_type)
+    {
+    case GTK_SCROLL_STEP_BACKWARD:
+      adj->value = CLAMP (adj->value - adj->step_increment, adj->lower,
+                         adj->upper - adj->page_size);
+      break;
+    case GTK_SCROLL_STEP_FORWARD:
+      adj->value = CLAMP (adj->value + adj->step_increment, adj->lower,
+                         adj->upper - adj->page_size);
+      break;
+    case GTK_SCROLL_PAGE_BACKWARD:
+      adj->value = CLAMP (adj->value - adj->page_increment, adj->lower,
+                         adj->upper - adj->page_size);
+      break;
+    case GTK_SCROLL_PAGE_FORWARD:
+      adj->value = CLAMP (adj->value + adj->page_increment, adj->lower,
+                         adj->upper - adj->page_size);
+      break;
+    case GTK_SCROLL_JUMP:
+      adj->value = CLAMP (adj->lower + (adj->upper - adj->lower) * position,
+                         adj->lower, adj->upper - adj->page_size);
+      break;
+    default:
+      break;
+    }
+  gtk_adjustment_value_changed (adj);
+}
+
+void
+gtk_list_scroll_vertical (GtkList       *list,
+                         GtkScrollType  scroll_type,
+                         gfloat         position)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+    return;
+
+  if (list->selection_mode == GTK_SELECTION_EXTENDED)
+    {
+      GtkContainer *container;
+
+      if (list->anchor >= 0)
+       return;
+
+      container = GTK_CONTAINER (list);
+      list->undo_focus_child = container->focus_child;
+      gtk_list_move_focus_child (list, scroll_type, position);
+      if (container->focus_child != list->undo_focus_child && !list->add_mode)
+       {
+         gtk_list_unselect_all (list);
+         gtk_list_select_child (list, container->focus_child);
+       }
+    }
+  else
+    gtk_list_move_focus_child (list, scroll_type, position);
+}
+
+static void
+gtk_list_move_focus_child (GtkList       *list,
+                          GtkScrollType  scroll_type,
+                          gfloat         position)
+{
+  GtkContainer *container;
+  GList *work;
+  GtkWidget *item;
+  GtkAdjustment *adj;
+  gint new_value;
+
+  g_return_if_fail (list != 0);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  container = GTK_CONTAINER (list);
+
+  if (container->focus_child)
+    work = g_list_find (list->children, container->focus_child);
+  else
+    work = list->children;
+
+  if (!work)
+    return;
+
+  switch (scroll_type)
+    {
+    case GTK_SCROLL_STEP_BACKWARD:
+      work = work->prev;
+      if (work)
+       gtk_widget_grab_focus (GTK_WIDGET (work->data));
+      break;
+
+    case GTK_SCROLL_STEP_FORWARD:
+      work = work->next;
+      if (work)
+       gtk_widget_grab_focus (GTK_WIDGET (work->data));
+      break;
+
+    case GTK_SCROLL_PAGE_BACKWARD:
+      if (!work->prev)
+       return;
+
+      item = work->data;
+      adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id);
+
+      if (adj)
+       {
+         gboolean correct = FALSE;
+
+         new_value = adj->value;
+
+         if (item->allocation.y <= adj->value)
+           {
+             new_value = MAX (item->allocation.y + item->allocation.height
+                              - adj->page_size, adj->lower);
+             correct = TRUE;
+           }
+
+         if (item->allocation.y > new_value)
+           for (; work; work = work->prev)
+             {
+               item = GTK_WIDGET (work->data);
+               if (item->allocation.y <= new_value &&
+                   item->allocation.y + item->allocation.height > new_value)
+                 break;
+             }
+         else
+           for (; work; work = work->next)
+             {
+               item = GTK_WIDGET (work->data);
+               if (item->allocation.y <= new_value &&
+                   item->allocation.y + item->allocation.height > new_value)
+                 break;
+             }
+
+         if (correct && work && work->next && item->allocation.y < new_value)
+           item = work->next->data;
+       }
+      else
+       item = list->children->data;
+         
+      gtk_widget_grab_focus (item);
+      break;
+         
+    case GTK_SCROLL_PAGE_FORWARD:
+      if (!work->next)
+       return;
+
+      item = work->data;
+      adj = gtk_object_get_data_by_id (GTK_OBJECT (list), vadjustment_key_id);
+
+      if (adj)
+       {
+         gboolean correct = FALSE;
+
+         new_value = adj->value;
+
+         if (item->allocation.y + item->allocation.height >=
+             adj->value + adj->page_size)
+           {
+             new_value = item->allocation.y;
+             correct = TRUE;
+           }
+
+         new_value = MIN (new_value + adj->page_size, adj->upper);
+
+         if (item->allocation.y > new_value)
+           for (; work; work = work->prev)
+             {
+               item = GTK_WIDGET (work->data);
+               if (item->allocation.y <= new_value &&
+                   item->allocation.y + item->allocation.height > new_value)
+                 break;
+             }
+         else
+           for (; work; work = work->next)
+             {
+               item = GTK_WIDGET (work->data);
+               if (item->allocation.y <= new_value &&
+                   item->allocation.y + item->allocation.height > new_value)
+                 break;
+             }
+
+         if (correct && work && work->prev &&
+             item->allocation.y + item->allocation.height - 1 > new_value)
+           item = work->prev->data;
+       }
+      else
+       item = g_list_last (work)->data;
+         
+      gtk_widget_grab_focus (item);
+      break;
+
+    case GTK_SCROLL_JUMP:
+      new_value = GTK_WIDGET(list)->allocation.height * CLAMP (position, 0, 1);
+
+      for (item = NULL, work = list->children; work; work =work->next)
+       {
+         item = GTK_WIDGET (work->data);
+         if (item->allocation.y <= new_value &&
+             item->allocation.y + item->allocation.height > new_value)
+           break;
+       }
+
+      gtk_widget_grab_focus (item);
+      break;
+
+    default:
+      break;
+    }
+}
+
+void
+gtk_list_select_all (GtkList *list)
+{
+  GtkContainer *container;
+  GList *work;
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (!list->children)
+    return;
+  
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+    gtk_list_end_drag_selection (list);
+
+  if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+    gtk_list_end_selection (list);
+
+  container = GTK_CONTAINER (list);
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_BROWSE:
+      if (container->focus_child)
+       {
+         gtk_list_select_child (list, container->focus_child);
+         return;
+       }
+      break;
+
+    case GTK_SELECTION_EXTENDED:
+      g_list_free (list->undo_selection);
+      g_list_free (list->undo_unselection);
+      list->undo_selection = NULL;
+      list->undo_unselection = NULL;
+
+      if (list->children &&
+         GTK_WIDGET_STATE (list->children->data) != GTK_STATE_SELECTED)
+       gtk_list_fake_toggle_row (list, GTK_WIDGET (list->children->data));
+
+      list->anchor_state =  GTK_STATE_SELECTED;
+      list->anchor = 0;
+      list->drag_pos = 0;
+      list->undo_focus_child = container->focus_child;
+      gtk_list_update_extended_selection (list, g_list_length(list->children));
+      gtk_list_end_selection (list);
+      return;
+
+    case GTK_SELECTION_MULTIPLE:
+      for (work = list->children; work; work = work->next)
+       {
+         if (GTK_WIDGET_STATE (work->data) == GTK_STATE_NORMAL)
+           gtk_list_select_child (list, GTK_WIDGET (work->data));
+       }
+      return;
+
+    default:
+      break;
+    }
+}
+
+void
+gtk_list_unselect_all (GtkList *list)
+{
+  GtkContainer *container;
+  GtkWidget *item;
+  GList *work;
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (!list->children)
+    return;
+  
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+    gtk_list_end_drag_selection (list);
+
+  if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+    gtk_list_end_selection (list);
+
+  container = GTK_CONTAINER (list);
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_BROWSE:
+      if (container->focus_child)
+       {
+         gtk_list_select_child (list, container->focus_child);
+         return;
+       }
+      break;
+
+    case GTK_SELECTION_EXTENDED:
+      g_list_free (list->undo_selection);
+      g_list_free (list->undo_unselection);
+      list->undo_selection = NULL;
+      list->undo_unselection = NULL;
+
+      list->anchor = -1;
+      list->drag_pos = -1;
+      list->undo_focus_child = container->focus_child;
+      break;
+
+    default:
+      break;
+    }
+
+  work = list->selection;
+
+  while (work)
+    {
+      item = work->data;
+      work = work->next;
+      gtk_list_unselect_child (list, item);
+    }
+}
+
+void
+gtk_list_extend_selection (GtkList       *list,
+                          GtkScrollType  scroll_type,
+                          gfloat         position,
+                          gboolean       auto_start_selection)
+{
+  GtkContainer *container;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) ||
+      list->selection_mode != GTK_SELECTION_EXTENDED)
+    return;
+
+  container = GTK_CONTAINER (list);
+
+  if (auto_start_selection)
+    {
+      gint focus_row;
+      focus_row = g_list_index (list->children, container->focus_child);
+      gtk_list_set_anchor (list, list->add_mode, focus_row,
+                          container->focus_child);
+    }
+  else if (list->anchor < 0)
+    return;
+
+  gtk_list_move_focus_child (list, scroll_type, position);
+  gtk_list_update_extended_selection 
+    (list, g_list_index (list->children, container->focus_child));
+}
+
+static void
+gtk_list_update_extended_selection (GtkList *list,
+                                   gint     row)
+{
+  gint i;
+  GList *work;
+  gint s1 = -1;
+  gint s2 = -1;
+  gint e1 = -1;
+  gint e2 = -1;
+  gint length;
+
+  if (row < 0)
+    row = 0;
+
+  length = g_list_length (list->children);
+  if (row >= length)
+    row = length - 1;
+
+  if (list->selection_mode != GTK_SELECTION_EXTENDED || !list->anchor < 0)
+    return;
+
+  /* extending downwards */
+  if (row > list->drag_pos && list->anchor <= list->drag_pos)
+    {
+      s2 = list->drag_pos + 1;
+      e2 = row;
+    }
+  /* extending upwards */
+  else if (row < list->drag_pos && list->anchor >= list->drag_pos)
+    {
+      s2 = row;
+      e2 = list->drag_pos - 1;
+    }
+  else if (row < list->drag_pos && list->anchor < list->drag_pos)
+    {
+      e1 = list->drag_pos;
+      /* row and drag_pos on different sides of anchor :
+        take back the selection between anchor and drag_pos,
+         select between anchor and row */
+      if (row < list->anchor)
+       {
+         s1 = list->anchor + 1;
+         s2 = row;
+         e2 = list->anchor - 1;
+       }
+      /* take back the selection between anchor and drag_pos */
+      else
+       s1 = row + 1;
+    }
+  else if (row > list->drag_pos && list->anchor > list->drag_pos)
+    {
+      s1 = list->drag_pos;
+      /* row and drag_pos on different sides of anchor :
+        take back the selection between anchor and drag_pos,
+         select between anchor and row */
+      if (row > list->anchor)
+       {
+         e1 = list->anchor - 1;
+         s2 = list->anchor + 1;
+         e2 = row;
+       }
+      /* take back the selection between anchor and drag_pos */
+      else
+       e1 = row - 1;
+    }
+
+  list->drag_pos = row;
+
+  /* restore the elements between s1 and e1 */
+  if (s1 >= 0)
+    {
+      for (i = s1, work = g_list_nth (list->children, i); i <= e1;
+          i++, work = work->next)
+       {
+         if (g_list_find (list->selection, work->data))
+            gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_SELECTED);
+          else
+            gtk_widget_set_state (GTK_WIDGET (work->data), GTK_STATE_NORMAL);
+       }
+    }
+
+  /* extend the selection between s2 and e2 */
+  if (s2 >= 0)
+    {
+      for (i = s2, work = g_list_nth (list->children, i); i <= e2;
+          i++, work = work->next)
+       if (GTK_WIDGET (work->data)->state != list->anchor_state)
+         gtk_widget_set_state (GTK_WIDGET (work->data), list->anchor_state);
+    }
+}
+
+void
+gtk_list_end_selection (GtkList *list)
+{
+  gint i;
+  gint e;
+  GList *work;
+  GtkWidget *item;
+  gint item_index;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) ||
+      list->anchor < 0)
+    return;
+
+  i = MIN (list->anchor, list->drag_pos);
+  e = MAX (list->anchor, list->drag_pos);
+  
+  list->anchor = -1;
+  list->drag_pos = -1;
+
+  if (list->undo_selection)
+    {
+      work = list->selection;
+      list->selection = list->undo_selection;
+      list->undo_selection = work;
+      work = list->selection;
+      while (work)
+       {
+         item = work->data;
+         work = work->next;
+         item_index = g_list_index (list->children, item);
+         if (item_index < i || item_index > e)
+           {
+             gtk_widget_set_state (item, GTK_STATE_SELECTED);
+             gtk_list_unselect_child (list, item);
+             list->undo_selection = g_list_prepend (list->undo_selection,
+                                                    item);
+           }
+       }
+    }    
+
+  for (work = g_list_nth (list->children, i); i <= e; i++, work = work->next)
+    {
+      item = work->data;
+      if (g_list_find (list->selection, item))
+         {
+           if (item->state == GTK_STATE_NORMAL)
+             {
+               gtk_widget_set_state (item, GTK_STATE_SELECTED);
+               gtk_list_unselect_child (list, item);
+               list->undo_selection = g_list_prepend (list->undo_selection,
+                                                      item);
+             }
+         }
+      else if (item->state == GTK_STATE_SELECTED)
+       {
+         gtk_widget_set_state (item, GTK_STATE_NORMAL);
+         list->undo_unselection = g_list_prepend (list->undo_unselection,
+                                                  item);
+       }
+    }
+
+  for (work = list->undo_unselection; work; work = work->next)
+    gtk_list_select_child (list, GTK_WIDGET (work->data));
+
+}
+
+void
+gtk_list_start_selection (GtkList *list)
+{
+  GtkContainer *container;
+  gint focus_row;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))
+    return;
+
+  container = GTK_CONTAINER (list);
+
+  if ((focus_row = g_list_index (list->selection, container->focus_child))
+      >= 0)
+    gtk_list_set_anchor (list, list->add_mode,
+                        focus_row, container->focus_child);
+}
+
+void
+gtk_list_toggle_row (GtkList   *list,
+                    GtkWidget *item)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
+    case GTK_SELECTION_SINGLE:
+
+      if (item->state == GTK_STATE_SELECTED)
+       {
+         gtk_list_unselect_child (list, item);
+         return;
+       }
+
+    case GTK_SELECTION_BROWSE:
+      gtk_list_select_child (list, item);
+      break;
+    }
+}
+
+void
+gtk_list_toggle_focus_row (GtkList *list)
+{
+  GtkContainer *container;
+  gint focus_row;
+
+  g_return_if_fail (list != 0);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  container = GTK_CONTAINER (list);
+
+  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) ||
+      !container->focus_child)
+    return;
+
+  switch (list->selection_mode)
+    {
+    case  GTK_SELECTION_SINGLE:
+    case  GTK_SELECTION_MULTIPLE:
+      
+      gtk_list_toggle_row (list, container->focus_child);
+      break;
+      
+    case GTK_SELECTION_EXTENDED:
+
+      if ((focus_row = g_list_index (list->children, container->focus_child))
+         < 0)
+       return;
+
+      g_list_free (list->undo_selection);
+      g_list_free (list->undo_unselection);
+      list->undo_selection = NULL;
+      list->undo_unselection = NULL;
+
+      list->anchor = focus_row;
+      list->drag_pos = focus_row;
+      list->undo_focus_child = container->focus_child;
+
+      if (list->add_mode)
+       gtk_list_fake_toggle_row (list, container->focus_child);
+      else
+       gtk_list_fake_unselect_all (list, container->focus_child);
+      
+      gtk_list_end_selection (list);
+      break;
+      
+    default:
+      break;
+    }
+}
+
+void
+gtk_list_toggle_add_mode (GtkList *list)
+{
+  GtkContainer *container;
+
+  g_return_if_fail (list != 0);
+  g_return_if_fail (GTK_IS_LIST (list));
+  
+  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) ||
+      list->selection_mode != GTK_SELECTION_EXTENDED)
+    return;
+  
+  container = GTK_CONTAINER (list);
+
+  if (list->add_mode)
+    {
+      list->add_mode = FALSE;
+      list->anchor_state = GTK_STATE_SELECTED;
+    }
+  else
+    list->add_mode = TRUE;
+  
+  if (container->focus_child)
+    gtk_widget_queue_draw (container->focus_child);
+}
+
+void
+gtk_list_undo_selection (GtkList *list)
+{
+  GList *work;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (list->selection_mode != GTK_SELECTION_EXTENDED ||
+      (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)))
+    return;
+  
+  if (list->anchor >= 0)
+    gtk_list_end_selection (list);
+
+  if (!(list->undo_selection || list->undo_unselection))
+    {
+      gtk_list_unselect_all (list);
+      return;
+    }
+
+  for (work = list->undo_selection; work; work = work->next)
+    gtk_list_select_child (list, GTK_WIDGET (work->data));
+
+  for (work = list->undo_unselection; work; work = work->next)
+    gtk_list_unselect_child (list, GTK_WIDGET (work->data));
+
+  if (list->undo_focus_child)
+    {
+      GtkContainer *container;
+
+      container = GTK_CONTAINER (list);
+
+      if (container->focus_child &&
+         GTK_WIDGET_HAS_FOCUS (container->focus_child))
+       gtk_widget_grab_focus (list->undo_focus_child);
+      else
+       gtk_container_set_focus_child (container, list->undo_focus_child);
+    }
+
+  list->undo_focus_child = NULL;
+  g_list_free (list->undo_selection);
+  g_list_free (list->undo_unselection);
+  list->undo_selection = NULL;
+  list->undo_unselection = NULL;
+}
+
+static void
+gtk_list_focus_lost (GtkWidget   *item,
+                    GdkEventKey *event,
+                    GtkList     *list)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+
+  if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0 &&
+      item == GTK_CONTAINER (list)->focus_child)
+    gtk_list_end_selection (list);
+}
+
+static void
+gtk_list_set_focus_child (GtkContainer *container,
+                         GtkWidget    *child)
+{
+  GtkList *list;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_LIST (container));
+
+  if (child)
+    g_return_if_fail (GTK_IS_WIDGET (child));
+
+  list = GTK_LIST (container);
+  list->last_focus_child = container->focus_child;
+
+  if (child != container->focus_child)
+    {
+      if (container->focus_child)
+        gtk_widget_unref (container->focus_child);
+      container->focus_child = child;
+      if (container->focus_child)
+        gtk_widget_ref (container->focus_child);
+    }
+
+  /* check for v adjustment */
+  if (container->focus_child)
+    {
+      GtkAdjustment *adjustment;
+
+      adjustment = gtk_object_get_data_by_id (GTK_OBJECT (container),
+                                             vadjustment_key_id);
+      if (adjustment)
+        gtk_adjustment_clamp_page (adjustment,
+                                   container->focus_child->allocation.y,
+                                   (container->focus_child->allocation.y +
+                                    container->focus_child->allocation.height));
+    }
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_BROWSE:
+      if (child)
+       gtk_list_select_child (list, child);
+      break;
+    default:
+      break;
+    }
+}
+
+
+static gint
+gtk_list_focus (GtkContainer     *container,
+               GtkDirectionType  direction)
+{
+  gint return_val = FALSE;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (container), FALSE);
+
+  if (!GTK_WIDGET_SENSITIVE (container))
+    return_val = FALSE;
+  else if (container->focus_child == NULL ||
+      !GTK_WIDGET_HAS_FOCUS (container->focus_child))
+    {
+      if (*GTK_CONTAINER_CLASS (parent_class)->focus)
+       return_val = (*GTK_CONTAINER_CLASS (parent_class)->focus)
+         (container, direction);
+    }
+  
+  if (!return_val)
+    {
+      GtkList *list;
+
+      list =  GTK_LIST (container);
+      if (list->selection_mode == GTK_SELECTION_EXTENDED && list->anchor >= 0)
+       gtk_list_end_selection (list);
+    }
+
+  return return_val;
+}
index ef6a3d5e6932e5aa720c57e146bb9aac3ca56b1d..368e9fcfdd5be970900832169a2996ec49483cfa 100644 (file)
@@ -23,7 +23,7 @@
 #include <gdk/gdk.h>
 #include <gtk/gtkenums.h>
 #include <gtk/gtkcontainer.h>
-
+#include <gtk/gtklistitem.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -48,13 +48,22 @@ struct _GtkList
   GList *children;
   GList *selection;
 
-  guint32 timer;
-  guint16 selection_start_pos;
-  guint16 selection_end_pos;
+  GList *undo_selection;
+  GList *undo_unselection;
+
+  GtkWidget *last_focus_child;
+  GtkWidget *undo_focus_child;
+
+  guint htimer;
+  guint vtimer;
+
+  gint anchor;
+  gint drag_pos;
+  GtkStateType anchor_state;
+
   guint selection_mode : 2;
-  guint scroll_direction : 1;
-  guint have_grab : 1;         /* unused */
-  guint16 button;              /* read by GtkCombo */
+  guint drag_selection:1;
+  guint add_mode:1;
 };
 
 struct _GtkListClass
@@ -98,6 +107,26 @@ gint           gtk_list_child_position        (GtkList          *list,
 void      gtk_list_set_selection_mode    (GtkList          *list,
                                           GtkSelectionMode  mode);
 
+void       gtk_list_extend_selection      (GtkList          *list,
+                                          GtkScrollType     scroll_type,
+                                          gfloat            position,
+                                          gboolean          auto_start_selection);
+void       gtk_list_start_selection       (GtkList          *list);
+void       gtk_list_end_selection         (GtkList          *list);
+void       gtk_list_select_all            (GtkList          *list);
+void       gtk_list_unselect_all          (GtkList          *list);
+void       gtk_list_scroll_horizontal     (GtkList          *list,
+                                          GtkScrollType     scroll_type,
+                                          gfloat            position);
+void       gtk_list_scroll_vertical       (GtkList          *list,
+                                          GtkScrollType     scroll_type,
+                                          gfloat            position);
+void       gtk_list_toggle_add_mode       (GtkList          *list);
+void       gtk_list_toggle_focus_row      (GtkList          *list);
+void       gtk_list_toggle_row            (GtkList          *list,
+                                          GtkWidget        *item);
+void       gtk_list_undo_selection        (GtkList          *list);
+void       gtk_list_end_drag_selection    (GtkList          *list);
 
 #ifdef __cplusplus
 }
index eb19513d2faf6400afd8dfbe635e8db11d512937..0793bc8f4b13b8504e4c02802bda1a5f522ca60e 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+#include "gtkbindings.h"
 #include "gtklabel.h"
 #include "gtklistitem.h"
 #include "gtklist.h"
+#include "gtksignal.h"
+#include <gdk/gdkkeysyms.h>
 
-static void gtk_list_item_class_init    (GtkListItemClass *klass);
-static void gtk_list_item_init          (GtkListItem      *list_item);
-static void gtk_list_item_realize       (GtkWidget        *widget);
-static void gtk_list_item_size_request  (GtkWidget        *widget,
-                                        GtkRequisition   *requisition);
-static void gtk_list_item_size_allocate (GtkWidget        *widget,
-                                        GtkAllocation    *allocation);
-static void gtk_list_item_draw          (GtkWidget        *widget,
-                                        GdkRectangle     *area);
-static void gtk_list_item_draw_focus    (GtkWidget        *widget);
-static gint gtk_list_item_button_press  (GtkWidget        *widget,
-                                        GdkEventButton   *event);
-static gint gtk_list_item_expose        (GtkWidget        *widget,
-                                        GdkEventExpose   *event);
-static gint gtk_list_item_focus_in      (GtkWidget        *widget,
-                                        GdkEventFocus    *event);
-static gint gtk_list_item_focus_out     (GtkWidget        *widget,
-                                        GdkEventFocus    *event);
-static void gtk_real_list_item_select   (GtkItem          *item);
-static void gtk_real_list_item_deselect (GtkItem          *item);
-static void gtk_real_list_item_toggle   (GtkItem          *item);
 
+enum
+{
+  TOGGLE_FOCUS_ROW,
+  SELECT_ALL,
+  UNSELECT_ALL,
+  UNDO_SELECTION,
+  START_SELECTION,
+  END_SELECTION,
+  TOGGLE_ADD_MODE,
+  EXTEND_SELECTION,
+  SCROLL_VERTICAL,
+  SCROLL_HORIZONTAL,
+  LAST_SIGNAL
+};
+
+static void gtk_list_item_class_init        (GtkListItemClass *klass);
+static void gtk_list_item_init              (GtkListItem      *list_item);
+static void gtk_list_item_realize           (GtkWidget        *widget);
+static void gtk_list_item_size_request      (GtkWidget        *widget,
+                                            GtkRequisition   *requisition);
+static void gtk_list_item_size_allocate     (GtkWidget        *widget,
+                                            GtkAllocation    *allocation);
+static void gtk_list_item_draw              (GtkWidget        *widget,
+                                            GdkRectangle     *area);
+static void gtk_list_item_draw_focus        (GtkWidget        *widget);
+static gint gtk_list_item_button_press      (GtkWidget        *widget,
+                                            GdkEventButton   *event);
+static gint gtk_list_item_expose            (GtkWidget        *widget,
+                                            GdkEventExpose   *event);
+static gint gtk_list_item_focus_in          (GtkWidget        *widget,
+                                            GdkEventFocus    *event);
+static gint gtk_list_item_focus_out         (GtkWidget        *widget,
+                                            GdkEventFocus    *event);
+static void gtk_real_list_item_select       (GtkItem          *item);
+static void gtk_real_list_item_deselect     (GtkItem          *item);
+static void gtk_real_list_item_toggle       (GtkItem          *item);
+
+
+static void gtk_list_item_toggle_focus_row  (GtkListItem      *list_item);
+static void gtk_list_item_select_all        (GtkListItem      *list_item);
+static void gtk_list_item_unselect_all      (GtkListItem      *list_item);
+static void gtk_list_item_undo_selection    (GtkListItem      *list_item);
+static void gtk_list_item_start_selection   (GtkListItem      *list_item);
+static void gtk_list_item_end_selection     (GtkListItem      *list_item);
+static void gtk_list_item_extend_selection  (GtkListItem      *list_item,
+                                            GtkScrollType      scroll_type,
+                                            gfloat            position,
+                                            gboolean          auto_start_selection);
+static void gtk_list_item_scroll_horizontal (GtkListItem      *list_item,
+                                            GtkScrollType     scroll_type,
+                                            gfloat            position);
+static void gtk_list_item_scroll_vertical   (GtkListItem      *list_item,
+                                            GtkScrollType     scroll_type,
+                                            gfloat            position);
+static void gtk_list_item_toggle_add_mode   (GtkListItem      *list_item);
 
 static GtkItemClass *parent_class = NULL;
+static guint list_item_signals[LAST_SIGNAL] = {0};
 
 
 GtkType
@@ -74,14 +113,89 @@ gtk_list_item_get_type (void)
 static void
 gtk_list_item_class_init (GtkListItemClass *class)
 {
+  GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
   GtkItemClass *item_class;
 
+  object_class = (GtkObjectClass*) class;
   widget_class = (GtkWidgetClass*) class;
   item_class = (GtkItemClass*) class;
 
   parent_class = gtk_type_class (gtk_item_get_type ());
 
+  list_item_signals[TOGGLE_FOCUS_ROW] =
+    gtk_signal_new ("toggle_focus_row",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, toggle_focus_row),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+  list_item_signals[SELECT_ALL] =
+    gtk_signal_new ("select_all",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, select_all),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+  list_item_signals[UNSELECT_ALL] =
+    gtk_signal_new ("unselect_all",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, unselect_all),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+  list_item_signals[UNDO_SELECTION] =
+    gtk_signal_new ("undo_selection",
+                   GTK_RUN_LAST | GTK_RUN_ACTION,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkListItemClass, undo_selection),
+                   gtk_marshal_NONE__NONE,
+                   GTK_TYPE_NONE, 0);
+  list_item_signals[START_SELECTION] =
+    gtk_signal_new ("start_selection",
+                   GTK_RUN_LAST | GTK_RUN_ACTION,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkListItemClass, start_selection),
+                   gtk_marshal_NONE__NONE,
+                   GTK_TYPE_NONE, 0);
+  list_item_signals[END_SELECTION] =
+    gtk_signal_new ("end_selection",
+                   GTK_RUN_LAST | GTK_RUN_ACTION,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkListItemClass, end_selection),
+                   gtk_marshal_NONE__NONE,
+                   GTK_TYPE_NONE, 0);
+  list_item_signals[TOGGLE_ADD_MODE] =
+    gtk_signal_new ("toggle_add_mode",
+                   GTK_RUN_LAST | GTK_RUN_ACTION,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkListItemClass, toggle_add_mode),
+                   gtk_marshal_NONE__NONE,
+                   GTK_TYPE_NONE, 0);
+  list_item_signals[EXTEND_SELECTION] =
+    gtk_signal_new ("extend_selection",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, extend_selection),
+                    gtk_marshal_NONE__ENUM_FLOAT_BOOL,
+                    GTK_TYPE_NONE, 3,
+                   GTK_TYPE_ENUM, GTK_TYPE_FLOAT, GTK_TYPE_BOOL);
+  list_item_signals[SCROLL_VERTICAL] =
+    gtk_signal_new ("scroll_vertical",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, scroll_vertical),
+                    gtk_marshal_NONE__ENUM_FLOAT,
+                    GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
+  list_item_signals[SCROLL_HORIZONTAL] =
+    gtk_signal_new ("scroll_horizontal",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListItemClass, scroll_horizontal),
+                    gtk_marshal_NONE__ENUM_FLOAT,
+                    GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
+
+
   widget_class->realize = gtk_list_item_realize;
   widget_class->size_request = gtk_list_item_size_request;
   widget_class->size_allocate = gtk_list_item_size_allocate;
@@ -95,6 +209,115 @@ gtk_list_item_class_init (GtkListItemClass *class)
   item_class->select = gtk_real_list_item_select;
   item_class->deselect = gtk_real_list_item_deselect;
   item_class->toggle = gtk_real_list_item_toggle;
+
+  class->toggle_focus_row = gtk_list_item_toggle_focus_row;
+  class->select_all = gtk_list_item_select_all;
+  class->unselect_all = gtk_list_item_unselect_all;
+  class->undo_selection = gtk_list_item_undo_selection;
+  class->start_selection = gtk_list_item_start_selection;
+  class->end_selection = gtk_list_item_end_selection;
+  class->extend_selection = gtk_list_item_extend_selection;
+  class->scroll_horizontal = gtk_list_item_scroll_horizontal;
+  class->scroll_vertical = gtk_list_item_scroll_vertical;
+  class->toggle_add_mode = gtk_list_item_toggle_add_mode;
+
+  {
+    GtkBindingSet *binding_set;
+
+    binding_set = gtk_binding_set_by_class (class);
+    gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
+                                 "scroll_vertical", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 1.0);
+
+    gtk_binding_entry_add_signal (binding_set, GDK_Up, GDK_SHIFT_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                                  GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+    gtk_binding_entry_add_signal (binding_set, GDK_Down, GDK_SHIFT_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                                  GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+    gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_SHIFT_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+                                  GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+    gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_SHIFT_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+                                  GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+    gtk_binding_entry_add_signal (binding_set, GDK_Home,
+                                 GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+    gtk_binding_entry_add_signal (binding_set, GDK_End,
+                                 GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+                                 "extend_selection", 3,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
+
+
+    gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
+                                 "scroll_horizontal", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
+                                 "scroll_horizontal", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
+                                 "scroll_horizontal", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 0.0);
+    gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
+                                 "scroll_horizontal", 2,
+                                 GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                                  GTK_TYPE_FLOAT, 1.0);
+
+
+    gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
+                                 "undo_selection", 0);
+    gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
+                                 "toggle_focus_row", 0);
+    gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK,
+                                 "toggle_add_mode", 0);
+    gtk_binding_entry_add_signal (binding_set, '/', GDK_CONTROL_MASK,
+                                 "select_all", 0);
+    gtk_binding_entry_add_signal (binding_set, '\\', GDK_CONTROL_MASK,
+                                 "unselect_all", 0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Shift_L,
+                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK,
+                                 "end_selection", 0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Shift_R,
+                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK,
+                                 "end_selection", 0);
+    gtk_binding_entry_add_signal (binding_set, GDK_Shift_R,
+                                 GDK_RELEASE_MASK | GDK_SHIFT_MASK |
+                                 GDK_CONTROL_MASK,
+                                 "end_selection", 0);
+  }
+
 }
 
 static void
@@ -141,11 +364,40 @@ gtk_list_item_deselect (GtkListItem *list_item)
 static void
 gtk_list_item_realize (GtkWidget *widget)
 {
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  /*if (GTK_WIDGET_CLASS (parent_class)->realize)
+    (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);*/
+
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
 
-  if (GTK_WIDGET_CLASS (parent_class)->realize)
-    (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = (gtk_widget_get_events (widget) |
+                          GDK_EXPOSURE_MASK |
+                          GDK_BUTTON_PRESS_MASK |
+                          GDK_BUTTON_RELEASE_MASK |
+                          GDK_KEY_PRESS_MASK |
+                          GDK_KEY_RELEASE_MASK |
+                          GDK_ENTER_NOTIFY_MASK |
+                          GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
 
   gdk_window_set_background (widget->window, 
                             &widget->style->base[GTK_STATE_NORMAL]);
@@ -259,9 +511,22 @@ gtk_list_item_draw_focus (GtkWidget *widget)
       else
        gc = widget->style->bg_gc[widget->state];
 
-      gdk_draw_rectangle (widget->window, gc, FALSE, 0, 0,
-                         widget->allocation.width - 1,
-                         widget->allocation.height - 1);
+      if (GTK_IS_LIST (widget->parent) && GTK_LIST (widget->parent)->add_mode)
+       {
+         gdk_gc_set_line_attributes (gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
+         gdk_gc_set_dashes (gc, 0, "\4\4", 2);
+
+         gdk_draw_rectangle (widget->window, gc, FALSE, 0, 0,
+                             widget->allocation.width - 1,
+                             widget->allocation.height - 1);
+         
+         gdk_gc_set_line_attributes (gc, 1, GDK_LINE_SOLID, 0, 0);
+       }
+      else
+       gdk_draw_rectangle (widget->window, gc, FALSE, 0, 0,
+                           widget->allocation.width - 1,
+                           widget->allocation.height - 1);
+
     }
 }
 
@@ -354,9 +619,6 @@ gtk_real_list_item_select (GtkItem *item)
   g_return_if_fail (item != NULL);
   g_return_if_fail (GTK_IS_LIST_ITEM (item));
 
-  if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED)
-    return;
-
   gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
   gtk_widget_queue_draw (GTK_WIDGET (item));
 }
@@ -397,3 +659,113 @@ gtk_real_list_item_toggle (GtkItem *item)
       gtk_widget_queue_draw (GTK_WIDGET (item));
     }
 }
+
+static void
+gtk_list_item_toggle_focus_row (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_toggle_focus_row (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_select_all (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_select_all (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_unselect_all (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_unselect_all (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_undo_selection (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_undo_selection (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_start_selection (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_start_selection (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_end_selection (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_end_selection (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
+
+static void
+gtk_list_item_extend_selection (GtkListItem   *list_item,
+                               GtkScrollType  scroll_type,
+                               gfloat         position,
+                               gboolean       auto_start_selection)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_extend_selection (GTK_LIST (GTK_WIDGET (list_item)->parent),
+                              scroll_type, position, auto_start_selection);
+}
+
+static void
+gtk_list_item_scroll_horizontal (GtkListItem   *list_item,
+                                GtkScrollType  scroll_type,
+                                gfloat         position)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_scroll_horizontal (GTK_LIST (GTK_WIDGET (list_item)->parent),
+                               scroll_type, position);
+}
+
+static void
+gtk_list_item_scroll_vertical (GtkListItem   *list_item,
+                              GtkScrollType  scroll_type,
+                              gfloat         position)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_scroll_vertical (GTK_LIST (GTK_WIDGET (list_item)->parent),
+                             scroll_type, position);
+}
+
+static void
+gtk_list_item_toggle_add_mode (GtkListItem *list_item)
+{
+  g_return_if_fail (list_item != 0);
+  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+
+  if (GTK_IS_LIST (GTK_WIDGET (list_item)->parent))
+    gtk_list_toggle_add_mode (GTK_LIST (GTK_WIDGET (list_item)->parent));
+}
index 7a1476b2e87d802136cd88b577601dec2873ffb5..f66e7d1797a0bbda7ef205d51944c0d52d5cebdf 100644 (file)
@@ -48,6 +48,24 @@ struct _GtkListItem
 struct _GtkListItemClass
 {
   GtkItemClass parent_class;
+
+  void (*toggle_focus_row)  (GtkListItem   *list_item);
+  void (*select_all)        (GtkListItem   *list_item);
+  void (*unselect_all)      (GtkListItem   *list_item);
+  void (*undo_selection)    (GtkListItem   *list_item);
+  void (*start_selection)   (GtkListItem   *list_item);
+  void (*end_selection)     (GtkListItem   *list_item);
+  void (*extend_selection)  (GtkListItem   *list_item,
+                            GtkScrollType  scroll_type,
+                            gfloat         position,
+                            gboolean       auto_start_selection);
+  void (*scroll_horizontal) (GtkListItem   *list_item,
+                            GtkScrollType  scroll_type,
+                            gfloat         position);
+  void (*scroll_vertical)   (GtkListItem   *list_item,
+                            GtkScrollType  scroll_type,
+                            gfloat         position);
+  void (*toggle_add_mode)   (GtkListItem   *list_item);
 };
 
 
@@ -58,6 +76,8 @@ void       gtk_list_item_select         (GtkListItem      *list_item);
 void       gtk_list_item_deselect       (GtkListItem      *list_item);
 
 
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 0cb94466312b6d99b36d7060a93c1177e77b7282..28aac144cb32e689f5e6c1c36357561008245346 100644 (file)
@@ -2802,11 +2802,15 @@ list_add (GtkWidget *widget,
   static int i = 1;
   gchar buffer[64];
   GtkWidget *list_item;
+  GtkContainer *container;
+
+  container = GTK_CONTAINER (list);
 
   sprintf (buffer, "added item %d", i++);
   list_item = gtk_list_item_new_with_label (buffer);
   gtk_widget_show (list_item);
-  gtk_container_add (GTK_CONTAINER (list), list_item);
+
+  gtk_container_add (container, list_item);
 }
 
 static void
@@ -2836,36 +2840,58 @@ static void
 list_clear (GtkWidget *widget,
            GtkWidget *list)
 {
-  gtk_list_clear_items (GTK_LIST (list), 3 - 1, 6 - 1);
+  gtk_list_clear_items (GTK_LIST (list), 0, -1);
+}
+
+static void
+list_undo_selection (GtkWidget *widget,
+                    GtkWidget *list)
+{
+  gtk_list_undo_selection (GTK_LIST (list));
+}
+
+#define RADIOMENUTOGGLED(_rmi_, __i) { \
+  GSList * __g; \
+  __i = 0; \
+  __g = gtk_radio_menu_item_group(_rmi_); \
+  while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
+    __g = __g->next; \
+    __i++; \
+  }\
+}
+
+static GtkWidget *list_omenu;
+
+static void 
+list_toggle_sel_mode (GtkWidget *widget, GtkList *list)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)list_omenu)->menu_item), i);
+
+  gtk_list_set_selection_mode (list, (GtkSelectionMode) (3-i));
 }
 
 static void
 create_list (void)
 {
   static GtkWidget *window = NULL;
-  static char *list_items[] =
-  {
-    "hello",
-    "world",
-    "blah",
-    "foo",
-    "bar",
-    "argh",
-    "spencer",
-    "is a",
-    "wussy",
-    "programmer",
-  };
-  static int nlist_items = sizeof (list_items) / sizeof (list_items[0]);
-
   GtkWidget *box1;
   GtkWidget *box2;
+  GtkWidget *hbox;
+  GtkWidget *label;
   GtkWidget *scrolled_win;
   GtkWidget *list;
-  GtkWidget *list_item;
   GtkWidget *button;
   GtkWidget *separator;
-  int i;
+  GtkWidget *menu;
+  GtkWidget *menu_item;
+  GSList *group;
+  FILE *infile;
 
   if (!window)
     {
@@ -2878,88 +2904,142 @@ create_list (void)
       gtk_window_set_title (GTK_WINDOW (window), "list");
       gtk_container_border_width (GTK_CONTAINER (window), 0);
 
-
       box1 = gtk_vbox_new (FALSE, 0);
       gtk_container_add (GTK_CONTAINER (window), box1);
-      gtk_widget_show (box1);
-
 
       box2 = gtk_vbox_new (FALSE, 10);
       gtk_container_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
-      gtk_widget_show (box2);
-
 
       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                                      GTK_POLICY_AUTOMATIC, 
                                      GTK_POLICY_AUTOMATIC);
       gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
-      gtk_widget_show (scrolled_win);
+      gtk_widget_set_usize (scrolled_win, -1, 300);
 
       list = gtk_list_new ();
-      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_MULTIPLE);
-      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_EXTENDED);
       gtk_container_add (GTK_CONTAINER (scrolled_win), list);
-      gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
-                                          gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
-      gtk_widget_show (list);
-
-      for (i = 0; i < nlist_items; i++)
+      gtk_container_set_focus_vadjustment
+       (GTK_CONTAINER (list),
+        gtk_scrolled_window_get_vadjustment
+        (GTK_SCROLLED_WINDOW (scrolled_win)));
+      gtk_container_set_focus_hadjustment
+       (GTK_CONTAINER (list),
+        gtk_scrolled_window_get_hadjustment
+        (GTK_SCROLLED_WINDOW (scrolled_win)));
+
+      if ((infile = fopen("gtkenums.h", "r")))
        {
-         list_item = gtk_list_item_new_with_label (list_items[i]);
-         gtk_container_add (GTK_CONTAINER (list), list_item);
-         gtk_widget_show (list_item);
+         char buffer[256];
+         char *pos;
+         GtkWidget *item;
+
+         while (fgets (buffer, 256, infile))
+           {
+             if ((pos = strchr (buffer, '\n')))
+               *pos = 0;
+             item = gtk_list_item_new_with_label (buffer);
+             gtk_container_add (GTK_CONTAINER (list), item);
+           }
+         
+         fclose (infile);
        }
 
-      button = gtk_button_new_with_label ("add");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      hbox = gtk_hbox_new (TRUE, 10);
+      gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Undo Selection");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                         GTK_SIGNAL_FUNC(list_add),
+                         GTK_SIGNAL_FUNC(list_undo_selection),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
-      button = gtk_button_new_with_label ("clear items 3 - 5");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      button = gtk_button_new_with_label ("Remove Selection");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                         GTK_SIGNAL_FUNC(list_clear),
+                         GTK_SIGNAL_FUNC (list_remove),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
-      button = gtk_button_new_with_label ("remove");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      button = gtk_button_new_with_label ("Clear List");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (list_clear),
+                         list);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 10);
+      gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Insert Row");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (list_add),
+                         list);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      label = gtk_label_new ("Selection Mode :");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
                          GTK_SIGNAL_FUNC(list_remove),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
 
+      list_omenu = gtk_option_menu_new ();
+      menu = gtk_menu_new ();
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Browse");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Multiple");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                      GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      gtk_widget_show (menu_item);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (list_omenu), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (list_omenu), 3);
 
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
-      gtk_widget_show (separator);
-
 
       box2 = gtk_vbox_new (FALSE, 10);
       gtk_container_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
-      gtk_widget_show (box2);
-
 
       button = gtk_button_new_with_label ("close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                                 GTK_SIGNAL_FUNC(gtk_widget_destroy),
                                 GTK_OBJECT (window));
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
       gtk_widget_grab_default (button);
-      gtk_widget_show (button);
     }
 
   if (!GTK_WIDGET_VISIBLE (window))
-    gtk_widget_show (window);
+    gtk_widget_show_all (window);
   else
     gtk_widget_destroy (window);
 }
@@ -3299,16 +3379,6 @@ undo_selection (GtkWidget *button, GtkCList *clist)
   gtk_clist_undo_selection (clist);
 }
 
-#define RADIOMENUTOGGLED(_rmi_, __i) { \
-  GSList * __g; \
-  __i = 0; \
-  __g = gtk_radio_menu_item_group(_rmi_); \
-  while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
-    __g = __g->next; \
-    __i++; \
-  }\
-}
-
 static void 
 clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
 {
@@ -3593,8 +3663,8 @@ void after_press (GtkCTree *ctree, gpointer data)
   gtk_label_set (GTK_LABEL (page_label), buf);
 }
 
-void after_move (GtkCTree *ctree, GList *child, GList *parent, 
-                GList *sibling, gpointer data)
+void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
+                GtkCTreeNode *sibling, gpointer data)
 {
   char *source;
   char *target1;
@@ -3617,7 +3687,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
 {
   gint row;
   gint column;
-  GList *work;
+  GtkCTreeNode *work;
   gint res;
   
   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
@@ -3625,7 +3695,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   if (!res && event->button != 3)
     return FALSE;
 
-  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+  work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
 
   switch (event->button)
     {
@@ -3657,7 +3727,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
 {
   gint row;
   gint column;
-  GList *work;
+  GtkCTreeNode *work;
   gint res;
   
   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
@@ -3665,7 +3735,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   if (!res || event->button != 1)
     return FALSE;
 
-  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+  work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
 
   if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
       event->state & GDK_SHIFT_MASK)
@@ -3681,7 +3751,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   return FALSE;
 }
 
-void count_items (GtkCTree *ctree, GList *list)
+void count_items (GtkCTree *ctree, GtkCTreeNode *list)
 {
   if (GTK_CTREE_ROW (list)->is_leaf)
     pages--;
@@ -3715,9 +3785,9 @@ void unselect_all (GtkWidget *widget, GtkCTree *ctree)
 
 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
 {
-  GList *work;
+  GtkCTreeNode *work;
+  GtkCTreeNode *new_sel;
   GList *selection;
-  GList *new_sel;
 
   selection = GTK_CLIST (ctree)->selection;
   new_sel = NULL;
@@ -3739,14 +3809,14 @@ void remove_selection (GtkWidget *widget, GtkCTree *ctree)
            {
              new_sel = GTK_CTREE_ROW (work)->sibling;
              if (!new_sel)
-               new_sel = work->prev;
+               new_sel = GTK_CTREE_NODE_NEXT (work);
            }
          else
            {
-             if (work->next)
-               new_sel = work->next;
+             if (GTK_CTREE_NODE_NEXT (work))
+               new_sel = GTK_CTREE_NODE_NEXT (work);
              else
-               new_sel = work->prev;
+               new_sel = GTK_CTREE_NODE_PREV (work);
            }
        }
 
@@ -3781,7 +3851,7 @@ void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
   gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
 }
 
-void set_background (GtkCTree *ctree, GList *node, gpointer data)
+void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
 {
   if (!node)
     return;
@@ -3789,9 +3859,12 @@ void set_background (GtkCTree *ctree, GList *node, gpointer data)
   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
     {
       if (GTK_CTREE_ROW (node)->is_leaf)
-       gtk_ctree_set_background 
-         (ctree, node,
-          GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data);
+       {
+         if (GTK_CTREE_ROW (node)->parent)
+           gtk_ctree_set_background 
+             (ctree, node,
+              GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data);
+       }
       else
        gtk_ctree_set_background (ctree, node, GTK_CTREE_ROW (node)->row.data);
     }
@@ -3813,8 +3886,7 @@ void ctree_toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
        ((GtkCTreeLineStyle) (3-i)) != GTK_CTREE_LINES_TABBED) ||
       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
        ((GtkCTreeLineStyle) (3-i)) == GTK_CTREE_LINES_TABBED))
-    gtk_ctree_pre_recursive (ctree, GTK_CLIST (ctree)->row_list,
-                            set_background, NULL);
+    gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
   gtk_ctree_set_line_style (ctree, (GtkCTreeLineStyle) (3-i));
 }
 
@@ -3847,12 +3919,12 @@ void ctree_toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
 }
 
 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
-                     gint num_books, gint num_pages, GList *parent)
+                     gint num_books, gint num_pages, GtkCTreeNode *parent)
 {
   gchar *text[2];
   gchar buf1[60];
   gchar buf2[60];
-  GList *sibling;
+  GtkCTreeNode *sibling;
   gint i;
 
   text[0] = buf1;
@@ -3919,7 +3991,7 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
   gchar *text [2];
   gchar label1[] = "Root";
   gchar label2[] = "";
-  GList *parent;
+  GtkCTreeNode *parent;
   guint b, d, p, n;
 
   text[0] = label1;
index 0cb94466312b6d99b36d7060a93c1177e77b7282..28aac144cb32e689f5e6c1c36357561008245346 100644 (file)
@@ -2802,11 +2802,15 @@ list_add (GtkWidget *widget,
   static int i = 1;
   gchar buffer[64];
   GtkWidget *list_item;
+  GtkContainer *container;
+
+  container = GTK_CONTAINER (list);
 
   sprintf (buffer, "added item %d", i++);
   list_item = gtk_list_item_new_with_label (buffer);
   gtk_widget_show (list_item);
-  gtk_container_add (GTK_CONTAINER (list), list_item);
+
+  gtk_container_add (container, list_item);
 }
 
 static void
@@ -2836,36 +2840,58 @@ static void
 list_clear (GtkWidget *widget,
            GtkWidget *list)
 {
-  gtk_list_clear_items (GTK_LIST (list), 3 - 1, 6 - 1);
+  gtk_list_clear_items (GTK_LIST (list), 0, -1);
+}
+
+static void
+list_undo_selection (GtkWidget *widget,
+                    GtkWidget *list)
+{
+  gtk_list_undo_selection (GTK_LIST (list));
+}
+
+#define RADIOMENUTOGGLED(_rmi_, __i) { \
+  GSList * __g; \
+  __i = 0; \
+  __g = gtk_radio_menu_item_group(_rmi_); \
+  while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
+    __g = __g->next; \
+    __i++; \
+  }\
+}
+
+static GtkWidget *list_omenu;
+
+static void 
+list_toggle_sel_mode (GtkWidget *widget, GtkList *list)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)list_omenu)->menu_item), i);
+
+  gtk_list_set_selection_mode (list, (GtkSelectionMode) (3-i));
 }
 
 static void
 create_list (void)
 {
   static GtkWidget *window = NULL;
-  static char *list_items[] =
-  {
-    "hello",
-    "world",
-    "blah",
-    "foo",
-    "bar",
-    "argh",
-    "spencer",
-    "is a",
-    "wussy",
-    "programmer",
-  };
-  static int nlist_items = sizeof (list_items) / sizeof (list_items[0]);
-
   GtkWidget *box1;
   GtkWidget *box2;
+  GtkWidget *hbox;
+  GtkWidget *label;
   GtkWidget *scrolled_win;
   GtkWidget *list;
-  GtkWidget *list_item;
   GtkWidget *button;
   GtkWidget *separator;
-  int i;
+  GtkWidget *menu;
+  GtkWidget *menu_item;
+  GSList *group;
+  FILE *infile;
 
   if (!window)
     {
@@ -2878,88 +2904,142 @@ create_list (void)
       gtk_window_set_title (GTK_WINDOW (window), "list");
       gtk_container_border_width (GTK_CONTAINER (window), 0);
 
-
       box1 = gtk_vbox_new (FALSE, 0);
       gtk_container_add (GTK_CONTAINER (window), box1);
-      gtk_widget_show (box1);
-
 
       box2 = gtk_vbox_new (FALSE, 10);
       gtk_container_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
-      gtk_widget_show (box2);
-
 
       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
                                      GTK_POLICY_AUTOMATIC, 
                                      GTK_POLICY_AUTOMATIC);
       gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
-      gtk_widget_show (scrolled_win);
+      gtk_widget_set_usize (scrolled_win, -1, 300);
 
       list = gtk_list_new ();
-      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_MULTIPLE);
-      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_EXTENDED);
       gtk_container_add (GTK_CONTAINER (scrolled_win), list);
-      gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
-                                          gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
-      gtk_widget_show (list);
-
-      for (i = 0; i < nlist_items; i++)
+      gtk_container_set_focus_vadjustment
+       (GTK_CONTAINER (list),
+        gtk_scrolled_window_get_vadjustment
+        (GTK_SCROLLED_WINDOW (scrolled_win)));
+      gtk_container_set_focus_hadjustment
+       (GTK_CONTAINER (list),
+        gtk_scrolled_window_get_hadjustment
+        (GTK_SCROLLED_WINDOW (scrolled_win)));
+
+      if ((infile = fopen("gtkenums.h", "r")))
        {
-         list_item = gtk_list_item_new_with_label (list_items[i]);
-         gtk_container_add (GTK_CONTAINER (list), list_item);
-         gtk_widget_show (list_item);
+         char buffer[256];
+         char *pos;
+         GtkWidget *item;
+
+         while (fgets (buffer, 256, infile))
+           {
+             if ((pos = strchr (buffer, '\n')))
+               *pos = 0;
+             item = gtk_list_item_new_with_label (buffer);
+             gtk_container_add (GTK_CONTAINER (list), item);
+           }
+         
+         fclose (infile);
        }
 
-      button = gtk_button_new_with_label ("add");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      hbox = gtk_hbox_new (TRUE, 10);
+      gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Undo Selection");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                         GTK_SIGNAL_FUNC(list_add),
+                         GTK_SIGNAL_FUNC(list_undo_selection),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
-      button = gtk_button_new_with_label ("clear items 3 - 5");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      button = gtk_button_new_with_label ("Remove Selection");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                         GTK_SIGNAL_FUNC(list_clear),
+                         GTK_SIGNAL_FUNC (list_remove),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
 
-      button = gtk_button_new_with_label ("remove");
-      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      button = gtk_button_new_with_label ("Clear List");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (list_clear),
+                         list);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 10);
+      gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Insert Row");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (list_add),
+                         list);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      label = gtk_label_new ("Selection Mode :");
       gtk_signal_connect (GTK_OBJECT (button), "clicked",
                          GTK_SIGNAL_FUNC(list_remove),
                          list);
-      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
-      gtk_widget_show (button);
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
 
+      list_omenu = gtk_option_menu_new ();
+      menu = gtk_menu_new ();
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Browse");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Multiple");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                      GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (list_toggle_sel_mode), list);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      gtk_widget_show (menu_item);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (list_omenu), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (list_omenu), 3);
 
       separator = gtk_hseparator_new ();
       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
-      gtk_widget_show (separator);
-
 
       box2 = gtk_vbox_new (FALSE, 10);
       gtk_container_border_width (GTK_CONTAINER (box2), 10);
       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
-      gtk_widget_show (box2);
-
 
       button = gtk_button_new_with_label ("close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                                 GTK_SIGNAL_FUNC(gtk_widget_destroy),
                                 GTK_OBJECT (window));
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
       gtk_widget_grab_default (button);
-      gtk_widget_show (button);
     }
 
   if (!GTK_WIDGET_VISIBLE (window))
-    gtk_widget_show (window);
+    gtk_widget_show_all (window);
   else
     gtk_widget_destroy (window);
 }
@@ -3299,16 +3379,6 @@ undo_selection (GtkWidget *button, GtkCList *clist)
   gtk_clist_undo_selection (clist);
 }
 
-#define RADIOMENUTOGGLED(_rmi_, __i) { \
-  GSList * __g; \
-  __i = 0; \
-  __g = gtk_radio_menu_item_group(_rmi_); \
-  while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
-    __g = __g->next; \
-    __i++; \
-  }\
-}
-
 static void 
 clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
 {
@@ -3593,8 +3663,8 @@ void after_press (GtkCTree *ctree, gpointer data)
   gtk_label_set (GTK_LABEL (page_label), buf);
 }
 
-void after_move (GtkCTree *ctree, GList *child, GList *parent, 
-                GList *sibling, gpointer data)
+void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
+                GtkCTreeNode *sibling, gpointer data)
 {
   char *source;
   char *target1;
@@ -3617,7 +3687,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
 {
   gint row;
   gint column;
-  GList *work;
+  GtkCTreeNode *work;
   gint res;
   
   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
@@ -3625,7 +3695,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   if (!res && event->button != 3)
     return FALSE;
 
-  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+  work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
 
   switch (event->button)
     {
@@ -3657,7 +3727,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
 {
   gint row;
   gint column;
-  GList *work;
+  GtkCTreeNode *work;
   gint res;
   
   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
@@ -3665,7 +3735,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   if (!res || event->button != 1)
     return FALSE;
 
-  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+  work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
 
   if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
       event->state & GDK_SHIFT_MASK)
@@ -3681,7 +3751,7 @@ gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
   return FALSE;
 }
 
-void count_items (GtkCTree *ctree, GList *list)
+void count_items (GtkCTree *ctree, GtkCTreeNode *list)
 {
   if (GTK_CTREE_ROW (list)->is_leaf)
     pages--;
@@ -3715,9 +3785,9 @@ void unselect_all (GtkWidget *widget, GtkCTree *ctree)
 
 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
 {
-  GList *work;
+  GtkCTreeNode *work;
+  GtkCTreeNode *new_sel;
   GList *selection;
-  GList *new_sel;
 
   selection = GTK_CLIST (ctree)->selection;
   new_sel = NULL;
@@ -3739,14 +3809,14 @@ void remove_selection (GtkWidget *widget, GtkCTree *ctree)
            {
              new_sel = GTK_CTREE_ROW (work)->sibling;
              if (!new_sel)
-               new_sel = work->prev;
+               new_sel = GTK_CTREE_NODE_NEXT (work);
            }
          else
            {
-             if (work->next)
-               new_sel = work->next;
+             if (GTK_CTREE_NODE_NEXT (work))
+               new_sel = GTK_CTREE_NODE_NEXT (work);
              else
-               new_sel = work->prev;
+               new_sel = GTK_CTREE_NODE_PREV (work);
            }
        }
 
@@ -3781,7 +3851,7 @@ void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
   gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
 }
 
-void set_background (GtkCTree *ctree, GList *node, gpointer data)
+void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
 {
   if (!node)
     return;
@@ -3789,9 +3859,12 @@ void set_background (GtkCTree *ctree, GList *node, gpointer data)
   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
     {
       if (GTK_CTREE_ROW (node)->is_leaf)
-       gtk_ctree_set_background 
-         (ctree, node,
-          GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data);
+       {
+         if (GTK_CTREE_ROW (node)->parent)
+           gtk_ctree_set_background 
+             (ctree, node,
+              GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data);
+       }
       else
        gtk_ctree_set_background (ctree, node, GTK_CTREE_ROW (node)->row.data);
     }
@@ -3813,8 +3886,7 @@ void ctree_toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
        ((GtkCTreeLineStyle) (3-i)) != GTK_CTREE_LINES_TABBED) ||
       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
        ((GtkCTreeLineStyle) (3-i)) == GTK_CTREE_LINES_TABBED))
-    gtk_ctree_pre_recursive (ctree, GTK_CLIST (ctree)->row_list,
-                            set_background, NULL);
+    gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
   gtk_ctree_set_line_style (ctree, (GtkCTreeLineStyle) (3-i));
 }
 
@@ -3847,12 +3919,12 @@ void ctree_toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
 }
 
 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
-                     gint num_books, gint num_pages, GList *parent)
+                     gint num_books, gint num_pages, GtkCTreeNode *parent)
 {
   gchar *text[2];
   gchar buf1[60];
   gchar buf2[60];
-  GList *sibling;
+  GtkCTreeNode *sibling;
   gint i;
 
   text[0] = buf1;
@@ -3919,7 +3991,7 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
   gchar *text [2];
   gchar label1[] = "Root";
   gchar label2[] = "";
-  GList *parent;
+  GtkCTreeNode *parent;
   guint b, d, p, n;
 
   text[0] = label1;