X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpspp-sheet-view.c;h=c4eec5637c9e2664d4b3cee3c39840f20b9e59b0;hb=933ad79a28fbde607ec062b42d248169a2d16353;hp=4eab74e3609992b486e409006f2c2c63400724e6;hpb=a0a6abd7f428676f2c5dfa43bebc7d980d687fbb;p=pspp diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c index 4eab74e360..c4eec5637c 100644 --- a/src/ui/gui/pspp-sheet-view.c +++ b/src/ui/gui/pspp-sheet-view.c @@ -144,7 +144,9 @@ enum { PROP_RUBBER_BANDING, PROP_ENABLE_GRID_LINES, PROP_TOOLTIP_COLUMN, - PROP_SPECIAL_CELLS + PROP_SPECIAL_CELLS, + PROP_FIXED_HEIGHT, + PROP_FIXED_HEIGHT_SET }; /* object signals */ @@ -397,8 +399,6 @@ static void pspp_sheet_view_real_start_editing (PsppSheetView *tree_view, GdkRectangle *cell_area, GdkEvent *event, guint flags); -static void pspp_sheet_view_stop_editing (PsppSheetView *tree_view, - gboolean cancel_editing); static gboolean pspp_sheet_view_real_start_interactive_search (PsppSheetView *tree_view, gboolean keybinding); static gboolean pspp_sheet_view_start_interactive_search (PsppSheetView *tree_view); @@ -639,6 +639,24 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) PSPP_SHEET_VIEW_SPECIAL_CELLS_DETECT, GTK_PARAM_READWRITE)); + g_object_class_install_property (o_class, + PROP_FIXED_HEIGHT, + g_param_spec_int ("fixed-height", + P_("Fixed Height"), + P_("Height of a single row. Normally the height of a row is determined automatically. Writing this property sets fixed-height-set to true, preventing this property's value from changing."), + -1, + G_MAXINT, + -1, + GTK_PARAM_READWRITE)); + + g_object_class_install_property (o_class, + PROP_FIXED_HEIGHT_SET, + g_param_spec_boolean ("fixed-height-set", + P_("Fixed Height Set"), + P_("Whether fixed-height was set externally."), + FALSE, + GTK_PARAM_READWRITE)); + /* Style properties */ #define _TREE_VIEW_EXPANDER_SIZE 12 #define _TREE_VIEW_VERTICAL_SEPARATOR 2 @@ -996,6 +1014,7 @@ pspp_sheet_view_init (PsppSheetView *tree_view) tree_view->priv->presize_handler_timer = 0; tree_view->priv->scroll_sync_timer = 0; tree_view->priv->fixed_height = -1; + tree_view->priv->fixed_height_set = FALSE; pspp_sheet_view_set_adjustments (tree_view, NULL, NULL); tree_view->priv->selection = _pspp_sheet_selection_new_with_tree_view (tree_view); tree_view->priv->enable_search = TRUE; @@ -1030,6 +1049,8 @@ pspp_sheet_view_init (PsppSheetView *tree_view) tree_view->priv->rubber_band_end_node = -1; tree_view->priv->anchor_column = NULL; + + tree_view->priv->button_style = NULL; } @@ -1091,6 +1112,29 @@ pspp_sheet_view_set_property (GObject *object, case PROP_SPECIAL_CELLS: pspp_sheet_view_set_special_cells (tree_view, g_value_get_enum (value)); break; + case PROP_FIXED_HEIGHT: + pspp_sheet_view_set_fixed_height (tree_view, g_value_get_int (value)); + break; + case PROP_FIXED_HEIGHT_SET: + if (g_value_get_boolean (value)) + { + if (!tree_view->priv->fixed_height_set + && tree_view->priv->fixed_height >= 0) + { + tree_view->priv->fixed_height_set = true; + g_object_notify (G_OBJECT (tree_view), "fixed-height-set"); + } + } + else + { + if (tree_view->priv->fixed_height_set) + { + tree_view->priv->fixed_height_set = false; + g_object_notify (G_OBJECT (tree_view), "fixed-height-set"); + install_presize_handler (tree_view); + } + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1151,6 +1195,12 @@ pspp_sheet_view_get_property (GObject *object, case PROP_SPECIAL_CELLS: g_value_set_enum (value, tree_view->priv->special_cells); break; + case PROP_FIXED_HEIGHT: + g_value_set_int (value, pspp_sheet_view_get_fixed_height (tree_view)); + break; + case PROP_FIXED_HEIGHT_SET: + g_value_set_boolean (value, tree_view->priv->fixed_height_set); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1289,6 +1339,12 @@ pspp_sheet_view_destroy (GtkObject *object) tree_view->priv->vadjustment = NULL; } + if (tree_view->priv->button_style) + { + g_object_unref (tree_view->priv->button_style); + tree_view->priv->button_style = NULL; + } + GTK_OBJECT_CLASS (pspp_sheet_view_parent_class)->destroy (object); } @@ -1312,14 +1368,15 @@ pspp_sheet_view_map_buttons (PsppSheetView *tree_view) for (list = tree_view->priv->columns; list; list = list->next) { column = list->data; - if (gtk_widget_get_visible (column->button) && + if (column->button != NULL && + gtk_widget_get_visible (column->button) && !gtk_widget_get_mapped (column->button)) gtk_widget_map (column->button); } for (list = tree_view->priv->columns; list; list = list->next) { column = list->data; - if (column->visible == FALSE) + if (column->visible == FALSE || column->window == NULL) continue; if (column->resizable) { @@ -1538,12 +1595,7 @@ pspp_sheet_view_size_request_columns (PsppSheetView *tree_view) GtkRequisition requisition; PsppSheetViewColumn *column = list->data; - if (column->button == NULL) - continue; - - column = list->data; - - gtk_widget_size_request (column->button, &requisition); + pspp_sheet_view_column_size_request (column, &requisition); column->button_request = requisition.width; tree_view->priv->header_height = MAX (tree_view->priv->header_height, requisition.height); } @@ -1707,6 +1759,15 @@ pspp_sheet_view_get_real_requested_width_from_column (PsppSheetView *tree_ return real_requested_width; } +static gboolean +span_intersects (int a0, int a_width, + int b0, int b_width) +{ + int a1 = a0 + a_width; + int b1 = b0 + b_width; + return (a0 >= b0 && a0 < b1) || (b0 >= a0 && b0 < a1); +} + /* GtkWidget::size_allocate helper */ static void pspp_sheet_view_size_allocate_columns (GtkWidget *widget, @@ -1717,13 +1778,12 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget, PsppSheetViewColumn *column; GtkAllocation allocation; gint width = 0; - gint extra, extra_per_column, extra_for_last; + gint extra, extra_per_column; gint full_requested_width = 0; gint number_of_expand_columns = 0; gboolean column_changed = FALSE; gboolean rtl; - gboolean update_expand; - + tree_view = PSPP_SHEET_VIEW (widget); for (last_column = g_list_last (tree_view->priv->columns); @@ -1757,42 +1817,12 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget, number_of_expand_columns++; } - /* Only update the expand value if the width of the widget has changed, - * or the number of expand columns has changed, or if there are no expand - * columns, or if we didn't have an size-allocation yet after the - * last validated node. - */ - update_expand = (width_changed && *width_changed == TRUE) - || number_of_expand_columns != tree_view->priv->last_number_of_expand_columns - || number_of_expand_columns == 0 - || tree_view->priv->post_validation_flag == TRUE; - - tree_view->priv->post_validation_flag = FALSE; - - if (!update_expand) - { - extra = tree_view->priv->last_extra_space; - extra_for_last = MAX (widget->allocation.width - full_requested_width - extra, 0); - } - else - { - extra = MAX (widget->allocation.width - full_requested_width, 0); - extra_for_last = 0; - - tree_view->priv->last_extra_space = extra; - } - + extra = MAX (widget->allocation.width - full_requested_width, 0); if (number_of_expand_columns > 0) extra_per_column = extra/number_of_expand_columns; else extra_per_column = 0; - if (update_expand) - { - tree_view->priv->last_extra_space_per_column = extra_per_column; - tree_view->priv->last_number_of_expand_columns = number_of_expand_columns; - } - for (list = (rtl ? last_column : first_column); list != (rtl ? first_column->prev : last_column->next); list = (rtl ? list->prev : list->next)) @@ -1816,8 +1846,8 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget, &(drag_allocation.height)); drag_allocation.x = 0; drag_allocation.y = 0; - gtk_widget_size_allocate (tree_view->priv->drag_column->button, - &drag_allocation); + pspp_sheet_view_column_size_allocate (tree_view->priv->drag_column, + &drag_allocation); width += drag_allocation.width; continue; } @@ -1842,19 +1872,9 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget, number_of_expand_columns --; } } - else if (number_of_expand_columns == 0 && - list == last_column) - { - column->width += extra; - } - /* In addition to expand, the last column can get even more - * extra space so all available space is filled up. - */ - if (extra_for_last > 0 && list == last_column) - column->width += extra_for_last; - - g_object_notify (G_OBJECT (column), "width"); + if (column->width != old_width) + g_object_notify (G_OBJECT (column), "width"); allocation.width = column->width; width += column->width; @@ -1862,7 +1882,13 @@ pspp_sheet_view_size_allocate_columns (GtkWidget *widget, if (column->width > old_width) column_changed = TRUE; - gtk_widget_size_allocate (column->button, &allocation); + pspp_sheet_view_column_size_allocate (column, &allocation); + + if (span_intersects (allocation.x, allocation.width, + tree_view->priv->hadjustment->value, + widget->allocation.width) + && gtk_widget_get_realized (widget)) + pspp_sheet_view_column_set_need_button (column, TRUE); if (column->window) gdk_window_move_resize (column->window, @@ -2277,7 +2303,6 @@ pspp_sheet_view_button_press (GtkWidget *widget, PsppSheetViewColumn *column = NULL; GtkCellRenderer *focus_cell = NULL; gboolean row_double_click = FALSE; - gboolean node_selected; /* Empty tree? */ if (tree_view->priv->row_count == 0) @@ -2299,7 +2324,6 @@ pspp_sheet_view_button_press (GtkWidget *widget, return TRUE; /* select */ - node_selected = pspp_sheet_view_node_is_selected (tree_view, node); pre_val = tree_view->priv->vadjustment->value; path = _pspp_sheet_view_find_path (tree_view, node); @@ -2365,7 +2389,6 @@ pspp_sheet_view_button_press (GtkWidget *widget, tree_view->priv->press_start_node = node; if (tree_view->priv->rubber_banding_enable - //&& !node_selected && (tree_view->priv->selection->type == PSPP_SHEET_SELECTION_MULTIPLE || tree_view->priv->selection->type == PSPP_SHEET_SELECTION_RECTANGLE)) { @@ -2458,7 +2481,7 @@ pspp_sheet_view_button_press (GtkWidget *widget, gtk_grab_add (widget); PSPP_SHEET_VIEW_SET_FLAG (tree_view, PSPP_SHEET_VIEW_IN_COLUMN_RESIZE); - column->resized_width = column->width - tree_view->priv->last_extra_space_per_column; + column->resized_width = column->width; /* block attached dnd signal handler */ drag_data = g_object_get_data (G_OBJECT (widget), "gtk-site-data"); @@ -2469,7 +2492,7 @@ pspp_sheet_view_button_press (GtkWidget *widget, drag_data); tree_view->priv->drag_pos = i; - tree_view->priv->x_drag = column->button->allocation.x + (rtl ? 0 : column->button->allocation.width); + tree_view->priv->x_drag = column->allocation.x + (rtl ? 0 : column->allocation.width); if (!gtk_widget_has_focus (widget)) gtk_widget_grab_focus (widget); @@ -2496,6 +2519,8 @@ pspp_sheet_view_button_release_drag_column (GtkWidget *widget, gdk_display_keyboard_ungrab (gtk_widget_get_display (widget), GDK_CURRENT_TIME); /* Move the button back */ + g_return_val_if_fail (tree_view->priv->drag_column->button, FALSE); + g_object_ref (tree_view->priv->drag_column->button); gtk_container_remove (GTK_CONTAINER (tree_view), tree_view->priv->drag_column->button); gtk_widget_set_parent_window (tree_view->priv->drag_column->button, tree_view->priv->header_window); @@ -2843,9 +2868,9 @@ pspp_sheet_view_motion_draw_column_motion_arrow (PsppSheetView *tree_view) GdkRectangle visible_rect; pspp_sheet_view_get_visible_rect (tree_view, &visible_rect); if (reorder->left_column) - x = reorder->left_column->button->allocation.x + reorder->left_column->button->allocation.width; + x = reorder->left_column->allocation.x + reorder->left_column->allocation.width; else - x = reorder->right_column->button->allocation.x; + x = reorder->right_column->allocation.x; if (x < visible_rect.x) arrow_type = DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT; @@ -2874,8 +2899,8 @@ pspp_sheet_view_motion_draw_column_motion_arrow (PsppSheetView *tree_view) attributes.wclass = GDK_INPUT_OUTPUT; attributes.x = tree_view->priv->drag_column_x; attributes.y = 0; - width = attributes.width = tree_view->priv->drag_column->button->allocation.width; - height = attributes.height = tree_view->priv->drag_column->button->allocation.height; + width = attributes.width = tree_view->priv->drag_column->allocation.width; + height = attributes.height = tree_view->priv->drag_column->allocation.height; attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view)); attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view)); attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK; @@ -2911,13 +2936,13 @@ pspp_sheet_view_motion_draw_column_motion_arrow (PsppSheetView *tree_view) gdk_window_get_origin (tree_view->priv->header_window, &x, &y); if (reorder->left_column) { - x += reorder->left_column->button->allocation.x + reorder->left_column->button->allocation.width - width/2; - height = reorder->left_column->button->allocation.height; + x += reorder->left_column->allocation.x + reorder->left_column->allocation.width - width/2; + height = reorder->left_column->allocation.height; } else { - x += reorder->right_column->button->allocation.x - width/2; - height = reorder->right_column->button->allocation.height; + x += reorder->right_column->allocation.x - width/2; + height = reorder->right_column->allocation.height; } y -= tree_view->priv->expander_size/2; /* The arrow takes up only half the space */ height += tree_view->priv->expander_size; @@ -2990,9 +3015,9 @@ pspp_sheet_view_motion_draw_column_motion_arrow (PsppSheetView *tree_view) x += widget->allocation.width - width; if (reorder->left_column) - height = reorder->left_column->button->allocation.height; + height = reorder->left_column->allocation.height; else - height = reorder->right_column->button->allocation.height; + height = reorder->right_column->allocation.height; y -= tree_view->priv->expander_size; height += 2*tree_view->priv->expander_size; @@ -3089,8 +3114,10 @@ pspp_sheet_view_motion_resize_column (GtkWidget *widget, { column->use_resized_width = TRUE; column->resized_width = new_width; +#if 0 if (column->expand) column->resized_width -= tree_view->priv->last_extra_space_per_column; +#endif gtk_widget_queue_resize (widget); } @@ -3194,7 +3221,7 @@ pspp_sheet_view_motion_drag_column (GtkWidget *widget, /* Handle moving the header */ gdk_window_get_position (tree_view->priv->drag_window, &x, &y); x = CLAMP (x + (gint)event->x - column->drag_x, 0, - MAX (tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.width) - column->button->allocation.width); + MAX (tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.width) - column->allocation.width); gdk_window_move (tree_view->priv->drag_window, x, y); /* autoscroll, if needed */ @@ -3665,7 +3692,9 @@ draw_empty_focus (PsppSheetView *tree_view, GdkRectangle *clip_area) static void pspp_sheet_view_draw_grid_lines (PsppSheetView *tree_view, GdkEventExpose *event, - gint n_visible_columns) + gint n_visible_columns, + gint min_y, + gint max_y) { GList *list = tree_view->priv->columns; gint i = 0; @@ -3696,8 +3725,8 @@ pspp_sheet_view_draw_grid_lines (PsppSheetView *tree_view, && current_x - 1 < event->area.x + event->area.width) gdk_draw_line (event->window, tree_view->priv->grid_line_gc, - current_x - 1, 0, - current_x - 1, height); + current_x - 1, min_y, + current_x - 1, max_y - min_y); } } @@ -3721,7 +3750,6 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, gint new_y; gint y_offset, cell_offset; gint max_height; - gint depth; GdkRectangle background_area; GdkRectangle cell_area; guint flags; @@ -3740,6 +3768,7 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, gint grid_line_width; gboolean row_ending_details; gboolean draw_vgrid_lines, draw_hgrid_lines; + gint min_y, max_y; rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL); @@ -3793,7 +3822,6 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, gtk_tree_model_get_iter (tree_view->priv->model, &iter, path); - depth = gtk_tree_path_get_depth (path); gtk_tree_path_free (path); cursor_path = NULL; @@ -3847,6 +3875,7 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, * order, drawing each successive node. */ + min_y = y_offset; do { gboolean parity; @@ -3861,6 +3890,7 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, background_area.y = y_offset + event->area.y; background_area.height = max_height; + max_y = background_area.y + max_height; flags = 0; @@ -4112,6 +4142,21 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, cell_offset += column->width; } + if (cell_offset < event->area.x) + { + gtk_paint_flat_box (widget->style, + event->window, + GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + &event->area, + widget, + "base", + cell_offset, + background_area.y, + event->area.x - cell_offset, + background_area.height); + } + if (node == drag_highlight) { /* Draw indicator for the drop @@ -4251,7 +4296,8 @@ pspp_sheet_view_bin_expose (GtkWidget *widget, while (y_offset < event->area.height); done: - pspp_sheet_view_draw_grid_lines (tree_view, event, n_visible_columns); + pspp_sheet_view_draw_grid_lines (tree_view, event, n_visible_columns, + min_y, max_y); if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) { @@ -4279,7 +4325,7 @@ done: static gboolean pspp_sheet_view_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { PsppSheetView *tree_view = PSPP_SHEET_VIEW (widget); @@ -4308,20 +4354,47 @@ pspp_sheet_view_expose (GtkWidget *widget, else if (event->window == tree_view->priv->header_window) { + gint n_visible_columns; GList *list; - + + gtk_paint_flat_box (widget->style, + event->window, + GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + &event->area, + widget, + "cell_odd", + event->area.x, + event->area.y, + event->area.width, + event->area.height); + for (list = tree_view->priv->columns; list != NULL; list = list->next) { PsppSheetViewColumn *column = list->data; - if (column == tree_view->priv->drag_column) + if (column == tree_view->priv->drag_column || !column->visible) continue; - if (column->visible) - gtk_container_propagate_expose (GTK_CONTAINER (tree_view), - column->button, - event); + if (span_intersects (column->allocation.x, column->allocation.width, + event->area.x, event->area.width) + && column->button != NULL) + gtk_container_propagate_expose (GTK_CONTAINER (tree_view), + column->button, event); } + + n_visible_columns = 0; + for (list = tree_view->priv->columns; list; list = list->next) + { + if (! PSPP_SHEET_VIEW_COLUMN (list->data)->visible) + continue; + n_visible_columns ++; + } + pspp_sheet_view_draw_grid_lines (tree_view, + event, + n_visible_columns, + event->area.y, + event->area.height); } else if (event->window == tree_view->priv->drag_window) { @@ -4579,7 +4652,7 @@ pspp_sheet_view_key_press (GtkWidget *widget, { PsppSheetViewColumn *column = PSPP_SHEET_VIEW_COLUMN (focus_column->data); - if (gtk_widget_has_focus (column->button)) + if (column->button && gtk_widget_has_focus (column->button)) break; } @@ -4608,7 +4681,7 @@ pspp_sheet_view_key_press (GtkWidget *widget, column->resized_width = 0; if (column->min_width == -1) - column->resized_width = MAX (column->button->requisition.width, + column->resized_width = MAX (column->button_request, column->resized_width); else column->resized_width = MAX (column->min_width, @@ -4925,7 +4998,6 @@ validate_row (PsppSheetView *tree_view, gint horizontal_separator; gint vertical_separator; gint focus_line_width; - gboolean retval = FALSE; gboolean draw_vgrid_lines, draw_hgrid_lines; gint focus_pad; gint grid_line_width; @@ -4988,10 +5060,7 @@ validate_row (PsppSheetView *tree_view, } if (tmp_width > column->requested_width) - { - retval = TRUE; - column->requested_width = tmp_width; - } + column->requested_width = tmp_width; } if (draw_hgrid_lines) @@ -5216,6 +5285,9 @@ initialize_fixed_height_mode (PsppSheetView *tree_view) if (!tree_view->priv->row_count) return; + if (tree_view->priv->fixed_height_set) + return; + if (tree_view->priv->fixed_height < 0) { GtkTreeIter iter; @@ -5229,6 +5301,8 @@ initialize_fixed_height_mode (PsppSheetView *tree_view) tree_view->priv->fixed_height = validate_row (tree_view, node, &iter, path); gtk_tree_path_free (path); + + g_object_notify (G_OBJECT (tree_view), "fixed-height"); } } @@ -6463,6 +6537,27 @@ pspp_sheet_view_has_special_cell (PsppSheetView *tree_view) return FALSE; } +static void +pspp_sheet_view_focus_column (PsppSheetView *tree_view, + PsppSheetViewColumn *focus_column, + gboolean clamp_column_visible) +{ + g_return_if_fail (focus_column != NULL); + + tree_view->priv->focus_column = focus_column; + if (!focus_column->button) + { + pspp_sheet_view_column_set_need_button (focus_column, TRUE); + g_return_if_fail (focus_column->button != NULL); + } + + if (GTK_CONTAINER (tree_view)->focus_child != focus_column->button) + gtk_widget_grab_focus (focus_column->button); + + if (clamp_column_visible) + pspp_sheet_view_clamp_column_visible (tree_view, focus_column, FALSE); +} + /* Returns TRUE if the focus is within the headers, after the focus operation is * done */ @@ -6472,7 +6567,7 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, gboolean clamp_column_visible) { GtkWidget *focus_child; - + PsppSheetViewColumn *focus_column; GList *last_column, *first_column; GList *tmp_list; gboolean rtl; @@ -6485,10 +6580,9 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, first_column = tree_view->priv->columns; while (first_column) { - if (gtk_widget_get_can_focus (PSPP_SHEET_VIEW_COLUMN (first_column->data)->button) && - PSPP_SHEET_VIEW_COLUMN (first_column->data)->visible && - (PSPP_SHEET_VIEW_COLUMN (first_column->data)->clickable || - PSPP_SHEET_VIEW_COLUMN (first_column->data)->reorderable)) + PsppSheetViewColumn *c = PSPP_SHEET_VIEW_COLUMN (first_column->data); + + if (pspp_sheet_view_column_can_focus (c) && c->visible) break; first_column = first_column->next; } @@ -6501,10 +6595,9 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, last_column = g_list_last (tree_view->priv->columns); while (last_column) { - if (gtk_widget_get_can_focus (PSPP_SHEET_VIEW_COLUMN (last_column->data)->button) && - PSPP_SHEET_VIEW_COLUMN (last_column->data)->visible && - (PSPP_SHEET_VIEW_COLUMN (last_column->data)->clickable || - PSPP_SHEET_VIEW_COLUMN (last_column->data)->reorderable)) + PsppSheetViewColumn *c = PSPP_SHEET_VIEW_COLUMN (last_column->data); + + if (pspp_sheet_view_column_can_focus (c) && c->visible) break; last_column = last_column->prev; } @@ -6521,12 +6614,13 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, if (focus_child == NULL) { if (tree_view->priv->focus_column != NULL && - gtk_widget_get_can_focus (tree_view->priv->focus_column->button)) - focus_child = tree_view->priv->focus_column->button; + pspp_sheet_view_column_can_focus (tree_view->priv->focus_column)) + focus_column = tree_view->priv->focus_column; else - focus_child = PSPP_SHEET_VIEW_COLUMN (first_column->data)->button; - gtk_widget_grab_focus (focus_child); - break; + focus_column = first_column->data; + pspp_sheet_view_focus_column (tree_view, focus_column, + clamp_column_visible); + return TRUE; } return FALSE; @@ -6535,20 +6629,25 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, if (focus_child == NULL) { if (tree_view->priv->focus_column != NULL) - focus_child = tree_view->priv->focus_column->button; + focus_column = tree_view->priv->focus_column; else if (dir == GTK_DIR_LEFT) - focus_child = PSPP_SHEET_VIEW_COLUMN (last_column->data)->button; + focus_column = last_column->data; else - focus_child = PSPP_SHEET_VIEW_COLUMN (first_column->data)->button; - gtk_widget_grab_focus (focus_child); - break; + focus_column = first_column->data; + pspp_sheet_view_focus_column (tree_view, focus_column, + clamp_column_visible); + return TRUE; } if (gtk_widget_child_focus (focus_child, dir)) { /* The focus moves inside the button. */ /* This is probably a great example of bad UI */ - break; + if (clamp_column_visible) + pspp_sheet_view_clamp_column_visible (tree_view, + tree_view->priv->focus_column, + FALSE); + return TRUE; } /* We need to move the focus among the row of buttons. */ @@ -6560,7 +6659,7 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, || (tmp_list == last_column && dir == (rtl ? GTK_DIR_LEFT : GTK_DIR_RIGHT))) { gtk_widget_error_bell (GTK_WIDGET (tree_view)); - break; + return TRUE; } while (tmp_list) @@ -6580,39 +6679,21 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, column = tmp_list->data; if (column->button && column->visible && - gtk_widget_get_can_focus (column->button)) + pspp_sheet_view_column_can_focus (column)) { - focus_child = column->button; - gtk_widget_grab_focus (column->button); - break; + pspp_sheet_view_focus_column (tree_view, column, + clamp_column_visible); + return TRUE; } } - break; + return FALSE; + default: g_assert_not_reached (); break; } - /* if focus child is non-null, we assume it's been set to the current focus child - */ - if (focus_child) - { - for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) - if (PSPP_SHEET_VIEW_COLUMN (tmp_list->data)->button == focus_child) - { - tree_view->priv->focus_column = PSPP_SHEET_VIEW_COLUMN (tmp_list->data); - break; - } - - if (clamp_column_visible) - { - pspp_sheet_view_clamp_column_visible (tree_view, - tree_view->priv->focus_column, - FALSE); - } - } - - return (focus_child != NULL); + return FALSE; } /* This function returns in 'path' the first focusable path, if the given path @@ -6736,6 +6817,13 @@ pspp_sheet_view_style_set (GtkWidget *widget, tree_view->priv->fixed_height = -1; + /* Invalidate cached button style. */ + if (tree_view->priv->button_style) + { + g_object_unref (tree_view->priv->button_style); + tree_view->priv->button_style = NULL; + } + gtk_widget_queue_resize (widget); } @@ -7220,8 +7308,8 @@ pspp_sheet_view_clamp_column_visible (PsppSheetView *tree_view, if (column == NULL) return; - x = column->button->allocation.x; - width = column->button->allocation.width; + x = column->allocation.x; + width = column->allocation.width; if (width > tree_view->priv->hadjustment->page_size) { @@ -7431,9 +7519,9 @@ pspp_sheet_view_set_column_drag_info (PsppSheetView *tree_view, if (tmp_list->next != NULL) { g_assert (tmp_list->next->data); - left = reorder->right_align = (reorder->right_column->button->allocation.x + - reorder->right_column->button->allocation.width + - ((PsppSheetViewColumnReorder *)tmp_list->next->data)->left_column->button->allocation.x)/2; + left = reorder->right_align = (reorder->right_column->allocation.x + + reorder->right_column->allocation.width + + ((PsppSheetViewColumnReorder *)tmp_list->next->data)->left_column->allocation.x)/2; } else { @@ -7457,6 +7545,7 @@ _pspp_sheet_view_column_start_drag (PsppSheetView *tree_view, g_return_if_fail (tree_view->priv->column_drag_info == NULL); g_return_if_fail (tree_view->priv->cur_reorder == NULL); + g_return_if_fail (column->button); pspp_sheet_view_set_column_drag_info (tree_view, column); @@ -7470,10 +7559,10 @@ _pspp_sheet_view_column_start_drag (PsppSheetView *tree_view, attributes.window_type = GDK_WINDOW_CHILD; attributes.wclass = GDK_INPUT_OUTPUT; - attributes.x = column->button->allocation.x; + attributes.x = column->allocation.x; attributes.y = 0; - attributes.width = column->button->allocation.width; - attributes.height = column->button->allocation.height; + attributes.width = column->allocation.width; + attributes.height = column->allocation.height; attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view)); attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view)); attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK; @@ -7523,8 +7612,8 @@ _pspp_sheet_view_column_start_drag (PsppSheetView *tree_view, gtk_widget_set_parent (column->button, GTK_WIDGET (tree_view)); g_object_unref (column->button); - tree_view->priv->drag_column_x = column->button->allocation.x; - allocation = column->button->allocation; + tree_view->priv->drag_column_x = column->allocation.x; + allocation = column->allocation; allocation.x = 0; gtk_widget_size_allocate (column->button, &allocation); gtk_widget_set_parent_window (column->button, tree_view->priv->drag_window); @@ -8315,7 +8404,7 @@ pspp_sheet_view_real_start_interactive_search (PsppSheetView *tree_view, if (! column->visible) continue; - if (gtk_widget_has_focus (column->button)) + if (column->button && gtk_widget_has_focus (column->button)) { found_focus = TRUE; break; @@ -8391,19 +8480,17 @@ pspp_sheet_view_new_column_width (PsppSheetView *tree_view, */ rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL); column = g_list_nth (tree_view->priv->columns, i)->data; - width = rtl ? (column->button->allocation.x + column->button->allocation.width - *x) : (*x - column->button->allocation.x); + width = rtl ? (column->allocation.x + column->allocation.width - *x) : (*x - column->allocation.x); /* Clamp down the value */ if (column->min_width == -1) - width = MAX (column->button->requisition.width, - width); + width = MAX (column->button_request, width); else - width = MAX (column->min_width, - width); + width = MAX (column->min_width, width); if (column->max_width != -1) width = MIN (width, column->max_width); - *x = rtl ? (column->button->allocation.x + column->button->allocation.width - width) : (column->button->allocation.x + width); + *x = rtl ? (column->allocation.x + column->allocation.width - width) : (column->allocation.x + width); return width; } @@ -8480,6 +8567,9 @@ adjust_allocation (GtkWidget *widget, adjust_allocation_recurse (widget, &scroll_data); } +void +pspp_sheet_view_column_update_button (PsppSheetViewColumn *tree_column); + /* Callbacks */ static void pspp_sheet_view_adjustment_changed (GtkAdjustment *adjustment, @@ -8487,6 +8577,7 @@ pspp_sheet_view_adjustment_changed (GtkAdjustment *adjustment, { if (gtk_widget_get_realized (GTK_WIDGET (tree_view))) { + GList *list; gint dy; gdk_window_move (tree_view->priv->bin_window, @@ -8534,8 +8625,20 @@ pspp_sheet_view_adjustment_changed (GtkAdjustment *adjustment, pspp_sheet_view_dy_to_top_row (tree_view); } - gdk_window_process_updates (tree_view->priv->header_window, TRUE); - gdk_window_process_updates (tree_view->priv->bin_window, TRUE); + for (list = tree_view->priv->columns; list; list = list->next) + { + PsppSheetViewColumn *column = list->data; + GtkAllocation *allocation = &column->allocation; + + if (span_intersects (allocation->x, allocation->width, + tree_view->priv->hadjustment->value, + GTK_WIDGET (tree_view)->allocation.width)) + { + pspp_sheet_view_column_set_need_button (column, TRUE); + if (!column->button) + pspp_sheet_view_column_update_button (column); + } + } } } @@ -8670,7 +8773,6 @@ pspp_sheet_view_set_model (PsppSheetView *tree_view, if (tree_view->priv->model) { gint i; - GtkTreeModelFlags flags; if (tree_view->priv->search_column == -1) { @@ -8704,8 +8806,6 @@ pspp_sheet_view_set_model (PsppSheetView *tree_view, G_CALLBACK (pspp_sheet_view_rows_reordered), tree_view); - flags = gtk_tree_model_get_flags (tree_view->priv->model); - tree_view->priv->row_count = gtk_tree_model_iter_n_children (tree_view->priv->model, NULL); /* FIXME: do I need to do this? pspp_sheet_view_create_buttons (tree_view); */ @@ -8879,7 +8979,8 @@ pspp_sheet_view_set_headers_visible (PsppSheetView *tree_view, for (list = tree_view->priv->columns; list; list = list->next) { column = list->data; - gtk_widget_unmap (column->button); + if (column->button) + gtk_widget_unmap (column->button); } gdk_window_hide (tree_view->priv->header_window); } @@ -10908,7 +11009,6 @@ pspp_sheet_view_create_row_drag_icon (PsppSheetView *tree_view, GdkRectangle background_area; GdkRectangle expose_area; GtkWidget *widget; - gint depth; /* start drawing inside the black outline */ gint x = 1, y = 1; GdkDrawable *drawable; @@ -10923,8 +11023,6 @@ pspp_sheet_view_create_row_drag_icon (PsppSheetView *tree_view, if (!gtk_widget_get_realized (widget)) return NULL; - depth = gtk_tree_path_get_depth (path); - _pspp_sheet_view_find_node (tree_view, path, &node); @@ -12010,9 +12108,9 @@ pspp_sheet_view_real_start_editing (PsppSheetView *tree_view, } } -static void +void pspp_sheet_view_stop_editing (PsppSheetView *tree_view, - gboolean cancel_editing) + gboolean cancel_editing) { PsppSheetViewColumn *column; GtkCellRenderer *cell; @@ -12294,12 +12392,10 @@ pspp_sheet_view_set_special_cells (PsppSheetView *tree_view, PsppSheetViewSpecialCells special_cells) { PsppSheetViewPrivate *priv; - GtkWidget *widget; g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view)); priv = tree_view->priv; - widget = GTK_WIDGET (tree_view); if (priv->special_cells != special_cells) { @@ -12309,6 +12405,31 @@ pspp_sheet_view_set_special_cells (PsppSheetView *tree_view, } } +int +pspp_sheet_view_get_fixed_height (const PsppSheetView *tree_view) +{ + /* XXX (re)calculate fixed_height if necessary */ + return tree_view->priv->fixed_height; +} + +void +pspp_sheet_view_set_fixed_height (PsppSheetView *tree_view, + int fixed_height) +{ + g_return_if_fail (fixed_height > 0); + + if (tree_view->priv->fixed_height != fixed_height) + { + tree_view->priv->fixed_height = fixed_height; + g_object_notify (G_OBJECT (tree_view), "fixed-height"); + } + if (!tree_view->priv->fixed_height_set) + { + tree_view->priv->fixed_height_set = TRUE; + g_object_notify (G_OBJECT (tree_view), "fixed-height-set"); + } +} + /** * pspp_sheet_view_set_tooltip_row: * @tree_view: a #PsppSheetView