diff --git a/ChangeLog b/ChangeLog index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 749c20c2d9..fc423e4492 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,25 @@ +Tue Feb 27 19:32:53 2001 Jonathan Blandford + + * 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. + 2001-02-26 Havoc Pennington * gtk/testgtk.c: test the window state stuff diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c index a37a728705..fc998bd3a9 100644 --- a/gtk/gtkcellrenderertext.c +++ b/gtk/gtkcellrenderertext.c @@ -705,7 +705,9 @@ gtk_cell_renderer_text_set_property (GObject *object, { GdkColor color; - if (gdk_color_parse (g_value_get_string (value), &color)) + if (!g_value_get_string (value)) + set_bg_color (celltext, NULL); /* reset to backgrounmd_set to FALSE */ + else if (gdk_color_parse (g_value_get_string (value), &color)) set_bg_color (celltext, &color); else g_warning ("Don't know color `%s'", g_value_get_string (value)); @@ -718,8 +720,10 @@ gtk_cell_renderer_text_set_property (GObject *object, { GdkColor color; - if (gdk_color_parse (g_value_get_string (value), &color)) - set_bg_color (celltext, &color); + if (!g_value_get_string (value)) + set_fg_color (celltext, NULL); /* reset to foreground_set to FALSE */ + else if (gdk_color_parse (g_value_get_string (value), &color)) + set_fg_color (celltext, &color); else g_warning ("Don't know color `%s'", g_value_get_string (value)); diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index d0eda95b2e..53a13e29fa 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -1009,7 +1009,6 @@ gtk_list_store_append (GtkListStore *list_store, GtkTreeIter *iter) { GtkTreePath *path; - gint i = 0; g_return_if_fail (list_store != NULL); g_return_if_fail (GTK_IS_LIST_STORE (list_store)); @@ -1030,7 +1029,7 @@ gtk_list_store_append (GtkListStore *list_store, validate_list_store (list_store); path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, i); + gtk_tree_path_append_index (path, list_store->length - 1); gtk_tree_model_inserted (GTK_TREE_MODEL (list_store), path, iter); gtk_tree_path_free (path); } diff --git a/gtk/gtkrbtree.c b/gtk/gtkrbtree.c index 2765599a5d..f4e7a17936 100644 --- a/gtk/gtkrbtree.c +++ b/gtk/gtkrbtree.c @@ -914,7 +914,14 @@ _gtk_rbtree_remove_node (GtkRBTree *tree, tree->root = x; if (y != node) - node->children = y->children; + { + /* Copy the node over */ + if (GTK_RBNODE_GET_COLOR (node) == GTK_RBNODE_BLACK) + node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_BLACK); + else + node->flags = ((y->flags & (GTK_RBNODE_NON_COLORS)) | GTK_RBNODE_RED); + node->children = y->children; + } if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK) _gtk_rbtree_remove_node_fixup (tree, x); diff --git a/gtk/gtkrbtree.h b/gtk/gtkrbtree.h index eea9160b62..8937b3200d 100644 --- a/gtk/gtkrbtree.h +++ b/gtk/gtkrbtree.h @@ -32,8 +32,8 @@ typedef enum GTK_RBNODE_IS_PARENT = 1 << 2, GTK_RBNODE_IS_SELECTED = 1 << 3, GTK_RBNODE_IS_PRELIT = 1 << 4, - GTK_RBNODE_IS_VIEW = 1 << 5 - + GTK_RBNODE_IS_VIEW = 1 << 5, + GTK_RBNODE_NON_COLORS = GTK_RBNODE_IS_PARENT | GTK_RBNODE_IS_SELECTED | GTK_RBNODE_IS_PRELIT | GTK_RBNODE_IS_VIEW, } GtkRBNodeColor; typedef struct _GtkRBTree GtkRBTree; diff --git a/gtk/gtktreemodel.c b/gtk/gtktreemodel.c index 8ad442dd7a..aa051f1155 100644 --- a/gtk/gtktreemodel.c +++ b/gtk/gtktreemodel.c @@ -516,6 +516,69 @@ struct _RowRefList GSList *list; }; + +/* + * row_reference + */ +void +_gtk_tree_row_reference_inserted (GtkTreeRowReference *reference, + GtkTreePath *path) +{ + if (reference->path) + { + gint depth = gtk_tree_path_get_depth (path); + gint ref_depth = gtk_tree_path_get_depth (reference->path); + + if (ref_depth >= depth) + { + gint *indices = gtk_tree_path_get_indices (path); + gint *ref_indices = gtk_tree_path_get_indices (reference->path); + gint i; + + /* This is the depth that might affect us. */ + i = depth - 1; + + if (indices[i] <= ref_indices[i]) + ref_indices[i] += 1; + } + } +} + +/* Returns TRUE if the reference path was deleted; FALSE otherwise */ +gboolean +_gtk_tree_row_reference_deleted (GtkTreeRowReference *reference, + GtkTreePath *path) +{ + if (reference->path) + { + gint depth = gtk_tree_path_get_depth (path); + gint ref_depth = gtk_tree_path_get_depth (reference->path); + + if (ref_depth >= depth) + { + /* Need to adjust path upward */ + gint *indices = gtk_tree_path_get_indices (path); + gint *ref_indices = gtk_tree_path_get_indices (reference->path); + gint i; + + i = depth - 1; + if (indices[i] < ref_indices[i]) + ref_indices[i] -= 1; + else if (indices[i] == ref_indices[i]) + { + /* the referenced node itself, or its parent, was + * deleted, mark invalid + */ + + gtk_tree_path_free (reference->path); + reference->path = NULL; + return TRUE; + } + } + } + return FALSE; +} + static void release_row_references (gpointer data) { @@ -562,28 +625,7 @@ inserted_callback (GtkTreeModel *tree_model, { GtkTreeRowReference *reference = tmp_list->data; - /* if reference->path == NULL then the reference was already - * deleted. - */ - - if (reference->path) - { - gint depth = gtk_tree_path_get_depth (path); - gint ref_depth = gtk_tree_path_get_depth (reference->path); - - if (ref_depth >= depth) - { - gint *indices = gtk_tree_path_get_indices (path); - gint *ref_indices = gtk_tree_path_get_indices (reference->path); - gint i; - - /* This is the depth that might affect us. */ - i = depth - 1; - - if (indices[i] <= ref_indices[i]) - ref_indices[i] += 1; - } - } + _gtk_tree_row_reference_inserted (reference, path); tmp_list = g_slist_next (tmp_list); } @@ -614,36 +656,7 @@ deleted_callback (GtkTreeModel *tree_model, { GtkTreeRowReference *reference = tmp_list->data; - /* if reference->path == NULL then the reference was already - * deleted. - */ - - if (reference->path) - { - gint depth = gtk_tree_path_get_depth (path); - gint ref_depth = gtk_tree_path_get_depth (reference->path); - - if (ref_depth >= depth) - { - /* Need to adjust path upward */ - gint *indices = gtk_tree_path_get_indices (path); - gint *ref_indices = gtk_tree_path_get_indices (reference->path); - gint i; - - i = depth - 1; - if (indices[i] < ref_indices[i]) - ref_indices[i] -= 1; - else if (indices[i] == ref_indices[i]) - { - /* the referenced node itself, or its parent, was - * deleted, mark invalid - */ - - gtk_tree_path_free (reference->path); - reference->path = NULL; - } - } - } + _gtk_tree_row_reference_deleted (reference, path); tmp_list = g_slist_next (tmp_list); } @@ -673,7 +686,7 @@ connect_ref_callbacks (GtkTreeModel *model, /* FIXME */ g_signal_connect_data (G_OBJECT (model), "reordered", - (GCallback) reorderedc_allback, + (GCallback) reordered_callback, refs, NULL, FALSE, @@ -721,7 +734,20 @@ gtk_tree_row_reference_new (GtkTreeModel *model, } refs->list = g_slist_prepend (refs->list, reference); + + return reference; +} + +GtkTreeRowReference * +_gtk_tree_row_reference_new_from_view (GtkTreePath *path) +{ + GtkTreeRowReference *reference; + reference = g_new (GtkTreeRowReference, 1); + + reference->model = NULL; + reference->path = gtk_tree_path_copy (path); + return reference; } diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h index 5e79d78fd0..74884b4f07 100644 --- a/gtk/gtktreeprivate.h +++ b/gtk/gtktreeprivate.h @@ -202,11 +202,19 @@ GtkTreePath *_gtk_tree_view_find_path (GtkTreeView *tree_v void _gtk_tree_view_update_size (GtkTreeView *tree_view); +void _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column, + GtkTreeView *tree_view); + GtkTreeSelection* _gtk_tree_selection_new (void); GtkTreeSelection* _gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view); void _gtk_tree_selection_set_tree_view (GtkTreeSelection *selection, GtkTreeView *tree_view); +GtkTreeRowReference *_gtk_tree_row_reference_new_from_view (GtkTreePath *path); +void _gtk_tree_row_reference_inserted (GtkTreeRowReference *reference, + GtkTreePath *path); +gboolean _gtk_tree_row_reference_deleted (GtkTreeRowReference *reference, + GtkTreePath *path); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtktreeselection.c b/gtk/gtktreeselection.c index baf424a141..a63fec367f 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->type == GTK_TREE_SELECTION_SINGLE) { - 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)) - { - gtk_tree_selection_select_range (selection, - anchor_path, - path); - } - else if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) - { - 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); - - 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); + /* 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 - dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE); + { + /* 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_SHIFT_MASK) == GDK_SHIFT_MASK) + else if (selection->type == GTK_TREE_SELECTION_MULTI) { - 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); + 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)) + { + 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 (selection->tree_view->priv->anchor) - gtk_tree_row_reference_free (selection->tree_view->priv->anchor); + 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_unselect_all (selection); + + 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) diff --git a/gtk/gtktreeselection.h b/gtk/gtktreeselection.h index ddbc91e265..9478872ca1 100644 --- a/gtk/gtktreeselection.h +++ b/gtk/gtktreeselection.h @@ -58,6 +58,7 @@ struct _GtkTreeSelection GtkTreeSelectionMode type; GtkTreeSelectionFunc user_func; gpointer user_data; + GtkDestroyNotify destroy; }; struct _GtkTreeSelectionClass @@ -74,7 +75,8 @@ void gtk_tree_selection_set_mode (GtkTreeSelection GtkTreeSelectionMode type); void gtk_tree_selection_set_select_function (GtkTreeSelection *selection, GtkTreeSelectionFunc func, - gpointer data); + gpointer data, + GtkDestroyNotify destroy); gpointer gtk_tree_selection_get_user_data (GtkTreeSelection *selection); GtkTreeView* gtk_tree_selection_get_tree_view (GtkTreeSelection *selection); diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 1c7ceb1a8f..3f3c5bfb1f 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -2742,7 +2742,8 @@ gtk_tree_view_deleted (GtkTreeModel *model, g_assert (tree_view->priv->prelight_node == NULL); - if (tree->root->count == 1) + if ((tree->root->count == 1) && + (tree_view->priv->tree != tree)) { _gtk_rbtree_remove (tree); } @@ -3438,7 +3439,10 @@ _gtk_tree_view_update_size (GtkTreeView *tree_view) width += TREE_VIEW_COLUMN_WIDTH (column); } - height = tree_view->priv->tree->root->offset + TREE_VIEW_VERTICAL_SEPARATOR; + if (tree_view->priv->tree == NULL) + height = 0; + else + height = tree_view->priv->tree->root->offset + TREE_VIEW_VERTICAL_SEPARATOR; if (tree_view->priv->width != width) { @@ -4416,6 +4420,13 @@ gtk_tree_view_get_background_xrange (GtkTreeView *tree_view, } } +void +_gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column, + GtkTreeView *tree_view) +{ + column->tree_view = tree_view; +} + static void gtk_tree_view_get_cell_xrange (GtkTreeView *tree_view, GtkRBTree *tree, diff --git a/tests/Makefile.am b/tests/Makefile.am index 1c39a38268..116d4f56aa 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -31,10 +31,17 @@ LDADDS = @STRIP_BEGIN@ \ @STRIP_END@ noinst_PROGRAMS = \ - testtreeview + testtreeview \ + testtreecolumns testtreeview_DEPENDENCIES = $(DEPS) testtreeview_LDADD = $(LDADDS) testtreeview_SOURCES = testtreeview.c + +testtreecolumns_DEPENDENCIES = $(DEPS) + +testtreecolumns_LDADD = $(LDADDS) + +testtreecolumns_SOURCES = testtreecolumns.c diff --git a/tests/testtreecolumns.c b/tests/testtreecolumns.c new file mode 100644 index 0000000000..8be6e1bc61 --- /dev/null +++ b/tests/testtreecolumns.c @@ -0,0 +1,127 @@ +#include + +GtkWidget *left_tree_view; +GtkWidget *right_tree_view; +GtkTreeModel *left_tree_model; +GtkTreeModel *right_tree_model; + +static void +add_clicked (GtkWidget *button, gpointer data) +{ + GtkTreeIter iter; + GtkTreeViewColumn *column; + static gint i = 0; + + gchar *label = g_strdup_printf ("Column %d", i); + column = gtk_tree_view_column_new (); + gtk_list_store_append (GTK_LIST_STORE (left_tree_model), &iter); + gtk_list_store_set (GTK_LIST_STORE (left_tree_model), &iter, 0, label, 1, column, -1); + g_free (label); + i++; +} + +static void +add_left_clicked (GtkWidget *button, gpointer data) +{ + +} + + +static void +add_right_clicked (GtkWidget *button, gpointer data) +{ + GtkTreeIter iter; + gchar *label; + GtkTreeViewColumn *column; + + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view)); + + gtk_tree_selection_get_selected (selection, NULL, &iter); + gtk_tree_model_get (GTK_TREE_MODEL (left_tree_model), + &iter, 0, &label, 1, &column, -1); + gtk_list_store_remove (GTK_LIST_STORE (left_tree_model), &iter); + + gtk_list_store_append (GTK_LIST_STORE (right_tree_model), &iter); + gtk_list_store_set (GTK_LIST_STORE (right_tree_model), &iter, 0, label, 1, column, -1); + g_free (label); +} + +static void +selection_changed (GtkTreeSelection *selection, GtkWidget *button) +{ + if (gtk_tree_selection_get_selected (selection, NULL, NULL)) + gtk_widget_set_sensitive (button, TRUE); + else + gtk_widget_set_sensitive (button, FALSE); +} + +int +main (int argc, char *argv[]) +{ + GtkWidget *window; + GtkWidget *hbox, *vbox, *bbox; + GtkWidget *button; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + GtkWidget *swindow; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (window), 500, 300); + vbox = gtk_vbox_new (FALSE, 8); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); + gtk_container_add (GTK_CONTAINER (window), vbox); + + hbox = gtk_hbox_new (FALSE, 8); + gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); + + cell = gtk_cell_renderer_text_new (); + g_object_set (G_OBJECT (cell), "foreground", "black", NULL); + left_tree_model = (GtkTreeModel *) gtk_list_store_new_with_types (2, G_TYPE_STRING, GTK_TYPE_POINTER); + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + left_tree_view = gtk_tree_view_new_with_model (left_tree_model); + gtk_container_add (GTK_CONTAINER (swindow), left_tree_view); + column = gtk_tree_view_column_new_with_attributes ("Unattached Columns", cell, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (left_tree_view), column); + gtk_box_pack_start (GTK_BOX (hbox), swindow, TRUE, TRUE, 0); + + bbox = gtk_vbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); + gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0); + gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, FALSE, 0); + + button = gtk_button_new_with_label ("<<"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), NULL); + gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0); + + button = gtk_button_new_with_label (">>"); + gtk_widget_set_sensitive (button, FALSE); + gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), NULL); + gtk_signal_connect (GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))), + "selection-changed", GTK_SIGNAL_FUNC (selection_changed), button); + gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0); + + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + right_tree_model = (GtkTreeModel *) gtk_list_store_new_with_types (2, G_TYPE_STRING, GTK_TYPE_POINTER); + right_tree_view = gtk_tree_view_new_with_model (right_tree_model); + column = gtk_tree_view_column_new_with_attributes ("Unattached Columns", cell, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (right_tree_view), column); + gtk_container_add (GTK_CONTAINER (swindow), right_tree_view); + gtk_box_pack_start (GTK_BOX (hbox), swindow, TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0); + + hbox = gtk_hbox_new (FALSE, 8); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + button = gtk_button_new_with_label ("Add new Column"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_clicked), left_tree_model); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + + gtk_widget_show_all (window); + gtk_main (); + + return 0; +}