X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpspp-sheet-view.c;h=a040954a407ebf6b665d604e8f13c5447a4efeb6;hb=refs%2Fbuilds%2F20121129032043%2Fpspp;hp=c569d20403c201d967cbe7832349f71452141901;hpb=368a055fded96761bc761a7d05b775ce7902be63;p=pspp diff --git a/src/ui/gui/pspp-sheet-view.c b/src/ui/gui/pspp-sheet-view.c index c569d20403..a040954a40 100644 --- a/src/ui/gui/pspp-sheet-view.c +++ b/src/ui/gui/pspp-sheet-view.c @@ -315,12 +315,16 @@ static void pspp_sheet_view_clamp_column_visible (PsppSheetView static gboolean pspp_sheet_view_maybe_begin_dragging_row (PsppSheetView *tree_view, GdkEventMotion *event); static void pspp_sheet_view_focus_to_cursor (PsppSheetView *tree_view); -static void pspp_sheet_view_move_cursor_up_down (PsppSheetView *tree_view, +static gboolean pspp_sheet_view_move_cursor_up_down (PsppSheetView *tree_view, gint count); static void pspp_sheet_view_move_cursor_page_up_down (PsppSheetView *tree_view, gint count); static void pspp_sheet_view_move_cursor_left_right (PsppSheetView *tree_view, gint count); +static void pspp_sheet_view_move_cursor_line_start_end (PsppSheetView *tree_view, + gint count); +static void pspp_sheet_view_move_cursor_tab (PsppSheetView *tree_view, + gint count); static void pspp_sheet_view_move_cursor_start_end (PsppSheetView *tree_view, gint count); static void pspp_sheet_view_real_set_cursor (PsppSheetView *tree_view, @@ -893,14 +897,14 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) GTK_MOVEMENT_DISPLAY_LINES, 1); pspp_sheet_view_add_move_binding (binding_set[i], GDK_Home, 0, TRUE, - GTK_MOVEMENT_BUFFER_ENDS, -1); + GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1); pspp_sheet_view_add_move_binding (binding_set[i], GDK_KP_Home, 0, TRUE, - GTK_MOVEMENT_BUFFER_ENDS, -1); + GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1); pspp_sheet_view_add_move_binding (binding_set[i], GDK_End, 0, TRUE, - GTK_MOVEMENT_BUFFER_ENDS, 1); + GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); pspp_sheet_view_add_move_binding (binding_set[i], GDK_KP_End, 0, TRUE, - GTK_MOVEMENT_BUFFER_ENDS, 1); + GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); pspp_sheet_view_add_move_binding (binding_set[i], GDK_Page_Up, 0, TRUE, GTK_MOVEMENT_PAGES, -1); @@ -921,6 +925,14 @@ pspp_sheet_view_class_init (PsppSheetViewClass *class) G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS, G_TYPE_INT, -1); + gtk_binding_entry_add_signal (binding_set[i], GDK_Tab, 0, "move-cursor", 2, + G_TYPE_ENUM, GTK_MOVEMENT_LOGICAL_POSITIONS, + G_TYPE_INT, 1); + + gtk_binding_entry_add_signal (binding_set[i], GDK_Tab, GDK_SHIFT_MASK, "move-cursor", 2, + G_TYPE_ENUM, GTK_MOVEMENT_LOGICAL_POSITIONS, + G_TYPE_INT, -1); + gtk_binding_entry_add_signal (binding_set[i], GDK_KP_Right, 0, "move-cursor", 2, G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS, G_TYPE_INT, 1); @@ -2321,7 +2333,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) @@ -2343,7 +2354,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); @@ -2409,7 +2419,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)) { @@ -2638,6 +2647,10 @@ pspp_sheet_view_button_release_edit (PsppSheetView *tree_view, if (event->window != tree_view->priv->bin_window) return FALSE; + /* Ignore a released button, if that button wasn't depressed */ + if (tree_view->priv->pressed_button != event->button) + return FALSE; + if (!find_click (tree_view, event->x, event->y, &node, &column, &background_area, &cell_area)) return FALSE; @@ -3771,7 +3784,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; @@ -3844,7 +3856,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; @@ -5021,7 +5032,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; @@ -5084,10 +5094,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) @@ -6707,13 +6714,16 @@ pspp_sheet_view_header_focus (PsppSheetView *tree_view, break; } column = tmp_list->data; - if (column->button && - column->visible && + if (column->visible && pspp_sheet_view_column_can_focus (column)) - { - pspp_sheet_view_focus_column (tree_view, column, - clamp_column_visible); - return TRUE; + { + pspp_sheet_view_column_set_need_button (column, TRUE); + if (column->button) + { + pspp_sheet_view_focus_column (tree_view, column, + clamp_column_visible); + return TRUE; + } } } return FALSE; @@ -6959,7 +6969,8 @@ pspp_sheet_view_real_move_cursor (PsppSheetView *tree_view, step == GTK_MOVEMENT_VISUAL_POSITIONS || step == GTK_MOVEMENT_DISPLAY_LINES || step == GTK_MOVEMENT_PAGES || - step == GTK_MOVEMENT_BUFFER_ENDS, FALSE); + step == GTK_MOVEMENT_BUFFER_ENDS || + step == GTK_MOVEMENT_DISPLAY_LINE_ENDS, FALSE); if (tree_view->priv->row_count == 0) return FALSE; @@ -6981,8 +6992,9 @@ pspp_sheet_view_real_move_cursor (PsppSheetView *tree_view, switch (step) { - /* currently we make no distinction. When we go bi-di, we need to */ case GTK_MOVEMENT_LOGICAL_POSITIONS: + pspp_sheet_view_move_cursor_tab (tree_view, count); + break; case GTK_MOVEMENT_VISUAL_POSITIONS: pspp_sheet_view_move_cursor_left_right (tree_view, count); break; @@ -6995,6 +7007,9 @@ pspp_sheet_view_real_move_cursor (PsppSheetView *tree_view, case GTK_MOVEMENT_BUFFER_ENDS: pspp_sheet_view_move_cursor_start_end (tree_view, count); break; + case GTK_MOVEMENT_DISPLAY_LINE_ENDS: + pspp_sheet_view_move_cursor_line_start_end (tree_view, count); + break; default: g_assert_not_reached (); } @@ -7799,7 +7814,7 @@ pspp_sheet_view_focus_to_cursor (PsppSheetView *tree_view) } } -static void +static gboolean pspp_sheet_view_move_cursor_up_down (PsppSheetView *tree_view, gint count) { @@ -7810,19 +7825,19 @@ pspp_sheet_view_move_cursor_up_down (PsppSheetView *tree_view, gboolean grab_focus = TRUE; if (! gtk_widget_has_focus (GTK_WIDGET (tree_view))) - return; + return FALSE; cursor_path = NULL; if (!gtk_tree_row_reference_valid (tree_view->priv->cursor)) /* FIXME: we lost the cursor; should we get the first? */ - return; + return FALSE; cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor); _pspp_sheet_view_find_node (tree_view, cursor_path, &cursor_node); if (cursor_node < 0) /* FIXME: we lost the cursor; should we get the first? */ - return; + return FALSE; selection_count = pspp_sheet_selection_count_selected_rows (tree_view->priv->selection); @@ -7914,6 +7929,8 @@ pspp_sheet_view_move_cursor_up_down (PsppSheetView *tree_view, if (grab_focus) gtk_widget_grab_focus (GTK_WIDGET (tree_view)); + + return new_cursor_node >= 0; } static void @@ -8102,6 +8119,209 @@ pspp_sheet_view_move_cursor_left_right (PsppSheetView *tree_view, tree_view->priv->focus_column, TRUE); } +static void +pspp_sheet_view_move_cursor_line_start_end (PsppSheetView *tree_view, + gint count) +{ + int cursor_node = -1; + GtkTreePath *cursor_path = NULL; + PsppSheetViewColumn *column; + PsppSheetViewColumn *found_column; + GtkTreeIter iter; + GList *list; + gboolean rtl; + + rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL); + + if (!gtk_widget_has_focus (GTK_WIDGET (tree_view))) + return; + + if (gtk_tree_row_reference_valid (tree_view->priv->cursor)) + cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor); + else + return; + + _pspp_sheet_view_find_node (tree_view, cursor_path, &cursor_node); + if (cursor_node < 0) + return; + if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path) == FALSE) + { + gtk_tree_path_free (cursor_path); + return; + } + gtk_tree_path_free (cursor_path); + + list = rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns); + if (tree_view->priv->focus_column) + { + for (; list; list = (rtl ? list->prev : list->next)) + { + if (list->data == tree_view->priv->focus_column) + break; + } + } + + found_column = NULL; + while (list) + { + gboolean left, right; + + column = list->data; + if (column->visible == FALSE || column->row_head) + goto loop_end; + + pspp_sheet_view_column_cell_set_cell_data (column, + tree_view->priv->model, + &iter); + + if (rtl) + { + right = list->prev ? TRUE : FALSE; + left = list->next ? TRUE : FALSE; + } + else + { + left = list->prev ? TRUE : FALSE; + right = list->next ? TRUE : FALSE; + } + + if (column->tabbable + && _pspp_sheet_view_column_cell_focus (column, count, left, right)) + found_column = column; + + loop_end: + if (count == 1) + list = rtl ? list->prev : list->next; + else + list = rtl ? list->next : list->prev; + } + + if (found_column) + { + tree_view->priv->focus_column = found_column; + _pspp_sheet_view_queue_draw_node (tree_view, cursor_node, NULL); + g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0); + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); + } + + pspp_sheet_view_clamp_column_visible (tree_view, + tree_view->priv->focus_column, TRUE); +} + +static gboolean +try_move_cursor_tab (PsppSheetView *tree_view, + gboolean start_at_focus_column, + gint count) +{ + PsppSheetViewColumn *column; + GtkTreeIter iter; + int cursor_node = -1; + GtkTreePath *cursor_path = NULL; + gboolean rtl; + GList *list; + + if (gtk_tree_row_reference_valid (tree_view->priv->cursor)) + cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor); + else + return TRUE; + + _pspp_sheet_view_find_node (tree_view, cursor_path, &cursor_node); + if (cursor_node < 0) + return TRUE; + if (gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path) == FALSE) + { + gtk_tree_path_free (cursor_path); + return TRUE; + } + gtk_tree_path_free (cursor_path); + + rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL; + if (start_at_focus_column) + { + list = (rtl + ? g_list_last (tree_view->priv->columns) + : g_list_first (tree_view->priv->columns)); + if (tree_view->priv->focus_column) + { + for (; list; list = (rtl ? list->prev : list->next)) + { + if (list->data == tree_view->priv->focus_column) + break; + } + } + } + else + { + list = (rtl ^ (count == 1) + ? g_list_first (tree_view->priv->columns) + : g_list_last (tree_view->priv->columns)); + } + + while (list) + { + gboolean left, right; + + column = list->data; + if (column->visible == FALSE || !column->tabbable) + goto loop_end; + + pspp_sheet_view_column_cell_set_cell_data (column, + tree_view->priv->model, + &iter); + + if (rtl) + { + right = list->prev ? TRUE : FALSE; + left = list->next ? TRUE : FALSE; + } + else + { + left = list->prev ? TRUE : FALSE; + right = list->next ? TRUE : FALSE; + } + + if (column->tabbable + && _pspp_sheet_view_column_cell_focus (column, count, left, right)) + { + tree_view->priv->focus_column = column; + _pspp_sheet_view_queue_draw_node (tree_view, cursor_node, NULL); + g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0); + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); + return TRUE; + } + loop_end: + if (count == 1) + list = rtl ? list->prev : list->next; + else + list = rtl ? list->next : list->prev; + } + + return FALSE; +} + +static void +pspp_sheet_view_move_cursor_tab (PsppSheetView *tree_view, + gint count) +{ + if (!gtk_widget_has_focus (GTK_WIDGET (tree_view))) + return; + + if (!try_move_cursor_tab (tree_view, TRUE, count)) + { + /* Shift+Tab goes backward, but Shift isn't supposed to act as Shift does + for other movement commands, that is, it shouldn't cause the selection + to be extended, so we need to act as though it is off. */ + tree_view->priv->shift_pressed = FALSE; + + if (pspp_sheet_view_move_cursor_up_down (tree_view, count) + && !try_move_cursor_tab (tree_view, FALSE, count)) + gtk_widget_error_bell (GTK_WIDGET (tree_view)); + } + + pspp_sheet_view_clamp_column_visible (tree_view, + tree_view->priv->focus_column, TRUE); +} + static void pspp_sheet_view_move_cursor_start_end (PsppSheetView *tree_view, gint count) @@ -8812,7 +9032,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) { @@ -8846,8 +9065,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); */ @@ -11052,7 +11269,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; @@ -11067,8 +11283,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); @@ -12138,7 +12352,6 @@ pspp_sheet_view_event (GtkWidget *widget, gboolean handled; gboolean cancel; guint keyval; - guint state; gint row; /* Intercept only key press events. @@ -12149,52 +12362,62 @@ pspp_sheet_view_event (GtkWidget *widget, if (event->type != GDK_KEY_PRESS) return FALSE; - if (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)) - { - /* Pass through most keys that include modifiers. */ - if ((event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) - && !(event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) - { - /* Special case for Shift-Tab. */ - } - else - return FALSE; - } - keyval = event->keyval; - state = event->state & ~(GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK); cancel = FALSE; - switch (event->keyval) + switch (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)) { - case GDK_Left: case GDK_KP_Left: - if (!is_all_selected (widget) && !is_at_left (widget)) - return FALSE; - break; - - case GDK_Right: case GDK_KP_Right: - if (!is_all_selected (widget) && !is_at_right (widget)) - return FALSE; - break; - - case GDK_Up: case GDK_KP_Up: - case GDK_Down: case GDK_KP_Down: - break; - - case GDK_Page_Up: case GDK_KP_Page_Up: - case GDK_Page_Down: case GDK_KP_Page_Down: - break; - - case GDK_Escape: - cancel = TRUE; + case 0: + switch (event->keyval) + { + case GDK_Left: case GDK_KP_Left: + case GDK_Home: case GDK_KP_Home: + if (!is_all_selected (widget) && !is_at_left (widget)) + return FALSE; + break; + + case GDK_Right: case GDK_KP_Right: + case GDK_End: case GDK_KP_End: + if (!is_all_selected (widget) && !is_at_right (widget)) + return FALSE; + break; + + case GDK_Up: case GDK_KP_Up: + case GDK_Down: case GDK_KP_Down: + break; + + case GDK_Page_Up: case GDK_KP_Page_Up: + case GDK_Page_Down: case GDK_KP_Page_Down: + break; + + case GDK_Escape: + cancel = TRUE; + break; + + case GDK_Return: + keyval = GDK_Down; + break; + + case GDK_Tab: case GDK_KP_Tab: + case GDK_ISO_Left_Tab: + keyval = GDK_Tab; + break; + + default: + return FALSE; + } break; - case GDK_Return: - keyval = GDK_Down; - break; + case GDK_SHIFT_MASK: + switch (event->keyval) + { + case GDK_Tab: + case GDK_ISO_Left_Tab: + keyval = GDK_Tab; + break; - case GDK_Tab: - case GDK_ISO_Left_Tab: - keyval = event->state & GDK_SHIFT_MASK ? GDK_Left : GDK_Right; + default: + return FALSE; + } break; default: @@ -12211,7 +12434,7 @@ pspp_sheet_view_event (GtkWidget *widget, pspp_sheet_view_set_cursor (tree_view, path, column, FALSE); gtk_tree_path_free (path); - handled = gtk_binding_set_activate (edit_bindings, keyval, state, + handled = gtk_binding_set_activate (edit_bindings, keyval, event->state, GTK_OBJECT (tree_view)); if (handled) g_signal_stop_emission_by_name (widget, "event"); @@ -12521,13 +12744,11 @@ pspp_sheet_view_set_grid_lines (PsppSheetView *tree_view, PsppSheetViewGridLines grid_lines) { PsppSheetViewPrivate *priv; - GtkWidget *widget; PsppSheetViewGridLines old_grid_lines; g_return_if_fail (PSPP_IS_SHEET_VIEW (tree_view)); priv = tree_view->priv; - widget = GTK_WIDGET (tree_view); old_grid_lines = priv->grid_lines; priv->grid_lines = grid_lines; @@ -12571,12 +12792,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) {