]> Pileus Git - ~andy/gtk/commitdiff
prefixed all clist flags with GTK_ to avoid name clashes. redefined
authorTim Janik <timj@gtk.org>
Fri, 1 May 1998 13:16:49 +0000 (13:16 +0000)
committerTim Janik <timj@src.gnome.org>
Fri, 1 May 1998 13:16:49 +0000 (13:16 +0000)
Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>

        * gtk/gtkclist.h:
                * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
                        clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
                                GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
                                        the GTK_ prefix (this solution involved less changes in the
                                                gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
                                                        the mem_chunk==NULL test in gtk_clist_construct. merged in changes
                                                                from lars & stefan to support the derivation of GtkCtree.

                                                                        * gtkctree.h:
                                                                                * gtkctree.c:
                                                                                        initial import of a tree widget derived from gtkclist, courtesy
                                                                                                of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
                                                                                                        it just damn rocks!

Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>

        * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
        for us.
        (gtk_list_insert_items):
        (gtk_list_remove_items_internal):
        (gtk_list_clear_items):
        remove a possible pointer grab, we might get thrown into a loop
        otherwise.
        (gtk_list_button_press): grab the pointer *before* selecting the child,
        because selection of items may cause the lists children to change,
        resulting in a grab release.
        (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
        children.
        (gtk_list_shutdown): remove all children from the list.
        (gtk_real_list_unselect_child):
        (gtk_real_list_select_child): *always* put our internal structures into
        sane state *before* signal emisions (i.e. list->selection updates prior
        to gtk_list_item_[de]select() calls).

        * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
        focused child walks out of the window.
        removed CAN_FOCUS for the combo arrow's button since it doesn't react
        to keyboard events ("clicked" connection is missing).

15 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/Makefile.am
gtk/gtk.h
gtk/gtkclist.c
gtk/gtkclist.h
gtk/gtkcombo.c
gtk/gtklist.c
gtk/testgtk.c
tests/testgtk.c

index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index e2471225122619a6b86406fa460af662c7c53671..4008086af01548e850fb34fd7c930da216a7e039 100644 (file)
@@ -1,10 +1,52 @@
+Fri May  1 13:57:36 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c: prefixed all clist flags with GTK_ to avoid name
+       clashes. redefined GTK_CLIST_SET_FLAGS and GTK_CLIST_UNSET_FLAGS as
+       GTK_CLIST_SET_FLAG and GTK_CLIST_UNSET_FLAG to automatically add
+       the GTK_ prefix (this solution involved less changes in the
+       gtkclist.c code). added a GTK_CLIST_CONSTRUCTED flag to substitute
+       the mem_chunk==NULL test in gtk_clist_construct. merged in changes
+       from lars & stefan to support the derivation of GtkCtree.
+
+       * gtkctree.h:
+       * gtkctree.c:
+       initial import of a tree widget derived from gtkclist, courtesy
+       of Lars Hamann <lars@gtk.org> and Stefan Jeske <jeske@gtk.org>,
+       it just damn rocks!
+
+Fri May  1 10:05:44 1998  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtklist.c (gtk_list_add): let gtk_list_append_items do the work
+       for us.
+       (gtk_list_insert_items):
+       (gtk_list_remove_items_internal): 
+       (gtk_list_clear_items): 
+       remove a possible pointer grab, we might get thrown into a loop
+       otherwise.
+       (gtk_list_button_press): grab the pointer *before* selecting the child,
+       because selection of items may cause the lists children to change,
+       resulting in a grab release.
+       (gtk_list_clear_items): use gtk_list_unselect_child() for unselection of
+       children.
+       (gtk_list_shutdown): remove all children from the list.
+       (gtk_real_list_unselect_child): 
+       (gtk_real_list_select_child): *always* put our internal structures into
+       sane state *before* signal emisions (i.e. list->selection updates prior
+       to gtk_list_item_[de]select() calls).
+
+       * gtk/gtkcombo.c (gtk_combo_init): adjust the scrollbar if the lists
+       focused child walks out of the window.
+       removed CAN_FOCUS for the combo arrow's button since it doesn't react
+       to keyboard events ("clicked" connection is missing).
+
 Fri May  1 00:42:25 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gdk/gdkwindow.c (gdk_window_get_colormap): Fix up
        getting colormap for FOREIGN windows to go along with
        Raster's fix for visuals.
 
-erges from gtk-1-0
+Merges from gtk-1-0
 ===================
        
 Thu Apr 30 23:32:51 1998  Owen Taylor  <otaylor@gtk.org>
index d0b99fcf2a525d234e2d4a7f2b6b45a393cf1be1..7082674d79db4cfcab6206f0b30a5058a66283e0 100644 (file)
@@ -20,6 +20,7 @@ libgtk_la_SOURCES = \
        gtkcolorsel.c           \
        gtkcombo.c              \
        gtkcontainer.c          \
+       gtkctree.c              \
        gtkcurve.c              \
        gtkdata.c               \
        gtkdialog.c             \
@@ -113,6 +114,7 @@ gtkinclude_HEADERS = \
        gtkcolorsel.h           \
        gtkcombo.h              \
        gtkcontainer.h          \
+       gtkctree.h              \
        gtkcurve.h              \
        gtkdata.h               \
        gtkdebug.h              \
index ba1bb5b0eb570c00c6f6cdd7248a4f8a5aa26084..5f31c9c5ef6e59e75d7c3e352849be7ca4c80a4d 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -36,6 +36,7 @@
 #include <gtk/gtkcolorsel.h>
 #include <gtk/gtkcombo.h>
 #include <gtk/gtkcontainer.h>
+#include <gtk/gtkctree.h>
 #include <gtk/gtkcurve.h>
 #include <gtk/gtkdata.h>
 #include <gtk/gtkdialog.h>
index 2f4686592c0e7959bdb2276ba5703c88d6855acc..bf61c60d8f458b46f73f9ec98f0d2d5baef0e1c1 100644 (file)
@@ -280,10 +280,10 @@ static GtkContainerClass *parent_class = NULL;
 static guint clist_signals[LAST_SIGNAL] = {0};
 
 
-guint
+GtkType
 gtk_clist_get_type ()
 {
-  static guint clist_type = 0;
+  static GtkType clist_type = 0;
 
   if (!clist_type)
     {
@@ -364,6 +364,8 @@ gtk_clist_class_init (GtkCListClass * klass)
   klass->unselect_row = real_unselect_row;
   klass->click_column = NULL;
 
+  klass->draw_row = draw_row;
+
   klass->scrollbar_spacing = 5;
 }
 
@@ -403,7 +405,7 @@ gtk_clist_init (GtkCList * clist)
   clist->flags = 0;
 
   GTK_WIDGET_UNSET_FLAGS (clist, GTK_NO_WINDOW);
-  GTK_CLIST_SET_FLAGS (clist, CLIST_FROZEN);
+  GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
 
   clist->row_mem_chunk = NULL;
   clist->cell_mem_chunk = NULL;
@@ -453,19 +455,24 @@ gtk_clist_construct (GtkCList * clist,
 
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
-  g_return_if_fail (clist->row_mem_chunk == NULL);
-
+  g_return_if_fail (GTK_CLIST_CONSTRUCTED (clist) == FALSE);
 
-  /* initalize memory chunks */
-  clist->row_mem_chunk = g_mem_chunk_new ("clist row mem chunk",
-                                         sizeof (GtkCListRow),
-                                         sizeof (GtkCListRow) * CLIST_OPTIMUM_SIZE, 
-                                         G_ALLOC_AND_FREE);
+  GTK_CLIST_SET_FLAG (clist, CLIST_CONSTRUCTED);
 
-  clist->cell_mem_chunk = g_mem_chunk_new ("clist cell mem chunk",
-                                          sizeof (GtkCell) * columns,
-                                          sizeof (GtkCell) * columns * CLIST_OPTIMUM_SIZE, 
-                                          G_ALLOC_AND_FREE);
+  /* initalize memory chunks, if this has not been done by any
+   * possibly derived widget
+   */
+  if (!clist->row_mem_chunk)
+    clist->row_mem_chunk = g_mem_chunk_new ("clist row mem chunk",
+                                           sizeof (GtkCListRow),
+                                           sizeof (GtkCListRow) * CLIST_OPTIMUM_SIZE, 
+                                           G_ALLOC_AND_FREE);
+
+  if (!clist->cell_mem_chunk)
+    clist->cell_mem_chunk = g_mem_chunk_new ("clist cell mem chunk",
+                                            sizeof (GtkCell) * columns,
+                                            sizeof (GtkCell) * columns * CLIST_OPTIMUM_SIZE, 
+                                            G_ALLOC_AND_FREE);
 
   /* set number of columns, allocate memory */
   clist->columns = columns;
@@ -481,13 +488,13 @@ gtk_clist_construct (GtkCList * clist,
 
   if (titles)
     {
-      GTK_CLIST_SET_FLAGS (clist, CLIST_SHOW_TITLES);
+      GTK_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES);
       for (i = 0; i < columns; i++)
        gtk_clist_set_column_title (clist, i, titles[i]);
     }
   else
     {
-      GTK_CLIST_UNSET_FLAGS (clist, CLIST_SHOW_TITLES);
+      GTK_CLIST_UNSET_FLAG (clist, CLIST_SHOW_TITLES);
     }
 }
 
@@ -550,7 +557,7 @@ gtk_clist_freeze (GtkCList * clist)
 {
   g_return_if_fail (clist != NULL);
 
-  GTK_CLIST_SET_FLAGS (clist, CLIST_FROZEN);
+  GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
 }
 
 void
@@ -558,7 +565,7 @@ gtk_clist_thaw (GtkCList * clist)
 {
   g_return_if_fail (clist != NULL);
 
-  GTK_CLIST_UNSET_FLAGS (clist, CLIST_FROZEN);
+  GTK_CLIST_UNSET_FLAG (clist, CLIST_FROZEN);
 
   adjust_scrollbars (clist);
   draw_rows (clist, NULL);
@@ -571,7 +578,7 @@ gtk_clist_column_titles_show (GtkCList * clist)
 
   if (!GTK_CLIST_SHOW_TITLES (clist))
     {
-      GTK_CLIST_SET_FLAGS (clist, CLIST_SHOW_TITLES);
+      GTK_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES);
       if (clist->title_window)
              gdk_window_show (clist->title_window);
       gtk_widget_queue_resize (GTK_WIDGET (clist));
@@ -585,7 +592,7 @@ gtk_clist_column_titles_hide (GtkCList * clist)
 
   if (GTK_CLIST_SHOW_TITLES (clist))
     {
-      GTK_CLIST_UNSET_FLAGS (clist, CLIST_SHOW_TITLES);
+      GTK_CLIST_UNSET_FLAG (clist, CLIST_SHOW_TITLES);
       if (clist->title_window)
              gdk_window_hide (clist->title_window);
       gtk_widget_queue_resize (GTK_WIDGET (clist));
@@ -842,7 +849,7 @@ gtk_clist_set_row_height (GtkCList * clist,
   else
     return;
 
-  GTK_CLIST_SET_FLAGS (clist, CLIST_ROW_HEIGHT_SET);
+  GTK_CLIST_SET_FLAG (clist, CLIST_ROW_HEIGHT_SET);
   
   if (GTK_WIDGET_REALIZED (clist))
     {
@@ -958,7 +965,8 @@ gtk_clist_set_text (GtkCList * clist,
   if (!GTK_CLIST_FROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       draw_row (clist, NULL, row, clist_row);
+       (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+         (clist, NULL, row, clist_row);
     }
 }
 
@@ -1016,7 +1024,8 @@ gtk_clist_set_pixmap (GtkCList * clist,
   if (!GTK_CLIST_FROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       draw_row (clist, NULL, row, clist_row);
+       (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+         (clist, NULL, row, clist_row);
     }
 }
 
@@ -1079,7 +1088,8 @@ gtk_clist_set_pixtext (GtkCList * clist,
   if (!GTK_CLIST_FROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       draw_row (clist, NULL, row, clist_row);
+       (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row) 
+         (clist, NULL, row, clist_row);
     }
 }
 
@@ -1143,7 +1153,8 @@ gtk_clist_set_foreground (GtkCList * clist,
 
   if (!GTK_CLIST_FROZEN (clist)
       && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-    draw_row (clist, NULL, row, clist_row);
+    (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+      (clist, NULL, row, clist_row);
 }
 
 void
@@ -1170,7 +1181,8 @@ gtk_clist_set_background (GtkCList * clist,
 
   if (!GTK_CLIST_FROZEN (clist)
       && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-    draw_row (clist, NULL, row, clist_row);
+    (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+      (clist, NULL, row, clist_row);
 }
 
 void
@@ -1196,7 +1208,8 @@ gtk_clist_set_shift (GtkCList * clist,
 
   if (!GTK_CLIST_FROZEN (clist)
       && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-    draw_row (clist, NULL, row, clist_row);
+    (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row) 
+      (clist, NULL, row, clist_row);
 }
 
 gint
@@ -1653,7 +1666,7 @@ gtk_clist_destroy (GtkObject * object)
   clist = GTK_CLIST (object);
 
   /* freeze the list */
-  GTK_CLIST_SET_FLAGS (clist, CLIST_FROZEN);
+  GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
 
   /* get rid of all the rows */
   gtk_clist_clear (clist);
@@ -1848,7 +1861,7 @@ gtk_clist_unrealize (GtkWidget * widget)
 
   clist = GTK_CLIST (widget);
 
-  GTK_CLIST_SET_FLAGS (clist, CLIST_FROZEN);
+  GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
 
   gdk_cursor_destroy (clist->cursor_drag);
   gdk_gc_destroy (clist->xor_gc);
@@ -1921,7 +1934,7 @@ gtk_clist_map (GtkWidget * widget)
        gtk_widget_map (clist->hscrollbar);
 
       /* unfreeze the list */
-      GTK_CLIST_UNSET_FLAGS (clist, CLIST_FROZEN);
+      GTK_CLIST_UNSET_FLAG (clist, CLIST_FROZEN);
     }
 }
 
@@ -1962,7 +1975,7 @@ gtk_clist_unmap (GtkWidget * widget)
          gtk_widget_unmap (clist->column[i].button);
 
       /* freeze the list */
-      GTK_CLIST_SET_FLAGS (clist, CLIST_FROZEN);
+      GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
     }
 }
 
@@ -2063,7 +2076,7 @@ gtk_clist_button_press (GtkWidget * widget,
   for (i = 0; i < clist->columns; i++)
     if (clist->column[i].window && event->window == clist->column[i].window)
       {
-       GTK_CLIST_SET_FLAGS (clist, CLIST_IN_DRAG);
+       GTK_CLIST_SET_FLAG (clist, CLIST_IN_DRAG);
        gtk_widget_get_pointer (widget, &clist->x_drag, NULL);
 
        gdk_pointer_grab (clist->column[i].window, FALSE,
@@ -2097,7 +2110,7 @@ gtk_clist_button_release (GtkWidget * widget,
     for (i = 0; i < clist->columns; i++)
       if (clist->column[i].window && event->window == clist->column[i].window)
        {
-         GTK_CLIST_UNSET_FLAGS (clist, CLIST_IN_DRAG);
+         GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
          gtk_widget_get_pointer (widget, &x, NULL);
          width = new_column_width (clist, i, &x, &visible);
          gdk_pointer_ungrab (event->time);
@@ -2794,7 +2807,8 @@ draw_rows (GtkCList * clist,
       if (i > last_row)
        return;
 
-      draw_row (clist, area, i, clist_row);
+      (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+       (clist, area, i, clist_row);
       i++;
     }
 
@@ -3065,7 +3079,8 @@ real_select_row (GtkCList * clist,
 
       if (!GTK_CLIST_FROZEN (clist)
          && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-       draw_row (clist, NULL, row, clist_row);
+       (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+         (clist, NULL, row, clist_row);
     }
 }
 
@@ -3091,7 +3106,8 @@ real_unselect_row (GtkCList * clist,
 
       if (!GTK_CLIST_FROZEN (clist)
          && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-       draw_row (clist, NULL, row, clist_row);
+       (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
+         (clist, NULL, row, clist_row);
     }
 }
 
index 82f316422ae77e828b15b316f4d36f13f699a5d8..af914a2ab0bb34a8501624a74f7d6516fd9f1a70 100644 (file)
@@ -36,10 +36,11 @@ extern "C"
 /* clist flags */
 enum                    
 {
-  CLIST_FROZEN          = 1 << 0,                                     
-  CLIST_IN_DRAG         = 1 << 1,                                        
-  CLIST_ROW_HEIGHT_SET  = 1 << 2,
-  CLIST_SHOW_TITLES     = 1 << 3
+  GTK_CLIST_FROZEN          = 1 << 0,                                     
+  GTK_CLIST_IN_DRAG         = 1 << 1,                                        
+  GTK_CLIST_ROW_HEIGHT_SET  = 1 << 2,
+  GTK_CLIST_SHOW_TITLES     = 1 << 3,
+  GTK_CLIST_CONSTRUCTED            = 1 << 4
 }; 
 
 /* cell types */
@@ -52,18 +53,19 @@ typedef enum
   GTK_CELL_WIDGET
 } GtkCellType;
 
-#define GTK_CLIST(obj)          GTK_CHECK_CAST (obj, gtk_clist_get_type (), GtkCList)
-#define GTK_CLIST_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_clist_get_type (), GtkCListClass)
-#define GTK_IS_CLIST(obj)       GTK_CHECK_TYPE (obj, gtk_clist_get_type ())
+#define GTK_CLIST(obj)          (GTK_CHECK_CAST ((obj), gtk_clist_get_type (), GtkCList))
+#define GTK_CLIST_CLASS(klass)  (GTK_CHECK_CLASS_CAST ((klass), gtk_clist_get_type (), GtkCListClass))
+#define GTK_IS_CLIST(obj)       (GTK_CHECK_TYPE ((obj), gtk_clist_get_type ()))
 
-#define GTK_CLIST_FLAGS(clist)             (GTK_CLIST (clist)->flags)
-#define GTK_CLIST_SET_FLAGS(clist,flag)    (GTK_CLIST_FLAGS (clist) |= (flag))
-#define GTK_CLIST_UNSET_FLAGS(clist,flag)  (GTK_CLIST_FLAGS (clist) &= ~(flag))
+#define GTK_CLIST_FLAGS(clist)            (GTK_CLIST (clist)->flags)
+#define GTK_CLIST_SET_FLAG(clist,flag)    (GTK_CLIST_FLAGS (clist) |= (GTK_ ## flag))
+#define GTK_CLIST_UNSET_FLAG(clist,flag)  (GTK_CLIST_FLAGS (clist) &= ~(GTK_ ## flag))
 
-#define GTK_CLIST_FROZEN(clist)            (GTK_CLIST_FLAGS (clist) & CLIST_FROZEN)
-#define GTK_CLIST_IN_DRAG(clist)           (GTK_CLIST_FLAGS (clist) & CLIST_IN_DRAG)
-#define GTK_CLIST_ROW_HEIGHT_SET(clist)    (GTK_CLIST_FLAGS (clist) & CLIST_ROW_HEIGHT_SET)
-#define GTK_CLIST_SHOW_TITLES(clist)       (GTK_CLIST_FLAGS (clist) & CLIST_SHOW_TITLES)
+#define GTK_CLIST_FROZEN(clist)            (GTK_CLIST_FLAGS (clist) & GTK_CLIST_FROZEN)
+#define GTK_CLIST_IN_DRAG(clist)           (GTK_CLIST_FLAGS (clist) & GTK_CLIST_IN_DRAG)
+#define GTK_CLIST_ROW_HEIGHT_SET(clist)    (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ROW_HEIGHT_SET)
+#define GTK_CLIST_SHOW_TITLES(clist)       (GTK_CLIST_FLAGS (clist) & GTK_CLIST_SHOW_TITLES)
+#define GTK_CLIST_CONSTRUCTED(clist)       (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CONSTRUCTED)
 
 /* pointer casting for cells */
 #define GTK_CELL_TEXT(cell)     (((GtkCellText *) &(cell)))
@@ -164,7 +166,10 @@ struct _GtkCListClass
                        GdkEventButton * event);
   void (*click_column) (GtkCList * clist,
                        gint column);
-
+  void (*draw_row) (GtkCList * clist,
+                   GdkRectangle * area,
+                   gint row,
+                   GtkCListRow * clist_row);
   gint scrollbar_spacing;
 };
 
@@ -268,7 +273,7 @@ struct _GtkCell
   } u;
 };
 
-guint gtk_clist_get_type (void);
+GtkType gtk_clist_get_type (void);
 
 /* constructers useful for gtk-- wrappers */
 void gtk_clist_construct (GtkCList * clist,
index 7ca02840c5e2e7693998ab01b9f9b24e5f2231f6..b8cfc4a5d95bfaf4ec5e6a2f95f81ba84b01a7b4 100644 (file)
@@ -112,6 +112,7 @@ static int
 gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * combo)
 {
   GList *li;
+
   /* completion? */
   /*if ( event->keyval == GDK_Tab ) {
      gtk_signal_emit_stop_by_name (GTK_OBJECT (entry), "key_press_event");
@@ -546,6 +547,7 @@ gtk_combo_init (GtkCombo * combo)
   gtk_container_add (GTK_CONTAINER (combo->button), arrow);
   gtk_box_pack_start (GTK_BOX (combo), combo->entry, TRUE, TRUE, 0);
   gtk_box_pack_end (GTK_BOX (combo), combo->button, FALSE, FALSE, 0);
+  GTK_WIDGET_UNSET_FLAGS (combo->button, GTK_CAN_FOCUS);
   gtk_widget_show (combo->entry);
   gtk_widget_show (combo->button);
   combo->entry_change_id = gtk_signal_connect (GTK_OBJECT (combo->entry), "changed",
@@ -585,14 +587,18 @@ gtk_combo_init (GtkCombo * combo)
 
   combo->popup = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (combo->popup),
-                               GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (combo->popup)->hscrollbar, GTK_CAN_FOCUS);
+  GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (combo->popup)->vscrollbar, GTK_CAN_FOCUS);
+  gtk_container_add (GTK_CONTAINER (frame), combo->popup);
+  gtk_widget_show (combo->popup);
 
   combo->list = gtk_list_new ();
   gtk_list_set_selection_mode(GTK_LIST(combo->list), GTK_SELECTION_BROWSE);
-  gtk_container_add (GTK_CONTAINER (frame), combo->popup);
   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_widget_show (combo->list);
-  gtk_widget_show (combo->popup);
 
   combo->list_change_id = gtk_signal_connect (GTK_OBJECT (combo->list), "selection_changed",
                             (GtkSignalFunc) gtk_combo_update_entry, combo);
index 56ba0c8e14aa92ed9e80d7244e6c5d70bb827e7d..c7531d5df52fa841968526878b7e433c5cb4a9f2 100644 (file)
@@ -37,6 +37,7 @@ typedef void (*GtkListSignal) (GtkObject *object,
 
 static void gtk_list_class_init             (GtkListClass   *klass);
 static void gtk_list_init           (GtkList        *list);
+static void gtk_list_shutdown       (GtkObject      *object);
 static void gtk_list_destroy        (GtkObject      *object);
 static void gtk_list_map            (GtkWidget      *widget);
 static void gtk_list_unmap          (GtkWidget      *widget);
@@ -141,6 +142,7 @@ gtk_list_class_init (GtkListClass *class)
 
   gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL);
 
+  object_class->shutdown = gtk_list_shutdown;
   object_class->destroy = gtk_list_destroy;
 
   widget_class->map = gtk_list_map;
@@ -182,6 +184,14 @@ gtk_list_new ()
   return GTK_WIDGET (gtk_type_new (gtk_list_get_type ()));
 }
 
+static void
+gtk_list_shutdown (GtkObject *object)
+{
+  gtk_list_clear_items (GTK_LIST (object), 0, -1);
+
+  GTK_OBJECT_CLASS (parent_class)->shutdown (object);
+}
+
 static void
 gtk_list_destroy (GtkObject *object)
 {
@@ -216,6 +226,20 @@ gtk_list_destroy (GtkObject *object)
     (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
+static void
+gtk_list_ungrab (GtkList *list)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (list->button)
+    {
+      list->button = 0;
+      gtk_grab_remove (GTK_WIDGET (list));
+      gdk_pointer_ungrab (GDK_CURRENT_TIME);
+    }
+}
+
 void
 gtk_list_insert_items (GtkList *list,
                       GList   *items,
@@ -232,6 +256,8 @@ gtk_list_insert_items (GtkList *list,
   if (!items)
     return;
 
+  gtk_list_ungrab (list);
+
   tmp_list = items;
   while (tmp_list)
     {
@@ -326,6 +352,11 @@ gtk_list_remove_items_internal (GtkList     *list,
   
   g_return_if_fail (list != NULL);
   g_return_if_fail (GTK_IS_LIST (list));
+
+  if (!items)
+    return;
+
+  gtk_list_ungrab (list);
   
   tmp_list = items;
   selected_widgets = NULL;
@@ -336,17 +367,15 @@ gtk_list_remove_items_internal (GtkList    *list,
       widget = tmp_list->data;
       tmp_list = tmp_list->next;
       
-      if (widget->state == GTK_STATE_SELECTED)
-       selected_widgets = g_list_prepend (selected_widgets, widget);
-      
-      list->children = g_list_remove (list->children, widget);
-      
-      if (GTK_WIDGET_MAPPED (widget))
-       gtk_widget_unmap (widget);
-      
       if (no_unref)
        gtk_widget_ref (widget);
-      gtk_widget_unparent (widget);
+
+      list->children = g_list_remove (list->children, widget);
+
+      if (widget->state == GTK_STATE_SELECTED)
+       selected_widgets = g_list_prepend (selected_widgets, widget);
+      else
+       gtk_widget_unparent (widget);
     }
   
   if (selected_widgets)
@@ -358,6 +387,8 @@ gtk_list_remove_items_internal (GtkList      *list,
          tmp_list = tmp_list->next;
          
          gtk_list_unselect_child (list, widget);
+
+         gtk_widget_unparent (widget);
        }
       
       gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
@@ -400,7 +431,6 @@ gtk_list_clear_items (GtkList *list,
   GList *end_list;
   GList *tmp_list;
   guint nchildren;
-  gboolean selection_changed;
 
   g_return_if_fail (list != NULL);
   g_return_if_fail (GTK_IS_LIST (list));
@@ -409,6 +439,8 @@ gtk_list_clear_items (GtkList *list,
 
   if (nchildren > 0)
     {
+      gboolean selection_changed;
+
       if ((end < 0) || (end > nchildren))
        end = nchildren;
 
@@ -418,6 +450,8 @@ 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);
+
       if (start_list->prev)
        start_list->prev->next = end_list;
       if (end_list && end_list->prev)
@@ -438,9 +472,8 @@ gtk_list_clear_items (GtkList *list,
 
          if (widget->state == GTK_STATE_SELECTED)
            {
+             gtk_list_unselect_child (list, widget);
              selection_changed = TRUE;
-             list->selection = g_list_remove (list->selection, widget);
-             gtk_widget_unref (widget);
            }
 
          gtk_widget_unparent (widget);
@@ -454,8 +487,7 @@ gtk_list_clear_items (GtkList *list,
          widget = list->children->data;
          gtk_list_select_child (list, widget);
        }
-
-      if (selection_changed)
+      else if (selection_changed)
        gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
 
       gtk_widget_queue_resize (GTK_WIDGET (list));
@@ -719,20 +751,22 @@ gtk_list_button_press (GtkWidget      *widget,
 
   if (list->button && (list->button != event->button))
     return FALSE;
-  list->button = event->button;
   
   while (item && !GTK_IS_LIST_ITEM (item))
     item = item->parent;
 
-  if (item && (item->parent == widget))
-    gtk_list_select_child (list, item);
-
+  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);
+  
   return FALSE;
 }
 
@@ -750,12 +784,8 @@ gtk_list_button_release (GtkWidget *widget,
   list = GTK_LIST (widget);
   item = gtk_get_event_widget ((GdkEvent*) event);
 
-  if (list->button != event->button)
-    return FALSE;
-  list->button = 0;
-  
-  gtk_grab_remove (widget);
-  gdk_pointer_ungrab (event->time);
+  if (list->button == event->button)
+    gtk_list_ungrab (list);
 
   return FALSE;
 }
@@ -848,34 +878,17 @@ static void
 gtk_list_add (GtkContainer *container,
              GtkWidget    *widget)
 {
-  GtkList *list;
+  GList *item_list;
 
   g_return_if_fail (container != NULL);
   g_return_if_fail (GTK_IS_LIST (container));
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
 
-  list = GTK_LIST (container);
-
-  gtk_widget_set_parent (widget, GTK_WIDGET (container));
-  if (GTK_WIDGET_VISIBLE (widget->parent))
-    {
-      if (GTK_WIDGET_REALIZED (widget->parent) &&
-         !GTK_WIDGET_REALIZED (widget))
-       gtk_widget_realize (widget);
-
-      if (GTK_WIDGET_MAPPED (widget->parent) &&
-         !GTK_WIDGET_MAPPED (widget))
-       gtk_widget_map (widget);
-    }
-
-  list->children = g_list_append (list->children, widget);
-
-  if (!list->selection && (list->selection_mode == GTK_SELECTION_BROWSE))
-    gtk_list_select_child (list, widget);
-
-  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
-    gtk_widget_queue_resize (widget);
+  item_list = g_list_alloc ();
+  item_list->data = widget;
+  
+  gtk_list_append_items (GTK_LIST (container), item_list);
 }
 
 static void
@@ -948,15 +961,14 @@ gtk_real_list_select_child (GtkList   *list,
 
          if (tmp_item != child)
            {
-             gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
-             
              tmp_list = selection;
              selection = selection->next;
 
              list->selection = g_list_remove_link (list->selection, tmp_list);
-             gtk_widget_unref (GTK_WIDGET (tmp_item));
-
              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;
@@ -964,14 +976,14 @@ gtk_real_list_select_child (GtkList   *list,
 
       if (child->state == GTK_STATE_NORMAL)
        {
-         gtk_list_item_select (GTK_LIST_ITEM (child));
          list->selection = g_list_prepend (list->selection, child);
          gtk_widget_ref (child);
+         gtk_list_item_select (GTK_LIST_ITEM (child));
        }
       else if (child->state == GTK_STATE_SELECTED)
        {
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
          list->selection = g_list_remove (list->selection, child);
+         gtk_list_item_deselect (GTK_LIST_ITEM (child));
          gtk_widget_unref (child);
        }
 
@@ -987,15 +999,14 @@ gtk_real_list_select_child (GtkList   *list,
 
          if (tmp_item != child)
            {
-             gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
-             
              tmp_list = selection;
              selection = selection->next;
 
              list->selection = g_list_remove_link (list->selection, tmp_list);
-             gtk_widget_unref (GTK_WIDGET (tmp_item));
-
              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;
@@ -1003,9 +1014,9 @@ gtk_real_list_select_child (GtkList   *list,
 
       if (child->state == GTK_STATE_NORMAL)
        {
-         gtk_list_item_select (GTK_LIST_ITEM (child));
          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;
@@ -1013,15 +1024,15 @@ gtk_real_list_select_child (GtkList   *list,
     case GTK_SELECTION_MULTIPLE:
       if (child->state == GTK_STATE_NORMAL)
        {
-         gtk_list_item_select (GTK_LIST_ITEM (child));
          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]);
        }
       else if (child->state == GTK_STATE_SELECTED)
        {
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
          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]);
        }
@@ -1048,8 +1059,8 @@ gtk_real_list_unselect_child (GtkList     *list,
     case GTK_SELECTION_BROWSE:
       if (child->state == GTK_STATE_SELECTED)
        {
-         gtk_list_item_deselect (GTK_LIST_ITEM (child));
          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]);
        }
index 677ca8d11a0a7c786fed8f7fbd303cfe84b6cd59..7dc08bf40e76791cff9f11d89d0b33a822007d7e 100644 (file)
@@ -3392,6 +3392,815 @@ create_clist ()
 
 }
 
+
+/*
+ * GtkCTree
+ */
+
+static char * book_open_xpm[] = {
+"16 16 4 1",
+"       c None s None",
+".      c black",
+"X      c #808080",
+"o      c white",
+"                ",
+"  ..            ",
+" .Xo.    ...    ",
+" .Xoo. ..oo.    ",
+" .Xooo.Xooo...  ",
+" .Xooo.oooo.X.  ",
+" .Xooo.Xooo.X.  ",
+" .Xooo.oooo.X.  ",
+" .Xooo.Xooo.X.  ",
+" .Xooo.oooo.X.  ",
+"  .Xoo.Xoo..X.  ",
+"   .Xo.o..ooX.  ",
+"    .X..XXXXX.  ",
+"    ..X.......  ",
+"     ..         ",
+"                "};
+
+static char * book_closed_xpm[] = {
+"16 16 6 1",
+"       c None s None",
+".      c black",
+"X      c red",
+"o      c yellow",
+"O      c #808080",
+"#      c white",
+"                ",
+"       ..       ",
+"     ..XX.      ",
+"   ..XXXXX.     ",
+" ..XXXXXXXX.    ",
+".ooXXXXXXXXX.   ",
+"..ooXXXXXXXXX.  ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX..  ",
+" .XX.ooXXX..#O  ",
+"  .XX.oo..##OO. ",
+"   .XX..##OO..  ",
+"    .X.#OO..    ",
+"     ..O..      ",
+"      ..        ",
+"                "};
+
+static char * mini_page_xpm[] = {
+"16 16 4 1",
+"       c None s None",
+".      c black",
+"X      c white",
+"o      c #808080",
+"                ",
+"   .......      ",
+"   .XXXXX..     ",
+"   .XoooX.X.    ",
+"   .XXXXX....   ",
+"   .XooooXoo.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   ..........o  ",
+"    oooooooooo  ",
+"                "};
+
+GdkPixmap *pixmap1;
+GdkPixmap *pixmap2;
+GdkPixmap *pixmap3;
+GdkBitmap *mask1;
+GdkBitmap *mask2;
+GdkBitmap *mask3;
+
+static gint books = 0;
+static gint pages = 0;
+
+static GtkWidget *book_label;
+static GtkWidget *page_label;
+static GtkWidget *sel_label;
+static GtkWidget *vis_label;
+static GtkWidget *omenu;
+static GtkWidget *omenu2;
+static GtkWidget *omenu3;
+static GtkWidget *spin1;
+static GtkWidget *spin2;
+static GtkWidget *spin3;
+
+#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++; \
+  }\
+}
+
+#define RADIOBUTTONTOGGLED(_rb_, __i) { \
+  GSList * __g; \
+  __i = 0; \
+  __g = gtk_radio_button_group(_rb_); \
+  while( __g  && !((GtkToggleButton *)(__g->data))->active) { \
+    __g = __g->next; \
+    __i++; \
+  }\
+}
+
+void after_press (GtkCTree *ctree, gpointer data)
+{
+  char buf[80];
+
+  sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
+  gtk_label_set (GTK_LABEL (sel_label), buf);
+
+  sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
+  gtk_label_set (GTK_LABEL (vis_label), buf);
+
+  sprintf (buf, "%d", books);
+  gtk_label_set (GTK_LABEL (book_label), buf);
+
+  sprintf (buf, "%d", pages);
+  gtk_label_set (GTK_LABEL (page_label), buf);
+}
+
+void after_move (GtkCTree *ctree, GList *child, GList *parent, 
+                GList *sibling, gpointer data)
+{
+  char *source;
+  char *target1;
+  char *target2;
+
+  gtk_ctree_get_pixtext (ctree, child, 0, &source, NULL, NULL, NULL);
+  if (parent)
+    gtk_ctree_get_pixtext (ctree, parent, 0, &target1, NULL, NULL, NULL);
+  if (sibling)
+    gtk_ctree_get_pixtext (ctree, sibling, 0, &target2, NULL, NULL, NULL);
+
+  g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
+          (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
+}
+
+gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
+{
+  gint row;
+  gint column;
+  GList *work;
+  gint res;
+  
+  res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
+                                     &row, &column);
+  if (!res && event->button != 3)
+    return FALSE;
+
+  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+
+  switch (event->button)
+    {
+    case 1:
+      if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
+         event->state & GDK_SHIFT_MASK)
+       gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),"button_press_event");
+      break;
+    case  2:
+      if (GTK_CTREE_ROW (work)->children && 
+         gtk_ctree_is_hot_spot (ctree, event->x, event->y))
+       {
+         gtk_clist_freeze (GTK_CLIST (ctree));
+         if (GTK_CTREE_ROW (work)->expanded)
+           gtk_ctree_collapse_recursive (ctree, work);
+         else
+           gtk_ctree_expand_recursive (ctree, work);
+         gtk_clist_thaw (GTK_CLIST (ctree));
+         after_press (ctree, NULL);
+         gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
+                                       "button_press_event");
+       }
+      break;
+    default:
+      break;
+    }
+  return FALSE;
+}
+
+gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
+{
+  gint row;
+  gint column;
+  GList *work;
+  gint res;
+  
+  res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
+                                     &row, &column);
+  if (!res || event->button != 1)
+    return FALSE;
+
+  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+
+  if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
+      event->state & GDK_SHIFT_MASK)
+    {
+      gtk_clist_freeze (GTK_CLIST (ctree));
+      if (GTK_CTREE_ROW (work)->row.state == GTK_STATE_SELECTED) 
+           gtk_ctree_unselect_recursive (ctree, work);
+      else
+       gtk_ctree_select_recursive (ctree, work);
+      gtk_clist_thaw (GTK_CLIST (ctree));
+      after_press (ctree, NULL);
+      gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
+                                   "button_release_event");
+    }
+  return FALSE;
+}
+
+void count_items (GtkCTree *ctree, GList *list)
+{
+  if (GTK_CTREE_ROW (list)->is_leaf)
+    pages--;
+  else
+    books--;
+}
+
+void expand_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_expand_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void collapse_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_collapse_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void select_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  if (GTK_CLIST (ctree)->selection_mode != GTK_SELECTION_MULTIPLE)
+    return;
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_select_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void unselect_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  if (GTK_CLIST (ctree)->selection_mode != GTK_SELECTION_MULTIPLE)
+    return;
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_unselect_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void remove_selection (GtkWidget *widget, GtkCTree *ctree)
+{
+  GList *work;
+  GList *selection;
+  GList *new_sel;
+
+  selection = GTK_CLIST (ctree)->selection;
+  new_sel = NULL;
+
+  gtk_clist_freeze (GTK_CLIST (ctree));
+
+  while (selection)
+    {
+      work = selection->data;
+      if (GTK_CTREE_ROW (work)->is_leaf)
+       pages--;
+      else
+       gtk_ctree_post_recursive (ctree, work, 
+                                 (GtkCTreeFunc) count_items, NULL);
+
+      if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_BROWSE)
+       {
+         if (GTK_CTREE_ROW (work)->children)
+           {
+             new_sel = GTK_CTREE_ROW (work)->sibling;
+             if (!new_sel)
+               new_sel = work->prev;
+           }
+         else
+           {
+             if (work->next)
+               new_sel = work->next;
+             else
+               new_sel = work->prev;
+           }
+       }
+
+      gtk_ctree_remove (ctree, work);
+      selection = GTK_CLIST (ctree)->selection;
+    }
+
+  if (new_sel)
+    gtk_ctree_select (ctree, new_sel);
+
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void sort_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_sort_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+}
+
+void change_indent (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
+}
+
+void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+void toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu2)->menu_item),i);
+
+  gtk_ctree_set_line_style (ctree, (GtkCTreeLineStyle) (2-i));
+}
+
+void toggle_justify (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu3)->menu_item),i);
+
+  gtk_clist_set_column_justification (GTK_CLIST (ctree), 0, 
+                                     (GtkJustification) (1-i));
+}
+
+void toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu)->menu_item), i);
+
+  gtk_ctree_set_selection_mode (ctree, (GtkSelectionMode) (3-i));
+  after_press (ctree, NULL);
+}
+
+
+void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
+                     gint num_books, gint num_pages, GList *parent)
+{
+  gchar *text [2];
+  gchar buf1[60];
+  gchar buf2[60];
+  GList *sibling;
+  gint i;
+  
+  text[0] = buf1;
+  text[1] = buf2;
+  sibling = NULL;
+
+  for (i = num_pages + num_books; i > num_books; i--)
+    {
+      pages++;
+      sprintf (buf1, "Page %02ld", random() % 100);
+      sprintf (buf2, "Item %d-%d", cur_depth, i);
+      sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap3,
+                                 mask3, NULL, NULL, TRUE, FALSE);
+    }
+
+  if (cur_depth == depth)
+    return;
+
+  for (i = num_books; i > 0; i--)
+    {
+      books++;
+      sprintf (buf1, "Book %02ld", random() % 100);
+      sprintf (buf2, "Item %d-%d", cur_depth, i);
+      sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap1,
+                                 mask1, pixmap2, mask2, FALSE, FALSE);
+      build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages, sibling);
+    }
+}
+
+void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
+{
+  gchar *text [2];
+  gchar label1[] = "Root";
+  gchar label2[] = "";
+  GList *parent;
+  guint b, d, p, n;
+
+  text[0] = label1;
+  text[1] = label2;
+  
+  d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
+  b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
+  p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
+
+  n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
+
+  if (n > 200000)
+    {
+      g_print ("%d total items? Try less\n",n);
+      return;
+    }
+
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_clear (ctree);
+
+  books = 1;
+  pages = 0;
+
+  parent = gtk_ctree_insert (ctree, NULL, NULL, text, 5, pixmap1,
+                            mask1, pixmap2, mask2, FALSE, TRUE);
+
+  build_recursive (ctree, 1, d, b, p, parent);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void create_ctree ()
+{
+  static GtkWidget *window = NULL;
+  GtkTooltips *tooltips;
+  GtkCTree *ctree;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  GtkWidget *hbox2;
+  GtkWidget *frame;
+  GtkWidget *label;
+  GtkWidget *button;
+  GtkWidget *menu_item;
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GtkWidget *check;
+  GtkAdjustment *adj;
+  GtkWidget *spinner;
+  GSList *group;
+  GdkColor transparent;
+
+  char *title[] = { "Tree" , "Info" };
+  char buf[80];
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      tooltips = gtk_tooltips_new ();
+      gtk_object_ref (GTK_OBJECT (tooltips));
+      gtk_object_sink (GTK_OBJECT (tooltips));
+
+      gtk_object_set_data_full (GTK_OBJECT (window),
+                               "tooltips",
+                               tooltips,
+                               (GtkDestroyNotify) gtk_object_unref);
+
+      vbox = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+      
+      label = gtk_label_new ("Depth :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
+      spin1 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
+  
+      label = gtk_label_new ("Books :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
+      spin2 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
+
+      label = gtk_label_new ("Pages :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
+      spin3 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
+
+      button = gtk_button_new_with_label ("Close");
+      gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
+                               (GtkSignalFunc) gtk_widget_destroy, 
+                               GTK_OBJECT(window));
+
+      button = gtk_button_new_with_label ("Rebuild tree");
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+      
+      ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
+      gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
+      gtk_ctree_set_reorderable (ctree, TRUE);
+      gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
+                         GTK_SIGNAL_FUNC (button_press), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
+                               GTK_SIGNAL_FUNC (after_press), NULL);
+      gtk_signal_connect (GTK_OBJECT (ctree), "button_release_event",
+                         GTK_SIGNAL_FUNC (button_release), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
+                               GTK_SIGNAL_FUNC (after_press), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
+                               GTK_SIGNAL_FUNC (after_move), NULL);
+      gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
+      gtk_clist_column_titles_passive (GTK_CLIST (ctree));
+      gtk_clist_set_column_justification (GTK_CLIST (ctree), 2, GTK_JUSTIFY_RIGHT);
+      gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_MULTIPLE);
+      gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, 
+                           GTK_POLICY_AUTOMATIC);
+      gtk_clist_set_column_width (GTK_CLIST (ctree), 0, 200);
+      gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
+
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (rebuild_tree), ctree);
+      
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Expand all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (expand_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Collapse all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (collapse_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Sort tree");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (sort_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Select all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (select_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Unselect all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (unselect_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Remove selection");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (remove_selection), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (TRUE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, TRUE, 0);
+      
+      label = gtk_label_new ("Indent :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
+      spinner = gtk_spin_button_new (adj, 0, 0);
+      gtk_tooltips_set_tip (tooltips, spinner, "Tree indentation.", NULL);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (change_indent), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox2), spinner, FALSE, TRUE, 5);
+      
+      check = gtk_check_button_new_with_label ("Reorderable");
+      gtk_tooltips_set_tip (tooltips, check,
+                           "Tree items can be reordered by dragging.", NULL);
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
+      gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check), TRUE);
+      
+      omenu2 = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu2, "The tree's line style.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Solid");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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, "Dotted");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "No lines");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu2), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu2), 1);
+      
+      omenu3 = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Left");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_justify), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Right");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_justify), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu3), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu3), 0);
+      
+      omenu = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu, "The list's selection mode.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
+      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 (toggle_sel_mode), ctree);
+      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 (toggle_sel_mode), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 2);
+      
+      gtk_widget_realize (window);
+      
+      pixmap1 = gdk_pixmap_create_from_xpm_d (window->window, &mask1, 
+                                             &transparent, book_closed_xpm);
+      pixmap2 = gdk_pixmap_create_from_xpm_d (window->window, &mask2, 
+                                             &transparent, book_open_xpm);
+      pixmap3 = gdk_pixmap_create_from_xpm_d (window->window, &mask3,
+                                             &transparent, mini_page_xpm);
+      
+      gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_container_border_width (GTK_CONTAINER (frame), 0);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+      
+      hbox = gtk_hbox_new (TRUE, 2);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Books :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", books);
+      book_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Pages :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", pages);
+      page_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Selected :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
+      sel_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Visible :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
+      vis_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
+
+      rebuild_tree (NULL, ctree);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show_all (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
 /*
  * GtkColorSelect
  */
@@ -3930,53 +4739,6 @@ GdkPixmap *book_closed;
 GdkBitmap *book_open_mask;
 GdkBitmap *book_closed_mask;
 
-static char * book_open_xpm[] = {
-"16 16 4 1",
-"       c None s None",
-".      c black",
-"X      c #808080",
-"o      c white",
-"                ",
-"  ..            ",
-" .Xo.    ...    ",
-" .Xoo. ..oo.    ",
-" .Xooo.Xooo...  ",
-" .Xooo.oooo.X.  ",
-" .Xooo.Xooo.X.  ",
-" .Xooo.oooo.X.  ",
-" .Xooo.Xooo.X.  ",
-" .Xooo.oooo.X.  ",
-"  .Xoo.Xoo..X.  ",
-"   .Xo.o..ooX.  ",
-"    .X..XXXXX.  ",
-"    ..X.......  ",
-"     ..         ",
-"                "};
-
-static char * book_closed_xpm[] = {
-"16 16 6 1",
-"       c None s None",
-".      c black",
-"X      c red",
-"o      c yellow",
-"O      c #808080",
-"#      c white",
-"                ",
-"       ..       ",
-"     ..XX.      ",
-"   ..XXXXX.     ",
-" ..XXXXXXXX.    ",
-".ooXXXXXXXXX.   ",
-"..ooXXXXXXXXX.  ",
-".X.ooXXXXXXXXX. ",
-".XX.ooXXXXXX..  ",
-" .XX.ooXXX..#O  ",
-"  .XX.oo..##OO. ",
-"   .XX..##OO..  ",
-"    .X.#OO..    ",
-"     ..O..      ",
-"      ..        ",
-"                "};
 
 static void
 notebook_reparent (GtkWidget *widget, GtkWidget *scrollwin)
@@ -5769,6 +6531,7 @@ create_main_window ()
       { "check buttons", create_check_buttons },
       { "clist", create_clist},
       { "color selection", create_color_selection },
+      { "ctree", create_ctree },
       { "cursors", create_cursors },
       { "dialog", create_dialog },
       { "dnd", create_dnd },
index 677ca8d11a0a7c786fed8f7fbd303cfe84b6cd59..7dc08bf40e76791cff9f11d89d0b33a822007d7e 100644 (file)
@@ -3392,6 +3392,815 @@ create_clist ()
 
 }
 
+
+/*
+ * GtkCTree
+ */
+
+static char * book_open_xpm[] = {
+"16 16 4 1",
+"       c None s None",
+".      c black",
+"X      c #808080",
+"o      c white",
+"                ",
+"  ..            ",
+" .Xo.    ...    ",
+" .Xoo. ..oo.    ",
+" .Xooo.Xooo...  ",
+" .Xooo.oooo.X.  ",
+" .Xooo.Xooo.X.  ",
+" .Xooo.oooo.X.  ",
+" .Xooo.Xooo.X.  ",
+" .Xooo.oooo.X.  ",
+"  .Xoo.Xoo..X.  ",
+"   .Xo.o..ooX.  ",
+"    .X..XXXXX.  ",
+"    ..X.......  ",
+"     ..         ",
+"                "};
+
+static char * book_closed_xpm[] = {
+"16 16 6 1",
+"       c None s None",
+".      c black",
+"X      c red",
+"o      c yellow",
+"O      c #808080",
+"#      c white",
+"                ",
+"       ..       ",
+"     ..XX.      ",
+"   ..XXXXX.     ",
+" ..XXXXXXXX.    ",
+".ooXXXXXXXXX.   ",
+"..ooXXXXXXXXX.  ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX..  ",
+" .XX.ooXXX..#O  ",
+"  .XX.oo..##OO. ",
+"   .XX..##OO..  ",
+"    .X.#OO..    ",
+"     ..O..      ",
+"      ..        ",
+"                "};
+
+static char * mini_page_xpm[] = {
+"16 16 4 1",
+"       c None s None",
+".      c black",
+"X      c white",
+"o      c #808080",
+"                ",
+"   .......      ",
+"   .XXXXX..     ",
+"   .XoooX.X.    ",
+"   .XXXXX....   ",
+"   .XooooXoo.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   .XooooooX.o  ",
+"   .XXXXXXXX.o  ",
+"   ..........o  ",
+"    oooooooooo  ",
+"                "};
+
+GdkPixmap *pixmap1;
+GdkPixmap *pixmap2;
+GdkPixmap *pixmap3;
+GdkBitmap *mask1;
+GdkBitmap *mask2;
+GdkBitmap *mask3;
+
+static gint books = 0;
+static gint pages = 0;
+
+static GtkWidget *book_label;
+static GtkWidget *page_label;
+static GtkWidget *sel_label;
+static GtkWidget *vis_label;
+static GtkWidget *omenu;
+static GtkWidget *omenu2;
+static GtkWidget *omenu3;
+static GtkWidget *spin1;
+static GtkWidget *spin2;
+static GtkWidget *spin3;
+
+#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++; \
+  }\
+}
+
+#define RADIOBUTTONTOGGLED(_rb_, __i) { \
+  GSList * __g; \
+  __i = 0; \
+  __g = gtk_radio_button_group(_rb_); \
+  while( __g  && !((GtkToggleButton *)(__g->data))->active) { \
+    __g = __g->next; \
+    __i++; \
+  }\
+}
+
+void after_press (GtkCTree *ctree, gpointer data)
+{
+  char buf[80];
+
+  sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
+  gtk_label_set (GTK_LABEL (sel_label), buf);
+
+  sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
+  gtk_label_set (GTK_LABEL (vis_label), buf);
+
+  sprintf (buf, "%d", books);
+  gtk_label_set (GTK_LABEL (book_label), buf);
+
+  sprintf (buf, "%d", pages);
+  gtk_label_set (GTK_LABEL (page_label), buf);
+}
+
+void after_move (GtkCTree *ctree, GList *child, GList *parent, 
+                GList *sibling, gpointer data)
+{
+  char *source;
+  char *target1;
+  char *target2;
+
+  gtk_ctree_get_pixtext (ctree, child, 0, &source, NULL, NULL, NULL);
+  if (parent)
+    gtk_ctree_get_pixtext (ctree, parent, 0, &target1, NULL, NULL, NULL);
+  if (sibling)
+    gtk_ctree_get_pixtext (ctree, sibling, 0, &target2, NULL, NULL, NULL);
+
+  g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
+          (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
+}
+
+gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
+{
+  gint row;
+  gint column;
+  GList *work;
+  gint res;
+  
+  res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
+                                     &row, &column);
+  if (!res && event->button != 3)
+    return FALSE;
+
+  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+
+  switch (event->button)
+    {
+    case 1:
+      if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
+         event->state & GDK_SHIFT_MASK)
+       gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),"button_press_event");
+      break;
+    case  2:
+      if (GTK_CTREE_ROW (work)->children && 
+         gtk_ctree_is_hot_spot (ctree, event->x, event->y))
+       {
+         gtk_clist_freeze (GTK_CLIST (ctree));
+         if (GTK_CTREE_ROW (work)->expanded)
+           gtk_ctree_collapse_recursive (ctree, work);
+         else
+           gtk_ctree_expand_recursive (ctree, work);
+         gtk_clist_thaw (GTK_CLIST (ctree));
+         after_press (ctree, NULL);
+         gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
+                                       "button_press_event");
+       }
+      break;
+    default:
+      break;
+    }
+  return FALSE;
+}
+
+gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
+{
+  gint row;
+  gint column;
+  GList *work;
+  gint res;
+  
+  res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
+                                     &row, &column);
+  if (!res || event->button != 1)
+    return FALSE;
+
+  work = g_list_nth (GTK_CLIST (ctree)->row_list, row);
+
+  if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
+      event->state & GDK_SHIFT_MASK)
+    {
+      gtk_clist_freeze (GTK_CLIST (ctree));
+      if (GTK_CTREE_ROW (work)->row.state == GTK_STATE_SELECTED) 
+           gtk_ctree_unselect_recursive (ctree, work);
+      else
+       gtk_ctree_select_recursive (ctree, work);
+      gtk_clist_thaw (GTK_CLIST (ctree));
+      after_press (ctree, NULL);
+      gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
+                                   "button_release_event");
+    }
+  return FALSE;
+}
+
+void count_items (GtkCTree *ctree, GList *list)
+{
+  if (GTK_CTREE_ROW (list)->is_leaf)
+    pages--;
+  else
+    books--;
+}
+
+void expand_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_expand_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void collapse_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_collapse_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void select_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  if (GTK_CLIST (ctree)->selection_mode != GTK_SELECTION_MULTIPLE)
+    return;
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_select_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void unselect_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  if (GTK_CLIST (ctree)->selection_mode != GTK_SELECTION_MULTIPLE)
+    return;
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_unselect_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void remove_selection (GtkWidget *widget, GtkCTree *ctree)
+{
+  GList *work;
+  GList *selection;
+  GList *new_sel;
+
+  selection = GTK_CLIST (ctree)->selection;
+  new_sel = NULL;
+
+  gtk_clist_freeze (GTK_CLIST (ctree));
+
+  while (selection)
+    {
+      work = selection->data;
+      if (GTK_CTREE_ROW (work)->is_leaf)
+       pages--;
+      else
+       gtk_ctree_post_recursive (ctree, work, 
+                                 (GtkCTreeFunc) count_items, NULL);
+
+      if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_BROWSE)
+       {
+         if (GTK_CTREE_ROW (work)->children)
+           {
+             new_sel = GTK_CTREE_ROW (work)->sibling;
+             if (!new_sel)
+               new_sel = work->prev;
+           }
+         else
+           {
+             if (work->next)
+               new_sel = work->next;
+             else
+               new_sel = work->prev;
+           }
+       }
+
+      gtk_ctree_remove (ctree, work);
+      selection = GTK_CLIST (ctree)->selection;
+    }
+
+  if (new_sel)
+    gtk_ctree_select (ctree, new_sel);
+
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void sort_all (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_sort_recursive (ctree, NULL);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+}
+
+void change_indent (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
+}
+
+void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
+{
+  gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+void toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu2)->menu_item),i);
+
+  gtk_ctree_set_line_style (ctree, (GtkCTreeLineStyle) (2-i));
+}
+
+void toggle_justify (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu3)->menu_item),i);
+
+  gtk_clist_set_column_justification (GTK_CLIST (ctree), 0, 
+                                     (GtkJustification) (1-i));
+}
+
+void toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)omenu)->menu_item), i);
+
+  gtk_ctree_set_selection_mode (ctree, (GtkSelectionMode) (3-i));
+  after_press (ctree, NULL);
+}
+
+
+void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
+                     gint num_books, gint num_pages, GList *parent)
+{
+  gchar *text [2];
+  gchar buf1[60];
+  gchar buf2[60];
+  GList *sibling;
+  gint i;
+  
+  text[0] = buf1;
+  text[1] = buf2;
+  sibling = NULL;
+
+  for (i = num_pages + num_books; i > num_books; i--)
+    {
+      pages++;
+      sprintf (buf1, "Page %02ld", random() % 100);
+      sprintf (buf2, "Item %d-%d", cur_depth, i);
+      sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap3,
+                                 mask3, NULL, NULL, TRUE, FALSE);
+    }
+
+  if (cur_depth == depth)
+    return;
+
+  for (i = num_books; i > 0; i--)
+    {
+      books++;
+      sprintf (buf1, "Book %02ld", random() % 100);
+      sprintf (buf2, "Item %d-%d", cur_depth, i);
+      sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap1,
+                                 mask1, pixmap2, mask2, FALSE, FALSE);
+      build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages, sibling);
+    }
+}
+
+void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
+{
+  gchar *text [2];
+  gchar label1[] = "Root";
+  gchar label2[] = "";
+  GList *parent;
+  guint b, d, p, n;
+
+  text[0] = label1;
+  text[1] = label2;
+  
+  d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
+  b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
+  p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
+
+  n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
+
+  if (n > 200000)
+    {
+      g_print ("%d total items? Try less\n",n);
+      return;
+    }
+
+  gtk_clist_freeze (GTK_CLIST (ctree));
+  gtk_ctree_clear (ctree);
+
+  books = 1;
+  pages = 0;
+
+  parent = gtk_ctree_insert (ctree, NULL, NULL, text, 5, pixmap1,
+                            mask1, pixmap2, mask2, FALSE, TRUE);
+
+  build_recursive (ctree, 1, d, b, p, parent);
+  gtk_clist_thaw (GTK_CLIST (ctree));
+  after_press (ctree, NULL);
+}
+
+void create_ctree ()
+{
+  static GtkWidget *window = NULL;
+  GtkTooltips *tooltips;
+  GtkCTree *ctree;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  GtkWidget *hbox2;
+  GtkWidget *frame;
+  GtkWidget *label;
+  GtkWidget *button;
+  GtkWidget *menu_item;
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GtkWidget *check;
+  GtkAdjustment *adj;
+  GtkWidget *spinner;
+  GSList *group;
+  GdkColor transparent;
+
+  char *title[] = { "Tree" , "Info" };
+  char buf[80];
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      tooltips = gtk_tooltips_new ();
+      gtk_object_ref (GTK_OBJECT (tooltips));
+      gtk_object_sink (GTK_OBJECT (tooltips));
+
+      gtk_object_set_data_full (GTK_OBJECT (window),
+                               "tooltips",
+                               tooltips,
+                               (GtkDestroyNotify) gtk_object_unref);
+
+      vbox = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), vbox);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+      
+      label = gtk_label_new ("Depth :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
+      spin1 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
+  
+      label = gtk_label_new ("Books :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
+      spin2 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
+
+      label = gtk_label_new ("Pages :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
+      spin3 = gtk_spin_button_new (adj, 0, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
+
+      button = gtk_button_new_with_label ("Close");
+      gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
+                               (GtkSignalFunc) gtk_widget_destroy, 
+                               GTK_OBJECT(window));
+
+      button = gtk_button_new_with_label ("Rebuild tree");
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+      
+      ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
+      gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
+      gtk_ctree_set_reorderable (ctree, TRUE);
+      gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
+                         GTK_SIGNAL_FUNC (button_press), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
+                               GTK_SIGNAL_FUNC (after_press), NULL);
+      gtk_signal_connect (GTK_OBJECT (ctree), "button_release_event",
+                         GTK_SIGNAL_FUNC (button_release), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
+                               GTK_SIGNAL_FUNC (after_press), NULL);
+      gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
+                               GTK_SIGNAL_FUNC (after_move), NULL);
+      gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
+      gtk_clist_column_titles_passive (GTK_CLIST (ctree));
+      gtk_clist_set_column_justification (GTK_CLIST (ctree), 2, GTK_JUSTIFY_RIGHT);
+      gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_MULTIPLE);
+      gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, 
+                           GTK_POLICY_AUTOMATIC);
+      gtk_clist_set_column_width (GTK_CLIST (ctree), 0, 200);
+      gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
+
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (rebuild_tree), ctree);
+      
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Expand all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (expand_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Collapse all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (collapse_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Sort tree");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (sort_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Select all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (select_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Unselect all");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (unselect_all), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      button = gtk_button_new_with_label ("Remove selection");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (remove_selection), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
+      hbox = gtk_hbox_new (TRUE, 5);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, TRUE, 0);
+      
+      label = gtk_label_new ("Indent :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
+      spinner = gtk_spin_button_new (adj, 0, 0);
+      gtk_tooltips_set_tip (tooltips, spinner, "Tree indentation.", NULL);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (change_indent), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox2), spinner, FALSE, TRUE, 5);
+      
+      check = gtk_check_button_new_with_label ("Reorderable");
+      gtk_tooltips_set_tip (tooltips, check,
+                           "Tree items can be reordered by dragging.", NULL);
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
+      gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
+      gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check), TRUE);
+      
+      omenu2 = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu2, "The tree's line style.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Solid");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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, "Dotted");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "No lines");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_line_style), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu2), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu2), 1);
+      
+      omenu3 = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Left");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_justify), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Right");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_justify), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu3), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu3), 0);
+      
+      omenu = gtk_option_menu_new ();
+      gtk_tooltips_set_tip (tooltips, omenu, "The list's selection mode.", NULL);
+      
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
+      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 (toggle_sel_mode), ctree);
+      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 (toggle_sel_mode), ctree);
+      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);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
+      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);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
+      gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, TRUE, 0);
+      
+      gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 2);
+      
+      gtk_widget_realize (window);
+      
+      pixmap1 = gdk_pixmap_create_from_xpm_d (window->window, &mask1, 
+                                             &transparent, book_closed_xpm);
+      pixmap2 = gdk_pixmap_create_from_xpm_d (window->window, &mask2, 
+                                             &transparent, book_open_xpm);
+      pixmap3 = gdk_pixmap_create_from_xpm_d (window->window, &mask3,
+                                             &transparent, mini_page_xpm);
+      
+      gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_container_border_width (GTK_CONTAINER (frame), 0);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+      
+      hbox = gtk_hbox_new (TRUE, 2);
+      gtk_container_border_width (GTK_CONTAINER (hbox), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Books :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", books);
+      book_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Pages :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", pages);
+      page_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Selected :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
+      sel_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
+      
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+      gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
+      
+      hbox2 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
+      gtk_container_add (GTK_CONTAINER (frame), hbox2);
+      
+      label = gtk_label_new ("Visible :");
+      gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
+      
+      sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
+      vis_label = gtk_label_new (buf);
+      gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
+
+      rebuild_tree (NULL, ctree);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show_all (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
 /*
  * GtkColorSelect
  */
@@ -3930,53 +4739,6 @@ GdkPixmap *book_closed;
 GdkBitmap *book_open_mask;
 GdkBitmap *book_closed_mask;
 
-static char * book_open_xpm[] = {
-"16 16 4 1",
-"       c None s None",
-".      c black",
-"X      c #808080",
-"o      c white",
-"                ",
-"  ..            ",
-" .Xo.    ...    ",
-" .Xoo. ..oo.    ",
-" .Xooo.Xooo...  ",
-" .Xooo.oooo.X.  ",
-" .Xooo.Xooo.X.  ",
-" .Xooo.oooo.X.  ",
-" .Xooo.Xooo.X.  ",
-" .Xooo.oooo.X.  ",
-"  .Xoo.Xoo..X.  ",
-"   .Xo.o..ooX.  ",
-"    .X..XXXXX.  ",
-"    ..X.......  ",
-"     ..         ",
-"                "};
-
-static char * book_closed_xpm[] = {
-"16 16 6 1",
-"       c None s None",
-".      c black",
-"X      c red",
-"o      c yellow",
-"O      c #808080",
-"#      c white",
-"                ",
-"       ..       ",
-"     ..XX.      ",
-"   ..XXXXX.     ",
-" ..XXXXXXXX.    ",
-".ooXXXXXXXXX.   ",
-"..ooXXXXXXXXX.  ",
-".X.ooXXXXXXXXX. ",
-".XX.ooXXXXXX..  ",
-" .XX.ooXXX..#O  ",
-"  .XX.oo..##OO. ",
-"   .XX..##OO..  ",
-"    .X.#OO..    ",
-"     ..O..      ",
-"      ..        ",
-"                "};
 
 static void
 notebook_reparent (GtkWidget *widget, GtkWidget *scrollwin)
@@ -5769,6 +6531,7 @@ create_main_window ()
       { "check buttons", create_check_buttons },
       { "clist", create_clist},
       { "color selection", create_color_selection },
+      { "ctree", create_ctree },
       { "cursors", create_cursors },
       { "dialog", create_dialog },
       { "dnd", create_dnd },