summaryrefslogtreecommitdiff
path: root/gtk/gtktreeselection.c
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2001-02-28 00:35:25 +0000
committerJonathan Blandford <jrb@src.gnome.org>2001-02-28 00:35:25 +0000
commitc82dc58f7fceed9878181b50783ebfc80a5a3ae8 (patch)
tree7d9d4fa9d0b659167cdf80eecb82ee2c453a16fb /gtk/gtktreeselection.c
parent75d79abf9801195a0241b02ed7974fafa8278f5c (diff)
downloadgdk-pixbuf-c82dc58f7fceed9878181b50783ebfc80a5a3ae8.tar.gz
Proxy out to _gtk_tree_row_reference_deleted. (inserted_callback): Proxy
Tue Feb 27 19:32:53 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtktreemodel.c (deleted_callback): Proxy out to _gtk_tree_row_reference_deleted. (inserted_callback): Proxy out to _gtk_tree_row_reference_inserted. (_gtk_tree_row_reference_new_from_view): Somewhat yukky hack to get around signal emission ordering problem. * gtk/gtktreeselection.c (gtk_tree_selection_real_unselect_all): fix to work with SINGLE (_gtk_tree_selection_internal_select_node): Major sanitization on selections. SINGLE now seems to work. * tests/Makefile.am: add testtreecolumn.c: * tests/testtreecolumn.c: New test. Mostly points out selection bugs currently, but will test columns later. * gtk/gtkrbtree.c (_gtk_rbtree_remove_node): Fix really nasty selection bug. I hate touching this code -- it's scary.
Diffstat (limited to 'gtk/gtktreeselection.c')
-rw-r--r--gtk/gtktreeselection.c171
1 files changed, 115 insertions, 56 deletions
diff --git a/gtk/gtktreeselection.c b/gtk/gtktreeselection.c
index baf424a14..a63fec367 100644
--- a/gtk/gtktreeselection.c
+++ b/gtk/gtktreeselection.c
@@ -24,6 +24,8 @@
static void gtk_tree_selection_init (GtkTreeSelection *selection);
static void gtk_tree_selection_class_init (GtkTreeSelectionClass *class);
+
+static void gtk_tree_selection_finalize (GObject *object);
static gint gtk_tree_selection_real_select_all (GtkTreeSelection *selection);
static gint gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection);
static gint gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
@@ -69,11 +71,12 @@ gtk_tree_selection_get_type (void)
static void
gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
- object_class = (GtkObjectClass*) class;
+ object_class = (GObjectClass*) class;
parent_class = g_type_class_peek_parent (class);
+ object_class->finalize = gtk_tree_selection_finalize;
class->selection_changed = NULL;
tree_selection_signals[SELECTION_CHANGED] =
@@ -91,6 +94,13 @@ gtk_tree_selection_init (GtkTreeSelection *selection)
selection->type = GTK_TREE_SELECTION_SINGLE;
}
+static void
+gtk_tree_selection_finalize (GObject *object)
+{
+ if (GTK_TREE_SELECTION (object)->destroy)
+ (* GTK_TREE_SELECTION (object)->destroy) (GTK_TREE_SELECTION (object)->user_data);
+}
+
/**
* _gtk_tree_selection_new:
*
@@ -214,6 +224,7 @@ gtk_tree_selection_set_mode (GtkTreeSelection *selection,
* @selection: A #GtkTreeSelection.
* @func: The selection function.
* @data: The selection function's data.
+ * @destroy: The destroy function for user data. May be NULL.
*
* Sets the selection function. If set, this function is called before any node
* is selected or unselected, giving some control over which nodes are selected.
@@ -221,7 +232,8 @@ gtk_tree_selection_set_mode (GtkTreeSelection *selection,
void
gtk_tree_selection_set_select_function (GtkTreeSelection *selection,
GtkTreeSelectionFunc func,
- gpointer data)
+ gpointer data,
+ GtkDestroyNotify destroy)
{
g_return_if_fail (selection != NULL);
g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
@@ -229,6 +241,7 @@ gtk_tree_selection_set_select_function (GtkTreeSelection *selection,
selection->user_func = func;
selection->user_data = data;
+ selection->destroy = destroy;
}
/**
@@ -263,9 +276,10 @@ gtk_tree_selection_get_tree_view (GtkTreeSelection *selection)
* @iter: The #GtkTreeIter, or NULL.
*
* Sets @iter to the currently selected node if @selection is set to
- * #GTK_TREE_SELECTION_SINGLE. Otherwise, it uses the anchor. @iter may be
- * NULL if you just want to test if @selection has any selected nodes. @model
- * is filled with the current model as a convenience.
+ * #GTK_TREE_SELECTION_SINGLE. @iter may be NULL if you just want to test if
+ * @selection has any selected nodes. @model is filled with the current model
+ * as a convenience. This function will not work if you use @selection is
+ * #GTK_TREE_SELECTION_MULTI.
*
* Return value: TRUE, if there is a selected node.
**/
@@ -281,6 +295,9 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection,
g_return_val_if_fail (selection != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
+ g_return_val_if_fail (selection->type == GTK_TREE_SELECTION_SINGLE, FALSE);
+ g_return_val_if_fail (selection->tree_view != NULL, FALSE);
+ g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
if (model)
*model = selection->tree_view->priv->model;
@@ -299,9 +316,6 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection,
return TRUE;
}
- g_return_val_if_fail (selection->tree_view != NULL, FALSE);
- g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
-
retval = FALSE;
if (!_gtk_tree_view_find_node (selection->tree_view,
@@ -713,8 +727,12 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
{
- gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
- return TRUE;
+ if (gtk_tree_selection_real_select_node (selection, tree, node, FALSE))
+ {
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+ selection->tree_view->priv->anchor = NULL;
+ return TRUE;
+ }
}
return FALSE;
}
@@ -870,8 +888,8 @@ gtk_tree_selection_select_range (GtkTreeSelection *selection,
if (gtk_tree_selection_real_select_range (selection, start_path, end_path))
gtk_signal_emit (GTK_OBJECT (selection), tree_selection_signals[SELECTION_CHANGED]);
}
+
/* Called internally by gtktreeview.c It handles actually selecting the tree.
- * This should almost certainly ever be called by anywhere else.
*/
void
_gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
@@ -884,62 +902,103 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
gint dirty = FALSE;
GtkTreePath *anchor_path = NULL;
+
if (selection->tree_view->priv->anchor)
anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
- if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
- {
- if (selection->tree_view->priv->anchor)
- gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
-
- selection->tree_view->priv->anchor =
- gtk_tree_row_reference_new (selection->tree_view->priv->model,
- path);
- dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
- }
- else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
+ if (selection->type == GTK_TREE_SELECTION_SINGLE)
{
- gtk_tree_selection_select_range (selection,
- anchor_path,
- path);
+ /* Did we try to select the same node again? */
+ if (anchor_path && gtk_tree_path_compare (path, anchor_path) == 0)
+ {
+ if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+ {
+ dirty = gtk_tree_selection_real_unselect_all (selection);
+ }
+ }
+ else
+ {
+ /* FIXME: We only want to select the new node if we can unselect the
+ * old one, and we can select the new one. We are currently
+ * unselecting the old one first, then trying the new one. */
+ if (anchor_path)
+ {
+ dirty = gtk_tree_selection_real_unselect_all (selection);
+ if (dirty)
+ {
+ if (selection->tree_view->priv->anchor)
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+ if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
+ {
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new (selection->tree_view->priv->model, path);
+ }
+ }
+ }
+ else
+ {
+ if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
+ {
+ dirty = TRUE;
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new (selection->tree_view->priv->model, path);
+ }
+ }
+ }
}
- else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+ else if (selection->type == GTK_TREE_SELECTION_MULTI)
{
- flags = node->flags;
- if (selection->type == GTK_TREE_SELECTION_SINGLE)
- dirty = gtk_tree_selection_real_unselect_all (selection);
-
- if (selection->tree_view->priv->anchor)
- gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+ if (((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) && (anchor_path == NULL))
+ {
+ if (selection->tree_view->priv->anchor)
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
- selection->tree_view->priv->anchor =
- gtk_tree_row_reference_new (selection->tree_view->priv->model,
- path);
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new (selection->tree_view->priv->model,
+ path);
+ dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+ }
+ else if ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK|GDK_CONTROL_MASK))
+ {
+ gtk_tree_selection_select_range (selection,
+ anchor_path,
+ path);
+ }
+ else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+ {
+ flags = node->flags;
+ if (selection->tree_view->priv->anchor)
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new (selection->tree_view->priv->model,
+ path);
- if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
- dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
+ if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
+ dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
+ else
+ dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+ }
+ else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
+ {
+ dirty = gtk_tree_selection_real_unselect_all (selection);
+ dirty |= gtk_tree_selection_real_select_range (selection,
+ anchor_path,
+ path);
+ }
else
- dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
- }
- else if ((state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)
- {
- dirty = gtk_tree_selection_real_unselect_all (selection);
- dirty |= gtk_tree_selection_real_select_range (selection,
- anchor_path,
- path);
- }
- else
- {
- dirty = gtk_tree_selection_real_unselect_all (selection);
+ {
+ dirty = gtk_tree_selection_real_unselect_all (selection);
- if (selection->tree_view->priv->anchor)
- gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
+ if (selection->tree_view->priv->anchor)
+ gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
- selection->tree_view->priv->anchor =
- gtk_tree_row_reference_new (selection->tree_view->priv->model,
- path);
+ selection->tree_view->priv->anchor =
+ gtk_tree_row_reference_new (selection->tree_view->priv->model,
+ path);
- dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+ dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
+ }
}
if (anchor_path)