]> Pileus Git - ~andy/gtk/blob - gtk/gtktreeselection.c
initialize anchor_path to NULL.
[~andy/gtk] / gtk / gtktreeselection.c
1 /* gtktreeselection.h
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
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 #include "gtktreeselection.h"
21 #include "gtktreeprivate.h"
22 #include "gtkrbtree.h"
23 #include "gtkmarshalers.h"
24
25 static void gtk_tree_selection_init              (GtkTreeSelection      *selection);
26 static void gtk_tree_selection_class_init        (GtkTreeSelectionClass *class);
27
28 static void gtk_tree_selection_finalize          (GObject               *object);
29 static gint gtk_tree_selection_real_select_all   (GtkTreeSelection      *selection);
30 static gint gtk_tree_selection_real_unselect_all (GtkTreeSelection      *selection);
31 static gint gtk_tree_selection_real_select_node  (GtkTreeSelection      *selection,
32                                                   GtkRBTree             *tree,
33                                                   GtkRBNode             *node,
34                                                   gboolean               select);
35
36 enum
37 {
38   CHANGED,
39   LAST_SIGNAL
40 };
41
42 static GObjectClass *parent_class = NULL;
43 static guint tree_selection_signals [LAST_SIGNAL] = { 0 };
44
45 GType
46 gtk_tree_selection_get_type (void)
47 {
48   static GType selection_type = 0;
49
50   if (!selection_type)
51     {
52       static const GTypeInfo selection_info =
53       {
54         sizeof (GtkTreeSelectionClass),
55         NULL,           /* base_init */
56         NULL,           /* base_finalize */
57         (GClassInitFunc) gtk_tree_selection_class_init,
58         NULL,           /* class_finalize */
59         NULL,           /* class_data */
60         sizeof (GtkTreeSelection),
61         0,              /* n_preallocs */
62         (GInstanceInitFunc) gtk_tree_selection_init
63       };
64
65       selection_type =
66         g_type_register_static (G_TYPE_OBJECT, "GtkTreeSelection",
67                                 &selection_info, 0);
68     }
69
70   return selection_type;
71 }
72
73 static void
74 gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
75 {
76   GObjectClass *object_class;
77
78   object_class = (GObjectClass*) class;
79   parent_class = g_type_class_peek_parent (class);
80
81   object_class->finalize = gtk_tree_selection_finalize;
82   class->changed = NULL;
83
84   tree_selection_signals[CHANGED] =
85     g_signal_new ("changed",
86                   G_OBJECT_CLASS_TYPE (object_class),
87                   G_SIGNAL_RUN_FIRST,
88                   G_STRUCT_OFFSET (GtkTreeSelectionClass, changed),
89                   NULL, NULL,
90                   _gtk_marshal_VOID__VOID,
91                   G_TYPE_NONE, 0);
92 }
93
94 static void
95 gtk_tree_selection_init (GtkTreeSelection *selection)
96 {
97   selection->type = GTK_SELECTION_SINGLE;
98 }
99
100 static void
101 gtk_tree_selection_finalize (GObject *object)
102 {
103   GtkTreeSelection *selection = GTK_TREE_SELECTION (object);
104
105   if (selection->destroy)
106     {
107       GtkDestroyNotify d = selection->destroy;
108
109       selection->destroy = NULL;
110       d (selection->user_data);
111     }
112
113   /* chain parent_class' handler */
114   G_OBJECT_CLASS (parent_class)->finalize (object);
115 }
116
117 /**
118  * _gtk_tree_selection_new:
119  *
120  * Creates a new #GtkTreeSelection object.  This function should not be invoked,
121  * as each #GtkTreeView will create it's own #GtkTreeSelection.
122  *
123  * Return value: A newly created #GtkTreeSelection object.
124  **/
125 GtkTreeSelection*
126 _gtk_tree_selection_new (void)
127 {
128   GtkTreeSelection *selection;
129
130   selection = g_object_new (GTK_TYPE_TREE_SELECTION, NULL);
131
132   return selection;
133 }
134
135 /**
136  * _gtk_tree_selection_new_with_tree_view:
137  * @tree_view: The #GtkTreeView.
138  *
139  * Creates a new #GtkTreeSelection object.  This function should not be invoked,
140  * as each #GtkTreeView will create it's own #GtkTreeSelection.
141  *
142  * Return value: A newly created #GtkTreeSelection object.
143  **/
144 GtkTreeSelection*
145 _gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view)
146 {
147   GtkTreeSelection *selection;
148
149   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
150
151   selection = _gtk_tree_selection_new ();
152   _gtk_tree_selection_set_tree_view (selection, tree_view);
153
154   return selection;
155 }
156
157 /**
158  * _gtk_tree_selection_set_tree_view:
159  * @selection: A #GtkTreeSelection.
160  * @tree_view: The #GtkTreeView.
161  *
162  * Sets the #GtkTreeView of @selection.  This function should not be invoked, as
163  * it is used internally by #GtkTreeView.
164  **/
165 void
166 _gtk_tree_selection_set_tree_view (GtkTreeSelection *selection,
167                                    GtkTreeView      *tree_view)
168 {
169   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
170   if (tree_view != NULL)
171     g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
172
173   selection->tree_view = tree_view;
174 }
175
176 /**
177  * gtk_tree_selection_set_mode:
178  * @selection: A #GtkTreeSelection.
179  * @type: The selection mode
180  *
181  * Sets the selection mode of the @selection.  If the previous type was
182  * #GTK_SELECTION_MULTIPLE, then the anchor is kept selected, if it was
183  * previously selected.
184  **/
185 void
186 gtk_tree_selection_set_mode (GtkTreeSelection *selection,
187                              GtkSelectionMode  type)
188 {
189   GtkTreeSelectionFunc tmp_func;
190   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
191
192   if (selection->type == type)
193     return;
194
195   
196   if (type == GTK_SELECTION_NONE)
197     {
198       /* We do this so that we unconditionally unset all rows
199        */
200       tmp_func = selection->user_func;
201       selection->user_func = NULL;
202       gtk_tree_selection_unselect_all (selection);
203       selection->user_func = tmp_func;
204
205       gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
206       selection->tree_view->priv->anchor = NULL;
207     }
208   else if (type == GTK_SELECTION_SINGLE ||
209            type == GTK_SELECTION_BROWSE)
210     {
211       GtkRBTree *tree = NULL;
212       GtkRBNode *node = NULL;
213       gint selected = FALSE;
214       GtkTreePath *anchor_path = NULL;
215
216       if (selection->tree_view->priv->anchor)
217         {
218           anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
219
220           if (anchor_path)
221             {
222               _gtk_tree_view_find_node (selection->tree_view,
223                                         anchor_path,
224                                         &tree,
225                                         &node);
226
227               if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
228                 selected = TRUE;
229             }
230         }
231
232       /* We do this so that we unconditionally unset all rows
233        */
234       tmp_func = selection->user_func;
235       selection->user_func = NULL;
236       gtk_tree_selection_unselect_all (selection);
237       selection->user_func = tmp_func;
238
239       if (node && selected)
240         _gtk_tree_selection_internal_select_node (selection,
241                                                   node,
242                                                   tree,
243                                                   anchor_path,
244                                                   0,
245                                                   FALSE);
246       if (anchor_path)
247         gtk_tree_path_free (anchor_path);
248     }
249
250   selection->type = type;
251 }
252
253 /**
254  * gtk_tree_selection_get_mode:
255  * @selection: a #GtkTreeSelection
256  *
257  * Gets the selection mode for @selection. See
258  * gtk_tree_selection_set_mode().
259  *
260  * Return value: the current selection mode
261  **/
262 GtkSelectionMode
263 gtk_tree_selection_get_mode (GtkTreeSelection *selection)
264 {
265   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), GTK_SELECTION_SINGLE);
266
267   return selection->type;
268 }
269
270 /**
271  * gtk_tree_selection_set_select_function:
272  * @selection: A #GtkTreeSelection.
273  * @func: The selection function.
274  * @data: The selection function's data.
275  * @destroy: The destroy function for user data.  May be NULL.
276  *
277  * Sets the selection function.  If set, this function is called before any node
278  * is selected or unselected, giving some control over which nodes are selected.
279  * The select function should return %TRUE if the state of the node may be toggled,
280  * and %FALSE if the state of the node should be left unchanged.
281  **/
282 void
283 gtk_tree_selection_set_select_function (GtkTreeSelection     *selection,
284                                         GtkTreeSelectionFunc  func,
285                                         gpointer              data,
286                                         GtkDestroyNotify      destroy)
287 {
288   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
289   g_return_if_fail (func != NULL);
290
291   if (selection->destroy)
292     {
293       GtkDestroyNotify d = selection->destroy;
294
295       selection->destroy = NULL;
296       d (selection->user_data);
297     }
298
299   selection->user_func = func;
300   selection->user_data = data;
301   selection->destroy = destroy;
302 }
303
304 /**
305  * gtk_tree_selection_get_user_data:
306  * @selection: A #GtkTreeSelection.
307  *
308  * Returns the user data for the selection function.
309  *
310  * Return value: The user data.
311  **/
312 gpointer
313 gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
314 {
315   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
316
317   return selection->user_data;
318 }
319
320 /**
321  * gtk_tree_selection_get_tree_view:
322  * @selection: A #GtkTreeSelection
323  * 
324  * Returns the tree view associated with @selection.
325  * 
326  * Return value: A #GtkTreeView
327  **/
328 GtkTreeView *
329 gtk_tree_selection_get_tree_view (GtkTreeSelection *selection)
330 {
331   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
332
333   return selection->tree_view;
334 }
335
336 /**
337  * gtk_tree_selection_get_selected:
338  * @selection: A #GtkTreeSelection.
339  * @model: A pointer to set to the #GtkTreeModel, or NULL.
340  * @iter: The #GtkTreeIter, or NULL.
341  *
342  * Sets @iter to the currently selected node if @selection is set to
343  * #GTK_SELECTION_SINGLE or #GTK_SELECTION_BROWSE.  @iter may be NULL if you
344  * just want to test if @selection has any selected nodes.  @model is filled
345  * with the current model as a convenience.  This function will not work if you
346  * use @selection is #GTK_SELECTION_MULTIPLE.
347  *
348  * Return value: TRUE, if there is a selected node.
349  **/
350 gboolean
351 gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
352                                  GtkTreeModel     **model,
353                                  GtkTreeIter       *iter)
354 {
355   GtkRBTree *tree;
356   GtkRBNode *node;
357   GtkTreePath *anchor_path;
358   gboolean retval;
359   gboolean found_node;
360
361   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
362   g_return_val_if_fail (selection->type != GTK_SELECTION_MULTIPLE, FALSE);
363   g_return_val_if_fail (selection->tree_view != NULL, FALSE);
364   g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
365
366   if (model)
367     *model = selection->tree_view->priv->model;
368
369   if (selection->tree_view->priv->anchor == NULL)
370     return FALSE;
371
372   anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
373
374   if (anchor_path == NULL)
375     return FALSE;
376
377   retval = FALSE;
378
379   found_node = !_gtk_tree_view_find_node (selection->tree_view,
380                                           anchor_path,
381                                           &tree,
382                                           &node);
383
384   if (found_node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
385     {
386       /* we only want to return the anchor if it exists in the rbtree and
387        * is selected.
388        */
389       if (iter == NULL)
390         retval = TRUE;
391       else
392         retval = gtk_tree_model_get_iter (selection->tree_view->priv->model,
393                                           iter,
394                                           anchor_path);
395     }
396   else
397     {
398       /* We don't want to return the anchor if it isn't actually selected.
399        */
400       retval = FALSE;
401     }
402
403   gtk_tree_path_free (anchor_path);
404
405   return retval;
406 }
407
408 /**
409  * gtk_tree_selection_get_selected_rows:
410  * @selection: A #GtkTreeSelection.
411  * @model: A pointer to set to the #GtkTreeModel, or NULL.
412  *
413  * Creates a list of path of all selected rows. Additionally, if you are
414  * planning on modifying the model after calling this function, you may
415  * want to convert the returned list into a list of #GtkTreeRowReference<!-- -->s.
416  * To do this, you can use gtk_tree_row_reference_new_proxy().
417  *
418  * To free the return value, use:
419  * <informalexample><programlisting>
420  * g_list_foreach (list, gtk_tree_path_free, NULL);
421  * g_list_free (list);
422  * </programlisting></informalexample>
423  *
424  * Return value: A #GList containing a #GtkTreePath for each selected row.
425  **/
426 GList *
427 gtk_tree_selection_get_selected_rows (GtkTreeSelection   *selection,
428                                       GtkTreeModel      **model)
429 {
430   GList *list = NULL;
431   GtkRBTree *tree = NULL;
432   GtkRBNode *node = NULL;
433   GtkTreePath *path;
434
435   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
436   g_return_val_if_fail (selection->tree_view != NULL, NULL);
437   g_return_val_if_fail (selection->tree_view->priv->model != NULL, NULL);
438
439   if (selection->tree_view->priv->tree == NULL ||
440       selection->tree_view->priv->tree->root == NULL)
441     return NULL;
442
443   if (model)
444     *model = selection->tree_view->priv->model;
445
446   if (selection->type == GTK_SELECTION_NONE)
447     return NULL;
448   else if (selection->type != GTK_SELECTION_MULTIPLE)
449     {
450       GtkTreeIter iter;
451
452       if (gtk_tree_selection_get_selected (selection, NULL, &iter))
453         {
454           GtkTreePath *path;
455
456           path = gtk_tree_model_get_path (*model, &iter);
457           list = g_list_append (list, path);
458
459           return list;
460         }
461
462       return NULL;
463     }
464
465   tree = selection->tree_view->priv->tree;
466   node = selection->tree_view->priv->tree->root;
467
468   while (node->left != tree->nil)
469     node = node->left;
470   path = gtk_tree_path_new_first ();
471
472   do
473     {
474       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
475         list = g_list_append (list, gtk_tree_path_copy (path));
476
477       if (node->children)
478         {
479           tree = node->children;
480           node = tree->root;
481
482           while (node->left != tree->nil)
483             node = node->left;
484
485           gtk_tree_path_append_index (path, 0);
486         }
487       else
488         {
489           gboolean done = FALSE;
490
491           do
492             {
493               node = _gtk_rbtree_next (tree, node);
494               if (node != NULL)
495                 {
496                   done = TRUE;
497                   gtk_tree_path_next (path);
498                 }
499               else
500                 {
501                   node = tree->parent_node;
502                   tree = tree->parent_tree;
503
504                   if (!tree)
505                     {
506                       gtk_tree_path_free (path);
507                       return list;
508                     }
509
510                   gtk_tree_path_up (path);
511                 }
512             }
513           while (!done);
514         }
515     }
516   while (TRUE);
517
518   gtk_tree_path_free (path);
519
520   return list;
521 }
522
523 static void
524 gtk_tree_selection_count_selected_rows_helper (GtkRBTree *tree,
525                                                GtkRBNode *node,
526                                                gpointer   data)
527 {
528   gint *count = (gint *)data;
529
530   if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
531     (*count)++;
532
533   if (node->children)
534     _gtk_rbtree_traverse (node->children, node->children->root,
535                           G_PRE_ORDER,
536                           gtk_tree_selection_count_selected_rows_helper, data);
537 }
538
539 /**
540  * gtk_tree_selection_count_selected_rows:
541  * @selection: A #GtkTreeSelection.
542  *
543  * Returns the number of rows that have been selected in @tree.
544  *
545  * Return value: The number of rows selected.
546  **/
547 gint
548 gtk_tree_selection_count_selected_rows (GtkTreeSelection *selection)
549 {
550   gint count = 0;
551   GtkRBTree *tree;
552   GtkRBNode *node;
553
554   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), 0);
555   g_return_val_if_fail (selection->tree_view != NULL, 0);
556   g_return_val_if_fail (selection->tree_view->priv->model != NULL, 0);
557
558   if (selection->tree_view->priv->tree == NULL ||
559       selection->tree_view->priv->tree->root == NULL)
560     return 0;
561
562   if (selection->type == GTK_SELECTION_SINGLE ||
563       selection->type == GTK_SELECTION_BROWSE)
564     {
565       if (gtk_tree_selection_get_selected (selection, NULL, NULL))
566         return 1;
567       else
568         return 0;
569     }
570
571   tree = selection->tree_view->priv->tree;
572   node = selection->tree_view->priv->tree->root;
573
574   _gtk_rbtree_traverse (selection->tree_view->priv->tree,
575                         selection->tree_view->priv->tree->root,
576                         G_PRE_ORDER,
577                         gtk_tree_selection_count_selected_rows_helper,
578                         &count);
579
580   return count;
581 }
582
583 /* gtk_tree_selection_selected_foreach helper */
584 static void
585 model_changed (gpointer data)
586 {
587   gboolean *stop = (gboolean *)data;
588
589   *stop = TRUE;
590 }
591
592 /**
593  * gtk_tree_selection_selected_foreach:
594  * @selection: A #GtkTreeSelection.
595  * @func: The function to call for each selected node.
596  * @data: user data to pass to the function.
597  *
598  * Calls a function for each selected node. Note that you cannot modify
599  * the tree or selection from within this function. As a result,
600  * gtk_tree_selection_get_selected_rows() might be more useful.
601  **/
602 void
603 gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
604                                      GtkTreeSelectionForeachFunc  func,
605                                      gpointer                     data)
606 {
607   GtkTreePath *path;
608   GtkRBTree *tree;
609   GtkRBNode *node;
610   GtkTreeIter iter;
611
612   guint inserted_id, deleted_id, reordered_id;
613   gboolean stop = FALSE, has_next = TRUE, has_parent = TRUE;
614
615   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
616   g_return_if_fail (selection->tree_view != NULL);
617   g_return_if_fail (selection->tree_view->priv->model != NULL);
618
619   if (func == NULL ||
620       selection->tree_view->priv->tree == NULL ||
621       selection->tree_view->priv->tree->root == NULL)
622     return;
623
624   if (selection->type == GTK_SELECTION_SINGLE ||
625       selection->type == GTK_SELECTION_BROWSE)
626     {
627       if (gtk_tree_row_reference_valid (selection->tree_view->priv->anchor))
628         {
629           path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
630           gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path);
631           (* func) (selection->tree_view->priv->model, path, &iter, data);
632           gtk_tree_path_free (path);
633         }
634       return;
635     }
636
637   tree = selection->tree_view->priv->tree;
638   node = selection->tree_view->priv->tree->root;
639   
640   while (node->left != tree->nil)
641     node = node->left;
642
643   /* connect to signals to monitor changes in treemodel */
644   inserted_id = g_signal_connect_swapped (selection->tree_view->priv->model,
645                                           "row_inserted",
646                                           G_CALLBACK (model_changed),
647                                           &stop);
648   deleted_id = g_signal_connect_swapped (selection->tree_view->priv->model,
649                                          "row_deleted",
650                                          G_CALLBACK (model_changed),
651                                          &stop);
652   reordered_id = g_signal_connect_swapped (selection->tree_view->priv->model,
653                                            "rows_reordered",
654                                            G_CALLBACK (model_changed),
655                                            &stop);
656
657   /* find the node internally */
658   path = gtk_tree_path_new_first ();
659   gtk_tree_model_get_iter (selection->tree_view->priv->model,
660                            &iter, path);
661
662   do
663     {
664       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
665         (* func) (selection->tree_view->priv->model, path, &iter, data);
666
667       if (stop)
668         goto out;
669
670       if (node->children)
671         {
672           gboolean has_child;
673           GtkTreeIter tmp;
674
675           tree = node->children;
676           node = tree->root;
677           while (node->left != tree->nil)
678             node = node->left;
679           tmp = iter;
680           has_child = gtk_tree_model_iter_children (selection->tree_view->priv->model, &iter, &tmp);
681           gtk_tree_path_append_index (path, 0);
682
683           /* we do the sanity check at the bottom of this function */
684           if (!has_child)
685             goto out;
686         }
687       else
688         {
689           gboolean done = FALSE;
690           do
691             {
692               node = _gtk_rbtree_next (tree, node);
693               if (node != NULL)
694                 {
695                   gboolean has_next;
696
697                   has_next = gtk_tree_model_iter_next (selection->tree_view->priv->model, &iter);
698                   done = TRUE;
699                   gtk_tree_path_next (path);
700
701                   /* we do the sanity check at the bottom of this function */
702                   if (!has_next)
703                     goto out;
704                 }
705               else
706                 {
707                   gboolean has_parent;
708                   GtkTreeIter tmp_iter = iter;
709
710                   node = tree->parent_node;
711                   tree = tree->parent_tree;
712                   if (tree == NULL)
713                     {
714                       /* we've run out of tree */
715                       /* We're done with this function */
716
717                       goto out;
718                     }
719
720                   has_parent = gtk_tree_model_iter_parent (selection->tree_view->priv->model, &iter, &tmp_iter);
721                   gtk_tree_path_up (path);
722
723                   /* we do the sanity check at the bottom of this function */
724                   if (!has_parent)
725                     goto out;
726                 }
727             }
728           while (!done);
729         }
730     }
731   while (TRUE);
732
733 out:
734   if (path)
735     gtk_tree_path_free (path);
736
737   g_signal_handler_disconnect (selection->tree_view->priv->model,
738                                inserted_id);
739   g_signal_handler_disconnect (selection->tree_view->priv->model,
740                                deleted_id);
741   g_signal_handler_disconnect (selection->tree_view->priv->model,
742                                reordered_id);
743
744   /* check if we have to spew a scary message */
745   if (!has_next)
746     TREE_VIEW_INTERNAL_ASSERT_VOID (has_next);
747   if (!has_parent)
748     TREE_VIEW_INTERNAL_ASSERT_VOID (has_parent);
749   if (stop)
750     g_warning
751       ("The model has been modified from within gtk_tree_selection_foreach.\n"
752        "This function is for observing the selections of the tree only.  If\n"
753        "you are trying to get all selected items from the tree, try using\n"
754        "gtk_tree_selection_get_selected_rows instead.\n");
755 }
756
757 /**
758  * gtk_tree_selection_select_path:
759  * @selection: A #GtkTreeSelection.
760  * @path: The #GtkTreePath to be selected.
761  *
762  * Select the row at @path.
763  **/
764 void
765 gtk_tree_selection_select_path (GtkTreeSelection *selection,
766                                 GtkTreePath      *path)
767 {
768   GtkRBNode *node;
769   GtkRBTree *tree;
770   GdkModifierType state = 0;
771   gboolean ret;
772
773   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
774   g_return_if_fail (selection->tree_view != NULL);
775   g_return_if_fail (path != NULL);
776
777   ret = _gtk_tree_view_find_node (selection->tree_view,
778                                   path,
779                                   &tree,
780                                   &node);
781
782   if (node == NULL || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
783       ret == TRUE)
784     return;
785
786   if (selection->type == GTK_SELECTION_MULTIPLE)
787     state = GDK_CONTROL_MASK;
788
789   _gtk_tree_selection_internal_select_node (selection,
790                                             node,
791                                             tree,
792                                             path,
793                                             state,
794                                             FALSE);
795 }
796
797 /**
798  * gtk_tree_selection_unselect_path:
799  * @selection: A #GtkTreeSelection.
800  * @path: The #GtkTreePath to be unselected.
801  *
802  * Unselects the row at @path.
803  **/
804 void
805 gtk_tree_selection_unselect_path (GtkTreeSelection *selection,
806                                   GtkTreePath      *path)
807 {
808   GtkRBNode *node;
809   GtkRBTree *tree;
810   gboolean ret;
811
812   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
813   g_return_if_fail (selection->tree_view != NULL);
814   g_return_if_fail (path != NULL);
815
816   ret = _gtk_tree_view_find_node (selection->tree_view,
817                                   path,
818                                   &tree,
819                                   &node);
820
821   if (node == NULL || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
822       ret == TRUE)
823     return;
824
825   _gtk_tree_selection_internal_select_node (selection,
826                                             node,
827                                             tree,
828                                             path,
829                                             GDK_CONTROL_MASK,
830                                             TRUE);
831 }
832
833 /**
834  * gtk_tree_selection_select_iter:
835  * @selection: A #GtkTreeSelection.
836  * @iter: The #GtkTreeIter to be selected.
837  *
838  * Selects the specified iterator.
839  **/
840 void
841 gtk_tree_selection_select_iter (GtkTreeSelection *selection,
842                                 GtkTreeIter      *iter)
843 {
844   GtkTreePath *path;
845
846   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
847   g_return_if_fail (selection->tree_view != NULL);
848   g_return_if_fail (selection->tree_view->priv->model != NULL);
849   g_return_if_fail (iter != NULL);
850
851   path = gtk_tree_model_get_path (selection->tree_view->priv->model,
852                                   iter);
853
854   if (path == NULL)
855     return;
856
857   gtk_tree_selection_select_path (selection, path);
858   gtk_tree_path_free (path);
859 }
860
861
862 /**
863  * gtk_tree_selection_unselect_iter:
864  * @selection: A #GtkTreeSelection.
865  * @iter: The #GtkTreeIter to be unselected.
866  *
867  * Unselects the specified iterator.
868  **/
869 void
870 gtk_tree_selection_unselect_iter (GtkTreeSelection *selection,
871                                   GtkTreeIter      *iter)
872 {
873   GtkTreePath *path;
874
875   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
876   g_return_if_fail (selection->tree_view != NULL);
877   g_return_if_fail (selection->tree_view->priv->model != NULL);
878   g_return_if_fail (iter != NULL);
879
880   path = gtk_tree_model_get_path (selection->tree_view->priv->model,
881                                   iter);
882
883   if (path == NULL)
884     return;
885
886   gtk_tree_selection_unselect_path (selection, path);
887   gtk_tree_path_free (path);
888 }
889
890 /**
891  * gtk_tree_selection_path_is_selected:
892  * @selection: A #GtkTreeSelection.
893  * @path: A #GtkTreePath to check selection on.
894  * 
895  * Returns %TRUE if the row pointed to by @path is currently selected.  If @path
896  * does not point to a valid location, %FALSE is returned
897  * 
898  * Return value: %TRUE if @path is selected.
899  **/
900 gboolean
901 gtk_tree_selection_path_is_selected (GtkTreeSelection *selection,
902                                      GtkTreePath      *path)
903 {
904   GtkRBNode *node;
905   GtkRBTree *tree;
906   gboolean ret;
907
908   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
909   g_return_val_if_fail (path != NULL, FALSE);
910   g_return_val_if_fail (selection->tree_view != NULL, FALSE);
911   g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
912
913   ret = _gtk_tree_view_find_node (selection->tree_view,
914                                   path,
915                                   &tree,
916                                   &node);
917
918   if ((node == NULL) || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
919       ret == TRUE)
920     return FALSE;
921
922   return TRUE;
923 }
924
925 /**
926  * gtk_tree_selection_iter_is_selected:
927  * @selection: A #GtkTreeSelection
928  * @iter: A valid #GtkTreeIter
929  * 
930  * Returns %TRUE if the row at @iter is currently selected.
931  * 
932  * Return value: %TRUE, if @iter is selected
933  **/
934 gboolean
935 gtk_tree_selection_iter_is_selected (GtkTreeSelection *selection,
936                                      GtkTreeIter      *iter)
937 {
938   GtkTreePath *path;
939   gboolean retval;
940
941   g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
942   g_return_val_if_fail (iter != NULL, FALSE);
943   g_return_val_if_fail (selection->tree_view != NULL, FALSE);
944   g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
945
946   path = gtk_tree_model_get_path (selection->tree_view->priv->model, iter);
947   if (path == NULL)
948     return FALSE;
949
950   retval = gtk_tree_selection_path_is_selected (selection, path);
951   gtk_tree_path_free (path);
952
953   return retval;
954 }
955
956
957 /* Wish I was in python, right now... */
958 struct _TempTuple {
959   GtkTreeSelection *selection;
960   gint dirty;
961 };
962
963 static void
964 select_all_helper (GtkRBTree  *tree,
965                    GtkRBNode  *node,
966                    gpointer    data)
967 {
968   struct _TempTuple *tuple = data;
969
970   if (node->children)
971     _gtk_rbtree_traverse (node->children,
972                           node->children->root,
973                           G_PRE_ORDER,
974                           select_all_helper,
975                           data);
976   if (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
977     {
978       tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, TRUE) || tuple->dirty;
979     }
980 }
981
982
983 /* We have a real_{un,}select_all function that doesn't emit the signal, so we
984  * can use it in other places without fear of the signal being emitted.
985  */
986 static gint
987 gtk_tree_selection_real_select_all (GtkTreeSelection *selection)
988 {
989   struct _TempTuple *tuple;
990
991   if (selection->tree_view->priv->tree == NULL)
992     return FALSE;
993
994   /* Mark all nodes selected */
995   tuple = g_new (struct _TempTuple, 1);
996   tuple->selection = selection;
997   tuple->dirty = FALSE;
998
999   _gtk_rbtree_traverse (selection->tree_view->priv->tree,
1000                         selection->tree_view->priv->tree->root,
1001                         G_PRE_ORDER,
1002                         select_all_helper,
1003                         tuple);
1004   if (tuple->dirty)
1005     {
1006       g_free (tuple);
1007       return TRUE;
1008     }
1009   g_free (tuple);
1010   return FALSE;
1011 }
1012
1013 /**
1014  * gtk_tree_selection_select_all:
1015  * @selection: A #GtkTreeSelection.
1016  *
1017  * Selects all the nodes.  @selection is must be set to #GTK_SELECTION_MULTIPLE
1018  * mode.
1019  **/
1020 void
1021 gtk_tree_selection_select_all (GtkTreeSelection *selection)
1022 {
1023   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
1024   g_return_if_fail (selection->tree_view != NULL);
1025   if (selection->tree_view->priv->tree == NULL)
1026     return;
1027   g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE);
1028
1029   if (gtk_tree_selection_real_select_all (selection))
1030     g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
1031 }
1032
1033 static void
1034 unselect_all_helper (GtkRBTree  *tree,
1035                      GtkRBNode  *node,
1036                      gpointer    data)
1037 {
1038   struct _TempTuple *tuple = data;
1039
1040   if (node->children)
1041     _gtk_rbtree_traverse (node->children,
1042                           node->children->root,
1043                           G_PRE_ORDER,
1044                           unselect_all_helper,
1045                           data);
1046   if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
1047     {
1048       tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, FALSE) || tuple->dirty;
1049     }
1050 }
1051
1052 static gint
1053 gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
1054 {
1055   struct _TempTuple *tuple;
1056
1057   if (selection->type == GTK_SELECTION_SINGLE ||
1058       selection->type == GTK_SELECTION_BROWSE)
1059     {
1060       GtkRBTree *tree = NULL;
1061       GtkRBNode *node = NULL;
1062       GtkTreePath *anchor_path;
1063
1064       if (selection->tree_view->priv->anchor == NULL)
1065         return FALSE;
1066
1067       anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
1068
1069       if (anchor_path == NULL)
1070         return FALSE;
1071
1072       _gtk_tree_view_find_node (selection->tree_view,
1073                                 anchor_path,
1074                                 &tree,
1075                                 &node);
1076
1077       gtk_tree_path_free (anchor_path);
1078
1079       if (tree == NULL)
1080         return FALSE;
1081
1082       if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
1083         {
1084           if (gtk_tree_selection_real_select_node (selection, tree, node, FALSE))
1085             {
1086               gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1087               selection->tree_view->priv->anchor = NULL;
1088               return TRUE;
1089             }
1090         }
1091       return FALSE;
1092     }
1093   else
1094     {
1095       tuple = g_new (struct _TempTuple, 1);
1096       tuple->selection = selection;
1097       tuple->dirty = FALSE;
1098
1099       _gtk_rbtree_traverse (selection->tree_view->priv->tree,
1100                             selection->tree_view->priv->tree->root,
1101                             G_PRE_ORDER,
1102                             unselect_all_helper,
1103                             tuple);
1104
1105       if (tuple->dirty)
1106         {
1107           g_free (tuple);
1108           return TRUE;
1109         }
1110       g_free (tuple);
1111       return FALSE;
1112     }
1113 }
1114
1115 /**
1116  * gtk_tree_selection_unselect_all:
1117  * @selection: A #GtkTreeSelection.
1118  *
1119  * Unselects all the nodes.
1120  **/
1121 void
1122 gtk_tree_selection_unselect_all (GtkTreeSelection *selection)
1123 {
1124   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
1125   g_return_if_fail (selection->tree_view != NULL);
1126   if (selection->tree_view->priv->tree == NULL)
1127     return;
1128   
1129   if (selection->tree_view->priv->tree == NULL)
1130     return;
1131
1132   if (gtk_tree_selection_real_unselect_all (selection))
1133     g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
1134 }
1135
1136 enum
1137 {
1138   RANGE_SELECT,
1139   RANGE_UNSELECT
1140 };
1141
1142 static gint
1143 gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
1144                                       gint              mode,
1145                                       GtkTreePath      *start_path,
1146                                       GtkTreePath      *end_path)
1147 {
1148   GtkRBNode *start_node, *end_node;
1149   GtkRBTree *start_tree, *end_tree;
1150   GtkTreePath *anchor_path = NULL;
1151   gboolean dirty = FALSE;
1152
1153   switch (gtk_tree_path_compare (start_path, end_path))
1154     {
1155     case 1:
1156       _gtk_tree_view_find_node (selection->tree_view,
1157                                 end_path,
1158                                 &start_tree,
1159                                 &start_node);
1160       _gtk_tree_view_find_node (selection->tree_view,
1161                                 start_path,
1162                                 &end_tree,
1163                                 &end_node);
1164       anchor_path = end_path;
1165       break;
1166     case 0:
1167       _gtk_tree_view_find_node (selection->tree_view,
1168                                 start_path,
1169                                 &start_tree,
1170                                 &start_node);
1171       end_tree = start_tree;
1172       end_node = start_node;
1173       anchor_path = start_path;
1174       break;
1175     case -1:
1176       _gtk_tree_view_find_node (selection->tree_view,
1177                                 start_path,
1178                                 &start_tree,
1179                                 &start_node);
1180       _gtk_tree_view_find_node (selection->tree_view,
1181                                 end_path,
1182                                 &end_tree,
1183                                 &end_node);
1184       anchor_path = start_path;
1185       break;
1186     }
1187
1188   g_return_val_if_fail (start_node != NULL, FALSE);
1189   g_return_val_if_fail (end_node != NULL, FALSE);
1190
1191   if (anchor_path)
1192     {
1193       if (selection->tree_view->priv->anchor)
1194         gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1195
1196       selection->tree_view->priv->anchor =
1197         gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view),
1198                                           selection->tree_view->priv->model,
1199                                           anchor_path);
1200     }
1201
1202   do
1203     {
1204       dirty |= gtk_tree_selection_real_select_node (selection, start_tree, start_node, (mode == RANGE_SELECT)?TRUE:FALSE);
1205
1206       if (start_node == end_node)
1207         break;
1208
1209       if (start_node->children)
1210         {
1211           start_tree = start_node->children;
1212           start_node = start_tree->root;
1213           while (start_node->left != start_tree->nil)
1214             start_node = start_node->left;
1215         }
1216       else
1217         {
1218           _gtk_rbtree_next_full (start_tree, start_node, &start_tree, &start_node);
1219           if (start_tree == NULL)
1220             {
1221               /* we just ran out of tree.  That means someone passed in bogus values.
1222                */
1223               return dirty;
1224             }
1225         }
1226     }
1227   while (TRUE);
1228
1229   return dirty;
1230 }
1231
1232 /**
1233  * gtk_tree_selection_select_range:
1234  * @selection: A #GtkTreeSelection.
1235  * @start_path: The initial node of the range.
1236  * @end_path: The final node of the range.
1237  *
1238  * Selects a range of nodes, determined by @start_path and @end_path inclusive.
1239  **/
1240 void
1241 gtk_tree_selection_select_range (GtkTreeSelection *selection,
1242                                  GtkTreePath      *start_path,
1243                                  GtkTreePath      *end_path)
1244 {
1245   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
1246   g_return_if_fail (selection->tree_view != NULL);
1247
1248   if (gtk_tree_selection_real_modify_range (selection, RANGE_SELECT, start_path, end_path))
1249     g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
1250 }
1251
1252 /**
1253  * gtk_tree_selection_unselect_range:
1254  * @selection: A #GtkTreeSelection.
1255  * @start_path: The initial node of the range.
1256  * @end_path: The initial node of the range.
1257  *
1258  * Unselects a range of nodes, determined by @start_path and @end_path
1259  * inclusive.
1260  **/
1261 void
1262 gtk_tree_selection_unselect_range (GtkTreeSelection *selection,
1263                                    GtkTreePath      *start_path,
1264                                    GtkTreePath      *end_path)
1265 {
1266   g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
1267   g_return_if_fail (selection->tree_view != NULL);
1268
1269   if (gtk_tree_selection_real_modify_range (selection, RANGE_UNSELECT, start_path, end_path))
1270     g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
1271 }
1272
1273 /* Called internally by gtktreeview.c It handles actually selecting the tree.
1274  */
1275
1276 /*
1277  * docs about the 'override_browse_mode', we set this flag when we want to
1278  * unset select the node and override the select browse mode behaviour (that is
1279  * 'one node should *always* be selected').
1280  */
1281 void
1282 _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
1283                                           GtkRBNode        *node,
1284                                           GtkRBTree        *tree,
1285                                           GtkTreePath      *path,
1286                                           GdkModifierType   state,
1287                                           gboolean          override_browse_mode)
1288 {
1289   gint flags;
1290   gint dirty = FALSE;
1291   GtkTreePath *anchor_path = NULL;
1292
1293   if (selection->type == GTK_SELECTION_NONE)
1294     return;
1295
1296   if (selection->tree_view->priv->anchor)
1297     anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
1298
1299   if (selection->type == GTK_SELECTION_SINGLE ||
1300       selection->type == GTK_SELECTION_BROWSE)
1301     {
1302       /* just unselect */
1303       if (selection->type == GTK_SELECTION_BROWSE && override_browse_mode)
1304         {
1305           dirty = gtk_tree_selection_real_unselect_all (selection);
1306         }
1307       /* Did we try to select the same node again? */
1308       else if (selection->type == GTK_SELECTION_SINGLE &&
1309                anchor_path && gtk_tree_path_compare (path, anchor_path) == 0)
1310         {
1311           if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
1312             {
1313               dirty = gtk_tree_selection_real_unselect_all (selection);
1314             }
1315         }
1316       else
1317         {
1318           if (anchor_path)
1319             {
1320               /* We only want to select the new node if we can unselect the old one,
1321                * and we can select the new one. */
1322               if (selection->user_func)
1323                 {
1324                   if ((*selection->user_func) (selection, selection->tree_view->priv->model, path,
1325                                                GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
1326                                                selection->user_data))
1327                     dirty = TRUE;
1328                 }
1329               else
1330                 {
1331                   dirty = TRUE;
1332                 }
1333
1334               /* if dirty is FALSE, we weren't able to select the new one, otherwise, we try to
1335                * unselect the new one
1336                */
1337               if (dirty)
1338                 dirty = gtk_tree_selection_real_unselect_all (selection);
1339
1340               /* if dirty is TRUE at this point, we successfully unselected the
1341                * old one, and can then select the new one */
1342               if (dirty)
1343                 {
1344                   if (selection->tree_view->priv->anchor)
1345                     gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1346                   if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
1347                     {
1348                       selection->tree_view->priv->anchor =
1349                         gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1350                     }
1351                 }
1352             }
1353           else
1354             {
1355               if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
1356                 {
1357                   dirty = TRUE;
1358                   if (selection->tree_view->priv->anchor)
1359                     gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1360
1361                   selection->tree_view->priv->anchor =
1362                     gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1363                 }
1364             }
1365         }
1366     }
1367   else if (selection->type == GTK_SELECTION_MULTIPLE)
1368     {
1369       if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
1370         {
1371           if (selection->tree_view->priv->anchor)
1372             gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1373
1374           selection->tree_view->priv->anchor =
1375             gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1376           dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1377         }
1378       else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
1379         {
1380           gtk_tree_selection_select_range (selection,
1381                                            anchor_path,
1382                                            path);
1383         }
1384       else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
1385         {
1386           flags = node->flags;
1387           if (selection->tree_view->priv->anchor)
1388             gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1389
1390           selection->tree_view->priv->anchor =
1391             gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1392
1393           if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
1394             dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
1395           else
1396             dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1397         }
1398       else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
1399         {
1400           dirty = gtk_tree_selection_real_unselect_all (selection);
1401           dirty |= gtk_tree_selection_real_modify_range (selection,
1402                                                          RANGE_SELECT,
1403                                                          anchor_path,
1404                                                          path);
1405         }
1406       else
1407         {
1408           dirty = gtk_tree_selection_real_unselect_all (selection);
1409
1410           if (selection->tree_view->priv->anchor)
1411             gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1412
1413           selection->tree_view->priv->anchor =
1414             gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1415
1416           dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1417         }
1418     }
1419
1420   if (anchor_path)
1421     gtk_tree_path_free (anchor_path);
1422
1423   if (dirty)
1424     g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
1425 }
1426
1427 /* NOTE: Any {un,}selection ever done _MUST_ be done through this function!
1428  */
1429
1430 static gint
1431 gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
1432                                      GtkRBTree        *tree,
1433                                      GtkRBNode        *node,
1434                                      gboolean          select)
1435 {
1436   gboolean selected = FALSE;
1437   GtkTreePath *path = NULL;
1438
1439   select = !! select;
1440
1441   if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) != select)
1442     {
1443       path = _gtk_tree_view_find_path (selection->tree_view, tree, node);
1444       if (selection->user_func)
1445         {
1446           if ((*selection->user_func) (selection, selection->tree_view->priv->model, path,
1447                                        GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
1448                                        selection->user_data))
1449             selected = TRUE;
1450         }
1451       else
1452         selected = TRUE;
1453       gtk_tree_path_free (path);
1454     }
1455
1456   if (selected == TRUE)
1457     {
1458       node->flags ^= GTK_RBNODE_IS_SELECTED;
1459
1460       _gtk_tree_view_queue_draw_node (selection->tree_view, tree, node, NULL);
1461       
1462       return TRUE;
1463     }
1464
1465   return FALSE;
1466 }
1467