void wb_control_sheet_add (WorkbookControl *wbc, SheetView *sv) { WorkbookControlClass *wbc_class; g_return_if_fail (IS_WORKBOOK_CONTROL (wbc)); wbc_class = WBC_CLASS (wbc); if (wbc_class != NULL && wbc_class->sheet.add != NULL) { Sheet *new_sheet = sv_sheet (sv); wbc_class->sheet.add (wbc, sv); /* If this is the current sheet init the display */ if (new_sheet == wb_control_cur_sheet (wbc)) { WorkbookView *wbv = wb_control_view (wbc); wb_control_sheet_focus (wbc, new_sheet); wb_view_selection_desc (wbv, TRUE, wbc); wb_view_edit_line_set (wbv, wbc); wb_control_style_feedback (wbc, NULL); wb_control_menu_state_update (wbc, MS_ALL); wb_control_update_action_sensitivity (wbc); } } }
/** * scenarios_cancel_clicked_cb: * @button: * @state: * * Cancel clicked on the scenario manager tool. **/ static void scenarios_cancel_clicked_cb (G_GNUC_UNUSED GtkWidget *button, ScenariosState *state) { GSList *cur; WorkbookControl *wbc; restore_old_values (state); wbc = WORKBOOK_CONTROL (state->base.wbcg); /* Remove report sheets created on this dialog session. */ for (cur = state->new_report_sheets; cur != NULL; cur = cur->next) { Sheet *sheet = cur->data; /* Check that if the focus is on a deleted sheet. */ if (wb_control_cur_sheet (wbc) == sheet) wb_control_sheet_focus (wbc, state->base.sheet); /* Delete a report sheet. */ workbook_sheet_delete (sheet); } /* Recover the deleted scenarios. */ scenario_recover_all (state->base.sheet); scenario_manager_free (state); gtk_widget_destroy (state->base.dialog); }
/** * wbcg_edit_finish: * @wbcg: #WBCGtk * @result: what should we do with the content * @showed_dialog: If non-NULL will indicate if a dialog was displayed. * * Return: TRUE if editing completed successfully, or we were no editing. **/ gboolean wbcg_edit_finish (WBCGtk *wbcg, WBCEditResult result, gboolean *showed_dialog) { Sheet *sheet; SheetView *sv; WorkbookControl *wbc; WorkbookView *wbv; g_return_val_if_fail (GNM_IS_WBC_GTK (wbcg), FALSE); wbc = GNM_WBC (wbcg); wbv = wb_control_view (wbc); wbcg_focus_cur_scg (wbcg); gnm_expr_entry_close_tips (wbcg_get_entry_logical (wbcg)); if (showed_dialog != NULL) *showed_dialog = FALSE; /* Remove the range selection cursor if it exists */ if (NULL != wbcg->rangesel) scg_rangesel_stop (wbcg->rangesel, result == WBC_EDIT_REJECT); if (!wbcg_is_editing (wbcg)) { /* We may have a guru up even if we are not editing. remove it. * Do NOT remove until later it if we are editing, it is possible * that we may want to continue editing. */ if (wbcg->edit_line.guru != NULL) { GtkWidget *w = wbcg->edit_line.guru; wbc_gtk_detach_guru (wbcg); gtk_widget_destroy (w); } return TRUE; } g_return_val_if_fail (IS_SHEET (wbcg->editing_sheet), TRUE); sheet = wbcg->editing_sheet; sv = sheet_get_view (sheet, wbv); /* Save the results before changing focus */ if (result != WBC_EDIT_REJECT) { ValidationStatus valid = GNM_VALIDATION_STATUS_VALID; char *free_txt = NULL; char const *txt; GnmStyle const *mstyle; char const *expr_txt = NULL; GOFormat const *fmt; GnmValue *value; GOUndo *u = NULL; GSList *selection = selection_get_ranges (sv, FALSE); GnmParsePos pp; GnmExprTop const *texpr = NULL; parse_pos_init_editpos (&pp, sv); /* Array only works on single range. */ if (result == WBC_EDIT_ACCEPT_ARRAY && (selection == NULL || selection->next != NULL)) result = WBC_EDIT_ACCEPT_RANGE; /******* Check whether we would split a range ********/ switch (result) { case (WBC_EDIT_ACCEPT_RANGE): case (WBC_EDIT_ACCEPT_ARRAY): { if (sheet_ranges_split_region (sheet, selection, GO_CMD_CONTEXT (wbc), _("Set Text"))) { range_fragment_free (selection); if (showed_dialog != NULL) *showed_dialog = TRUE; return FALSE; } if (result == WBC_EDIT_ACCEPT_ARRAY && sheet_range_contains_merges_or_arrays (sheet, selection->data, GO_CMD_CONTEXT (wbc), _("Set Text"), TRUE, FALSE)) { range_fragment_free (selection); if (showed_dialog != NULL) *showed_dialog = TRUE; return FALSE; } break; } case (WBC_EDIT_ACCEPT_WO_AC): case (WBC_EDIT_ACCEPT): { GnmCell const *cell = sheet_cell_get (sheet, sv->edit_pos.col, sv->edit_pos.row); if (gnm_cell_is_nonsingleton_array (cell)) { gnm_cmd_context_error_splits_array (GO_CMD_CONTEXT (wbc), _("Set Text"), NULL); if (showed_dialog != NULL) *showed_dialog = TRUE; range_fragment_free (selection); return FALSE; } break; } case (WBC_EDIT_REJECT): default: /* We should not be able to get here! */ break; } /******* Check whether the range is locked ********/ switch (result) { case (WBC_EDIT_ACCEPT_RANGE): case (WBC_EDIT_ACCEPT_ARRAY): { if (cmd_selection_is_locked_effective (sheet, selection, wbc, _("Set Text"))) { range_fragment_free (selection); if (showed_dialog != NULL) *showed_dialog = TRUE; return FALSE; } break; } case (WBC_EDIT_ACCEPT_WO_AC): case (WBC_EDIT_ACCEPT): { GnmRange r; r.end = r.start = pp.eval; if (cmd_cell_range_is_locked_effective (sheet, &r, wbc, _("Set Text"))) { range_fragment_free (selection); if (showed_dialog != NULL) *showed_dialog = TRUE; return FALSE; } break; } case (WBC_EDIT_REJECT): default: /* We should not be able to get here! */ break; } /*****************************************************/ txt = wbcg_edit_get_display_text (wbcg); mstyle = sheet_style_get (sheet, sv->edit_pos.col, sv->edit_pos.row); fmt = gnm_cell_get_format (sheet_cell_fetch (sheet, sv->edit_pos.col, sv->edit_pos.row)); value = format_match (txt, fmt, workbook_date_conv (sheet->workbook)); if (value == NULL) expr_txt = gnm_expr_char_start_p (txt); else value_release (value); /* NOTE : do not modify gnm_expr_char_start_p to exclude "-" * it _can_ start an expression, which is required for rangesel * it just isn't an expression. */ if (expr_txt != NULL && *expr_txt != '\0' && strcmp (expr_txt, "-")) { GnmExprTop const *texpr_test = NULL; GnmParseError perr; parse_error_init (&perr); texpr_test = gnm_expr_parse_str (expr_txt, &pp, GNM_EXPR_PARSE_DEFAULT, NULL, &perr); /* Try adding a single extra closing paren to see if it helps */ if (texpr_test == NULL && perr.err != NULL && perr.err->code == PERR_MISSING_PAREN_CLOSE) { GnmParseError tmp_err; char *tmp = g_strconcat (txt, ")", NULL); parse_error_init (&tmp_err); texpr_test = gnm_expr_parse_str (gnm_expr_char_start_p (tmp), &pp, GNM_EXPR_PARSE_DEFAULT, NULL, &tmp_err); parse_error_free (&tmp_err); if (texpr_test != NULL) { txt = free_txt = tmp; expr_txt = gnm_expr_char_start_p (txt); } else g_free (tmp); } if (texpr_test == NULL && perr.err != NULL) { ValidationStatus reedit; /* set focus _before_ selection. gtk2 seems to * screw with selection in gtk_entry_grab_focus * (no longer required now that we clear * gtk-entry-select-on-focus) */ gtk_window_set_focus (wbcg_toplevel (wbcg), (GtkWidget *) wbcg_get_entry (wbcg)); if (perr.begin_char != 0 || perr.end_char != 0) { int offset = expr_txt - txt; gtk_editable_select_region (GTK_EDITABLE (wbcg_get_entry (wbcg)), offset + perr.begin_char, offset + perr.end_char); } else gtk_editable_set_position ( GTK_EDITABLE (wbcg_get_entry (wbcg)), -1); reedit = wb_control_validation_msg (GNM_WBC (wbcg), GNM_VALIDATION_STYLE_PARSE_ERROR, NULL, perr.err->message); if (showed_dialog != NULL) *showed_dialog = TRUE; parse_error_free (&perr); if (reedit == GNM_VALIDATION_STATUS_INVALID_EDIT) { range_fragment_free (selection); return FALSE; } /* restore focus to sheet , or we'll leave edit * mode only to jump right back in the new * cell because it looks like someone just * focused on the edit line (eg hit F2) */ wbcg_focus_cur_scg (wbcg); } if (texpr_test != NULL) gnm_expr_top_unref (texpr_test); } /* We only enter an array formula if the text is a formula */ if (result == WBC_EDIT_ACCEPT_ARRAY && !expr_txt) result = WBC_EDIT_ACCEPT_RANGE; if (result == WBC_EDIT_ACCEPT_ARRAY) { GnmParsePos pp_array; GnmRange *r = selection->data; parse_pos_init (&pp_array, sheet->workbook, sheet, r->start.col, r->start.row); if ((texpr = gnm_expr_parse_str (expr_txt, &pp_array, GNM_EXPR_PARSE_DEFAULT, sheet_get_conventions (sheet), NULL)) == NULL) result = WBC_EDIT_ACCEPT_RANGE; } /* We need to save the information that we will temporarily overwrite */ /* We then assign the information. No need to worry about formatting */ /* Finally we can check the validation! */ switch (result) { case (WBC_EDIT_ACCEPT_RANGE): { GSList *l; for (l = selection; l != NULL; l = l->next) { GnmRange *r = l->data; u = go_undo_combine (u, clipboard_copy_range_undo (sheet, r)); } for (l = selection; l != NULL; l = l->next) { GnmRange *r = l->data; /* We do this separately since there may be overlap between ranges */ sheet_range_set_text (&pp, r, txt); valid = gnm_validation_eval_range (wbc, sheet, &sv->edit_pos, r, showed_dialog); if (valid != GNM_VALIDATION_STATUS_VALID) break; } break; } case (WBC_EDIT_ACCEPT_ARRAY): { GnmRange *r = selection->data; u = go_undo_combine (u, clipboard_copy_range_undo (sheet, r)); if (texpr) { gnm_expr_top_ref (texpr); gnm_cell_set_array_formula (sheet, r->start.col, r->start.row, r->end.col, r->end.row, texpr); sheet_region_queue_recalc (sheet, r); } valid = gnm_validation_eval_range (wbc, sheet, &sv->edit_pos, r, showed_dialog); break; } case (WBC_EDIT_ACCEPT_WO_AC): case (WBC_EDIT_ACCEPT): { GnmRange r; GnmCell *cell; range_init_cellpos (&r, &sv->edit_pos); u = clipboard_copy_range_undo (sheet, &r); cell = sheet_cell_fetch (sheet, sv->edit_pos.col, sv->edit_pos.row); sheet_cell_set_text (cell, txt, wbcg->edit_line.markup); valid = gnm_validation_eval (wbc, mstyle, sheet, &sv->edit_pos, showed_dialog); break; } case (WBC_EDIT_REJECT): default: /* We should not be able to get here! */ break; } range_fragment_free (selection); /* We need to rebuild the original info first. */ go_undo_undo (u); g_object_unref (u); /* Now we can respond to our validation information */ if (valid != GNM_VALIDATION_STATUS_VALID) { result = WBC_EDIT_REJECT; if (valid == GNM_VALIDATION_STATUS_INVALID_EDIT) { gtk_window_set_focus (wbcg_toplevel (wbcg), (GtkWidget *) wbcg_get_entry (wbcg)); g_free (free_txt); if (texpr != NULL) gnm_expr_top_unref (texpr); return FALSE; } } else { if (result == WBC_EDIT_ACCEPT_ARRAY) { cmd_area_set_array_expr (wbc, sv, texpr); } else { PangoAttrList *res_markup = wbcg->edit_line.markup ? pango_attr_list_copy (wbcg->edit_line.markup) : NULL; if (result == WBC_EDIT_ACCEPT) cmd_set_text (wbc, sheet, &sv->edit_pos, txt, res_markup, TRUE); else if (result == WBC_EDIT_ACCEPT_WO_AC) cmd_set_text (wbc, sheet, &sv->edit_pos, txt, res_markup, FALSE); else cmd_area_set_text (wbc, sv, txt, res_markup); if (res_markup) pango_attr_list_unref (res_markup); } } if (texpr != NULL) gnm_expr_top_unref (texpr); g_free (free_txt); } else { if (sv == wb_control_cur_sheet_view (wbc)) { /* Redraw the cell contents in case there was a span */ GnmRange tmp; tmp.start = tmp.end = sv->edit_pos; sheet_range_bounding_box (sv->sheet, &tmp); sv_redraw_range (wb_control_cur_sheet_view (wbc), &tmp); } /* Reload the entry widget with the original contents */ wb_view_edit_line_set (wbv, wbc); } /* Stop editing */ wbcg->editing = FALSE; wbcg->editing_sheet = NULL; wbcg->editing_cell = NULL; if (wbcg->edit_line.guru != NULL) { GtkWidget *w = wbcg->edit_line.guru; wbc_gtk_detach_guru (wbcg); gtk_widget_destroy (w); } if (wbcg->edit_line.signal_insert) { g_signal_handler_disconnect (wbcg_get_entry (wbcg), wbcg->edit_line.signal_insert); wbcg->edit_line.signal_insert = 0; } if (wbcg->edit_line.signal_delete) { g_signal_handler_disconnect (wbcg_get_entry (wbcg), wbcg->edit_line.signal_delete); wbcg->edit_line.signal_delete = 0; } if (wbcg->edit_line.signal_cursor_pos) { g_signal_handler_disconnect (wbcg_get_entry (wbcg), wbcg->edit_line.signal_cursor_pos); wbcg->edit_line.signal_cursor_pos = 0; } if (wbcg->edit_line.signal_selection_bound) { g_signal_handler_disconnect (wbcg_get_entry (wbcg), wbcg->edit_line.signal_selection_bound); wbcg->edit_line.signal_selection_bound = 0; } if (wbcg->edit_line.cell_attrs != NULL) { pango_attr_list_unref (wbcg->edit_line.cell_attrs); wbcg->edit_line.cell_attrs = NULL; } if (wbcg->edit_line.markup) { pango_attr_list_unref (wbcg->edit_line.markup); wbcg->edit_line.markup = NULL; } if (wbcg->edit_line.full_content != NULL) { pango_attr_list_unref (wbcg->edit_line.full_content); wbcg->edit_line.full_content = NULL; } if (wbcg->edit_line.cur_fmt) { pango_attr_list_unref (wbcg->edit_line.cur_fmt); wbcg->edit_line.cur_fmt = NULL; } /* set pos to 0, to ensure that if we start editing by clicking on the * editline at the last position, we'll get the right style feedback */ gtk_editable_set_position ((GtkEditable *) wbcg_get_entry (wbcg), 0); wb_control_update_action_sensitivity (wbc); if (!sheet->workbook->during_destruction) { /* restore focus to original sheet in case things were being selected * on a different page. Do no go through the view, rangesel is * specific to the control. */ wb_control_sheet_focus (wbc, sheet); /* Only the edit sheet has an edit cursor */ scg_edit_stop (wbcg_cur_scg (wbcg)); } wbcg_auto_complete_destroy (wbcg); wb_control_style_feedback (wbc, NULL); /* in case markup messed with things */ return TRUE; }