From 4038cd76b331ad4214ee5ae8b517ad79fcc65913 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Tue, 30 Nov 2010 16:36:07 +0900 Subject: [PATCH] Removed GtkTreeViewPrivate from gtktreeprivate.h and added a few more accessors. This actually much simplifies interaction with GtkTreeSelection (at least reduces code size where dealing width the treeview anchor path). --- gtk/gtkcombobox.c | 8 +- gtk/gtktreeprivate.h | 249 +++------------------------------ gtk/gtktreeselection.c | 198 ++++++++++++--------------- gtk/gtktreeview.c | 297 +++++++++++++++++++++++++++++++++++++++- gtk/gtktreeviewcolumn.c | 33 ++--- 5 files changed, 420 insertions(+), 365 deletions(-) diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index 4775fe930d..15c8df31f6 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -4415,10 +4415,12 @@ gtk_combo_box_list_select_func (GtkTreeSelection *selection, gboolean path_currently_selected, gpointer data) { - GList *list; + GList *list, *columns; gboolean sensitive = FALSE; - for (list = selection->tree_view->priv->columns; list && !sensitive; list = list->next) + columns = gtk_tree_view_get_columns (selection->tree_view); + + for (list = columns; list && !sensitive; list = list->next) { GList *cells, *cell; gboolean cell_sensitive, cell_visible; @@ -4450,6 +4452,8 @@ gtk_combo_box_list_select_func (GtkTreeSelection *selection, sensitive = cell_sensitive; } + g_list_free (columns); + return sensitive; } diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h index d018bdca9f..3277680b1f 100644 --- a/gtk/gtktreeprivate.h +++ b/gtk/gtktreeprivate.h @@ -37,238 +37,6 @@ typedef enum } GtkTreeSelectMode; -typedef struct _GtkTreeViewColumnReorder GtkTreeViewColumnReorder; -struct _GtkTreeViewColumnReorder -{ - gint left_align; - gint right_align; - GtkTreeViewColumn *left_column; - GtkTreeViewColumn *right_column; -}; - -struct _GtkTreeViewPrivate -{ - GtkTreeModel *model; - - guint flags; - /* tree information */ - GtkRBTree *tree; - - /* Container info */ - GList *children; - gint width; - gint height; - - /* Adjustments */ - GtkAdjustment *hadjustment; - GtkAdjustment *vadjustment; - gint min_display_width; - gint min_display_height; - - /* Sub windows */ - GdkWindow *bin_window; - GdkWindow *header_window; - - /* Scroll position state keeping */ - GtkTreeRowReference *top_row; - gint top_row_dy; - /* dy == y pos of top_row + top_row_dy */ - /* we cache it for simplicity of the code */ - gint dy; - - guint presize_handler_timer; - guint validate_rows_timer; - guint scroll_sync_timer; - - /* Indentation and expander layout */ - gint expander_size; - GtkTreeViewColumn *expander_column; - - gint level_indentation; - - /* Key navigation (focus), selection */ - gint cursor_offset; - - GtkTreeRowReference *anchor; - GtkTreeRowReference *cursor; - - GtkTreeViewColumn *focus_column; - - /* Current pressed node, previously pressed, prelight */ - GtkRBNode *button_pressed_node; - GtkRBTree *button_pressed_tree; - - gint pressed_button; - gint press_start_x; - gint press_start_y; - - gint event_last_x; - gint event_last_y; - - guint last_button_time; - gint last_button_x; - gint last_button_y; - - GtkRBNode *prelight_node; - GtkRBTree *prelight_tree; - - /* Cell Editing */ - GtkTreeViewColumn *edited_column; - - /* The node that's currently being collapsed or expanded */ - GtkRBNode *expanded_collapsed_node; - GtkRBTree *expanded_collapsed_tree; - guint expand_collapse_timeout; - - /* Auto expand/collapse timeout in hover mode */ - guint auto_expand_timeout; - - /* Selection information */ - GtkTreeSelection *selection; - - /* Header information */ - gint n_columns; - GList *columns; - gint header_height; - - GtkTreeViewColumnDropFunc column_drop_func; - gpointer column_drop_func_data; - GDestroyNotify column_drop_func_data_destroy; - GList *column_drag_info; - GtkTreeViewColumnReorder *cur_reorder; - - gint prev_width_before_expander; - - /* Interactive Header reordering */ - GdkWindow *drag_window; - GdkWindow *drag_highlight_window; - GtkTreeViewColumn *drag_column; - gint drag_column_x; - - /* Interactive Header Resizing */ - gint drag_pos; - gint x_drag; - - /* Non-interactive Header Resizing, expand flag support */ - gint prev_width; - - gint last_extra_space; - gint last_extra_space_per_column; - gint last_number_of_expand_columns; - - /* ATK Hack */ - GtkTreeDestroyCountFunc destroy_count_func; - gpointer destroy_count_data; - GDestroyNotify destroy_count_destroy; - - /* Scroll timeout (e.g. during dnd, rubber banding) */ - guint scroll_timeout; - - /* Row drag-and-drop */ - GtkTreeRowReference *drag_dest_row; - GtkTreeViewDropPosition drag_dest_pos; - guint open_dest_timeout; - - /* Rubber banding */ - gint rubber_band_status; - gint rubber_band_x; - gint rubber_band_y; - gint rubber_band_shift; - gint rubber_band_ctrl; - - GtkRBNode *rubber_band_start_node; - GtkRBTree *rubber_band_start_tree; - - GtkRBNode *rubber_band_end_node; - GtkRBTree *rubber_band_end_tree; - - /* fixed height */ - gint fixed_height; - - /* Scroll-to functionality when unrealized */ - GtkTreeRowReference *scroll_to_path; - GtkTreeViewColumn *scroll_to_column; - gfloat scroll_to_row_align; - gfloat scroll_to_col_align; - - /* Interactive search */ - gint selected_iter; - gint search_column; - GtkTreeViewSearchPositionFunc search_position_func; - GtkTreeViewSearchEqualFunc search_equal_func; - gpointer search_user_data; - GDestroyNotify search_destroy; - gpointer search_position_user_data; - GDestroyNotify search_position_destroy; - GtkWidget *search_window; - GtkWidget *search_entry; - gulong search_entry_changed_id; - guint typeselect_flush_timeout; - - /* Grid and tree lines */ - GtkTreeViewGridLines grid_lines; - double grid_line_dashes[2]; - int grid_line_width; - - gboolean tree_lines_enabled; - double tree_line_dashes[2]; - int tree_line_width; - - /* Row separators */ - GtkTreeViewRowSeparatorFunc row_separator_func; - gpointer row_separator_data; - GDestroyNotify row_separator_destroy; - - /* Tooltip support */ - gint tooltip_column; - - /* Here comes the bitfield */ - guint scroll_to_use_align : 1; - - guint fixed_height_mode : 1; - guint fixed_height_check : 1; - - guint reorderable : 1; - guint header_has_focus : 1; - guint drag_column_window_state : 3; - /* hint to display rows in alternating colors */ - guint has_rules : 1; - guint mark_rows_col_dirty : 1; - - /* for DnD */ - guint empty_view_drop : 1; - - guint ctrl_pressed : 1; - guint shift_pressed : 1; - - guint init_hadjust_value : 1; - - guint in_top_row_to_dy : 1; - - /* interactive search */ - guint enable_search : 1; - guint disable_popdown : 1; - guint search_custom_entry_set : 1; - - guint hover_selection : 1; - guint hover_expand : 1; - guint imcontext_changed : 1; - - guint rubber_banding_enable : 1; - - guint in_grab : 1; - - guint post_validation_flag : 1; - - /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */ - guint search_entry_avoid_unhandled_binding : 1; - - /* GtkScrollablePolicy needs to be checked when - * driving the scrollable adjustment values */ - guint hscroll_policy : 1; - guint vscroll_policy : 1; -}; - /* functions that shouldn't be exported */ void _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, GtkRBNode *node, @@ -304,11 +72,26 @@ void _gtk_tree_view_remove_editable (GtkTreeView *tree_v GtkTreeViewColumn *column, GtkCellEditable *cell_editable); -void _gtk_tree_view_install_mark_rows_col_dirty (GtkTreeView *tree_view); +void _gtk_tree_view_install_mark_rows_col_dirty (GtkTreeView *tree_view, + gboolean install_handler); void _gtk_tree_view_column_autosize (GtkTreeView *tree_view, GtkTreeViewColumn *column); gint _gtk_tree_view_get_header_height (GtkTreeView *tree_view); +void _gtk_tree_view_get_row_separator_func (GtkTreeView *tree_view, + GtkTreeViewRowSeparatorFunc *func, + gpointer *data); +GtkTreePath *_gtk_tree_view_get_anchor_path (GtkTreeView *tree_view); +void _gtk_tree_view_set_anchor_path (GtkTreeView *tree_view, + GtkTreePath *anchor_path); +GtkRBTree * _gtk_tree_view_get_rbtree (GtkTreeView *tree_view); + +GtkTreeViewColumn *_gtk_tree_view_get_focus_column (GtkTreeView *tree_view); +void _gtk_tree_view_set_focus_column (GtkTreeView *tree_view, + GtkTreeViewColumn *column); +GdkWindow *_gtk_tree_view_get_header_window (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, diff --git a/gtk/gtktreeselection.c b/gtk/gtktreeselection.c index 5ae0866146..8d2a164541 100644 --- a/gtk/gtktreeselection.c +++ b/gtk/gtktreeselection.c @@ -214,8 +214,7 @@ gtk_tree_selection_set_mode (GtkTreeSelection *selection, gtk_tree_selection_unselect_all (selection); selection->user_func = tmp_func; - gtk_tree_row_reference_free (selection->tree_view->priv->anchor); - selection->tree_view->priv->anchor = NULL; + _gtk_tree_view_set_anchor_path (selection->tree_view, NULL); } else if (type == GTK_SELECTION_SINGLE || type == GTK_SELECTION_BROWSE) @@ -225,20 +224,17 @@ gtk_tree_selection_set_mode (GtkTreeSelection *selection, gint selected = FALSE; GtkTreePath *anchor_path = NULL; - if (selection->tree_view->priv->anchor) + anchor_path = _gtk_tree_view_get_anchor_path (selection->tree_view); + + if (anchor_path) { - anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor); - - if (anchor_path) - { - _gtk_tree_view_find_node (selection->tree_view, - anchor_path, - &tree, - &node); - - if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED)) - selected = TRUE; - } + _gtk_tree_view_find_node (selection->tree_view, + anchor_path, + &tree, + &node); + + if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED)) + selected = TRUE; } /* We do this so that we unconditionally unset all rows @@ -393,12 +389,9 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection, memset (iter, 0, sizeof (GtkTreeIter)); if (model) - *model = selection->tree_view->priv->model; + *model = gtk_tree_view_get_model (selection->tree_view); - if (selection->tree_view->priv->anchor == NULL) - return FALSE; - - anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor); + anchor_path = _gtk_tree_view_get_anchor_path (selection->tree_view); if (anchor_path == NULL) return FALSE; @@ -418,7 +411,7 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection, if (iter == NULL) retval = TRUE; else - retval = gtk_tree_model_get_iter (selection->tree_view->priv->model, + retval = gtk_tree_model_get_iter (gtk_tree_view_get_model (selection->tree_view), iter, anchor_path); } @@ -467,10 +460,11 @@ gtk_tree_selection_get_selected_rows (GtkTreeSelection *selection, g_return_val_if_fail (selection->tree_view != NULL, NULL); if (model) - *model = selection->tree_view->priv->model; + *model = gtk_tree_view_get_model (selection->tree_view); - if (selection->tree_view->priv->tree == NULL || - selection->tree_view->priv->tree->root == NULL) + tree = _gtk_tree_view_get_rbtree (selection->tree_view); + + if (tree == NULL || tree->root == NULL) return NULL; if (selection->type == GTK_SELECTION_NONE) @@ -483,7 +477,7 @@ gtk_tree_selection_get_selected_rows (GtkTreeSelection *selection, { GtkTreePath *path; - path = gtk_tree_model_get_path (selection->tree_view->priv->model, &iter); + path = gtk_tree_model_get_path (gtk_tree_view_get_model (selection->tree_view), &iter); list = g_list_append (list, path); return list; @@ -492,8 +486,7 @@ gtk_tree_selection_get_selected_rows (GtkTreeSelection *selection, return NULL; } - tree = selection->tree_view->priv->tree; - node = selection->tree_view->priv->tree->root; + node = tree->root; while (node->left != tree->nil) node = node->left; @@ -582,12 +575,14 @@ gint gtk_tree_selection_count_selected_rows (GtkTreeSelection *selection) { gint count = 0; + GtkRBTree *tree; g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), 0); g_return_val_if_fail (selection->tree_view != NULL, 0); - if (selection->tree_view->priv->tree == NULL || - selection->tree_view->priv->tree->root == NULL) + tree = _gtk_tree_view_get_rbtree (selection->tree_view); + + if (tree == NULL || tree->root == NULL) return 0; if (selection->type == GTK_SELECTION_SINGLE || @@ -599,8 +594,7 @@ gtk_tree_selection_count_selected_rows (GtkTreeSelection *selection) return 0; } - _gtk_rbtree_traverse (selection->tree_view->priv->tree, - selection->tree_view->priv->tree->root, + _gtk_rbtree_traverse (tree, tree->root, G_PRE_ORDER, gtk_tree_selection_count_selected_rows_helper, &count); @@ -644,31 +638,32 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection *selection, g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - if (func == NULL || - selection->tree_view->priv->tree == NULL || - selection->tree_view->priv->tree->root == NULL) + tree = _gtk_tree_view_get_rbtree (selection->tree_view); + + if (func == NULL || tree == NULL || tree->root == NULL) return; + model = gtk_tree_view_get_model (selection->tree_view); + if (selection->type == GTK_SELECTION_SINGLE || selection->type == GTK_SELECTION_BROWSE) { - if (gtk_tree_row_reference_valid (selection->tree_view->priv->anchor)) + path = _gtk_tree_view_get_anchor_path (selection->tree_view); + + if (path) { - path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor); - gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path); - (* func) (selection->tree_view->priv->model, path, &iter, data); + gtk_tree_model_get_iter (model, &iter, path); + (* func) (model, path, &iter, data); gtk_tree_path_free (path); } return; } - tree = selection->tree_view->priv->tree; - node = selection->tree_view->priv->tree->root; + node = tree->root; while (node->left != tree->nil) node = node->left; - model = selection->tree_view->priv->model; g_object_ref (model); /* connect to signals to monitor changes in treemodel */ @@ -848,14 +843,16 @@ gtk_tree_selection_select_iter (GtkTreeSelection *selection, GtkTreeIter *iter) { GtkTreePath *path; + GtkTreeModel *model; g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - g_return_if_fail (selection->tree_view->priv->model != NULL); + + model = gtk_tree_view_get_model (selection->tree_view); + g_return_if_fail (model != NULL); g_return_if_fail (iter != NULL); - path = gtk_tree_model_get_path (selection->tree_view->priv->model, - iter); + path = gtk_tree_model_get_path (model, iter); if (path == NULL) return; @@ -877,14 +874,16 @@ gtk_tree_selection_unselect_iter (GtkTreeSelection *selection, GtkTreeIter *iter) { GtkTreePath *path; + GtkTreeModel *model; g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - g_return_if_fail (selection->tree_view->priv->model != NULL); + + model = gtk_tree_view_get_model (selection->tree_view); + g_return_if_fail (model != NULL); g_return_if_fail (iter != NULL); - path = gtk_tree_model_get_path (selection->tree_view->priv->model, - iter); + path = gtk_tree_model_get_path (model, iter); if (path == NULL) return; @@ -915,7 +914,7 @@ gtk_tree_selection_path_is_selected (GtkTreeSelection *selection, g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (selection->tree_view != NULL, FALSE); - if (selection->tree_view->priv->model == NULL) + if (gtk_tree_view_get_model (selection->tree_view) == NULL) return FALSE; ret = _gtk_tree_view_find_node (selection->tree_view, @@ -944,14 +943,17 @@ gtk_tree_selection_iter_is_selected (GtkTreeSelection *selection, GtkTreeIter *iter) { GtkTreePath *path; + GtkTreeModel *model; gboolean retval; g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE); g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (selection->tree_view != NULL, FALSE); - g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE); - path = gtk_tree_model_get_path (selection->tree_view->priv->model, iter); + model = gtk_tree_view_get_model (selection->tree_view); + g_return_val_if_fail (model != NULL, FALSE); + + path = gtk_tree_model_get_path (model, iter); if (path == NULL) return FALSE; @@ -995,8 +997,11 @@ static gint gtk_tree_selection_real_select_all (GtkTreeSelection *selection) { struct _TempTuple *tuple; + GtkRBTree *tree; - if (selection->tree_view->priv->tree == NULL) + tree = _gtk_tree_view_get_rbtree (selection->tree_view); + + if (tree == NULL) return FALSE; /* Mark all nodes selected */ @@ -1004,8 +1009,7 @@ gtk_tree_selection_real_select_all (GtkTreeSelection *selection) tuple->selection = selection; tuple->dirty = FALSE; - _gtk_rbtree_traverse (selection->tree_view->priv->tree, - selection->tree_view->priv->tree->root, + _gtk_rbtree_traverse (tree, tree->root, G_PRE_ORDER, select_all_helper, tuple); @@ -1031,7 +1035,8 @@ gtk_tree_selection_select_all (GtkTreeSelection *selection) g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - if (selection->tree_view->priv->tree == NULL || selection->tree_view->priv->model == NULL) + if (_gtk_tree_view_get_rbtree (selection->tree_view) == NULL || + gtk_tree_view_get_model (selection->tree_view) == NULL) return; g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE); @@ -1071,10 +1076,7 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection) GtkRBNode *node = NULL; GtkTreePath *anchor_path; - if (selection->tree_view->priv->anchor == NULL) - return FALSE; - - anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor); + anchor_path = _gtk_tree_view_get_anchor_path (selection->tree_view); if (anchor_path == NULL) return FALSE; @@ -1093,8 +1095,7 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection) { 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; + _gtk_tree_view_set_anchor_path (selection->tree_view, NULL); return TRUE; } } @@ -1102,12 +1103,14 @@ gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection) } else { + GtkRBTree *tree; + tuple = g_new (struct _TempTuple, 1); tuple->selection = selection; tuple->dirty = FALSE; - _gtk_rbtree_traverse (selection->tree_view->priv->tree, - selection->tree_view->priv->tree->root, + tree = _gtk_tree_view_get_rbtree (selection->tree_view); + _gtk_rbtree_traverse (tree, tree->root, G_PRE_ORDER, unselect_all_helper, tuple); @@ -1134,7 +1137,8 @@ gtk_tree_selection_unselect_all (GtkTreeSelection *selection) g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - if (selection->tree_view->priv->tree == NULL || selection->tree_view->priv->model == NULL) + if (_gtk_tree_view_get_rbtree (selection->tree_view) == NULL || + gtk_tree_view_get_model (selection->tree_view) == NULL) return; if (gtk_tree_selection_real_unselect_all (selection)) @@ -1197,15 +1201,7 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection, g_return_val_if_fail (end_node != NULL, FALSE); if (anchor_path) - { - 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_proxy (G_OBJECT (selection->tree_view), - selection->tree_view->priv->model, - anchor_path); - } + _gtk_tree_view_set_anchor_path (selection->tree_view, anchor_path); do { @@ -1254,7 +1250,7 @@ gtk_tree_selection_select_range (GtkTreeSelection *selection, g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE); - g_return_if_fail (selection->tree_view->priv->model != NULL); + g_return_if_fail (gtk_tree_view_get_model (selection->tree_view) != NULL); if (gtk_tree_selection_real_modify_range (selection, RANGE_SELECT, start_path, end_path)) g_signal_emit (selection, tree_selection_signals[CHANGED], 0); @@ -1278,7 +1274,7 @@ gtk_tree_selection_unselect_range (GtkTreeSelection *selection, { g_return_if_fail (GTK_IS_TREE_SELECTION (selection)); g_return_if_fail (selection->tree_view != NULL); - g_return_if_fail (selection->tree_view->priv->model != NULL); + g_return_if_fail (gtk_tree_view_get_model (selection->tree_view) != NULL); if (gtk_tree_selection_real_modify_range (selection, RANGE_UNSELECT, start_path, end_path)) g_signal_emit (selection, tree_selection_signals[CHANGED], 0); @@ -1290,22 +1286,28 @@ _gtk_tree_selection_row_is_selectable (GtkTreeSelection *selection, GtkTreePath *path) { GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeViewRowSeparatorFunc separator_func; + gpointer separator_data; gboolean sensitive = FALSE; - if (!gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path)) + model = gtk_tree_view_get_model (selection->tree_view); + + _gtk_tree_view_get_row_separator_func (selection->tree_view, + &separator_func, &separator_data); + + if (!gtk_tree_model_get_iter (model, &iter, path)) sensitive = TRUE; - if (!sensitive && selection->tree_view->priv->row_separator_func) + if (!sensitive && separator_func) { /* never allow separators to be selected */ - if ((* selection->tree_view->priv->row_separator_func) (selection->tree_view->priv->model, - &iter, - selection->tree_view->priv->row_separator_data)) + if ((* separator_func) (model, &iter, separator_data)) return FALSE; } if (selection->user_func) - return (*selection->user_func) (selection, selection->tree_view->priv->model, path, + return (*selection->user_func) (selection, model, path, GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED), selection->user_data); else @@ -1336,8 +1338,7 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, if (selection->type == GTK_SELECTION_NONE) return; - if (selection->tree_view->priv->anchor) - anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor); + anchor_path = _gtk_tree_view_get_anchor_path (selection->tree_view); if (selection->type == GTK_SELECTION_SINGLE || selection->type == GTK_SELECTION_BROWSE) @@ -1374,17 +1375,11 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, * old one, and can then select the new one */ if (dirty) { - if (selection->tree_view->priv->anchor) - { - gtk_tree_row_reference_free (selection->tree_view->priv->anchor); - selection->tree_view->priv->anchor = NULL; - } + + _gtk_tree_view_set_anchor_path (selection->tree_view, NULL); if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE)) - { - selection->tree_view->priv->anchor = - gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path); - } + _gtk_tree_view_set_anchor_path (selection->tree_view, path); } } else @@ -1392,11 +1387,8 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE)) { dirty = TRUE; - 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_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path); + _gtk_tree_view_set_anchor_path (selection->tree_view, path); } } } @@ -1406,11 +1398,8 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, if ((mode & GTK_TREE_SELECT_MODE_EXTEND) == GTK_TREE_SELECT_MODE_EXTEND && (anchor_path == NULL)) { - if (selection->tree_view->priv->anchor) - gtk_tree_row_reference_free (selection->tree_view->priv->anchor); + _gtk_tree_view_set_anchor_path (selection->tree_view, path); - selection->tree_view->priv->anchor = - gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path); dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE); } else if ((mode & (GTK_TREE_SELECT_MODE_EXTEND | GTK_TREE_SELECT_MODE_TOGGLE)) == (GTK_TREE_SELECT_MODE_EXTEND | GTK_TREE_SELECT_MODE_TOGGLE)) @@ -1422,11 +1411,8 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *selection, else if ((mode & GTK_TREE_SELECT_MODE_TOGGLE) == GTK_TREE_SELECT_MODE_TOGGLE) { 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_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path); + _gtk_tree_view_set_anchor_path (selection->tree_view, path); if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED) dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE); @@ -1445,11 +1431,7 @@ _gtk_tree_selection_internal_select_node (GtkTreeSelection *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); - - selection->tree_view->priv->anchor = - gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path); + _gtk_tree_view_set_anchor_path (selection->tree_view, path); dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE); } diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 22b7a5b611..bc72795cce 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -274,6 +274,14 @@ enum #define ROW_HEIGHT(tree_view,height) \ ((height > 0) ? (height) : (tree_view)->priv->expander_size) +typedef struct _GtkTreeViewColumnReorder GtkTreeViewColumnReorder; +struct _GtkTreeViewColumnReorder +{ + gint left_align; + gint right_align; + GtkTreeViewColumn *left_column; + GtkTreeViewColumn *right_column; +}; typedef struct _GtkTreeViewChild GtkTreeViewChild; struct _GtkTreeViewChild @@ -300,6 +308,230 @@ struct _TreeViewDragInfo }; +struct _GtkTreeViewPrivate +{ + GtkTreeModel *model; + + guint flags; + /* tree information */ + GtkRBTree *tree; + + /* Container info */ + GList *children; + gint width; + gint height; + + /* Adjustments */ + GtkAdjustment *hadjustment; + GtkAdjustment *vadjustment; + gint min_display_width; + gint min_display_height; + + /* Sub windows */ + GdkWindow *bin_window; + GdkWindow *header_window; + + /* Scroll position state keeping */ + GtkTreeRowReference *top_row; + gint top_row_dy; + /* dy == y pos of top_row + top_row_dy */ + /* we cache it for simplicity of the code */ + gint dy; + + guint presize_handler_timer; + guint validate_rows_timer; + guint scroll_sync_timer; + + /* Indentation and expander layout */ + gint expander_size; + GtkTreeViewColumn *expander_column; + + gint level_indentation; + + /* Key navigation (focus), selection */ + gint cursor_offset; + + GtkTreeRowReference *anchor; + GtkTreeRowReference *cursor; + + GtkTreeViewColumn *focus_column; + + /* Current pressed node, previously pressed, prelight */ + GtkRBNode *button_pressed_node; + GtkRBTree *button_pressed_tree; + + gint pressed_button; + gint press_start_x; + gint press_start_y; + + gint event_last_x; + gint event_last_y; + + guint last_button_time; + gint last_button_x; + gint last_button_y; + + GtkRBNode *prelight_node; + GtkRBTree *prelight_tree; + + /* Cell Editing */ + GtkTreeViewColumn *edited_column; + + /* The node that's currently being collapsed or expanded */ + GtkRBNode *expanded_collapsed_node; + GtkRBTree *expanded_collapsed_tree; + guint expand_collapse_timeout; + + /* Auto expand/collapse timeout in hover mode */ + guint auto_expand_timeout; + + /* Selection information */ + GtkTreeSelection *selection; + + /* Header information */ + gint n_columns; + GList *columns; + gint header_height; + + GtkTreeViewColumnDropFunc column_drop_func; + gpointer column_drop_func_data; + GDestroyNotify column_drop_func_data_destroy; + GList *column_drag_info; + GtkTreeViewColumnReorder *cur_reorder; + + gint prev_width_before_expander; + + /* Interactive Header reordering */ + GdkWindow *drag_window; + GdkWindow *drag_highlight_window; + GtkTreeViewColumn *drag_column; + gint drag_column_x; + + /* Interactive Header Resizing */ + gint drag_pos; + gint x_drag; + + /* Non-interactive Header Resizing, expand flag support */ + gint prev_width; + + gint last_extra_space; + gint last_extra_space_per_column; + gint last_number_of_expand_columns; + + /* ATK Hack */ + GtkTreeDestroyCountFunc destroy_count_func; + gpointer destroy_count_data; + GDestroyNotify destroy_count_destroy; + + /* Scroll timeout (e.g. during dnd, rubber banding) */ + guint scroll_timeout; + + /* Row drag-and-drop */ + GtkTreeRowReference *drag_dest_row; + GtkTreeViewDropPosition drag_dest_pos; + guint open_dest_timeout; + + /* Rubber banding */ + gint rubber_band_status; + gint rubber_band_x; + gint rubber_band_y; + gint rubber_band_shift; + gint rubber_band_ctrl; + + GtkRBNode *rubber_band_start_node; + GtkRBTree *rubber_band_start_tree; + + GtkRBNode *rubber_band_end_node; + GtkRBTree *rubber_band_end_tree; + + /* fixed height */ + gint fixed_height; + + /* Scroll-to functionality when unrealized */ + GtkTreeRowReference *scroll_to_path; + GtkTreeViewColumn *scroll_to_column; + gfloat scroll_to_row_align; + gfloat scroll_to_col_align; + + /* Interactive search */ + gint selected_iter; + gint search_column; + GtkTreeViewSearchPositionFunc search_position_func; + GtkTreeViewSearchEqualFunc search_equal_func; + gpointer search_user_data; + GDestroyNotify search_destroy; + gpointer search_position_user_data; + GDestroyNotify search_position_destroy; + GtkWidget *search_window; + GtkWidget *search_entry; + gulong search_entry_changed_id; + guint typeselect_flush_timeout; + + /* Grid and tree lines */ + GtkTreeViewGridLines grid_lines; + double grid_line_dashes[2]; + int grid_line_width; + + gboolean tree_lines_enabled; + double tree_line_dashes[2]; + int tree_line_width; + + /* Row separators */ + GtkTreeViewRowSeparatorFunc row_separator_func; + gpointer row_separator_data; + GDestroyNotify row_separator_destroy; + + /* Tooltip support */ + gint tooltip_column; + + /* Here comes the bitfield */ + guint scroll_to_use_align : 1; + + guint fixed_height_mode : 1; + guint fixed_height_check : 1; + + guint reorderable : 1; + guint header_has_focus : 1; + guint drag_column_window_state : 3; + /* hint to display rows in alternating colors */ + guint has_rules : 1; + guint mark_rows_col_dirty : 1; + + /* for DnD */ + guint empty_view_drop : 1; + + guint ctrl_pressed : 1; + guint shift_pressed : 1; + + guint init_hadjust_value : 1; + + guint in_top_row_to_dy : 1; + + /* interactive search */ + guint enable_search : 1; + guint disable_popdown : 1; + guint search_custom_entry_set : 1; + + guint hover_selection : 1; + guint hover_expand : 1; + guint imcontext_changed : 1; + + guint rubber_banding_enable : 1; + + guint in_grab : 1; + + guint post_validation_flag : 1; + + /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */ + guint search_entry_avoid_unhandled_binding : 1; + + /* GtkScrollablePolicy needs to be checked when + * driving the scrollable adjustment values */ + guint hscroll_policy : 1; + guint vscroll_policy : 1; +}; + + /* Signals */ enum { @@ -6880,11 +7112,13 @@ gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view) void -_gtk_tree_view_install_mark_rows_col_dirty (GtkTreeView *tree_view) +_gtk_tree_view_install_mark_rows_col_dirty (GtkTreeView *tree_view, + gboolean install_handler) { tree_view->priv->mark_rows_col_dirty = TRUE; - install_presize_handler (tree_view); + if (install_handler) + install_presize_handler (tree_view); } /* @@ -9729,6 +9963,65 @@ _gtk_tree_view_get_header_height (GtkTreeView *tree_view) return tree_view->priv->header_height; } +void +_gtk_tree_view_get_row_separator_func (GtkTreeView *tree_view, + GtkTreeViewRowSeparatorFunc *func, + gpointer *data) +{ + *func = tree_view->priv->row_separator_func; + *data = tree_view->priv->row_separator_data; +} + +GtkTreePath * +_gtk_tree_view_get_anchor_path (GtkTreeView *tree_view) +{ + if (tree_view->priv->anchor) + return gtk_tree_row_reference_get_path (tree_view->priv->anchor); + + return NULL; +} + +void +_gtk_tree_view_set_anchor_path (GtkTreeView *tree_view, + GtkTreePath *anchor_path) +{ + if (tree_view->priv->anchor) + { + gtk_tree_row_reference_free (tree_view->priv->anchor); + tree_view->priv->anchor = NULL; + } + + if (anchor_path && tree_view->priv->model) + tree_view->priv->anchor = + gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), + tree_view->priv->model, anchor_path); +} + +GtkRBTree * +_gtk_tree_view_get_rbtree (GtkTreeView *tree_view) +{ + return tree_view->priv->tree; +} + +GtkTreeViewColumn * +_gtk_tree_view_get_focus_column (GtkTreeView *tree_view) +{ + return tree_view->priv->focus_column; +} + +GdkWindow * +_gtk_tree_view_get_header_window (GtkTreeView *tree_view) +{ + return tree_view->priv->header_window; +} + +void +_gtk_tree_view_set_focus_column (GtkTreeView *tree_view, + GtkTreeViewColumn *column) +{ + tree_view->priv->focus_column = column; +} + static void gtk_tree_view_queue_draw_path (GtkTreeView *tree_view, diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index 33c9645894..76e32ce2d5 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -757,8 +757,9 @@ gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column) gtk_widget_pop_composite_child (); /* make sure we own a reference to it as well. */ - if (tree_view->priv->header_window) - gtk_widget_set_parent_window (priv->button, tree_view->priv->header_window); + if (_gtk_tree_view_get_header_window (tree_view)) + gtk_widget_set_parent_window (priv->button, _gtk_tree_view_get_header_window (tree_view)); + gtk_widget_set_parent (priv->button, GTK_WIDGET (tree_view)); g_signal_connect (priv->button, "event", @@ -1057,8 +1058,7 @@ gtk_tree_view_column_mnemonic_activate (GtkWidget *widget, g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (column), FALSE); - /* XXX Direct access to treeview */ - GTK_TREE_VIEW (priv->tree_view)->priv->focus_column = column; + _gtk_tree_view_set_focus_column (GTK_TREE_VIEW (priv->tree_view), column); if (priv->clickable) gtk_button_clicked (GTK_BUTTON (priv->button)); @@ -1262,9 +1262,8 @@ _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column) g_return_if_fail (gtk_widget_get_realized (priv->tree_view)); g_return_if_fail (priv->button != NULL); - /* XXX Access to GtkTreeView->priv */ - g_return_if_fail (tree_view->priv->header_window != NULL); - gtk_widget_set_parent_window (priv->button, tree_view->priv->header_window); + g_return_if_fail (_gtk_tree_view_get_header_window (tree_view) != NULL); + gtk_widget_set_parent_window (priv->button, _gtk_tree_view_get_header_window (tree_view)); if (priv->visible) gtk_widget_show (priv->button); @@ -1279,16 +1278,16 @@ _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column) GDK_POINTER_MOTION_HINT_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y; - attr.cursor = gdk_cursor_new_for_display (gdk_window_get_display (tree_view->priv->header_window), - GDK_SB_H_DOUBLE_ARROW); + attr.cursor = gdk_cursor_new_for_display + (gdk_window_get_display (_gtk_tree_view_get_header_window (tree_view)), GDK_SB_H_DOUBLE_ARROW); attr.y = 0; attr.width = TREE_VIEW_DRAG_WIDTH; - attr.height = tree_view->priv->header_height; + attr.height = _gtk_tree_view_get_header_height (tree_view); gtk_widget_get_allocation (priv->button, &allocation); attr.x = (allocation.x + (rtl ? 0 : allocation.width)) - TREE_VIEW_DRAG_WIDTH / 2; - priv->window = gdk_window_new (tree_view->priv->header_window, - &attr, attributes_mask); + priv->window = gdk_window_new (_gtk_tree_view_get_header_window (tree_view), + &attr, attributes_mask); gdk_window_set_user_data (priv->window, tree_view); gtk_tree_view_column_update_button (column); @@ -2764,9 +2763,7 @@ _gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column, /* if we are the current focus column and have multiple editable cells, * try to select the next one, else move the focus to the next column */ - - /* XXX Access to GtkTreeViewPrivate */ - if (GTK_TREE_VIEW (priv->tree_view)->priv->focus_column == tree_column) + if (_gtk_tree_view_get_focus_column (GTK_TREE_VIEW (priv->tree_view)) == tree_column) { if (gtk_cell_area_focus (priv->cell_area, direction)) /* Focus stays in this column, so we are done */ @@ -2859,11 +2856,7 @@ _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column, if (priv->tree_view && gtk_widget_get_realized (priv->tree_view)) { - if (install_handler) - _gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (priv->tree_view)); - else - /* XXX Access to GtkTreeViewPrivate */ - GTK_TREE_VIEW (priv->tree_view)->priv->mark_rows_col_dirty = TRUE; + _gtk_tree_view_install_mark_rows_col_dirty (GTK_TREE_VIEW (priv->tree_view), install_handler); gtk_widget_queue_resize (priv->tree_view); } }