]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.c
Initial revision
[helm.git] / helm / DEVEL / lablgtk / lablgtk_20001129-0.1.0 / applications / radtest / gtktree2.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "gtktree2.h"
28 #include "gtktreeitem2.h"
29
30 #include <gtk/gtkmain.h>
31 #include <gtk/gtksignal.h>
32 #include <gtk/gtklist.h>
33
34 enum {
35   SELECTION_CHANGED,
36   SELECT_CHILD,
37   UNSELECT_CHILD,
38   LAST_SIGNAL
39 };
40
41 static void gtk_tree2_class_init      (GtkTree2Class   *klass);
42 static void gtk_tree2_init            (GtkTree2        *tree);
43 static void gtk_tree2_destroy         (GtkObject      *object);
44 static void gtk_tree2_map             (GtkWidget      *widget);
45 static void gtk_tree2_unmap           (GtkWidget      *widget);
46 static void gtk_tree2_realize         (GtkWidget      *widget);
47 static void gtk_tree2_draw            (GtkWidget      *widget,
48                                       GdkRectangle   *area);
49 static gint gtk_tree2_expose          (GtkWidget      *widget,
50                                       GdkEventExpose *event);
51 static gint gtk_tree2_motion_notify   (GtkWidget      *widget,
52                                       GdkEventMotion *event);
53 static gint gtk_tree2_button_press    (GtkWidget      *widget,
54                                       GdkEventButton *event);
55 static gint gtk_tree2_button_release  (GtkWidget      *widget,
56                                       GdkEventButton *event);
57 static void gtk_tree2_size_request    (GtkWidget      *widget,
58                                       GtkRequisition *requisition);
59 static void gtk_tree2_size_allocate   (GtkWidget      *widget,
60                                       GtkAllocation  *allocation);
61 static void gtk_tree2_add             (GtkContainer   *container,
62                                       GtkWidget      *widget);
63 static void gtk_tree2_forall          (GtkContainer   *container,
64                                       gboolean        include_internals,
65                                       GtkCallback     callback,
66                                       gpointer        callback_data);
67
68 static void gtk_real_tree2_select_child   (GtkTree2       *tree,
69                                           GtkWidget     *child);
70 static void gtk_real_tree2_unselect_child (GtkTree2       *tree,
71                                           GtkWidget     *child);
72
73 static GtkType gtk_tree2_child_type  (GtkContainer   *container);
74
75 static GtkContainerClass *parent_class = NULL;
76 static guint tree_signals[LAST_SIGNAL] = { 0 };
77
78 GtkType
79 gtk_tree2_get_type (void)
80 {
81   static GtkType tree_type = 0;
82   
83   if (!tree_type)
84     {
85       static const GtkTypeInfo tree_info =
86       {
87         "GtkTree2",
88         sizeof (GtkTree2),
89         sizeof (GtkTree2Class),
90         (GtkClassInitFunc) gtk_tree2_class_init,
91         (GtkObjectInitFunc) gtk_tree2_init,
92         /* reserved_1 */ NULL,
93         /* reserved_2 */ NULL,
94         (GtkClassInitFunc) NULL,
95       };
96       
97       tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
98     }
99   
100   return tree_type;
101 }
102
103 static void
104 gtk_tree2_class_init (GtkTree2Class *class)
105 {
106   GtkObjectClass *object_class;
107   GtkWidgetClass *widget_class;
108   GtkContainerClass *container_class;
109   
110   object_class = (GtkObjectClass*) class;
111   widget_class = (GtkWidgetClass*) class;
112   container_class = (GtkContainerClass*) class;
113   
114   parent_class = gtk_type_class (gtk_container_get_type ());
115   
116   tree_signals[SELECTION_CHANGED] =
117     gtk_signal_new ("selection_changed",
118                     GTK_RUN_FIRST,
119                     object_class->type,
120                     GTK_SIGNAL_OFFSET (GtkTree2Class, selection_changed),
121                     gtk_marshal_NONE__NONE,
122                     GTK_TYPE_NONE, 0);
123   tree_signals[SELECT_CHILD] =
124     gtk_signal_new ("select_child",
125                     GTK_RUN_FIRST,
126                     object_class->type,
127                     GTK_SIGNAL_OFFSET (GtkTree2Class, select_child),
128                     gtk_marshal_NONE__POINTER,
129                     GTK_TYPE_NONE, 1,
130                     GTK_TYPE_WIDGET);
131   tree_signals[UNSELECT_CHILD] =
132     gtk_signal_new ("unselect_child",
133                     GTK_RUN_FIRST,
134                     object_class->type,
135                     GTK_SIGNAL_OFFSET (GtkTree2Class, unselect_child),
136                     gtk_marshal_NONE__POINTER,
137                     GTK_TYPE_NONE, 1,
138                     GTK_TYPE_WIDGET);
139   
140   gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL);
141   
142   object_class->destroy = gtk_tree2_destroy;
143   
144   widget_class->map = gtk_tree2_map;
145   widget_class->unmap = gtk_tree2_unmap;
146   widget_class->realize = gtk_tree2_realize;
147   widget_class->draw = gtk_tree2_draw;
148   widget_class->expose_event = gtk_tree2_expose;
149   widget_class->motion_notify_event = gtk_tree2_motion_notify;
150   widget_class->button_press_event = gtk_tree2_button_press;
151   widget_class->button_release_event = gtk_tree2_button_release;
152   widget_class->size_request = gtk_tree2_size_request;
153   widget_class->size_allocate = gtk_tree2_size_allocate;
154   
155   container_class->add = gtk_tree2_add;
156   container_class->remove = 
157     (void (*)(GtkContainer *, GtkWidget *)) gtk_tree2_remove_item;
158   container_class->forall = gtk_tree2_forall;
159   container_class->child_type = gtk_tree2_child_type;
160   
161   class->selection_changed = NULL;
162   class->select_child = gtk_real_tree2_select_child;
163   class->unselect_child = gtk_real_tree2_unselect_child;
164 }
165
166 static GtkType
167 gtk_tree2_child_type (GtkContainer     *container)
168 {
169   return GTK_TYPE_TREE_ITEM2;
170 }
171
172 static void
173 gtk_tree2_init (GtkTree2 *tree)
174 {
175   tree->children = NULL;
176   tree->root_tree = NULL;
177   tree->selection = NULL;
178   tree->tree_owner = NULL;
179   tree->selection_mode = GTK_SELECTION_SINGLE;
180   tree->indent_value = 9;
181   tree->current_indent = 0;
182   tree->level = 0;
183   tree->view_mode = GTK_TREE2_VIEW_LINE;
184   tree->view_line = 1;
185 }
186
187 GtkWidget*
188 gtk_tree2_new (void)
189 {
190   return GTK_WIDGET (gtk_type_new (gtk_tree2_get_type ()));
191 }
192
193 void
194 gtk_tree2_append (GtkTree2   *tree,
195                  GtkWidget *tree_item)
196 {
197   g_return_if_fail (tree != NULL);
198   g_return_if_fail (GTK_IS_TREE2 (tree));
199   g_return_if_fail (tree_item != NULL);
200   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
201   
202   gtk_tree2_insert (tree, tree_item, -1);
203 }
204
205 void
206 gtk_tree2_prepend (GtkTree2   *tree,
207                   GtkWidget *tree_item)
208 {
209   g_return_if_fail (tree != NULL);
210   g_return_if_fail (GTK_IS_TREE2 (tree));
211   g_return_if_fail (tree_item != NULL);
212   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
213   
214   gtk_tree2_insert (tree, tree_item, 0);
215 }
216
217 void
218 gtk_tree2_insert (GtkTree2   *tree,
219                  GtkWidget *tree_item,
220                  gint       position)
221 {
222   gint nchildren;
223   
224   g_return_if_fail (tree != NULL);
225   g_return_if_fail (GTK_IS_TREE2 (tree));
226   g_return_if_fail (tree_item != NULL);
227   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
228   
229   nchildren = g_list_length (tree->children);
230   
231   if ((position < 0) || (position > nchildren))
232     position = nchildren;
233   
234   if (position == nchildren)
235     tree->children = g_list_append (tree->children, tree_item);
236   else
237     tree->children = g_list_insert (tree->children, tree_item, position);
238   
239   gtk_widget_set_parent (tree_item, GTK_WIDGET (tree));
240   
241   if (GTK_WIDGET_REALIZED (tree_item->parent))
242     gtk_widget_realize (tree_item);
243
244   if (GTK_WIDGET_VISIBLE (tree_item->parent) && GTK_WIDGET_VISIBLE (tree_item))
245     {
246       if (GTK_WIDGET_MAPPED (tree_item->parent))
247         gtk_widget_map (tree_item);
248
249       gtk_widget_queue_resize (tree_item);
250     }
251 }
252
253 /* moves the pos child up in the tree */
254 void
255 gtk_tree2_item_up (GtkTree2   *tree,
256                  gint       position)
257 {
258   gint nchildren, i;
259   GList *children, *tmp;
260   
261   g_return_if_fail (tree != NULL);
262   g_return_if_fail (GTK_IS_TREE2 (tree));
263   
264   children = (tree->children);
265   nchildren = g_list_length (tree->children);
266   
267   if ((position < 1) || (position >= nchildren))
268     return;
269   
270   for (i=1; i < position; i++)
271     children = (children->next);
272
273   tmp = children->next;
274   if (position == 1)
275     {
276       tree->children = children->next;
277       children->next->prev = NULL;
278     }
279   else
280     {
281       children->prev->next = children->next;
282       children->next->prev = children->prev;
283     }
284   children->next = tmp->next;
285   children->prev = tmp;
286   if (tmp->next)
287       tmp->next->prev = children;
288   tmp->next = children;
289   
290   if (GTK_WIDGET_VISIBLE (tree))
291     {
292 /*      if (GTK_WIDGET_VISIBLE (GTK_WIDGET(children->data)))
293         gtk_widget_queue_resize (GTK_WIDGET(children->data));
294       if (GTK_WIDGET_VISIBLE (GTK_WIDGET(tmp->data)))
295         gtk_widget_queue_resize (GTK_WIDGET(tmp->data));
296 */
297       gtk_widget_queue_resize (GTK_WIDGET(tree));
298     }
299 }
300
301 static void
302 gtk_tree2_add (GtkContainer *container,
303               GtkWidget    *child)
304 {
305   GtkTree2 *tree;
306   
307   g_return_if_fail (container != NULL);
308   g_return_if_fail (GTK_IS_TREE2 (container));
309   g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
310   
311   tree = GTK_TREE2 (container);
312   
313   tree->children = g_list_append (tree->children, child);
314   
315   gtk_widget_set_parent (child, GTK_WIDGET (container));
316   
317   if (GTK_WIDGET_REALIZED (child->parent))
318     gtk_widget_realize (child);
319
320   if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
321     {
322       if (GTK_WIDGET_MAPPED (child->parent))
323         gtk_widget_map (child);
324
325       gtk_widget_queue_resize (child);
326     }
327   
328   if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE))
329     gtk_tree2_select_child (tree, child);
330 }
331
332 static gint
333 gtk_tree2_button_press (GtkWidget      *widget,
334                        GdkEventButton *event)
335 {
336   GtkTree2 *tree;
337   GtkWidget *item;
338   
339   g_return_val_if_fail (widget != NULL, FALSE);
340   g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
341   g_return_val_if_fail (event != NULL, FALSE);
342   
343   tree = GTK_TREE2 (widget);
344   item = gtk_get_event_widget ((GdkEvent*) event);
345   
346   while (item && !GTK_IS_TREE_ITEM2 (item))
347     item = item->parent;
348   
349   if (!item || (item->parent != widget))
350     return FALSE;
351   
352   switch(event->button) 
353     {
354     case 1:
355       gtk_tree2_select_child (tree, item);
356       break;
357     case 2:
358       if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_expand(GTK_TREE_ITEM2(item));
359       break;
360     case 3:
361       if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_collapse(GTK_TREE_ITEM2(item));
362       break;
363     }
364   
365   return TRUE;
366 }
367
368 static gint
369 gtk_tree2_button_release (GtkWidget      *widget,
370                          GdkEventButton *event)
371 {
372   GtkTree2 *tree;
373   GtkWidget *item;
374   
375   g_return_val_if_fail (widget != NULL, FALSE);
376   g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
377   g_return_val_if_fail (event != NULL, FALSE);
378   
379   tree = GTK_TREE2 (widget);
380   item = gtk_get_event_widget ((GdkEvent*) event);
381   
382   return TRUE;
383 }
384
385 gint
386 gtk_tree2_child_position (GtkTree2   *tree,
387                          GtkWidget *child)
388 {
389   GList *children;
390   gint pos;
391   
392   
393   g_return_val_if_fail (tree != NULL, -1);
394   g_return_val_if_fail (GTK_IS_TREE2 (tree), -1);
395   g_return_val_if_fail (child != NULL, -1);
396   
397   pos = 0;
398   children = tree->children;
399   
400   while (children)
401     {
402       if (child == GTK_WIDGET (children->data)) 
403         return pos;
404       
405       pos += 1;
406       children = children->next;
407     }
408   
409   
410   return -1;
411 }
412
413 void
414 gtk_tree2_clear_items (GtkTree2 *tree,
415                       gint     start,
416                       gint     end)
417 {
418   GtkWidget *widget;
419   GList *clear_list;
420   GList *tmp_list;
421   guint nchildren;
422   guint index;
423   
424   g_return_if_fail (tree != NULL);
425   g_return_if_fail (GTK_IS_TREE2 (tree));
426   
427   nchildren = g_list_length (tree->children);
428   
429   if (nchildren > 0)
430     {
431       if ((end < 0) || (end > nchildren))
432         end = nchildren;
433       
434       if (start >= end)
435         return;
436       
437       tmp_list = g_list_nth (tree->children, start);
438       clear_list = NULL;
439       index = start;
440       while (tmp_list && index <= end)
441         {
442           widget = tmp_list->data;
443           tmp_list = tmp_list->next;
444           index++;
445           
446           clear_list = g_list_prepend (clear_list, widget);
447         }
448       
449       gtk_tree2_remove_items (tree, clear_list);
450     }
451 }
452
453 static void
454 gtk_tree2_destroy (GtkObject *object)
455 {
456   GtkTree2 *tree;
457   GtkWidget *child;
458   GList *children;
459   
460   g_return_if_fail (object != NULL);
461   g_return_if_fail (GTK_IS_TREE2 (object));
462   
463   tree = GTK_TREE2 (object);
464   
465   children = tree->children;
466   while (children)
467     {
468       child = children->data;
469       children = children->next;
470       
471       gtk_widget_ref (child);
472       gtk_widget_unparent (child);
473       gtk_widget_destroy (child);
474       gtk_widget_unref (child);
475     }
476   
477   g_list_free (tree->children);
478   tree->children = NULL;
479   
480   if (tree->root_tree == tree)
481     {
482       GList *node;
483       for (node = tree->selection; node; node = node->next)
484         gtk_widget_unref ((GtkWidget *)node->data);
485       g_list_free (tree->selection);
486       tree->selection = NULL;
487     }
488   
489   if (GTK_OBJECT_CLASS (parent_class)->destroy)
490     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
491 }
492
493 static void
494 gtk_tree2_draw (GtkWidget    *widget,
495                GdkRectangle *area)
496 {
497   GtkTree2 *tree;
498   GtkWidget *subtree;
499   GtkWidget *child;
500   GdkRectangle child_area;
501   GList *children;
502   
503   
504   g_return_if_fail (widget != NULL);
505   g_return_if_fail (GTK_IS_TREE2 (widget));
506   g_return_if_fail (area != NULL);
507   
508   if (GTK_WIDGET_DRAWABLE (widget))
509     {
510       tree = GTK_TREE2 (widget);
511       
512       children = tree->children;
513       while (children)
514         {
515           child = children->data;
516           children = children->next;
517           
518           if (gtk_widget_intersect (child, area, &child_area))
519             gtk_widget_draw (child, &child_area);
520           
521           if((subtree = GTK_TREE_ITEM2(child)->subtree) &&
522              GTK_WIDGET_VISIBLE(subtree) &&
523              gtk_widget_intersect (subtree, area, &child_area))
524             gtk_widget_draw (subtree, &child_area);
525         }
526     }
527   
528 }
529
530 static gint
531 gtk_tree2_expose (GtkWidget      *widget,
532                  GdkEventExpose *event)
533 {
534   GtkTree2 *tree;
535   GtkWidget *child;
536   GdkEventExpose child_event;
537   GList *children;
538   
539   
540   g_return_val_if_fail (widget != NULL, FALSE);
541   g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
542   g_return_val_if_fail (event != NULL, FALSE);
543   
544   if (GTK_WIDGET_DRAWABLE (widget))
545     {
546       tree = GTK_TREE2 (widget);
547       
548       child_event = *event;
549       
550       children = tree->children;
551       while (children)
552         {
553           child = children->data;
554           children = children->next;
555           
556           if (GTK_WIDGET_NO_WINDOW (child) &&
557               gtk_widget_intersect (child, &event->area, &child_event.area))
558             gtk_widget_event (child, (GdkEvent*) &child_event);
559         }
560     }
561   
562   
563   return FALSE;
564 }
565
566 static void
567 gtk_tree2_forall (GtkContainer *container,
568                  gboolean      include_internals,
569                  GtkCallback   callback,
570                  gpointer      callback_data)
571 {
572   GtkTree2 *tree;
573   GtkWidget *child;
574   GList *children;
575   
576   
577   g_return_if_fail (container != NULL);
578   g_return_if_fail (GTK_IS_TREE2 (container));
579   g_return_if_fail (callback != NULL);
580   
581   tree = GTK_TREE2 (container);
582   children = tree->children;
583   
584   while (children)
585     {
586       child = children->data;
587       children = children->next;
588
589       (* callback) (child, callback_data);
590
591       if (include_internals && GTK_TREE_ITEM2(child)->subtree)
592       (* callback) (GTK_TREE_ITEM2(child)->subtree, callback_data);
593     }
594 }
595
596 static void
597 gtk_tree2_map (GtkWidget *widget)
598 {
599   GtkTree2 *tree;
600   GtkWidget *child;
601   GList *children;
602   
603   
604   g_return_if_fail (widget != NULL);
605   g_return_if_fail (GTK_IS_TREE2 (widget));
606   
607   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
608   tree = GTK_TREE2 (widget);
609   
610   if(GTK_IS_TREE2(widget->parent)) 
611     {
612       /* set root tree for this tree */
613       tree->root_tree = GTK_TREE2(widget->parent)->root_tree;
614       
615       tree->level = GTK_TREE2(GTK_WIDGET(tree)->parent)->level+1;
616       tree->indent_value = GTK_TREE2(GTK_WIDGET(tree)->parent)->indent_value;
617       tree->current_indent = GTK_TREE2(GTK_WIDGET(tree)->parent)->current_indent + 
618         tree->indent_value;
619       tree->view_mode = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_mode;
620       tree->view_line = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_line;
621     } 
622   else
623     tree->root_tree = tree;
624   
625   children = tree->children;
626   while (children)
627     {
628       child = children->data;
629       children = children->next;
630       
631       if (GTK_WIDGET_VISIBLE (child) &&
632           !GTK_WIDGET_MAPPED (child))
633         gtk_widget_map (child);
634       
635       if (GTK_TREE_ITEM2 (child)->subtree)
636         {
637           child = GTK_WIDGET (GTK_TREE_ITEM2 (child)->subtree);
638           
639           if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
640             gtk_widget_map (child);
641         }
642     }
643
644   gdk_window_show (widget->window);
645 }
646
647 static gint
648 gtk_tree2_motion_notify (GtkWidget      *widget,
649                         GdkEventMotion *event)
650 {
651   g_return_val_if_fail (widget != NULL, FALSE);
652   g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE);
653   g_return_val_if_fail (event != NULL, FALSE);
654   
655 #ifdef TREE_DEBUG
656   g_message("gtk_tree2_motion_notify\n");
657 #endif /* TREE_DEBUG */
658   
659   return FALSE;
660 }
661
662 static void
663 gtk_tree2_realize (GtkWidget *widget)
664 {
665   GdkWindowAttr attributes;
666   gint attributes_mask;
667   
668   
669   g_return_if_fail (widget != NULL);
670   g_return_if_fail (GTK_IS_TREE2 (widget));
671   
672   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
673   
674   attributes.window_type = GDK_WINDOW_CHILD;
675   attributes.x = widget->allocation.x;
676   attributes.y = widget->allocation.y;
677   attributes.width = widget->allocation.width;
678   attributes.height = widget->allocation.height;
679   attributes.wclass = GDK_INPUT_OUTPUT;
680   attributes.visual = gtk_widget_get_visual (widget);
681   attributes.colormap = gtk_widget_get_colormap (widget);
682   attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
683   
684   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
685   
686   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
687   gdk_window_set_user_data (widget->window, widget);
688   
689   widget->style = gtk_style_attach (widget->style, widget->window);
690   gdk_window_set_background (widget->window, 
691                              &widget->style->base[GTK_STATE_NORMAL]);
692 }
693
694 void
695 gtk_tree2_remove_item (GtkTree2      *container,
696                       GtkWidget    *widget)
697 {
698   GList *item_list;
699   
700   g_return_if_fail (container != NULL);
701   g_return_if_fail (GTK_IS_TREE2 (container));
702   g_return_if_fail (widget != NULL);
703   g_return_if_fail (container == GTK_TREE2 (widget->parent));
704   
705   item_list = g_list_append (NULL, widget);
706   
707   gtk_tree2_remove_items (GTK_TREE2 (container), item_list);
708   
709   g_list_free (item_list);
710 }
711
712 /* used by gtk_tree2_remove_items to make the function independant of
713    order in list of items to remove.
714    Sort item bu depth in tree */
715 static gint 
716 gtk_tree2_sort_item_by_depth(GtkWidget* a, GtkWidget* b)
717 {
718   if((GTK_TREE2(a->parent)->level) < (GTK_TREE2(b->parent)->level))
719     return 1;
720   if((GTK_TREE2(a->parent)->level) > (GTK_TREE2(b->parent)->level))
721     return -1;
722   
723   return 0;
724 }
725
726 void
727 gtk_tree2_remove_items (GtkTree2 *tree,
728                        GList   *items)
729 {
730   GtkWidget *widget;
731   GList *selected_widgets;
732   GList *tmp_list;
733   GList *sorted_list;
734   GtkTree2 *real_tree;
735   GtkTree2 *root_tree;
736   
737   g_return_if_fail (tree != NULL);
738   g_return_if_fail (GTK_IS_TREE2 (tree));
739   
740 #ifdef TREE_DEBUG
741   g_message("+ gtk_tree2_remove_items [ tree %#x items list %#x ]\n", (int)tree, (int)items);
742 #endif /* TREE_DEBUG */
743   
744   /* We may not yet be mapped, so we actively have to find our
745    * root tree
746    */
747   if (tree->root_tree)
748     root_tree = tree->root_tree;
749   else
750     {
751       GtkWidget *tmp = GTK_WIDGET (tree);
752       while (tmp->parent && GTK_IS_TREE2 (tmp->parent))
753         tmp = tmp->parent;
754       
755       root_tree = GTK_TREE2 (tmp);
756     }
757   
758   tmp_list = items;
759   selected_widgets = NULL;
760   sorted_list = NULL;
761   widget = NULL;
762   
763 #ifdef TREE_DEBUG
764   g_message("* sort list by depth\n");
765 #endif /* TREE_DEBUG */
766   
767   while (tmp_list)
768     {
769       
770 #ifdef TREE_DEBUG
771       g_message ("* item [%#x] depth [%d]\n", 
772                  (int)tmp_list->data,
773                  (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level);
774 #endif /* TREE_DEBUG */
775       
776       sorted_list = g_list_insert_sorted(sorted_list,
777                                          tmp_list->data,
778                                          (GCompareFunc)gtk_tree2_sort_item_by_depth);
779       tmp_list = g_list_next(tmp_list);
780     }
781   
782 #ifdef TREE_DEBUG
783   /* print sorted list */
784   g_message("* sorted list result\n");
785   tmp_list = sorted_list;
786   while(tmp_list)
787     {
788       g_message("* item [%#x] depth [%d]\n", 
789                 (int)tmp_list->data,
790                 (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level);
791       tmp_list = g_list_next(tmp_list);
792     }
793 #endif /* TREE_DEBUG */
794   
795 #ifdef TREE_DEBUG
796   g_message("* scan sorted list\n");
797 #endif /* TREE_DEBUG */
798   
799   tmp_list = sorted_list;
800   while (tmp_list)
801     {
802       widget = tmp_list->data;
803       tmp_list = tmp_list->next;
804       
805 #ifdef TREE_DEBUG
806       g_message("* item [%#x] subtree [%#x]\n", 
807                 (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget));
808 #endif /* TREE_DEBUG */
809       
810       /* get real owner of this widget */
811       real_tree = GTK_TREE2(widget->parent);
812 #ifdef TREE_DEBUG
813       g_message("* subtree having this widget [%#x]\n", (int)real_tree);
814 #endif /* TREE_DEBUG */
815       
816       
817       if (widget->state == GTK_STATE_SELECTED)
818         {
819           selected_widgets = g_list_prepend (selected_widgets, widget);
820 #ifdef TREE_DEBUG
821           g_message("* selected widget - adding it in selected list [%#x]\n",
822                     (int)selected_widgets);
823 #endif /* TREE_DEBUG */
824         }
825       
826       /* remove this item from its real parent */
827 #ifdef TREE_DEBUG
828       g_message("* remove widget from its owner tree\n");
829 #endif /* TREE_DEBUG */
830       real_tree->children = g_list_remove (real_tree->children, widget);
831       
832       /* remove subtree associate at this item if it exist */      
833       if(GTK_TREE_ITEM2(widget)->subtree) 
834         {
835 #ifdef TREE_DEBUG
836           g_message("* remove subtree associate at this item [%#x]\n",
837                     (int) GTK_TREE_ITEM2(widget)->subtree);
838 #endif /* TREE_DEBUG */
839           if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM2(widget)->subtree))
840             gtk_widget_unmap (GTK_TREE_ITEM2(widget)->subtree);
841           
842           gtk_widget_unparent (GTK_TREE_ITEM2(widget)->subtree);
843           GTK_TREE_ITEM2(widget)->subtree = NULL;
844         }
845       
846       /* really remove widget for this item */
847 #ifdef TREE_DEBUG
848       g_message("* unmap and unparent widget [%#x]\n", (int)widget);
849 #endif /* TREE_DEBUG */
850       if (GTK_WIDGET_MAPPED (widget))
851         gtk_widget_unmap (widget);
852       
853       gtk_widget_unparent (widget);
854       
855       /* delete subtree if there is no children in it */
856 /* HF supprime */
857 /*       if(real_tree->children == NULL && 
858          real_tree != root_tree)
859         {
860 */
861 #ifdef TREE_DEBUG
862           g_message("* owner tree don't have children ... destroy it\n");
863 #endif /* TREE_DEBUG */
864 /*
865           gtk_tree_item2_remove_subtree(GTK_TREE_ITEM2(real_tree->tree_owner));
866         }
867 */      
868 #ifdef TREE_DEBUG
869       g_message("* next item in list\n");
870 #endif /* TREE_DEBUG */
871     }
872   
873   if (selected_widgets)
874     {
875 #ifdef TREE_DEBUG
876       g_message("* scan selected item list\n");
877 #endif /* TREE_DEBUG */
878       tmp_list = selected_widgets;
879       while (tmp_list)
880         {
881           widget = tmp_list->data;
882           tmp_list = tmp_list->next;
883           
884 #ifdef TREE_DEBUG
885           g_message("* widget [%#x] subtree [%#x]\n", 
886                     (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget));
887 #endif /* TREE_DEBUG */
888           
889           /* remove widget of selection */
890           root_tree->selection = g_list_remove (root_tree->selection, widget);
891           
892           /* unref it to authorize is destruction */
893           gtk_widget_unref (widget);
894         }
895       
896       /* emit only one selection_changed signal */
897       gtk_signal_emit (GTK_OBJECT (root_tree), 
898                        tree_signals[SELECTION_CHANGED]);
899     }
900   
901 #ifdef TREE_DEBUG
902   g_message("* free selected_widgets list\n");
903 #endif /* TREE_DEBUG */
904   g_list_free (selected_widgets);
905   g_list_free (sorted_list);
906   
907   if (root_tree->children && !root_tree->selection &&
908       (root_tree->selection_mode == GTK_SELECTION_BROWSE))
909     {
910 #ifdef TREE_DEBUG
911       g_message("* BROWSE mode, select another item\n");
912 #endif /* TREE_DEBUG */
913       widget = root_tree->children->data;
914       gtk_tree2_select_child (root_tree, widget);
915     }
916   
917   if (GTK_WIDGET_VISIBLE (root_tree))
918     {
919 #ifdef TREE_DEBUG
920       g_message("* query queue resizing for root_tree\n");
921 #endif /* TREE_DEBUG */      
922       gtk_widget_queue_resize (GTK_WIDGET (root_tree));
923     }
924 }
925
926 void
927 gtk_tree2_select_child (GtkTree2   *tree,
928                        GtkWidget *tree_item)
929 {
930   g_return_if_fail (tree != NULL);
931   g_return_if_fail (GTK_IS_TREE2 (tree));
932   g_return_if_fail (tree_item != NULL);
933   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
934   
935   gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], tree_item);
936 }
937
938 void
939 gtk_tree2_select_next_child (GtkTree2   *tree,
940                        GtkWidget *tree_item, gboolean descend)
941 {
942   GList *children;
943
944   g_return_if_fail (tree != NULL);
945   g_return_if_fail (GTK_IS_TREE2 (tree));
946   g_return_if_fail (tree_item != NULL);
947   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
948   
949   if (descend && GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children)
950     {
951       gtk_signal_emit (GTK_OBJECT (GTK_TREE_ITEM2(tree_item)->subtree), tree_signals[SELECT_CHILD], GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children->data);
952       return;
953     }
954
955   children = tree->children;
956   while (children)
957     {
958       if (tree_item == GTK_WIDGET (children->data)) 
959         break;
960       
961       children = children->next;
962     }
963   if (!children) return;
964   
965   if (children->next)
966     gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], children->next->data);
967   else if (tree != tree->root_tree)
968     {
969       children = GTK_TREE2(GTK_WIDGET(tree)->parent)->children;
970         gtk_tree2_select_next_child (GTK_TREE2(GTK_WIDGET(tree)->parent), tree->tree_owner, FALSE);
971     }
972
973 }
974
975 /* we know that tree is not the roor_tree and that
976    tree_items always have subtrees */
977 void
978 gtk_tree2_select_prev_child (GtkTree2   *tree,
979                        GtkWidget *tree_item)
980 {
981   GList *children;
982   GtkTreeItem2 *tree_item2;
983
984   g_return_if_fail (tree != NULL);
985   g_return_if_fail (GTK_IS_TREE2 (tree));
986   g_return_if_fail (tree_item != NULL);
987   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
988   
989
990   children = tree->children;
991   while (children)
992     {
993       if (tree_item == GTK_WIDGET (children->data)) 
994         break;
995       
996       children = children->next;
997     }
998   if (!children) return;
999   
1000   if (children = children->prev)
1001     {
1002       tree_item2 = GTK_TREE_ITEM2(children->data);
1003       while (GTK_TREE2(tree_item2->subtree)->children)
1004         {
1005           children = GTK_TREE2(tree_item2->subtree)->children;
1006           while (children->next)
1007             children = children->next;
1008           tree_item2 = GTK_TREE_ITEM2(children->data);
1009         }
1010     gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree_item2)->parent), tree_signals[SELECT_CHILD], tree_item2);
1011     }
1012   else
1013     {
1014       gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree)->parent), tree_signals[SELECT_CHILD], tree->tree_owner);
1015     }
1016
1017 }
1018
1019 void
1020 gtk_tree2_select_item (GtkTree2   *tree,
1021                       gint       item)
1022 {
1023   GList *tmp_list;
1024   
1025   g_return_if_fail (tree != NULL);
1026   g_return_if_fail (GTK_IS_TREE2 (tree));
1027   
1028   tmp_list = g_list_nth (tree->children, item);
1029   if (tmp_list)
1030     gtk_tree2_select_child (tree, GTK_WIDGET (tmp_list->data));
1031   
1032 }
1033
1034 static void
1035 gtk_tree2_size_allocate (GtkWidget     *widget,
1036                         GtkAllocation *allocation)
1037 {
1038   GtkTree2 *tree;
1039   GtkWidget *child, *subtree;
1040   GtkAllocation child_allocation;
1041   GList *children;
1042   
1043   
1044   g_return_if_fail (widget != NULL);
1045   g_return_if_fail (GTK_IS_TREE2 (widget));
1046   g_return_if_fail (allocation != NULL);
1047   
1048   tree = GTK_TREE2 (widget);
1049   
1050   widget->allocation = *allocation;
1051   if (GTK_WIDGET_REALIZED (widget))
1052     gdk_window_move_resize (widget->window,
1053                             allocation->x, allocation->y,
1054                             allocation->width, allocation->height);
1055   
1056   if (tree->children)
1057     {
1058       child_allocation.x = GTK_CONTAINER (tree)->border_width;
1059       child_allocation.y = GTK_CONTAINER (tree)->border_width;
1060       child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2);
1061       
1062       children = tree->children;
1063       
1064       while (children)
1065         {
1066           child = children->data;
1067           children = children->next;
1068           
1069           if (GTK_WIDGET_VISIBLE (child))
1070             {
1071               GtkRequisition child_requisition;
1072               gtk_widget_get_child_requisition (child, &child_requisition);
1073               
1074               child_allocation.height = child_requisition.height;
1075               
1076               gtk_widget_size_allocate (child, &child_allocation);
1077               
1078               child_allocation.y += child_allocation.height;
1079               
1080               if((subtree = GTK_TREE_ITEM2(child)->subtree))
1081                 if(GTK_WIDGET_VISIBLE (subtree))
1082                   {
1083                     child_allocation.height = subtree->requisition.height;
1084                     gtk_widget_size_allocate (subtree, &child_allocation);
1085                     child_allocation.y += child_allocation.height;
1086                   }
1087             }
1088         }
1089     }
1090   
1091 }
1092
1093 static void
1094 gtk_tree2_size_request (GtkWidget      *widget,
1095                        GtkRequisition *requisition)
1096 {
1097   GtkTree2 *tree;
1098   GtkWidget *child, *subtree;
1099   GList *children;
1100   GtkRequisition child_requisition;
1101   
1102   
1103   g_return_if_fail (widget != NULL);
1104   g_return_if_fail (GTK_IS_TREE2 (widget));
1105   g_return_if_fail (requisition != NULL);
1106   
1107   tree = GTK_TREE2 (widget);
1108   requisition->width = 0;
1109   requisition->height = 0;
1110   
1111   children = tree->children;
1112   while (children)
1113     {
1114       child = children->data;
1115       children = children->next;
1116       
1117       if (GTK_WIDGET_VISIBLE (child))
1118         {
1119           gtk_widget_size_request (child, &child_requisition);
1120           
1121           requisition->width = MAX (requisition->width, child_requisition.width);
1122           requisition->height += child_requisition.height;
1123           
1124           if((subtree = GTK_TREE_ITEM2(child)->subtree) &&
1125              GTK_WIDGET_VISIBLE (subtree))
1126             {
1127               gtk_widget_size_request (subtree, &child_requisition);
1128               
1129               requisition->width = MAX (requisition->width, 
1130                                         child_requisition.width);
1131               
1132               requisition->height += child_requisition.height;
1133             }
1134         }
1135     }
1136   
1137   requisition->width += GTK_CONTAINER (tree)->border_width * 2;
1138   requisition->height += GTK_CONTAINER (tree)->border_width * 2;
1139   
1140   requisition->width = MAX (requisition->width, 1);
1141   requisition->height = MAX (requisition->height, 1);
1142   
1143 }
1144
1145 static void
1146 gtk_tree2_unmap (GtkWidget *widget)
1147 {
1148   
1149   g_return_if_fail (widget != NULL);
1150   g_return_if_fail (GTK_IS_TREE2 (widget));
1151   
1152   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1153   gdk_window_hide (widget->window);
1154   
1155 }
1156
1157 void
1158 gtk_tree2_unselect_child (GtkTree2   *tree,
1159                          GtkWidget *tree_item)
1160 {
1161   g_return_if_fail (tree != NULL);
1162   g_return_if_fail (GTK_IS_TREE2 (tree));
1163   g_return_if_fail (tree_item != NULL);
1164   g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item));
1165   
1166   gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], tree_item);
1167 }
1168
1169 void
1170 gtk_tree2_unselect_item (GtkTree2 *tree,
1171                         gint     item)
1172 {
1173   GList *tmp_list;
1174   
1175   g_return_if_fail (tree != NULL);
1176   g_return_if_fail (GTK_IS_TREE2 (tree));
1177   
1178   tmp_list = g_list_nth (tree->children, item);
1179   if (tmp_list)
1180     gtk_tree2_unselect_child (tree, GTK_WIDGET (tmp_list->data));
1181   
1182 }
1183
1184 static void
1185 gtk_real_tree2_select_child (GtkTree2   *tree,
1186                             GtkWidget *child)
1187 {
1188   GList *selection, *root_selection;
1189   GList *tmp_list;
1190   GtkWidget *tmp_item;
1191   
1192   g_return_if_fail (tree != NULL);
1193   g_return_if_fail (GTK_IS_TREE2 (tree));
1194   g_return_if_fail (child != NULL);
1195   g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
1196   
1197   root_selection = tree->root_tree->selection;
1198   
1199   switch (tree->root_tree->selection_mode)
1200     {
1201     case GTK_SELECTION_SINGLE:
1202       
1203       selection = root_selection;
1204       
1205       /* remove old selection list */
1206       while (selection)
1207         {
1208           tmp_item = selection->data;
1209           
1210           if (tmp_item != child)
1211             {
1212               gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item));
1213               
1214               tmp_list = selection;
1215               selection = selection->next;
1216               
1217               root_selection = g_list_remove_link (root_selection, tmp_list);
1218               gtk_widget_unref (tmp_item);
1219               
1220               g_list_free (tmp_list);
1221             }
1222           else
1223             selection = selection->next;
1224         }
1225       
1226       if (child->state == GTK_STATE_NORMAL)
1227         {
1228           gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1229           root_selection = g_list_prepend (root_selection, child);
1230           gtk_widget_ref (child);
1231         }
1232       else if (child->state == GTK_STATE_SELECTED)
1233         {
1234           gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1235           root_selection = g_list_remove (root_selection, child);
1236           gtk_widget_unref (child);
1237         }
1238       
1239       tree->root_tree->selection = root_selection;
1240       
1241       gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1242                        tree_signals[SELECTION_CHANGED]);
1243       break;
1244       
1245       
1246     case GTK_SELECTION_BROWSE:
1247       selection = root_selection;
1248       
1249       while (selection)
1250         {
1251           tmp_item = selection->data;
1252           
1253           if (tmp_item != child)
1254             {
1255               gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item));
1256               
1257               tmp_list = selection;
1258               selection = selection->next;
1259               
1260               root_selection = g_list_remove_link (root_selection, tmp_list);
1261               gtk_widget_unref (tmp_item);
1262               
1263               g_list_free (tmp_list);
1264             }
1265           else
1266             selection = selection->next;
1267         }
1268       
1269       tree->root_tree->selection = root_selection;
1270       
1271       if (child->state == GTK_STATE_NORMAL)
1272         {
1273           gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1274           root_selection = g_list_prepend (root_selection, child);
1275           gtk_widget_ref (child);
1276           tree->root_tree->selection = root_selection;
1277           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1278                            tree_signals[SELECTION_CHANGED]);
1279         }
1280       break;
1281       
1282     case GTK_SELECTION_MULTIPLE:
1283       if (child->state == GTK_STATE_NORMAL)
1284         {
1285           gtk_tree_item2_select (GTK_TREE_ITEM2 (child));
1286           root_selection = g_list_prepend (root_selection, child);
1287           gtk_widget_ref (child);
1288           tree->root_tree->selection = root_selection;
1289           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1290                            tree_signals[SELECTION_CHANGED]);
1291         }
1292       else if (child->state == GTK_STATE_SELECTED)
1293         {
1294           gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1295           root_selection = g_list_remove (root_selection, child);
1296           gtk_widget_unref (child);
1297           tree->root_tree->selection = root_selection;
1298           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1299                            tree_signals[SELECTION_CHANGED]);
1300         }
1301       break;
1302       
1303     case GTK_SELECTION_EXTENDED:
1304       break;
1305     }
1306 }
1307
1308 static void
1309 gtk_real_tree2_unselect_child (GtkTree2   *tree,
1310                               GtkWidget *child)
1311 {
1312   g_return_if_fail (tree != NULL);
1313   g_return_if_fail (GTK_IS_TREE2 (tree));
1314   g_return_if_fail (child != NULL);
1315   g_return_if_fail (GTK_IS_TREE_ITEM2 (child));
1316   
1317   switch (tree->selection_mode)
1318     {
1319     case GTK_SELECTION_SINGLE:
1320     case GTK_SELECTION_MULTIPLE:
1321     case GTK_SELECTION_BROWSE:
1322       if (child->state == GTK_STATE_SELECTED)
1323         {
1324           GtkTree2* root_tree = GTK_TREE2_ROOT_TREE(tree);
1325           gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child));
1326           root_tree->selection = g_list_remove (root_tree->selection, child);
1327           gtk_widget_unref (child);
1328           gtk_signal_emit (GTK_OBJECT (tree->root_tree), 
1329                            tree_signals[SELECTION_CHANGED]);
1330         }
1331       break;
1332       
1333     case GTK_SELECTION_EXTENDED:
1334       break;
1335     }
1336 }
1337
1338 void
1339 gtk_tree2_set_selection_mode (GtkTree2       *tree,
1340                              GtkSelectionMode mode) 
1341 {
1342   g_return_if_fail (tree != NULL);
1343   g_return_if_fail (GTK_IS_TREE2 (tree));
1344   
1345   tree->selection_mode = mode;
1346 }
1347
1348 void
1349 gtk_tree2_set_view_mode (GtkTree2       *tree,
1350                         GtkTree2ViewMode mode) 
1351 {
1352   g_return_if_fail (tree != NULL);
1353   g_return_if_fail (GTK_IS_TREE2 (tree));
1354   
1355   tree->view_mode = mode;
1356 }
1357
1358 void
1359 gtk_tree2_set_view_lines (GtkTree2       *tree,
1360                          guint          flag) 
1361 {
1362   g_return_if_fail (tree != NULL);
1363   g_return_if_fail (GTK_IS_TREE2 (tree));
1364   
1365   tree->view_line = flag;
1366 }
1367
1368 void 
1369 gtk_tree2_item_up_1 (GtkTree2       *tree,
1370                    guint pos)
1371 {
1372   GList *tmp;
1373   guint length;
1374   gpointer data;
1375
1376   g_return_if_fail (tree != NULL);
1377   g_return_if_fail (GTK_IS_TREE2 (tree));
1378   
1379   tmp = tree->children;
1380   length = g_list_length (tmp);
1381   if (pos <= 0 || pos >= length) { return; }
1382   data = g_list_nth_data (tree->children, pos);
1383   g_list_remove (tree->children, data);
1384   tree->children = g_list_insert (tree->children, data, pos-1);
1385 }