2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
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.
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.
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.
20 #include "gtktreeselection.h"
21 #include "gtktreeprivate.h"
22 #include "gtkrbtree.h"
23 #include "gtkmarshalers.h"
24 #include "gtksignal.h"
26 static void gtk_tree_selection_init (GtkTreeSelection *selection);
27 static void gtk_tree_selection_class_init (GtkTreeSelectionClass *class);
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,
43 static GObjectClass *parent_class = NULL;
44 static guint tree_selection_signals [LAST_SIGNAL] = { 0 };
47 gtk_tree_selection_get_type (void)
49 static GtkType selection_type = 0;
53 static const GTypeInfo selection_info =
55 sizeof (GtkTreeSelectionClass),
57 NULL, /* base_finalize */
58 (GClassInitFunc) gtk_tree_selection_class_init,
59 NULL, /* class_finalize */
60 NULL, /* class_data */
61 sizeof (GtkTreeSelection),
63 (GInstanceInitFunc) gtk_tree_selection_init
66 selection_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeSelection", &selection_info, 0);
69 return selection_type;
73 gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
75 GObjectClass *object_class;
77 object_class = (GObjectClass*) class;
78 parent_class = g_type_class_peek_parent (class);
80 object_class->finalize = gtk_tree_selection_finalize;
81 class->changed = NULL;
83 tree_selection_signals[CHANGED] =
84 gtk_signal_new ("changed",
86 GTK_CLASS_TYPE (object_class),
87 GTK_SIGNAL_OFFSET (GtkTreeSelectionClass, changed),
88 _gtk_marshal_VOID__VOID,
93 gtk_tree_selection_init (GtkTreeSelection *selection)
95 selection->type = GTK_SELECTION_SINGLE;
99 gtk_tree_selection_finalize (GObject *object)
101 if (GTK_TREE_SELECTION (object)->destroy)
102 (* GTK_TREE_SELECTION (object)->destroy) (GTK_TREE_SELECTION (object)->user_data);
104 /* chain parent_class' handler */
105 G_OBJECT_CLASS (parent_class)->finalize (object);
109 * _gtk_tree_selection_new:
111 * Creates a new #GtkTreeSelection object. This function should not be invoked,
112 * as each #GtkTreeView will create it's own #GtkTreeSelection.
114 * Return value: A newly created #GtkTreeSelection object.
117 _gtk_tree_selection_new (void)
119 GtkTreeSelection *selection;
121 selection = GTK_TREE_SELECTION (g_object_new (GTK_TYPE_TREE_SELECTION, NULL));
127 * _gtk_tree_selection_new_with_tree_view:
128 * @tree_view: The #GtkTreeView.
130 * Creates a new #GtkTreeSelection object. This function should not be invoked,
131 * as each #GtkTreeView will create it's own #GtkTreeSelection.
133 * Return value: A newly created #GtkTreeSelection object.
136 _gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view)
138 GtkTreeSelection *selection;
140 g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
142 selection = _gtk_tree_selection_new ();
143 _gtk_tree_selection_set_tree_view (selection, tree_view);
149 * _gtk_tree_selection_set_tree_view:
150 * @selection: A #GtkTreeSelection.
151 * @tree_view: The #GtkTreeView.
153 * Sets the #GtkTreeView of @selection. This function should not be invoked, as
154 * it is used internally by #GtkTreeView.
157 _gtk_tree_selection_set_tree_view (GtkTreeSelection *selection,
158 GtkTreeView *tree_view)
160 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
161 if (tree_view != NULL)
162 g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
164 selection->tree_view = tree_view;
168 * gtk_tree_selection_set_mode:
169 * @selection: A #GtkTreeSelection.
170 * @type: The selection mode
172 * Sets the selection mode of the @selection. If the previous type was
173 * #GTK_SELECTION_MULTIPLE, then the anchor is kept selected, if it was
174 * previously selected.
177 gtk_tree_selection_set_mode (GtkTreeSelection *selection,
178 GtkSelectionMode type)
180 GtkTreeSelectionFunc tmp_func;
181 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
183 if (selection->type == type)
187 if (type == GTK_SELECTION_NONE)
189 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
190 /* We do this so that we unconditionally unset all rows
192 tmp_func = selection->user_func;
193 selection->user_func = NULL;
194 gtk_tree_selection_unselect_all (selection);
195 selection->user_func = tmp_func;
197 else if (type == GTK_SELECTION_SINGLE ||
198 type == GTK_SELECTION_BROWSE)
200 GtkRBTree *tree = NULL;
201 GtkRBNode *node = NULL;
202 gint selected = FALSE;
203 GtkTreePath *anchor_path = NULL;
205 if (selection->tree_view->priv->anchor)
207 anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
211 _gtk_tree_view_find_node (selection->tree_view,
216 if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
221 /* We do this so that we unconditionally unset all rows
223 tmp_func = selection->user_func;
224 selection->user_func = NULL;
225 gtk_tree_selection_unselect_all (selection);
226 selection->user_func = tmp_func;
228 if (node && selected)
229 _gtk_tree_selection_internal_select_node (selection,
235 gtk_tree_path_free (anchor_path);
238 selection->type = type;
242 * gtk_tree_selection_get_mode:
243 * @selection: a #GtkTreeSelection
245 * Gets the selection mode for @selection. See
246 * gtk_tree_selection_set_mode().
248 * Return value: the current selection mode
251 gtk_tree_selection_get_mode (GtkTreeSelection *selection)
253 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), GTK_SELECTION_SINGLE);
255 return selection->type;
259 * gtk_tree_selection_set_select_function:
260 * @selection: A #GtkTreeSelection.
261 * @func: The selection function.
262 * @data: The selection function's data.
263 * @destroy: The destroy function for user data. May be NULL.
265 * Sets the selection function. If set, this function is called before any node
266 * is selected or unselected, giving some control over which nodes are selected.
267 * The select function should return %TRUE if the state of the node may be toggled,
268 * and %FALSE if the state of the node should be left unchanged.
271 gtk_tree_selection_set_select_function (GtkTreeSelection *selection,
272 GtkTreeSelectionFunc func,
274 GtkDestroyNotify destroy)
276 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
277 g_return_if_fail (func != NULL);
279 selection->user_func = func;
280 selection->user_data = data;
281 selection->destroy = destroy;
285 * gtk_tree_selection_get_user_data:
286 * @selection: A #GtkTreeSelection.
288 * Returns the user data for the selection function.
290 * Return value: The user data.
293 gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
295 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
297 return selection->user_data;
301 * gtk_tree_selection_get_tree_view:
302 * @selection: A #GtkTreeSelection
304 * Returns the tree view associated with @selection.
306 * Return value: A #GtkTreeView
309 gtk_tree_selection_get_tree_view (GtkTreeSelection *selection)
311 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
313 return selection->tree_view;
317 * gtk_tree_selection_get_selected:
318 * @selection: A #GtkTreeSelection.
319 * @model: A pointer set to the #GtkTreeModel, or NULL.
320 * @iter: The #GtkTreeIter, or NULL.
322 * Sets @iter to the currently selected node if @selection is set to
323 * #GTK_SELECTION_SINGLE or #GTK_SELECTION_BROWSE. @iter may be NULL if you
324 * just want to test if @selection has any selected nodes. @model is filled
325 * with the current model as a convenience. This function will not work if you
326 * use @selection is #GTK_SELECTION_MULTIPLE.
328 * Return value: TRUE, if there is a selected node.
331 gtk_tree_selection_get_selected (GtkTreeSelection *selection,
332 GtkTreeModel **model,
337 GtkTreePath *anchor_path;
340 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
341 g_return_val_if_fail (selection->type != GTK_SELECTION_MULTIPLE, FALSE);
342 g_return_val_if_fail (selection->tree_view != NULL, FALSE);
343 g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
346 *model = selection->tree_view->priv->model;
348 if (selection->tree_view->priv->anchor == NULL)
351 anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
353 if (anchor_path == NULL)
358 gtk_tree_path_free (anchor_path);
364 if (!_gtk_tree_view_find_node (selection->tree_view,
368 ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
370 /* We don't want to return the anchor if it isn't actually selected.
376 retval = gtk_tree_model_get_iter (selection->tree_view->priv->model,
381 gtk_tree_path_free (anchor_path);
387 * gtk_tree_selection_selected_foreach:
388 * @selection: A #GtkTreeSelection.
389 * @func: The function to call for each selected node.
390 * @data: user data to pass to the function.
392 * Calls a function for each selected node.
395 gtk_tree_selection_selected_foreach (GtkTreeSelection *selection,
396 GtkTreeSelectionForeachFunc func,
404 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
405 g_return_if_fail (selection->tree_view != NULL);
406 g_return_if_fail (selection->tree_view->priv->model != NULL);
409 selection->tree_view->priv->tree == NULL ||
410 selection->tree_view->priv->tree->root == NULL)
413 if (selection->type == GTK_SELECTION_SINGLE ||
414 selection->type == GTK_SELECTION_BROWSE)
416 if (gtk_tree_row_reference_valid (selection->tree_view->priv->anchor))
418 path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
419 gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path);
420 (* func) (selection->tree_view->priv->model, path, &iter, data);
421 gtk_tree_path_free (path);
426 tree = selection->tree_view->priv->tree;
427 node = selection->tree_view->priv->tree->root;
429 while (node->left != tree->nil)
432 /* find the node internally */
433 path = gtk_tree_path_new_root ();
434 gtk_tree_model_get_iter (selection->tree_view->priv->model,
439 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
440 (* func) (selection->tree_view->priv->model, path, &iter, data);
446 tree = node->children;
448 while (node->left != tree->nil)
451 has_child = gtk_tree_model_iter_children (selection->tree_view->priv->model, &iter, &tmp);
452 gtk_tree_path_append_index (path, 0);
454 TREE_VIEW_INTERNAL_ASSERT_VOID (has_child);
458 gboolean done = FALSE;
461 node = _gtk_rbtree_next (tree, node);
466 has_next = gtk_tree_model_iter_next (selection->tree_view->priv->model, &iter);
468 gtk_tree_path_next (path);
471 TREE_VIEW_INTERNAL_ASSERT_VOID (has_next);
476 GtkTreeIter tmp_iter = iter;
478 node = tree->parent_node;
479 tree = tree->parent_tree;
482 gtk_tree_path_free (path);
483 /* we've run out of tree */
484 /* We're done with this function */
487 has_parent = gtk_tree_model_iter_parent (selection->tree_view->priv->model, &iter, &tmp_iter);
488 gtk_tree_path_up (path);
490 TREE_VIEW_INTERNAL_ASSERT_VOID (has_parent);
500 * gtk_tree_selection_select_path:
501 * @selection: A #GtkTreeSelection.
502 * @path: The #GtkTreePath to be selected.
504 * Select the row at @path.
507 gtk_tree_selection_select_path (GtkTreeSelection *selection,
512 GdkModifierType state = 0;
514 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
515 g_return_if_fail (selection->tree_view != NULL);
516 g_return_if_fail (path != NULL);
518 _gtk_tree_view_find_node (selection->tree_view,
523 if (node == NULL || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
526 if (selection->type == GTK_SELECTION_MULTIPLE)
527 state = GDK_CONTROL_MASK;
529 _gtk_tree_selection_internal_select_node (selection,
537 * gtk_tree_selection_unselect_path:
538 * @selection: A #GtkTreeSelection.
539 * @path: The #GtkTreePath to be unselected.
541 * Unselects the row at @path.
544 gtk_tree_selection_unselect_path (GtkTreeSelection *selection,
550 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
551 g_return_if_fail (selection->tree_view != NULL);
552 g_return_if_fail (path != NULL);
554 _gtk_tree_view_find_node (selection->tree_view,
559 if (node == NULL || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
562 _gtk_tree_selection_internal_select_node (selection,
570 * gtk_tree_selection_select_iter:
571 * @selection: A #GtkTreeSelection.
572 * @iter: The #GtkTreeIter to be selected.
574 * Selects the specified iterator.
577 gtk_tree_selection_select_iter (GtkTreeSelection *selection,
582 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
583 g_return_if_fail (selection->tree_view != NULL);
584 g_return_if_fail (selection->tree_view->priv->model != NULL);
585 g_return_if_fail (iter != NULL);
587 path = gtk_tree_model_get_path (selection->tree_view->priv->model,
593 gtk_tree_selection_select_path (selection, path);
594 gtk_tree_path_free (path);
599 * gtk_tree_selection_unselect_iter:
600 * @selection: A #GtkTreeSelection.
601 * @iter: The #GtkTreeIter to be unselected.
603 * Unselects the specified iterator.
606 gtk_tree_selection_unselect_iter (GtkTreeSelection *selection,
611 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
612 g_return_if_fail (selection->tree_view != NULL);
613 g_return_if_fail (selection->tree_view->priv->model != NULL);
614 g_return_if_fail (iter != NULL);
616 path = gtk_tree_model_get_path (selection->tree_view->priv->model,
622 gtk_tree_selection_select_path (selection, path);
623 gtk_tree_path_free (path);
627 * gtk_tree_selection_path_is_selected:
628 * @selection: A #GtkTreeSelection.
629 * @path: A #GtkTreePath to check selection on.
631 * Returns %TRUE if the row pointed to by @path is currently selected. If @path
632 * does not point to a valid location, %FALSE is returned
634 * Return value: %TRUE if @path is selected.
637 gtk_tree_selection_path_is_selected (GtkTreeSelection *selection,
643 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
644 g_return_val_if_fail (path != NULL, FALSE);
645 g_return_val_if_fail (selection->tree_view != NULL, FALSE);
646 g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
648 _gtk_tree_view_find_node (selection->tree_view,
653 if ((node == NULL) || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
660 * gtk_tree_selection_iter_is_selected:
661 * @selection: A #GtkTreeSelection
662 * @iter: A valid #GtkTreeIter
664 * Returns %TRUE if the row pointed to by @path is currently selected.
666 * Return value: %TRUE, if @iter is selected
669 gtk_tree_selection_iter_is_selected (GtkTreeSelection *selection,
675 g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
676 g_return_val_if_fail (iter != NULL, FALSE);
677 g_return_val_if_fail (selection->tree_view != NULL, FALSE);
678 g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
680 path = gtk_tree_model_get_path (selection->tree_view->priv->model, iter);
684 retval = gtk_tree_selection_path_is_selected (selection, path);
685 gtk_tree_path_free (path);
691 /* Wish I was in python, right now... */
693 GtkTreeSelection *selection;
698 select_all_helper (GtkRBTree *tree,
702 struct _TempTuple *tuple = data;
705 _gtk_rbtree_traverse (node->children,
706 node->children->root,
710 if (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
712 tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, TRUE) || tuple->dirty;
717 /* We have a real_{un,}select_all function that doesn't emit the signal, so we
718 * can use it in other places without fear of the signal being emitted.
721 gtk_tree_selection_real_select_all (GtkTreeSelection *selection)
723 struct _TempTuple *tuple;
725 if (selection->tree_view->priv->tree == NULL)
728 /* Mark all nodes selected */
729 tuple = g_new (struct _TempTuple, 1);
730 tuple->selection = selection;
731 tuple->dirty = FALSE;
733 _gtk_rbtree_traverse (selection->tree_view->priv->tree,
734 selection->tree_view->priv->tree->root,
748 * gtk_tree_selection_select_all:
749 * @selection: A #GtkTreeSelection.
751 * Selects all the nodes. @selection is must be set to #GTK_SELECTION_MULTIPLE
755 gtk_tree_selection_select_all (GtkTreeSelection *selection)
757 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
758 g_return_if_fail (selection->tree_view != NULL);
759 if (selection->tree_view->priv->tree == NULL)
761 g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE);
763 if (gtk_tree_selection_real_select_all (selection))
764 g_signal_emit (G_OBJECT (selection), tree_selection_signals[CHANGED], 0);
768 unselect_all_helper (GtkRBTree *tree,
772 struct _TempTuple *tuple = data;
775 _gtk_rbtree_traverse (node->children,
776 node->children->root,
780 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
782 tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, FALSE) || tuple->dirty;
787 gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
789 struct _TempTuple *tuple;
791 if (selection->type == GTK_SELECTION_SINGLE ||
792 selection->type == GTK_SELECTION_BROWSE)
794 GtkRBTree *tree = NULL;
795 GtkRBNode *node = NULL;
796 GtkTreePath *anchor_path;
798 if (selection->tree_view->priv->anchor == NULL)
801 anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
803 if (anchor_path == NULL)
806 _gtk_tree_view_find_node (selection->tree_view,
811 gtk_tree_path_free (anchor_path);
816 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
818 if (gtk_tree_selection_real_select_node (selection, tree, node, FALSE))
820 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
821 selection->tree_view->priv->anchor = NULL;
829 tuple = g_new (struct _TempTuple, 1);
830 tuple->selection = selection;
831 tuple->dirty = FALSE;
833 _gtk_rbtree_traverse (selection->tree_view->priv->tree,
834 selection->tree_view->priv->tree->root,
850 * gtk_tree_selection_unselect_all:
851 * @selection: A #GtkTreeSelection.
853 * Unselects all the nodes.
856 gtk_tree_selection_unselect_all (GtkTreeSelection *selection)
858 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
859 g_return_if_fail (selection->tree_view != NULL);
860 if (selection->tree_view->priv->tree == NULL)
863 if (selection->tree_view->priv->tree == NULL)
866 if (gtk_tree_selection_real_unselect_all (selection))
867 g_signal_emit (G_OBJECT (selection), tree_selection_signals[CHANGED], 0);
871 gtk_tree_selection_real_select_range (GtkTreeSelection *selection,
872 GtkTreePath *start_path,
873 GtkTreePath *end_path)
875 GtkRBNode *start_node, *end_node;
876 GtkRBTree *start_tree, *end_tree;
877 gboolean dirty = FALSE;
879 switch (gtk_tree_path_compare (start_path, end_path))
882 _gtk_tree_view_find_node (selection->tree_view,
886 _gtk_tree_view_find_node (selection->tree_view,
892 _gtk_tree_view_find_node (selection->tree_view,
896 end_tree = start_tree;
897 end_node = start_node;
900 _gtk_tree_view_find_node (selection->tree_view,
904 _gtk_tree_view_find_node (selection->tree_view,
911 g_return_val_if_fail (start_node != NULL, FALSE);
912 g_return_val_if_fail (end_node != NULL, FALSE);
916 dirty |= gtk_tree_selection_real_select_node (selection, start_tree, start_node, TRUE);
918 if (start_node == end_node)
921 if (start_node->children)
923 start_tree = start_node->children;
924 start_node = start_tree->root;
925 while (start_node->left != start_tree->nil)
926 start_node = start_node->left;
930 _gtk_rbtree_next_full (start_tree, start_node, &start_tree, &start_node);
931 if (start_tree == NULL)
933 /* we just ran out of tree. That means someone passed in bogus values.
945 * gtk_tree_selection_select_range:
946 * @selection: A #GtkTreeSelection.
947 * @start_path: The initial node of the range.
948 * @end_path: The final node of the range.
950 * Selects a range of nodes, determined by @start_path and @end_path inclusive.
953 gtk_tree_selection_select_range (GtkTreeSelection *selection,
954 GtkTreePath *start_path,
955 GtkTreePath *end_path)
957 g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
958 g_return_if_fail (selection->tree_view != NULL);
960 if (gtk_tree_selection_real_select_range (selection, start_path, end_path))
961 g_signal_emit (G_OBJECT (selection), tree_selection_signals[CHANGED], 0);
964 /* Called internally by gtktreeview.c It handles actually selecting the tree.
967 _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
971 GdkModifierType state)
975 GtkTreePath *anchor_path = NULL;
977 if (selection->type == GTK_SELECTION_NONE)
980 if (selection->tree_view->priv->anchor)
981 anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
983 if (selection->type == GTK_SELECTION_SINGLE ||
984 selection->type == GTK_SELECTION_BROWSE)
986 /* Did we try to select the same node again? */
987 if (selection->type == GTK_SELECTION_SINGLE &&
988 anchor_path && gtk_tree_path_compare (path, anchor_path) == 0)
990 if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
992 dirty = gtk_tree_selection_real_unselect_all (selection);
997 /* FIXME: We only want to select the new node if we can unselect the
998 * old one, and we can select the new one. We are currently
999 * unselecting the old one first, then trying the new one. */
1002 dirty = gtk_tree_selection_real_unselect_all (selection);
1005 if (selection->tree_view->priv->anchor)
1006 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1007 if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
1009 selection->tree_view->priv->anchor =
1010 gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1016 if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
1019 selection->tree_view->priv->anchor =
1020 gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1025 else if (selection->type == GTK_SELECTION_MULTIPLE)
1027 if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
1029 if (selection->tree_view->priv->anchor)
1030 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1032 selection->tree_view->priv->anchor =
1033 gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1034 dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1036 else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
1038 gtk_tree_selection_select_range (selection,
1042 else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
1044 flags = node->flags;
1045 if (selection->tree_view->priv->anchor)
1046 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1048 selection->tree_view->priv->anchor =
1049 gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1051 if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
1052 dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
1054 dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1056 else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
1058 dirty = gtk_tree_selection_real_unselect_all (selection);
1059 dirty |= gtk_tree_selection_real_select_range (selection,
1065 dirty = gtk_tree_selection_real_unselect_all (selection);
1067 if (selection->tree_view->priv->anchor)
1068 gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
1070 selection->tree_view->priv->anchor =
1071 gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
1073 dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
1078 gtk_tree_path_free (anchor_path);
1081 g_signal_emit (G_OBJECT (selection), tree_selection_signals[CHANGED], 0);
1084 /* NOTE: Any {un,}selection ever done _MUST_ be done through this function!
1088 gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
1093 gboolean selected = FALSE;
1094 GtkTreePath *path = NULL;
1096 if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) != select)
1098 path = _gtk_tree_view_find_path (selection->tree_view, tree, node);
1099 if (selection->user_func)
1101 if ((*selection->user_func) (selection, selection->tree_view->priv->model, path,
1102 GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
1103 selection->user_data))
1108 gtk_tree_path_free (path);
1111 if (selected == TRUE)
1113 node->flags ^= GTK_RBNODE_IS_SELECTED;
1115 /* FIXME: just draw the one node*/
1116 gtk_widget_queue_draw (GTK_WIDGET (selection->tree_view));