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