Update Spanish translation
[gnumeric.git] / src / wbc-gtk-actions.c
blob17d96e724024ecd96f4d413edcec050703b36fe5
2 /*
3 * wbcg-actions.c: The callbacks and tables for all the menus and stock toolbars
5 * Copyright (C) 2003-2006 Jody Goldberg (jody@gnome.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) version 3.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 * USA
23 #include <gnumeric-config.h>
24 #include <gnumeric.h>
26 #include <libgnumeric.h>
27 #include <application.h>
28 #include <gnm-commands-slicer.h>
29 #include <commands.h>
30 #include <clipboard.h>
31 #include <selection.h>
32 #include <search.h>
33 #include <ranges.h>
34 #include <cell.h>
35 #include <stf.h>
36 #include <value.h>
37 #include <gnm-format.h>
38 #include <sheet.h>
39 #include <sort.h>
40 #include <sheet-merge.h>
41 #include <sheet-filter.h>
42 #include <sheet-utils.h>
43 #include <sheet-style.h>
44 #include <style-border.h>
45 #include <style-color.h>
46 #include <tools/filter.h>
47 #include <sheet-control-gui-priv.h>
48 #include <sheet-view.h>
49 #include <cmd-edit.h>
50 #include <workbook.h>
51 #include <workbook-view.h>
52 #include <wbc-gtk-impl.h>
53 #include <workbook-cmd-format.h>
54 #include <dialogs/dialogs.h>
55 #include <sheet-object-image.h>
56 #include <sheet-object-widget.h>
57 #include <gnm-so-filled.h>
58 #include <gnm-so-line.h>
59 #include <sheet-object-graph.h>
60 #include <sheet-object-component.h>
61 #include <gui-util.h>
62 #include <gui-file.h>
63 #include <gnumeric-conf.h>
64 #include <expr.h>
65 #include <print.h>
66 #include <print-info.h>
67 #include <gnm-pane-impl.h>
68 #include <gutils.h>
69 #include <widgets/gnm-fontbutton.h>
71 #include <goffice/goffice.h>
72 #include <goffice/component/goffice-component.h>
74 #include <glib/gi18n-lib.h>
75 #include <gsf/gsf-input.h>
76 #include <string.h>
77 #include <glib/gstdio.h>
78 #include <errno.h>
80 static gboolean
81 cb_cleanup_sendto (gpointer path)
83 char *dir = g_path_get_dirname (path);
85 g_unlink (path);
86 g_free (path); /* the attachment */
88 g_rmdir (dir);
89 g_free (dir); /* the tempdir */
91 return FALSE;
95 static GNM_ACTION_DEF (cb_file_new)
97 GdkScreen *screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
98 Workbook *wb = workbook_new_with_sheets
99 (gnm_conf_get_core_workbook_n_sheet ());
100 WBCGtk *new_wbcg = wbc_gtk_new (NULL, wb, screen, NULL);
101 wbcg_copy_toolbar_visibility (new_wbcg, wbcg);
104 static GNM_ACTION_DEF (cb_file_open) { gui_file_open (wbcg, GNM_FILE_OPEN_STYLE_OPEN, NULL); }
105 static GNM_ACTION_DEF (cb_file_save) { gui_file_save (wbcg, wb_control_view (GNM_WBC (wbcg))); }
106 static GNM_ACTION_DEF (cb_file_save_as) { gui_file_save_as
107 (wbcg, wb_control_view (GNM_WBC (wbcg)),
108 GNM_FILE_SAVE_AS_STYLE_SAVE, NULL); }
110 static GNM_ACTION_DEF (cb_file_sendto) {
111 WorkbookControl *wbc = GNM_WBC (wbcg);
112 WorkbookView *wbv = wb_control_view (wbc);
113 GOCmdContext *gcc = GO_CMD_CONTEXT (wbcg);
114 gboolean problem = FALSE;
115 GOIOContext *io_context;
116 Workbook *wb;
117 GOFileSaver *fs;
119 wb = wb_control_get_workbook (wbc);
120 g_object_ref (wb);
121 fs = workbook_get_file_saver (wb);
122 if (fs == NULL)
123 fs = go_file_saver_get_default ();
125 io_context = go_io_context_new (gcc);
126 if (fs != NULL) {
127 char *template, *full_name, *uri;
128 char *basename = g_path_get_basename (go_doc_get_uri (GO_DOC (wb)));
130 template = g_build_filename (g_get_tmp_dir (),
131 ".gnm-sendto-XXXXXX", NULL);
132 problem = (g_mkdtemp_full (template, 0600) == NULL);
134 if (problem) {
135 g_free (template);
136 goto out;
139 full_name = g_build_filename (template, basename, NULL);
140 g_free (basename);
141 uri = go_filename_to_uri (full_name);
143 workbook_view_save_to_uri (wbv, fs, uri, io_context);
145 if (go_io_error_occurred (io_context) ||
146 go_io_warning_occurred (io_context))
147 go_io_error_display (io_context);
149 if (go_io_error_occurred (io_context)) {
150 problem = TRUE;
151 } else {
152 /* mutt does not handle urls with no destination
153 * so pick something to arbitrary */
154 GError *err;
155 GdkScreen *screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
156 char *url, *tmp = go_url_encode (full_name, 0);
157 url = g_strdup_printf ("mailto:someone?attach=%s", tmp);
158 g_free (tmp);
160 err = go_gtk_url_show (url, screen);
162 if (err != NULL) {
163 go_cmd_context_error (GO_CMD_CONTEXT (io_context), err);
164 g_error_free (err);
165 go_io_error_display (io_context);
166 problem = TRUE;
169 g_free (template);
170 g_free (uri);
172 if (problem) {
173 cb_cleanup_sendto (full_name);
174 } else {
176 * We wait a while before we clean up to ensure the file is
177 * loaded by the mailer.
179 g_timeout_add (1000 * 10, cb_cleanup_sendto, full_name);
181 } else {
182 go_cmd_context_error_export (GO_CMD_CONTEXT (io_context),
183 _("Default file saver is not available."));
184 go_io_error_display (io_context);
185 problem = TRUE;
188 out:
189 g_object_unref (io_context);
190 g_object_unref (wb);
192 /* What do we do with "problem"? */
195 static GNM_ACTION_DEF (cb_file_page_setup)
197 dialog_printer_setup (wbcg, wbcg_cur_sheet (wbcg));
200 static GNM_ACTION_DEF (cb_file_print_area_set)
202 Sheet *sheet = wbcg_cur_sheet (wbcg);
203 SheetView *sv = sheet_get_view (sheet, wb_control_view (GNM_WBC (wbcg)));
204 GnmParsePos pp;
205 char *message;
206 char * selection;
207 GnmRange const *r = selection_first_range (sv,
208 GO_CMD_CONTEXT (wbcg), _("Set Print Area"));
209 if (r != NULL) {
210 parse_pos_init_sheet (&pp, sheet);
211 selection = undo_range_name (sheet, r);
212 message = g_strdup_printf (_("Set Print Area to %s"), selection);
213 cmd_define_name (GNM_WBC (wbcg), "Print_Area", &pp,
214 gnm_expr_top_new_constant
215 (value_new_cellrange_r (NULL, r)),
216 message);
217 g_free (selection);
218 g_free (message);
222 static GNM_ACTION_DEF (cb_file_print_area_clear)
224 GnmParsePos pp;
225 Sheet *sheet = wbcg_cur_sheet (wbcg);
227 parse_pos_init_sheet (&pp, sheet);
228 cmd_define_name (GNM_WBC (wbcg), "Print_Area", &pp,
229 gnm_expr_top_new_constant
230 (value_new_error_REF (NULL)),
231 _("Clear Print Area"));
234 static GNM_ACTION_DEF (cb_file_print_area_show)
236 Sheet *sheet = wbcg_cur_sheet (wbcg);
237 GnmRange *r = sheet_get_nominal_printarea (sheet);
239 if (r != NULL) {
240 SheetView *sv = sheet_get_view (sheet,
241 wb_control_view (GNM_WBC (wbcg)));
242 wb_control_sheet_focus (GNM_WBC (wbcg), sheet);
243 sv_selection_reset (sv);
244 sv_selection_add_range (sv, r);
245 gnm_sheet_view_make_cell_visible (sv, r->start.col, r->start.row, FALSE);
246 g_free (r);
250 static GNM_ACTION_DEF (cb_file_print_area_toggle_col)
252 cmd_page_break_toggle (GNM_WBC (wbcg),
253 wbcg_cur_sheet (wbcg),
254 TRUE);
256 static GNM_ACTION_DEF (cb_file_print_area_toggle_row)
258 cmd_page_break_toggle (GNM_WBC (wbcg),
259 wbcg_cur_sheet (wbcg),
260 FALSE);
263 static GNM_ACTION_DEF (cb_file_print_area_clear_pagebreaks)
265 cmd_page_breaks_clear (GNM_WBC (wbcg), wbcg_cur_sheet (wbcg));
268 static GNM_ACTION_DEF (cb_file_print)
270 gnm_print_sheet (GNM_WBC (wbcg),
271 wbcg_cur_sheet (wbcg), FALSE, GNM_PRINT_SAVED_INFO, NULL);
274 static GNM_ACTION_DEF (cb_file_print_preview)
276 gnm_print_sheet (GNM_WBC (wbcg),
277 wbcg_cur_sheet (wbcg), TRUE, GNM_PRINT_ACTIVE_SHEET, NULL);
280 static GNM_ACTION_DEF (cb_doc_meta_data) { dialog_doc_metadata_new (wbcg, 0); }
281 static GNM_ACTION_DEF (cb_file_preferences) { dialog_preferences (wbcg, NULL); }
282 static GNM_ACTION_DEF (cb_file_history_full) { dialog_recent_used (wbcg); }
283 static GNM_ACTION_DEF (cb_file_close) { wbc_gtk_close (wbcg); }
285 static GNM_ACTION_DEF (cb_file_quit)
287 /* If we are still loading initial files, short circuit */
288 if (!gnm_app_initial_open_complete ()) {
289 g_object_set (gnm_app_get_app (), "shutting-down", TRUE, NULL);
290 return;
293 /* If we were editing when the quit request came in abort the edit. */
294 wbcg_edit_finish (wbcg, WBC_EDIT_REJECT, NULL);
296 dialog_quit (wbcg);
299 /****************************************************************************/
301 static GNM_ACTION_DEF (cb_edit_clear_all)
303 cmd_selection_clear (GNM_WBC (wbcg),
304 CLEAR_VALUES | CLEAR_FORMATS | CLEAR_OBJECTS | CLEAR_COMMENTS);
307 static GNM_ACTION_DEF (cb_edit_clear_formats)
308 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_FORMATS); }
309 static GNM_ACTION_DEF (cb_edit_clear_comments)
310 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_COMMENTS); }
311 static GNM_ACTION_DEF (cb_edit_clear_content)
312 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_VALUES); }
313 static GNM_ACTION_DEF (cb_edit_clear_all_filtered)
315 cmd_selection_clear (GNM_WBC (wbcg),
316 CLEAR_VALUES | CLEAR_FORMATS | CLEAR_OBJECTS | CLEAR_COMMENTS | CLEAR_FILTERED_ONLY);
319 static GNM_ACTION_DEF (cb_edit_clear_formats_filtered)
320 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_FORMATS | CLEAR_FILTERED_ONLY); }
321 static GNM_ACTION_DEF (cb_edit_clear_comments_filtered)
322 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_COMMENTS | CLEAR_FILTERED_ONLY); }
323 static GNM_ACTION_DEF (cb_edit_clear_content_filtered)
324 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_VALUES | CLEAR_FILTERED_ONLY); }
326 static GNM_ACTION_DEF (cb_edit_delete_rows)
328 WorkbookControl *wbc = GNM_WBC (wbcg);
329 SheetView *sv = wb_control_cur_sheet_view (wbc);
330 Sheet *sheet = wb_control_cur_sheet (wbc);
331 GnmRange const *sel;
332 int rows;
334 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Delete"))))
335 return;
336 rows = range_height (sel);
338 cmd_delete_rows (wbc, sheet, sel->start.row, rows);
340 static GNM_ACTION_DEF (cb_edit_delete_columns)
342 WorkbookControl *wbc = GNM_WBC (wbcg);
343 SheetView *sv = wb_control_cur_sheet_view (wbc);
344 Sheet *sheet = wb_control_cur_sheet (wbc);
345 GnmRange const *sel;
346 int cols;
348 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Delete"))))
349 return;
350 cols = range_width (sel);
352 cmd_delete_cols (wbc, sheet, sel->start.col, cols);
355 static GNM_ACTION_DEF (cb_edit_delete_cells)
357 dialog_delete_cells (wbcg);
359 static GNM_ACTION_DEF (cb_edit_delete_links)
361 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
362 GnmStyle *style = gnm_style_new ();
363 GSList *l;
364 int n_links = 0;
365 gchar const *format;
366 gchar *name;
367 WorkbookControl *wbc = GNM_WBC (wbcg);
368 Sheet *sheet = wb_control_cur_sheet (wbc);
370 for (l = scg_view (scg)->selections; l != NULL; l = l->next) {
371 GnmRange const *r = l->data;
372 GnmStyleList *styles;
374 styles = sheet_style_collect_hlinks (sheet, r);
375 n_links += g_slist_length (styles);
376 style_list_free (styles);
378 format = ngettext ("Remove %d Link", "Remove %d Links", n_links);
379 name = g_strdup_printf (format, n_links);
380 gnm_style_set_hlink (style, NULL);
381 cmd_selection_format (wbc, style, NULL, name);
382 g_free (name);
385 static GNM_ACTION_DEF (cb_edit_select_all)
387 scg_select_all (wbcg_cur_scg (wbcg));
389 static GNM_ACTION_DEF (cb_edit_select_row)
391 sv_select_cur_row (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
393 static GNM_ACTION_DEF (cb_edit_select_col)
395 sv_select_cur_col (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
397 static GNM_ACTION_DEF (cb_edit_select_array)
399 sv_select_cur_array (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
401 static GNM_ACTION_DEF (cb_edit_select_depends)
403 sv_select_cur_depends (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
405 static GNM_ACTION_DEF (cb_edit_select_inputs)
407 sv_select_cur_inputs (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
409 static GNM_ACTION_DEF (cb_edit_select_object)
411 scg_object_select_next (wbcg_cur_scg (wbcg), FALSE);
414 static GNM_ACTION_DEF (cb_edit_cut)
416 if (!wbcg_is_editing (wbcg)) {
417 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
418 WorkbookControl *wbc = GNM_WBC (wbcg);
419 SheetView *sv = wb_control_cur_sheet_view (wbc);
420 if (scg != NULL && scg->selected_objects != NULL)
421 gnm_app_clipboard_cut_copy_obj (wbc, TRUE, sv,
422 go_hash_keys (scg->selected_objects));
423 else
424 gnm_sheet_view_selection_cut (sv, wbc);
425 } else
426 gtk_editable_cut_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
429 static GNM_ACTION_DEF (cb_edit_copy)
431 if (!wbcg_is_editing (wbcg)) {
432 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
433 WorkbookControl *wbc = GNM_WBC (wbcg);
434 SheetView *sv = wb_control_cur_sheet_view (wbc);
435 if (scg != NULL && scg->selected_objects != NULL)
436 gnm_app_clipboard_cut_copy_obj (wbc, FALSE, sv,
437 go_hash_keys (scg->selected_objects));
438 else
439 gnm_sheet_view_selection_copy (sv, wbc);
440 } else
441 gtk_editable_copy_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
444 static GNM_ACTION_DEF (cb_edit_paste)
446 if (!wbcg_is_editing (wbcg)) {
447 WorkbookControl *wbc = GNM_WBC (wbcg);
448 SheetView *sv = wb_control_cur_sheet_view (wbc);
449 cmd_paste_to_selection (wbc, sv, PASTE_DEFAULT);
450 } else
451 gtk_editable_paste_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
454 static GNM_ACTION_DEF (cb_edit_paste_special)
456 dialog_paste_special (wbcg);
459 static GNM_ACTION_DEF (cb_sheet_remove)
461 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
462 if (scg)
463 scg_delete_sheet_if_possible (scg);
466 static void
467 common_cell_goto (WBCGtk *wbcg, Sheet *sheet, GnmCellPos const *pos)
469 SheetView *sv;
470 WorkbookView *wbv;
472 if (!sheet_is_visible (sheet))
473 return;
475 wbv = wb_control_view (GNM_WBC (wbcg));
476 sv = sheet_get_view (sheet, wbv);
477 wb_view_sheet_focus (wbv, sheet);
478 sv_selection_set (sv, pos,
479 pos->col, pos->row,
480 pos->col, pos->row);
481 gnm_sheet_view_make_cell_visible (sv, pos->col, pos->row, FALSE);
484 static int
485 cb_edit_search_replace_query (GnmSearchReplaceQuery q, GnmSearchReplace *sr, ...)
487 int res;
488 va_list pvar;
489 WBCGtk *wbcg = sr->user_data;
491 va_start (pvar, sr);
493 switch (q) {
494 case GNM_SRQ_FAIL: {
495 GnmCell *cell = va_arg (pvar, GnmCell *);
496 char const *old_text = va_arg (pvar, char const *);
497 char const *new_text = va_arg (pvar, char const *);
498 char *err = g_strdup_printf
499 (_("In cell %s, the current contents\n"
500 " %s\n"
501 "would have been replaced by\n"
502 " %s\n"
503 "which is invalid.\n\n"
504 "The replace has been aborted "
505 "and nothing has been changed."),
506 cell_name (cell),
507 old_text,
508 new_text);
510 go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR,
511 "%s", err);
512 g_free (err);
513 res = GTK_RESPONSE_NO;
514 break;
517 case GNM_SRQ_QUERY: {
518 GnmCell *cell = va_arg (pvar, GnmCell *);
519 char const *old_text = va_arg (pvar, char const *);
520 char const *new_text = va_arg (pvar, char const *);
521 Sheet *sheet = cell->base.sheet;
522 char *pos_name = g_strconcat (sheet->name_unquoted, "!",
523 cell_name (cell), NULL);
525 common_cell_goto (wbcg, sheet, &cell->pos);
527 res = dialog_search_replace_query (wbcg, sr, pos_name,
528 old_text, new_text);
529 g_free (pos_name);
530 break;
533 case GNM_SRQ_QUERY_COMMENT: {
534 Sheet *sheet = va_arg (pvar, Sheet *);
535 GnmCellPos *cp = va_arg (pvar, GnmCellPos *);
536 char const *old_text = va_arg (pvar, char const *);
537 char const *new_text = va_arg (pvar, char const *);
538 char *pos_name = g_strdup_printf (_("Comment in cell %s!%s"),
539 sheet->name_unquoted,
540 cellpos_as_string (cp));
541 common_cell_goto (wbcg, sheet, cp);
543 res = dialog_search_replace_query (wbcg, sr, pos_name,
544 old_text, new_text);
545 g_free (pos_name);
546 break;
549 default:
550 /* Shouldn't really happen. */
551 res = GTK_RESPONSE_CANCEL;
554 va_end (pvar);
555 return res;
558 static gboolean
559 cb_edit_search_replace_action (WBCGtk *wbcg,
560 GnmSearchReplace *sr)
562 WorkbookControl *wbc = GNM_WBC (wbcg);
564 sr->query_func = cb_edit_search_replace_query;
565 sr->user_data = wbcg;
567 return cmd_search_replace (wbc, sr);
571 static GNM_ACTION_DEF (cb_edit_search_replace) { dialog_search_replace (wbcg, cb_edit_search_replace_action); }
572 static GNM_ACTION_DEF (cb_edit_search) { dialog_search (wbcg); }
574 static GNM_ACTION_DEF (cb_edit_fill_autofill)
576 WorkbookControl *wbc = GNM_WBC (wbcg);
577 SheetView *sv = wb_control_cur_sheet_view (wbc);
578 Sheet *sheet = wb_control_cur_sheet (wbc);
580 GnmRange const *total = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Autofill"));
581 if (total) {
582 GnmRange src = *total;
583 gboolean do_loop;
584 GSList *merges, *ptr;
586 if (sheet_range_trim (sheet, &src, TRUE, TRUE))
587 return; /* Region totally empty */
589 /* trim is a bit overzealous, it forgets about merges */
590 do {
591 do_loop = FALSE;
592 merges = gnm_sheet_merge_get_overlap (sheet, &src);
593 for (ptr = merges ; ptr != NULL ; ptr = ptr->next) {
594 GnmRange const *r = ptr->data;
595 if (src.end.col < r->end.col) {
596 src.end.col = r->end.col;
597 do_loop = TRUE;
599 if (src.end.row < r->end.row) {
600 src.end.row = r->end.row;
601 do_loop = TRUE;
604 } while (do_loop);
606 /* Make it autofill in only one direction */
607 if ((total->end.col - src.end.col) >=
608 (total->end.row - src.end.row))
609 src.end.row = total->end.row;
610 else
611 src.end.col = total->end.col;
613 cmd_autofill (wbc, sheet, FALSE,
614 total->start.col, total->start.row,
615 src.end.col - total->start.col + 1,
616 src.end.row - total->start.row + 1,
617 total->end.col, total->end.row,
618 FALSE);
622 static GNM_ACTION_DEF (cb_edit_fill_series)
624 dialog_fill_series (wbcg);
627 static GNM_ACTION_DEF (cb_edit_goto_top)
629 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_top);
631 static GNM_ACTION_DEF (cb_edit_goto_bottom)
633 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_bottom);
635 static GNM_ACTION_DEF (cb_edit_goto_first)
637 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_first);
639 static GNM_ACTION_DEF (cb_edit_goto_last)
641 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_last);
643 static GNM_ACTION_DEF (cb_edit_goto)
645 dialog_goto_cell (wbcg);
647 static GNM_ACTION_DEF (cb_edit_goto_cell_indicator)
649 if (GNM_IS_WBC_GTK (wbcg))
650 wbcg_focus_current_cell_indicator (WBC_GTK (wbcg));
653 static GNM_ACTION_DEF (cb_edit_recalc)
655 /* TODO:
656 * f9 - do any necessary calculations across all sheets
657 * shift-f9 - do any necessary calcs on current sheet only
658 * ctrl-alt-f9 - force a full recalc across all sheets
659 * ctrl-alt-shift-f9 - a full-monty super recalc
661 workbook_recalc_all (wb_control_get_workbook (GNM_WBC (wbcg)));
664 static GNM_ACTION_DEF (cb_repeat) { command_repeat (GNM_WBC (wbcg)); }
666 /****************************************************************************/
668 static GNM_ACTION_DEF (cb_direction)
670 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
671 cmd_toggle_rtl (GNM_WBC (wbcg), sheet);
674 static GNM_ACTION_DEF (cb_view_zoom_in)
676 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
677 int zoom = (int)(sheet->last_zoom_factor_used * 100. + .5) - 10;
678 if ((zoom % 15) != 0)
679 zoom = 15 * (int)(zoom/15);
680 zoom += 15;
681 if (zoom <= 390)
682 cmd_zoom (GNM_WBC (wbcg), g_slist_append (NULL, sheet),
683 (double) (zoom + 10) / 100);
685 static GNM_ACTION_DEF (cb_view_zoom_out)
687 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
688 int zoom = (int)(sheet->last_zoom_factor_used * 100. + .5) - 10;
689 if ((zoom % 15) != 0)
690 zoom = 15 * (int)(zoom/15);
691 else
692 zoom -= 15;
693 if (0 <= zoom)
694 cmd_zoom (GNM_WBC (wbcg), g_slist_append (NULL, sheet),
695 (double) (zoom + 10) / 100);
698 static GNM_ACTION_DEF (cb_view_fullscreen)
700 if (wbcg->is_fullscreen)
701 gtk_window_unfullscreen (wbcg_toplevel (wbcg));
702 else
703 gtk_window_fullscreen (wbcg_toplevel (wbcg));
706 static GNM_ACTION_DEF (cb_view_zoom) { dialog_zoom (wbcg, wbcg_cur_sheet (wbcg)); }
707 static GNM_ACTION_DEF (cb_view_new) { dialog_new_view (wbcg); }
708 static GNM_ACTION_DEF (cb_view_freeze_panes)
710 WorkbookControl *wbc = GNM_WBC (wbcg);
711 SheetView *sv = wb_control_cur_sheet_view (wbc);
712 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
714 scg_mode_edit (scg);
715 if (scg->active_panes == 1) {
716 gboolean center = FALSE;
717 GnmPane const *pane = scg_pane (scg, 0);
718 GnmCellPos frozen_tl, unfrozen_tl;
720 frozen_tl = pane->first;
721 unfrozen_tl = sv->edit_pos;
723 if (unfrozen_tl.row == 0 && unfrozen_tl.col == 0) {
724 GnmRange const *first = selection_first_range (sv, NULL, NULL);
725 Sheet *sheet = sv_sheet (sv);
726 gboolean full_rows = range_is_full (first, sheet, TRUE);
727 gboolean full_cols = range_is_full (first, sheet, FALSE);
728 if (!full_rows || !full_cols) {
729 if (!full_rows && !full_cols) {
730 unfrozen_tl.row = first->end.row + 1;
731 unfrozen_tl.col = first->end.col + 1;
732 } else if (full_rows) {
733 unfrozen_tl.row = first->end.row + 1;
734 unfrozen_tl.col = 0;
735 } else {
736 unfrozen_tl.row = 0;
737 unfrozen_tl.col = first->end.col + 1;
742 /* If edit pos is out of visible range */
743 if (unfrozen_tl.col < pane->first.col ||
744 unfrozen_tl.col > pane->last_visible.col ||
745 unfrozen_tl.row < pane->first.row ||
746 unfrozen_tl.row > pane->last_visible.row)
747 center = TRUE;
749 if (unfrozen_tl.col == pane->first.col) {
750 /* or edit pos is in top left visible cell */
751 if (unfrozen_tl.row == pane->first.row)
752 center = TRUE;
753 else
754 unfrozen_tl.col = frozen_tl.col = 0;
755 } else if (unfrozen_tl.row == pane->first.row)
756 unfrozen_tl.row = frozen_tl.row = 0;
758 if (center) {
759 unfrozen_tl.col = (pane->first.col +
760 pane->last_visible.col) / 2;
761 unfrozen_tl.row = (pane->first.row +
762 pane->last_visible.row) / 2;
765 g_return_if_fail (unfrozen_tl.col > frozen_tl.col ||
766 unfrozen_tl.row > frozen_tl.row);
768 gnm_sheet_view_freeze_panes (sv, &frozen_tl, &unfrozen_tl);
769 } else
770 gnm_sheet_view_freeze_panes (sv, NULL, NULL);
773 /****************************************************************************/
775 static void
776 insert_date_time_common (WBCGtk *wbcg, gboolean do_date, gboolean do_time)
778 if (wbcg_edit_start (wbcg, FALSE, FALSE)) {
779 WorkbookControl *wbc = GNM_WBC (wbcg);
780 SheetView *sv = wb_control_cur_sheet_view (wbc);
781 Sheet *sheet = sv_sheet (sv);
782 GnmCell const *cell = sheet_cell_fetch (sheet,
783 sv->edit_pos.col,
784 sv->edit_pos.row);
785 GODateConventions const *date_conv = sheet_date_conv (sheet);
786 GnmValue *v = value_new_float
787 (go_date_timet_to_serial_raw (time (NULL), date_conv));
788 char *txt;
789 char *dtxt = NULL;
790 char *ttxt = NULL;
792 if (do_date) {
793 GOFormat *fmt = gnm_format_for_date_editing (cell);
794 dtxt = format_value (fmt, v, -1, date_conv);
795 go_format_unref (fmt);
798 if (do_time) {
799 GOFormat const *fmt = go_format_default_time ();
800 ttxt = format_value (fmt, v, -1, date_conv);
803 if (do_date && do_time) {
804 txt = g_strconcat (dtxt, " ", ttxt, NULL);
805 g_free (dtxt);
806 g_free (ttxt);
807 } else if (do_date)
808 txt = dtxt;
809 else
810 txt = ttxt;
812 wb_control_edit_line_set (wbc, txt);
814 value_release (v);
815 g_free (txt);
821 static GNM_ACTION_DEF (cb_insert_current_date_time)
823 insert_date_time_common (wbcg, TRUE, TRUE);
825 static GNM_ACTION_DEF (cb_insert_current_date)
827 insert_date_time_common (wbcg, TRUE, FALSE);
830 static GNM_ACTION_DEF (cb_insert_current_time)
832 insert_date_time_common (wbcg, FALSE, TRUE);
835 static GNM_ACTION_DEF (cb_define_name)
837 dialog_define_names (wbcg);
839 static GNM_ACTION_DEF (cb_paste_names)
841 dialog_paste_names (wbcg);
844 static GNM_ACTION_DEF (cb_insert_rows)
846 WorkbookControl *wbc = GNM_WBC (wbcg);
847 Sheet *sheet = wb_control_cur_sheet (wbc);
848 SheetView *sv = wb_control_cur_sheet_view (wbc);
849 GnmRange const *sel;
851 /* TODO : No need to check simplicty. XL applies for each non-discrete
852 * selected region, (use selection_apply). Arrays and Merged regions
853 * are permitted.
855 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Insert rows"))))
856 return;
857 cmd_insert_rows (wbc, sheet, sel->start.row, range_height (sel));
860 static GNM_ACTION_DEF (cb_insert_cols)
862 WorkbookControl *wbc = GNM_WBC (wbcg);
863 Sheet *sheet = wb_control_cur_sheet (wbc);
864 SheetView *sv = wb_control_cur_sheet_view (wbc);
865 GnmRange const *sel;
867 /* TODO : No need to check simplicty. XL applies for each non-discrete
868 * selected region, (use selection_apply). Arrays and Merged regions
869 * are permitted.
871 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc),
872 _("Insert columns"))))
873 return;
874 cmd_insert_cols (wbc, sheet, sel->start.col, range_width (sel));
877 static GNM_ACTION_DEF (cb_insert_cells) { dialog_insert_cells (wbcg); }
879 static GNM_ACTION_DEF (cb_insert_comment)
881 WorkbookControl *wbc = GNM_WBC (wbcg);
882 Sheet *sheet = wb_control_cur_sheet (wbc);
883 SheetView *sv = wb_control_cur_sheet_view (wbc);
884 dialog_cell_comment (wbcg, sheet, &sv->edit_pos);
887 /****************************************************************************/
889 static GNM_ACTION_DEF (cb_sheet_name)
891 WorkbookControl *wbc = GNM_WBC (wbcg);
892 Sheet *sheet = wb_control_cur_sheet (wbc);
893 dialog_sheet_rename (wbcg, sheet);
896 static GNM_ACTION_DEF (cb_sheet_order) { dialog_sheet_order (wbcg); }
897 static GNM_ACTION_DEF (cb_sheet_resize) { dialog_sheet_resize (wbcg); }
898 static GNM_ACTION_DEF (cb_format_cells) { dialog_cell_format (wbcg, FD_CURRENT, 0); }
899 static GNM_ACTION_DEF (cb_format_cells_cond) { dialog_cell_format_cond (wbcg); }
900 static GNM_ACTION_DEF (cb_autoformat) { dialog_autoformat (wbcg); }
901 static GNM_ACTION_DEF (cb_workbook_attr) { dialog_workbook_attr (wbcg); }
902 static GNM_ACTION_DEF (cb_tools_plugins) { dialog_plugin_manager (wbcg); }
903 static GNM_ACTION_DEF (cb_tools_autocorrect) { dialog_preferences (wbcg, "Auto Correct"); }
904 static GNM_ACTION_DEF (cb_tools_auto_save) { dialog_autosave (wbcg); }
905 static GNM_ACTION_DEF (cb_tools_goal_seek) { dialog_goal_seek (wbcg, wbcg_cur_sheet (wbcg)); }
906 static GNM_ACTION_DEF (cb_tools_tabulate) { dialog_tabulate (wbcg, wbcg_cur_sheet (wbcg)); }
907 static GNM_ACTION_DEF (cb_tools_merge) { dialog_merge (wbcg); }
909 static GNM_ACTION_DEF (cb_tools_solver) { dialog_solver (wbcg, wbcg_cur_sheet (wbcg)); }
911 static GNM_ACTION_DEF (cb_tools_scenario_add) { dialog_scenario_add (wbcg); }
912 static GNM_ACTION_DEF (cb_tools_scenarios) { dialog_scenarios (wbcg); }
913 static GNM_ACTION_DEF (cb_tools_simulation) { dialog_simulation (wbcg, wbcg_cur_sheet (wbcg)); }
914 static GNM_ACTION_DEF (cb_tools_compare) { dialog_sheet_compare (wbcg); }
915 static GNM_ACTION_DEF (cb_tools_anova_one_factor) { dialog_anova_single_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
916 static GNM_ACTION_DEF (cb_tools_anova_two_factor) { dialog_anova_two_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
917 static GNM_ACTION_DEF (cb_tools_chi_square_independence) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), TRUE); }
918 static GNM_ACTION_DEF (cb_tools_chi_square_homogeneity) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), FALSE); }
919 static GNM_ACTION_DEF (cb_tools_correlation) { dialog_correlation_tool (wbcg, wbcg_cur_sheet (wbcg)); }
920 static GNM_ACTION_DEF (cb_tools_covariance) { dialog_covariance_tool (wbcg, wbcg_cur_sheet (wbcg)); }
921 static GNM_ACTION_DEF (cb_tools_desc_statistics) { dialog_descriptive_stat_tool (wbcg, wbcg_cur_sheet (wbcg)); }
922 static GNM_ACTION_DEF (cb_tools_exp_smoothing) { dialog_exp_smoothing_tool (wbcg, wbcg_cur_sheet (wbcg)); }
923 static GNM_ACTION_DEF (cb_tools_average) { dialog_average_tool (wbcg, wbcg_cur_sheet (wbcg)); }
924 static GNM_ACTION_DEF (cb_tools_fourier) { dialog_fourier_tool (wbcg, wbcg_cur_sheet (wbcg)); }
925 static GNM_ACTION_DEF (cb_tools_frequency) { dialog_frequency_tool (wbcg, wbcg_cur_sheet (wbcg)); }
926 static GNM_ACTION_DEF (cb_tools_histogram) { dialog_histogram_tool (wbcg, wbcg_cur_sheet (wbcg)); }
927 static GNM_ACTION_DEF (cb_tools_kaplan_meier) { dialog_kaplan_meier_tool (wbcg, wbcg_cur_sheet (wbcg)); }
928 static GNM_ACTION_DEF (cb_tools_normality_tests){ dialog_normality_tool (wbcg, wbcg_cur_sheet (wbcg)); }
929 static GNM_ACTION_DEF (cb_tools_one_mean_test) { dialog_one_mean_test_tool (wbcg, wbcg_cur_sheet (wbcg)); }
930 static GNM_ACTION_DEF (cb_tools_principal_components) { dialog_principal_components_tool (wbcg, wbcg_cur_sheet (wbcg)); }
931 static GNM_ACTION_DEF (cb_tools_ranking) { dialog_ranking_tool (wbcg, wbcg_cur_sheet (wbcg)); }
932 static GNM_ACTION_DEF (cb_tools_regression) { dialog_regression_tool (wbcg, wbcg_cur_sheet (wbcg)); }
933 static GNM_ACTION_DEF (cb_tools_sampling) { dialog_sampling_tool (wbcg, wbcg_cur_sheet (wbcg)); }
934 static GNM_ACTION_DEF (cb_tools_sign_test_one_median) { dialog_sign_test_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST); }
935 static GNM_ACTION_DEF (cb_tools_sign_test_two_medians) { dialog_sign_test_two_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST); }
936 static GNM_ACTION_DEF (cb_tools_wilcoxon_signed_rank_one_median) { dialog_sign_test_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST_WILCOXON); }
937 static GNM_ACTION_DEF (cb_tools_wilcoxon_signed_rank_two_medians) { dialog_sign_test_two_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST_WILCOXON); }
938 static GNM_ACTION_DEF (cb_tools_wilcoxon_mann_whitney) { dialog_wilcoxon_m_w_tool (wbcg, wbcg_cur_sheet (wbcg)); }
939 static GNM_ACTION_DEF (cb_tools_ttest_paired) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_PAIRED); }
940 static GNM_ACTION_DEF (cb_tools_ttest_equal_var) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_UNPAIRED_EQUALVARIANCES); }
941 static GNM_ACTION_DEF (cb_tools_ttest_unequal_var) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_UNPAIRED_UNEQUALVARIANCES); }
942 static GNM_ACTION_DEF (cb_tools_ztest) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_ZTEST); }
943 static GNM_ACTION_DEF (cb_tools_ftest) { dialog_ftest_tool (wbcg, wbcg_cur_sheet (wbcg)); }
944 static GNM_ACTION_DEF (cb_tools_random_generator_uncorrelated) { dialog_random_tool (wbcg, wbcg_cur_sheet (wbcg)); }
945 static GNM_ACTION_DEF (cb_tools_random_generator_correlated) { dialog_random_cor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
946 static GNM_ACTION_DEF (cb_data_sort) { dialog_cell_sort (wbcg); }
947 static GNM_ACTION_DEF (cb_data_shuffle) { dialog_shuffle (wbcg); }
948 static GNM_ACTION_DEF (cb_data_import_text) { gui_file_open
949 (wbcg, GNM_FILE_OPEN_STYLE_IMPORT, "Gnumeric_stf:stf_assistant"); }
950 static GNM_ACTION_DEF (cb_data_import_other) { gui_file_open
951 (wbcg, GNM_FILE_OPEN_STYLE_IMPORT, NULL); }
953 static GNM_ACTION_DEF (cb_auto_filter) { cmd_autofilter_add_remove (GNM_WBC (wbcg)); }
954 static GNM_ACTION_DEF (cb_show_all) { filter_show_all (GNM_WBC (wbcg)); }
955 static GNM_ACTION_DEF (cb_data_filter) { dialog_advanced_filter (wbcg); }
956 static GNM_ACTION_DEF (cb_data_validate) { dialog_cell_format (wbcg, FD_VALIDATION,
957 (1 << FD_VALIDATION) | (1 << FD_INPUT_MSG)); }
958 static GNM_ACTION_DEF (cb_data_text_to_columns) { stf_text_to_columns (GNM_WBC (wbcg), GO_CMD_CONTEXT (wbcg)); }
959 static GNM_ACTION_DEF (cb_data_consolidate) { dialog_consolidate (wbcg); }
960 static GNM_ACTION_DEF (cb_data_table) { dialog_data_table (wbcg); }
961 static GNM_ACTION_DEF (cb_data_slicer_create) { dialog_data_slicer (wbcg, TRUE); }
962 static GNM_ACTION_DEF (cb_data_slicer_refresh) { cmd_slicer_refresh (GNM_WBC (wbcg)); }
963 static GNM_ACTION_DEF (cb_data_slicer_edit) { dialog_data_slicer (wbcg, FALSE); }
964 static GNM_ACTION_DEF (cb_data_export) { gui_file_save_as
965 (wbcg, wb_control_view (GNM_WBC (wbcg)),
966 GNM_FILE_SAVE_AS_STYLE_EXPORT, NULL); }
967 static GNM_ACTION_DEF (cb_data_export_text) { gui_file_save_as
968 (wbcg, wb_control_view (GNM_WBC (wbcg)),
969 GNM_FILE_SAVE_AS_STYLE_EXPORT, "Gnumeric_stf:stf_assistant"); }
970 static GNM_ACTION_DEF (cb_data_export_csv) { gui_file_save_as
971 (wbcg, wb_control_view (GNM_WBC (wbcg)),
972 GNM_FILE_SAVE_AS_STYLE_EXPORT, "Gnumeric_stf:stf_csv"); }
973 static GNM_ACTION_DEF (cb_data_export_repeat) { gui_file_export_repeat (wbcg); }
975 static void
976 hide_show_detail_real (WBCGtk *wbcg, gboolean is_cols, gboolean show)
978 WorkbookControl *wbc = GNM_WBC (wbcg);
979 SheetView *sv = wb_control_cur_sheet_view (wbc);
980 char const *operation = show ? _("Show Detail") : _("Hide Detail");
981 GnmRange const *r = selection_first_range (sv, GO_CMD_CONTEXT (wbc),
982 operation);
984 /* This operation can only be performed on a whole existing group */
985 if (sheet_colrow_can_group (sv_sheet (sv), r, is_cols)) {
986 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbc), operation,
987 _("can only be performed on an existing group"));
988 return;
991 cmd_selection_colrow_hide (wbc, is_cols, show);
994 static void
995 hide_show_detail (WBCGtk *wbcg, gboolean show)
997 WorkbookControl *wbc = GNM_WBC (wbcg);
998 SheetView *sv = wb_control_cur_sheet_view (wbc);
999 Sheet const *sheet = sv_sheet (sv);
1000 char const *operation = show ? _("Show Detail") : _("Hide Detail");
1001 GnmRange const *r = selection_first_range (sv,
1002 GO_CMD_CONTEXT (wbc), operation);
1003 gboolean is_cols;
1005 /* We only operate on a single selection */
1006 if (r == NULL)
1007 return;
1009 /* Do we need to ask the user what he/she wants to group/ungroup? */
1010 if (range_is_full (r, sheet, TRUE) ^ range_is_full (r, sheet, FALSE))
1011 is_cols = !range_is_full (r, sheet, TRUE);
1012 else {
1013 dialog_col_row (wbcg, operation,
1014 (ColRowCallback_t) hide_show_detail_real,
1015 GINT_TO_POINTER (show));
1016 return;
1019 hide_show_detail_real (wbcg, is_cols, show);
1022 static void
1023 group_ungroup_colrow (WBCGtk *wbcg, gboolean group)
1025 WorkbookControl *wbc = GNM_WBC (wbcg);
1026 SheetView *sv = wb_control_cur_sheet_view (wbc);
1027 Sheet const *sheet = sv_sheet (sv);
1028 char const *operation = group ? _("Group") : _("Ungroup");
1029 GnmRange const *r = selection_first_range (sv,
1030 GO_CMD_CONTEXT (wbc), operation);
1031 gboolean is_cols;
1033 /* We only operate on a single selection */
1034 if (r == NULL)
1035 return;
1037 /* Do we need to ask the user what he/she wants to group/ungroup? */
1038 if (range_is_full (r, sheet, TRUE) ^ range_is_full (r, sheet, FALSE))
1039 is_cols = !range_is_full (r, sheet, TRUE);
1040 else {
1041 dialog_col_row (wbcg, operation,
1042 (ColRowCallback_t) cmd_selection_group,
1043 GINT_TO_POINTER (group));
1044 return;
1047 cmd_selection_group (wbc, is_cols, group);
1050 static GNM_ACTION_DEF (cb_data_hide_detail) { hide_show_detail (wbcg, FALSE); }
1051 static GNM_ACTION_DEF (cb_data_show_detail) { hide_show_detail (wbcg, TRUE); }
1052 static GNM_ACTION_DEF (cb_data_group) { group_ungroup_colrow (wbcg, TRUE); }
1053 static GNM_ACTION_DEF (cb_data_ungroup) { group_ungroup_colrow (wbcg, FALSE); }
1055 static GNM_ACTION_DEF (cb_help_function) { dialog_function_select_help (wbcg); }
1056 static GNM_ACTION_DEF (cb_help_docs)
1058 char *argv[] = { NULL, NULL, NULL };
1059 GError *err = NULL;
1061 #ifndef G_OS_WIN32
1062 argv[0] = (char *)"yelp";
1063 argv[1] = (char *)"help:gnumeric";
1064 g_spawn_async (NULL, argv, NULL,
1065 G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL
1066 | G_SPAWN_STDERR_TO_DEV_NULL,
1067 NULL, NULL, NULL, &err);
1068 #else
1069 /* TODO : Should really start in same directory as the gspawn-* helpers
1070 * are installed in case they are not in the path */
1071 argv[0] = (char *)"hh";
1072 argv[1] = g_build_filename (gnm_sys_data_dir (), "doc", "C",
1073 "gnumeric.chm", NULL);
1074 g_spawn_async (NULL, argv, NULL,
1075 G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL
1076 | G_SPAWN_STDERR_TO_DEV_NULL,
1077 NULL, NULL, NULL, &err);
1078 g_free (argv[1]);
1079 #endif
1080 if (NULL != err) {
1081 GOErrorInfo *ei = go_error_info_new_printf
1082 (_("Unable to start the help browser (%s).\n"
1083 "The system error message is: \n\n%s"),
1084 argv[0], err->message);
1085 go_cmd_context_error_info (GO_CMD_CONTEXT (wbcg), ei);
1086 g_error_free (err);
1087 g_free (ei);
1091 static void
1092 show_url (WBCGtk *wbcg, const char *url)
1094 GError *err;
1095 GdkScreen *screen;
1097 screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
1098 err = go_gtk_url_show (url, screen);
1099 if (err != NULL) {
1100 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), err);
1101 g_error_free (err);
1106 static GNM_ACTION_DEF (cb_help_web)
1108 show_url (wbcg, "http://www.gnumeric.org/");
1111 static GNM_ACTION_DEF (cb_help_irc)
1113 show_url (wbcg, "irc://irc.gnome.org/gnumeric");
1116 static GNM_ACTION_DEF (cb_help_bug)
1118 show_url (wbcg, "http://bugzilla.gnome.org/enter_bug.cgi?product=Gnumeric");
1121 static GNM_ACTION_DEF (cb_help_about) { dialog_about (wbcg); }
1123 static GNM_ACTION_DEF (cb_autosum)
1125 GtkEntry *entry;
1126 gchar const *txt;
1128 if (wbcg_is_editing (wbcg))
1129 return;
1131 entry = wbcg_get_entry (wbcg);
1132 txt = gtk_entry_get_text (entry);
1133 if (strncmp (txt, "=sum(", 5)) {
1134 if (!wbcg_edit_start (wbcg, TRUE, TRUE))
1135 return; /* attempt to edit failed */
1136 gtk_entry_set_text (entry, "=sum()");
1137 gtk_editable_set_position (GTK_EDITABLE (entry), 5);
1138 } else {
1139 if (!wbcg_edit_start (wbcg, FALSE, TRUE))
1140 return; /* attempt to edit failed */
1143 * FIXME : This is crap!
1144 * When the function druid is more complete use that.
1146 gtk_editable_set_position (GTK_EDITABLE (entry),
1147 gtk_entry_get_text_length (entry)-1);
1151 static GNM_ACTION_DEF (cb_insert_image)
1153 char *uri = go_gtk_select_image (wbcg_toplevel (wbcg), NULL);
1155 if (uri) {
1156 GError *err = NULL;
1157 GsfInput *input = go_file_open (uri, &err);
1159 if (input != NULL) {
1160 unsigned len = gsf_input_size (input);
1161 guint8 const *data = gsf_input_read (input, len, NULL);
1162 SheetObjectImage *soi = g_object_new (GNM_SO_IMAGE_TYPE, NULL);
1163 sheet_object_image_set_image (soi, "", data, len);
1164 wbcg_insert_object (wbcg, GNM_SO (soi));
1165 g_object_unref (input);
1166 } else
1167 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), err);
1169 g_free (uri);
1173 static GNM_ACTION_DEF (cb_insert_hyperlink) { dialog_hyperlink (wbcg, GNM_SHEET_CONTROL (wbcg_cur_scg (wbcg))); }
1174 static GNM_ACTION_DEF (cb_formula_guru) { dialog_formula_guru (wbcg, NULL); }
1175 static GNM_ACTION_DEF (cb_insert_sort_ascending) { workbook_cmd_wrap_sort (GNM_WBC (wbcg), 1);}
1176 static GNM_ACTION_DEF (cb_insert_sort_descending){ workbook_cmd_wrap_sort (GNM_WBC (wbcg), 0);}
1178 static void
1179 sort_by_rows (WBCGtk *wbcg, gboolean descending)
1181 SheetView *sv;
1182 GnmRange *sel;
1183 GnmRange tmp_ns ={{0,0},{0,0}}, tmp_s ={{0,0},{0,0}};
1184 GnmSortData *data;
1185 GnmSortClause *clause;
1186 int numclause, i;
1187 GSList *l;
1188 int cnt_singletons = 0, cnt_non_singletons = 0;
1189 gboolean top_to_bottom = TRUE;
1190 gboolean not_acceptable = FALSE;
1192 g_return_if_fail (GNM_IS_WBC_GTK (wbcg));
1194 sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
1195 for (l = sv->selections; l != NULL; l = l->next) {
1196 GnmRange const *r = l->data;
1197 if (range_is_singleton (r)) {
1198 cnt_singletons++;
1199 tmp_s = *r;
1200 } else {
1201 cnt_non_singletons++;
1202 tmp_ns = *r;
1206 not_acceptable = (cnt_non_singletons > 1 ||
1207 (cnt_non_singletons == 0 && cnt_singletons > 1));
1209 if (!not_acceptable && cnt_singletons > 0 && cnt_non_singletons == 1) {
1210 gboolean first = TRUE;
1211 for (l = sv->selections; l != NULL; l = l->next) {
1212 GnmRange const *r = l->data;
1213 gboolean t_b = FALSE, l_r = FALSE;
1215 if (!range_is_singleton (r))
1216 continue;
1217 t_b = r->start.col >= tmp_ns.start.col &&
1218 r->end.col <= tmp_ns.end.col;
1219 l_r = r->start.row >= tmp_ns.start.row &&
1220 r->end.row <= tmp_ns.end.row;
1221 if (!t_b && !l_r) {
1222 not_acceptable = TRUE;
1223 break;
1225 if (!t_b || !l_r) {
1226 if (first) {
1227 first = FALSE;
1228 top_to_bottom = t_b;
1229 } else {
1230 if ((top_to_bottom && !t_b) ||
1231 (!top_to_bottom && !l_r)) {
1232 not_acceptable = TRUE;
1233 break;
1240 if (not_acceptable) {
1241 GError *msg = g_error_new (go_error_invalid(), 0,
1242 _("%s does not support multiple ranges"),
1243 _("Sort"));
1244 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), msg);
1245 g_error_free (msg);
1246 return;
1249 if (cnt_singletons == 1 && cnt_non_singletons == 0) {
1250 Sheet *sheet = sv_sheet (sv);
1252 sel = g_new0 (GnmRange, 1);
1253 range_init_full_sheet (sel, sheet);
1254 sel->start.row = tmp_s.start.row;
1255 range_clip_to_finite (sel, sheet);
1256 numclause = 1;
1257 clause = g_new0 (GnmSortClause, 1);
1258 clause[0].offset = tmp_s.start.col - sel->start.col;
1259 clause[0].asc = descending;
1260 clause[0].cs = gnm_conf_get_core_sort_default_by_case ();
1261 clause[0].val = TRUE;
1262 } else if (cnt_singletons == 0) {
1263 sel = gnm_range_dup (&tmp_ns);
1264 range_clip_to_finite (sel, sv_sheet (sv));
1266 numclause = range_width (sel);
1267 clause = g_new0 (GnmSortClause, numclause);
1268 for (i = 0; i < numclause; i++) {
1269 clause[i].offset = i;
1270 clause[i].asc = descending;
1271 clause[i].cs = gnm_conf_get_core_sort_default_by_case ();
1272 clause[i].val = TRUE;
1274 } else /* cnt_singletons > 0 && cnt_non_singletons == 1*/ {
1275 sel = gnm_range_dup (&tmp_ns);
1276 range_clip_to_finite (sel, sv_sheet (sv));
1277 numclause = cnt_singletons;
1278 clause = g_new0 (GnmSortClause, numclause);
1279 i = numclause - 1;
1280 for (l = sv->selections; l != NULL; l = l->next) {
1281 GnmRange const *r = l->data;
1282 if (!range_is_singleton (r))
1283 continue;
1284 if (i >= 0) {
1285 clause[i].offset = (top_to_bottom) ?
1286 r->start.col - sel->start.col
1287 : r->start.row - sel->start.row;
1288 clause[i].asc = descending;
1289 clause[i].cs = gnm_conf_get_core_sort_default_by_case ();
1290 clause[i].val = TRUE;
1292 i--;
1296 data = g_new (GnmSortData, 1);
1297 data->sheet = sv_sheet (sv);
1298 data->range = sel;
1299 data->num_clause = numclause;
1300 data->clauses = clause;
1301 data->locale = NULL;
1303 data->retain_formats = gnm_conf_get_core_sort_default_retain_formats ();
1305 /* Hard code sorting by row. I would prefer not to, but user testing
1306 * indicates
1307 * - that the button should always does the same things
1308 * - that the icon matches the behavior
1309 * - XL does this.
1312 /* Note that if the user specified rows by singleton selection we switch */
1313 /* to column sorting */
1314 data->top = top_to_bottom;
1316 if (sheet_range_has_heading (data->sheet, data->range, data->top, FALSE))
1317 data->range->start.row += 1;
1319 cmd_sort (GNM_WBC (wbcg), data);
1321 static GNM_ACTION_DEF (cb_sort_ascending) { sort_by_rows (wbcg, FALSE); }
1322 static GNM_ACTION_DEF (cb_sort_descending) { sort_by_rows (wbcg, TRUE); }
1324 static void
1325 cb_add_graph (GogGraph *graph, gpointer wbcg)
1327 GnmGraphDataClosure *data = (GnmGraphDataClosure *) g_object_get_data (G_OBJECT (graph), "data-closure");
1328 if (data) {
1329 if (data->new_sheet) {
1330 WorkbookControl *wbc = GNM_WBC (wbcg);
1331 Sheet *sheet = wb_control_cur_sheet (wbc);
1332 WorkbookSheetState *old_state = workbook_sheet_state_new (wb_control_get_workbook (wbc));
1333 Sheet *new_sheet = workbook_sheet_add_with_type (
1334 wb_control_get_workbook (wbc),
1335 GNM_SHEET_OBJECT, -1,
1336 gnm_sheet_get_max_cols (sheet),
1337 gnm_sheet_get_max_rows (sheet));
1338 SheetObject *sog = sheet_object_graph_new (graph);
1339 print_info_set_paper_orientation (new_sheet->print_info, GTK_PAGE_ORIENTATION_LANDSCAPE);
1340 sheet_object_set_sheet (sog, new_sheet);
1341 wb_view_sheet_focus (wb_control_view (wbc), new_sheet);
1342 cmd_reorganize_sheets (wbc, old_state, sheet);
1343 g_object_unref (sog);
1344 return;
1347 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_graph_new (graph));
1350 static GNM_ACTION_DEF (cb_launch_chart_guru)
1352 GClosure *closure = g_cclosure_new (G_CALLBACK (cb_add_graph),
1353 wbcg, NULL);
1354 sheet_object_graph_guru (wbcg, NULL, closure);
1355 g_closure_sink (closure);
1358 static void
1359 cb_add_component_new (GOComponent *component, gpointer wbcg)
1361 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
1364 static void
1365 component_changed_cb (GOComponent *component, gpointer data)
1367 cb_add_component_new (component, data);
1370 static GNM_ACTION_DEF (cb_launch_go_component_new)
1372 gchar const *mime_type;
1373 gint result;
1374 GtkWidget *dialog = go_component_mime_dialog_new ();
1375 result = gtk_dialog_run (GTK_DIALOG (dialog));
1376 if (result == GTK_RESPONSE_OK) {
1377 mime_type = go_component_mime_dialog_get_mime_type ((GOComponentMimeDialog *) dialog);
1378 if (mime_type) {
1379 GtkWindow *win;
1380 GOComponent *component = go_component_new_by_mime_type (mime_type);
1381 if (component) {
1382 g_signal_connect (G_OBJECT (component), "changed", G_CALLBACK (component_changed_cb), wbcg);
1383 win = go_component_edit (component);
1384 gtk_window_set_transient_for (win, GTK_WINDOW (wbcg_toplevel (wbcg)));
1385 g_object_set_data_full (G_OBJECT (win), "component", component, g_object_unref);
1389 gtk_widget_destroy (dialog);
1392 static GNM_ACTION_DEF (cb_launch_go_component_from_file)
1394 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Choose object file"),
1395 GTK_WINDOW (wbcg_toplevel (wbcg)),
1396 GTK_FILE_CHOOSER_ACTION_OPEN,
1397 GNM_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1398 GNM_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1399 NULL);
1400 go_components_add_filter (GTK_FILE_CHOOSER (dlg));
1401 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
1402 char *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg));
1403 GOComponent *component;
1404 component = go_component_new_from_uri (uri);
1405 g_free (uri);
1406 if (component) {
1407 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
1408 g_object_unref (component);
1411 gtk_widget_destroy (dlg);
1414 static void
1415 create_object (WBCGtk *wbcg, GType t,
1416 char const *first_property_name,
1417 ...)
1419 va_list args;
1420 va_start (args, first_property_name);
1421 wbcg_insert_object (wbcg, (SheetObject *)
1422 g_object_new_valist (t, first_property_name, args));
1423 va_end (args);
1426 static GNM_ACTION_DEF (cmd_create_frame)
1427 { create_object (wbcg, sheet_widget_frame_get_type(), NULL); }
1428 static GNM_ACTION_DEF (cmd_create_button)
1429 { create_object (wbcg, sheet_widget_button_get_type(), NULL); }
1430 static GNM_ACTION_DEF (cmd_create_radiobutton)
1431 { create_object (wbcg, sheet_widget_radio_button_get_type(), NULL); }
1432 static GNM_ACTION_DEF (cmd_create_scrollbar)
1433 { create_object (wbcg, sheet_widget_scrollbar_get_type(), NULL); }
1434 static GNM_ACTION_DEF (cmd_create_slider)
1435 { create_object (wbcg, sheet_widget_slider_get_type(), NULL); }
1436 static GNM_ACTION_DEF (cmd_create_spinbutton)
1437 { create_object (wbcg, sheet_widget_spinbutton_get_type(), NULL); }
1438 static GNM_ACTION_DEF (cmd_create_checkbox)
1439 { create_object (wbcg, sheet_widget_checkbox_get_type(), NULL); }
1440 static GNM_ACTION_DEF (cmd_create_list)
1441 { create_object (wbcg, sheet_widget_list_get_type(), NULL); }
1442 static GNM_ACTION_DEF (cmd_create_combo)
1443 { create_object (wbcg, sheet_widget_combo_get_type(), NULL); }
1444 static GNM_ACTION_DEF (cmd_create_line)
1445 { create_object (wbcg, GNM_SO_LINE_TYPE, NULL); }
1446 static GNM_ACTION_DEF (cmd_create_arrow) {
1447 GOArrow arrow;
1448 go_arrow_init_kite (&arrow, 8., 10., 3.);
1449 create_object (wbcg, GNM_SO_LINE_TYPE, "end-arrow", &arrow, NULL);
1451 static GNM_ACTION_DEF (cmd_create_rectangle)
1452 { create_object (wbcg, GNM_SO_FILLED_TYPE, NULL); }
1453 static GNM_ACTION_DEF (cmd_create_ellipse)
1454 { create_object (wbcg, GNM_SO_FILLED_TYPE, "is-oval", TRUE, NULL); }
1456 /*****************************************************************************/
1457 static void
1458 wbcg_set_selection_halign (WBCGtk *wbcg, GnmHAlign halign)
1460 WorkbookControl *wbc = GNM_WBC (wbcg);
1461 WorkbookView *wb_view;
1462 GnmStyle *style;
1464 if (wbcg->updating_ui)
1465 return;
1467 /* This is a toggle button. If we are already enabled
1468 * then revert to general */
1469 wb_view = wb_control_view (wbc);
1470 if (gnm_style_get_align_h (wb_view->current_style) == halign)
1471 halign = GNM_HALIGN_GENERAL;
1473 style = gnm_style_new ();
1474 gnm_style_set_align_h (style, halign);
1475 cmd_selection_format (wbc, style, NULL, _("Set Horizontal Alignment"));
1477 static GNM_ACTION_DEF (cb_align_left)
1478 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_LEFT); }
1479 static GNM_ACTION_DEF (cb_align_right)
1480 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_RIGHT); }
1481 static GNM_ACTION_DEF (cb_align_center)
1482 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_CENTER); }
1483 static GNM_ACTION_DEF (cb_center_across_selection)
1484 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_CENTER_ACROSS_SELECTION); }
1486 /*****************************************************************************/
1488 static void
1489 wbcg_set_selection_valign (WBCGtk *wbcg, GnmVAlign valign)
1491 WorkbookControl *wbc = GNM_WBC (wbcg);
1492 WorkbookView *wb_view;
1493 GnmStyle *style;
1495 if (wbcg->updating_ui)
1496 return;
1498 /* This is a toggle button. If we are already enabled
1499 * then revert to general */
1500 wb_view = wb_control_view (wbc);
1501 if (gnm_style_get_align_v (wb_view->current_style) == valign) {
1502 if (valign == GNM_VALIGN_BOTTOM)
1503 return;
1504 valign = GNM_VALIGN_BOTTOM;
1507 style = gnm_style_new ();
1508 gnm_style_set_align_v (style, valign);
1509 cmd_selection_format (wbc, style, NULL, _("Set Vertical Alignment"));
1511 static GNM_ACTION_DEF (cb_align_top)
1512 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_TOP); }
1513 static GNM_ACTION_DEF (cb_align_vcenter)
1514 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_CENTER); }
1515 static GNM_ACTION_DEF (cb_align_bottom)
1516 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_BOTTOM); }
1518 /*****************************************************************************/
1520 static GNM_ACTION_DEF (cb_merge_and_center)
1522 WorkbookControl *wbc = GNM_WBC (wbcg);
1523 GSList *range_list = selection_get_ranges (
1524 wb_control_cur_sheet_view (wbc), FALSE);
1525 cmd_merge_cells (wbc, wb_control_cur_sheet (wbc), range_list, TRUE);
1526 range_fragment_free (range_list);
1529 static GNM_ACTION_DEF (cb_merge_cells)
1531 WorkbookControl *wbc = GNM_WBC (wbcg);
1532 GSList *range_list = selection_get_ranges (
1533 wb_control_cur_sheet_view (wbc), FALSE);
1534 cmd_merge_cells (wbc, wb_control_cur_sheet (wbc), range_list, FALSE);
1535 range_fragment_free (range_list);
1538 static GNM_ACTION_DEF (cb_unmerge_cells)
1540 WorkbookControl *wbc = GNM_WBC (wbcg);
1541 GSList *range_list = selection_get_ranges (
1542 wb_control_cur_sheet_view (wbc), FALSE);
1543 cmd_unmerge_cells (wbc, wb_control_cur_sheet (wbc), range_list);
1544 range_fragment_free (range_list);
1547 static GNM_ACTION_DEF (cb_view_statusbar)
1549 wbcg_toggle_visibility (wbcg, GTK_TOGGLE_ACTION (a));
1552 /*****************************************************************************/
1554 static void
1555 toggle_font_attr (WBCGtk *wbcg, GtkToggleAction *act,
1556 GnmStyleElement t, unsigned true_val, unsigned false_val)
1558 WorkbookControl *wbc = GNM_WBC (wbcg);
1559 GnmStyle *new_style;
1560 unsigned val;
1562 /* If the user did not initiate this action ignore it.
1563 * This happens whenever the ui updates and the current cell makes a
1564 * change to the toolbar indicators.
1566 if (wbcg->updating_ui)
1567 return;
1569 val = gtk_toggle_action_get_active (act) ? true_val : false_val;
1570 if (wbcg_is_editing (wbcg)) {
1571 PangoAttribute *attr = NULL;
1572 switch (t) {
1573 default:
1574 case MSTYLE_FONT_BOLD:
1575 attr = pango_attr_weight_new (val ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
1576 break;
1577 case MSTYLE_FONT_ITALIC:
1578 attr = pango_attr_style_new (val ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
1579 break;
1580 case MSTYLE_FONT_UNDERLINE:
1581 attr = pango_attr_underline_new
1582 (gnm_translate_underline_to_pango (val));
1583 break;
1584 case MSTYLE_FONT_STRIKETHROUGH:
1585 attr = pango_attr_strikethrough_new (val);
1586 break;
1587 case MSTYLE_FONT_SCRIPT:
1588 switch (val) {
1589 default:
1590 case GO_FONT_SCRIPT_STANDARD:
1591 wbcg_edit_add_markup
1592 (wbcg, go_pango_attr_superscript_new (FALSE));
1593 attr = go_pango_attr_subscript_new (FALSE);
1594 break;
1595 case GO_FONT_SCRIPT_SUPER:
1596 attr = go_pango_attr_superscript_new (TRUE);
1597 break;
1598 case GO_FONT_SCRIPT_SUB:
1599 attr = go_pango_attr_subscript_new (TRUE);
1600 break;
1602 break;
1604 wbcg_edit_add_markup (wbcg, attr);
1605 return;
1608 new_style = gnm_style_new ();
1609 switch (t) {
1610 default:
1611 case MSTYLE_FONT_BOLD: gnm_style_set_font_bold (new_style, val); break;
1612 case MSTYLE_FONT_ITALIC: gnm_style_set_font_italic (new_style, val); break;
1613 case MSTYLE_FONT_UNDERLINE: gnm_style_set_font_uline (new_style, val); break;
1614 case MSTYLE_FONT_STRIKETHROUGH: gnm_style_set_font_strike (new_style, val); break;
1615 case MSTYLE_FONT_SCRIPT: gnm_style_set_font_script (new_style, val); break;
1618 cmd_selection_format_toggle_font_style (wbc, new_style, t);
1621 static void cb_font_bold (GtkToggleAction *act, WBCGtk *wbcg)
1622 { toggle_font_attr (wbcg, act, MSTYLE_FONT_BOLD, TRUE, FALSE); }
1623 static void cb_font_italic (GtkToggleAction *act, WBCGtk *wbcg)
1624 { toggle_font_attr (wbcg, act, MSTYLE_FONT_ITALIC, TRUE, FALSE); }
1625 static void cb_font_underline (GtkToggleAction *act, WBCGtk *wbcg)
1626 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_SINGLE, UNDERLINE_NONE); }
1627 static void cb_font_double_underline (GtkToggleAction *act, WBCGtk *wbcg)
1628 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_DOUBLE, UNDERLINE_NONE); }
1629 static void cb_font_underline_low (GtkToggleAction *act, WBCGtk *wbcg)
1630 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_SINGLE_LOW, UNDERLINE_NONE); }
1631 static void cb_font_double_underline_low (GtkToggleAction *act, WBCGtk *wbcg)
1632 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_DOUBLE_LOW, UNDERLINE_NONE); }
1633 static void cb_font_strikethrough (GtkToggleAction *act, WBCGtk *wbcg)
1634 { toggle_font_attr (wbcg, act, MSTYLE_FONT_STRIKETHROUGH, TRUE, FALSE); }
1635 static void cb_font_subscript (GtkToggleAction *act, WBCGtk *wbcg)
1636 { toggle_font_attr (wbcg, act, MSTYLE_FONT_SCRIPT, GO_FONT_SCRIPT_SUB, GO_FONT_SCRIPT_STANDARD); }
1637 static void cb_font_superscript (GtkToggleAction *act, WBCGtk *wbcg)
1638 { toggle_font_attr (wbcg, act, MSTYLE_FONT_SCRIPT, GO_FONT_SCRIPT_SUPER, GO_FONT_SCRIPT_STANDARD); }
1640 static void
1641 apply_number_format (WBCGtk *wbcg,
1642 GOFormat *format,
1643 char const *descriptor)
1645 GnmStyle *mstyle = gnm_style_new ();
1646 gnm_style_set_format (mstyle, format);
1647 cmd_selection_format (GNM_WBC (wbcg), mstyle, NULL, descriptor);
1650 static GNM_ACTION_DEF (cb_format_as_general)
1652 apply_number_format (wbcg,
1653 go_format_general (),
1654 _("Format as General"));
1657 static GNM_ACTION_DEF (cb_format_as_number)
1659 GOFormat *fmt = go_format_new_from_XL ("0");
1660 apply_number_format (wbcg, fmt, _("Format as Number"));
1661 go_format_unref (fmt);
1664 static GNM_ACTION_DEF (cb_format_as_currency)
1666 GOFormatDetails *details = go_format_details_new (GO_FORMAT_CURRENCY);
1667 GString *str = g_string_new (NULL);
1668 GOFormat *fmt;
1670 details->currency = go_format_locale_currency ();
1671 details->num_decimals = 2;
1672 go_format_generate_str (str, details);
1673 go_format_details_free (details);
1675 fmt = go_format_new_from_XL (str->str);
1676 g_string_free (str, TRUE);
1677 apply_number_format (wbcg, fmt, _("Format as Currency"));
1678 go_format_unref (fmt);
1681 static GNM_ACTION_DEF (cb_format_as_accounting)
1683 apply_number_format (wbcg,
1684 go_format_default_accounting (),
1685 _("Format as Accounting"));
1688 static GNM_ACTION_DEF (cb_format_as_percentage)
1690 GOFormat *fmt = go_format_new_from_XL ("0%");
1691 apply_number_format (wbcg, fmt, _("Format as Percentage"));
1692 go_format_unref (fmt);
1695 static GNM_ACTION_DEF (cb_format_as_scientific)
1697 GOFormat *fmt = go_format_new_from_XL ("0.00E+00");
1698 apply_number_format (wbcg, fmt, _("Format as Percentage"));
1699 go_format_unref (fmt);
1702 static GNM_ACTION_DEF (cb_format_as_time)
1704 apply_number_format (wbcg,
1705 go_format_default_time (),
1706 _("Format as Time"));
1709 static GNM_ACTION_DEF (cb_format_as_date)
1711 apply_number_format (wbcg,
1712 go_format_default_date (),
1713 _("Format as Date"));
1716 /* Adds borders to all the selected regions on the sheet.
1717 * FIXME: This is a little more simplistic then it should be, it always
1718 * removes and/or overwrites any borders. What we should do is
1719 * 1) When adding -> don't add a border if the border is thicker than 'THIN'
1720 * 2) When removing -> don't remove unless the border is 'THIN'
1722 static void
1723 mutate_borders (WBCGtk *wbcg, gboolean add)
1725 GnmBorder *borders [GNM_STYLE_BORDER_EDGE_MAX];
1726 int i;
1728 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; ++i)
1729 if (i <= GNM_STYLE_BORDER_RIGHT)
1730 borders[i] = gnm_style_border_fetch (
1731 add ? GNM_STYLE_BORDER_THIN : GNM_STYLE_BORDER_NONE,
1732 style_color_black (), gnm_style_border_get_orientation (i));
1733 else
1734 borders[i] = NULL;
1736 cmd_selection_format (GNM_WBC (wbcg), NULL, borders,
1737 add ? _("Add Borders") : _("Remove borders"));
1740 static GNM_ACTION_DEF (cb_format_add_borders) { mutate_borders (wbcg, TRUE); }
1741 static GNM_ACTION_DEF (cb_format_clear_borders) { mutate_borders (wbcg, FALSE); }
1743 static void
1744 modify_format (WBCGtk *wbcg,
1745 GOFormat *(*format_modify_fn) (GOFormat const *format),
1746 char const *descriptor)
1748 WorkbookControl *wbc = GNM_WBC (wbcg);
1749 WorkbookView const *wbv;
1750 GOFormat *new_fmt;
1752 wbv = wb_control_view (wbc);
1753 g_return_if_fail (wbv != NULL);
1754 g_return_if_fail (wbv->current_style != NULL);
1756 new_fmt = (*format_modify_fn) (gnm_style_get_format (wbv->current_style));
1757 if (new_fmt != NULL) {
1758 GnmStyle *style = gnm_style_new ();
1759 gnm_style_set_format (style, new_fmt);
1760 cmd_selection_format (wbc, style, NULL, descriptor);
1761 go_format_unref (new_fmt);
1765 static GnmValue *
1766 cb_calc_decs (GnmCellIter const *iter, gpointer user)
1768 int *pdecs = user;
1769 int decs = 0;
1770 GnmCell *cell = iter->cell;
1771 char *text;
1772 const char *p;
1773 GString const *dec = go_locale_get_decimal ();
1775 if (!cell || !cell->value || !VALUE_IS_NUMBER (cell->value))
1776 return NULL;
1779 * If we are displaying an equation, we don't want to look into
1780 * the rendered text.
1782 if (gnm_cell_has_expr (cell) && cell->base.sheet->display_formulas)
1783 return NULL;
1785 text = gnm_cell_get_rendered_text (cell);
1786 p = strstr (text, dec->str);
1787 if (p) {
1788 p += dec->len;
1790 while (g_ascii_isdigit (*p))
1791 decs++, p++;
1794 *pdecs = MAX (*pdecs, decs);
1796 g_free (text);
1798 return NULL;
1801 static void
1802 inc_dec (WBCGtk *wbcg,
1803 int dir,
1804 GOFormat *(*format_modify_fn) (GOFormat const *format),
1805 char const *descriptor)
1807 WorkbookControl *wbc = GNM_WBC (wbcg);
1808 WorkbookView *wbv = wb_control_view (wbc);
1809 GOFormat const *fmt = gnm_style_get_format (wbv->current_style);
1810 SheetView *sv;
1811 GOFormat *new_fmt;
1812 GnmStyle *style;
1813 GSList *l;
1814 int decs = -2;
1815 GString *new_fmt_str;
1817 if (!go_format_is_general (fmt)) {
1818 modify_format (wbcg, format_modify_fn, descriptor);
1819 return;
1822 sv = wb_view_cur_sheet_view (wbv);
1823 if (!sv)
1824 return;
1826 for (l = sv->selections; l ; l = l->next) {
1827 GnmRange const *r = l->data;
1828 sheet_foreach_cell_in_range (sv_sheet (sv),
1829 CELL_ITER_IGNORE_BLANK |
1830 CELL_ITER_IGNORE_HIDDEN,
1831 r, cb_calc_decs, &decs);
1834 new_fmt_str = g_string_new ("0");
1835 if (decs + dir > 0) {
1836 g_string_append_c (new_fmt_str, '.');
1837 go_string_append_c_n (new_fmt_str, '0', decs + dir);
1839 new_fmt = go_format_new_from_XL (new_fmt_str->str);
1840 g_string_free (new_fmt_str, TRUE);
1842 style = gnm_style_new ();
1843 gnm_style_set_format (style, new_fmt);
1844 cmd_selection_format (wbc, style, NULL, descriptor);
1845 go_format_unref (new_fmt);
1848 static GNM_ACTION_DEF (cb_format_inc_precision)
1849 { inc_dec (wbcg, 1,
1850 &go_format_inc_precision, _("Increase precision")); }
1851 static GNM_ACTION_DEF (cb_format_dec_precision)
1852 { inc_dec (wbcg, -1,
1853 &go_format_dec_precision, _("Decrease precision")); }
1854 static GNM_ACTION_DEF (cb_format_with_thousands)
1855 { modify_format (wbcg, &go_format_toggle_1000sep, _("Toggle thousands separator")); }
1857 static GNM_ACTION_DEF (cb_format_dec_indent) { workbook_cmd_dec_indent (GNM_WBC (wbcg)); }
1858 static GNM_ACTION_DEF (cb_format_inc_indent) { workbook_cmd_inc_indent (GNM_WBC (wbcg)); }
1860 static GNM_ACTION_DEF (cb_copydown)
1862 WorkbookControl *wbc = GNM_WBC (wbcg);
1863 cmd_copyrel (wbc, 0, -1, _("Copy down"));
1866 static GNM_ACTION_DEF (cb_copyright)
1868 WorkbookControl *wbc = GNM_WBC (wbcg);
1869 /* xgettext: copy from the cell to the left into current cell --
1870 this has nothing whatsoever to do with copyright. */
1871 cmd_copyrel (wbc, -1, 0, _("Copy right"));
1874 static GNM_ACTION_DEF (cb_format_cells_auto_fit_height)
1876 WorkbookControl *wbc = GNM_WBC (wbcg);
1877 workbook_cmd_autofit_selection
1878 (wbc, wb_control_cur_sheet (wbc), FALSE);
1881 static GNM_ACTION_DEF (cb_format_cells_auto_fit_width)
1883 WorkbookControl *wbc = GNM_WBC (wbcg);
1884 workbook_cmd_autofit_selection
1885 (wbc, wb_control_cur_sheet (wbc), TRUE);
1888 static GNM_ACTION_DEF (cb_format_column_auto_fit)
1890 WorkbookControl *wbc = GNM_WBC (wbcg);
1891 workbook_cmd_resize_selected_colrow (wbc,
1892 wb_control_cur_sheet (wbc), TRUE, -1);
1894 static GNM_ACTION_DEF (cb_set_column_width)
1896 dialog_col_width (wbcg, FALSE);
1898 static GNM_ACTION_DEF (cb_format_column_std_width)
1900 dialog_col_width (wbcg, TRUE);
1902 static GNM_ACTION_DEF (cb_format_column_hide)
1904 cmd_selection_colrow_hide (GNM_WBC (wbcg), TRUE, FALSE);
1906 static GNM_ACTION_DEF (cb_format_column_unhide)
1908 cmd_selection_colrow_hide (GNM_WBC (wbcg), TRUE, TRUE);
1911 static GNM_ACTION_DEF (cb_format_row_auto_fit)
1913 WorkbookControl *wbc = GNM_WBC (wbcg);
1914 workbook_cmd_resize_selected_colrow (wbc,
1915 wb_control_cur_sheet (wbc), FALSE, -1);
1917 static GNM_ACTION_DEF (cb_set_row_height)
1919 dialog_row_height (wbcg, FALSE);
1921 static GNM_ACTION_DEF (cb_format_row_std_height)
1923 dialog_row_height (wbcg, TRUE);
1925 static GNM_ACTION_DEF (cb_format_row_hide)
1927 cmd_selection_colrow_hide (GNM_WBC (wbcg), FALSE, FALSE);
1929 static GNM_ACTION_DEF (cb_format_row_unhide)
1931 cmd_selection_colrow_hide (GNM_WBC (wbcg), FALSE, TRUE);
1934 static GNM_ACTION_DEF (cb_file_menu)
1936 wbc_gtk_load_templates (wbcg);
1939 static GNM_ACTION_DEF (cb_insert_menu)
1941 GtkAction *action = wbcg_find_action (wbcg, "MenuInsertObject");
1942 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
1943 gtk_action_set_sensitive (action, go_components_get_mime_types () != NULL && scg && scg_sheet (scg)->sheet_type == GNM_SHEET_DATA);
1946 #define TOGGLE_HANDLER(flag,property) \
1947 static GNM_ACTION_DEF (cb_sheet_pref_ ## flag ) \
1949 g_return_if_fail (GNM_IS_WBC_GTK (wbcg)); \
1951 if (!wbcg->updating_ui) { \
1952 Sheet *sheet = wbcg_cur_sheet (wbcg); \
1953 go_object_toggle (sheet, property); \
1954 sheet_update (sheet); \
1958 TOGGLE_HANDLER (display_formulas, "display-formulas")
1959 TOGGLE_HANDLER (hide_zero, "display-zeros")
1960 TOGGLE_HANDLER (hide_grid, "display-grid")
1961 TOGGLE_HANDLER (hide_col_header, "display-column-header")
1962 TOGGLE_HANDLER (hide_row_header, "display-row-header")
1963 TOGGLE_HANDLER (display_outlines, "display-outlines")
1964 TOGGLE_HANDLER (outline_symbols_below, "display-outlines-below")
1965 TOGGLE_HANDLER (outline_symbols_right, "display-outlines-right")
1966 TOGGLE_HANDLER (use_r1c1, "use-r1c1")
1968 /* Actions that are always sensitive */
1969 static GnmActionEntry const permanent_actions[] = {
1970 { .name = "MenuFile",
1971 .label = N_("_File"),
1972 .callback = G_CALLBACK (cb_file_menu)
1974 { .name = "MenuFileNewFromTemplate",
1975 .icon = "document-new",
1976 .label = N_("New From Template")
1978 { .name = "FileNew",
1979 .icon = "document-new",
1980 .label = N_("_New"),
1981 .accelerator = "<control>n",
1982 .tooltip = N_("Create a new workbook"),
1983 .callback = G_CALLBACK (cb_file_new)
1985 { .name = "FileOpen",
1986 .icon = "document-open",
1987 .label = GNM_N_STOCK_OPEN,
1988 .label_context = GNM_STOCK_LABEL_CONTEXT,
1989 .accelerator = "<control>o",
1990 .tooltip = N_("Open a file"),
1991 .callback = G_CALLBACK (cb_file_open)
1993 { .name = "FileSave",
1994 .icon = "document-save",
1995 .label = GNM_N_STOCK_SAVE,
1996 .label_context = GNM_STOCK_LABEL_CONTEXT,
1997 .accelerator = "<control>s",
1998 .tooltip = N_("Save the current workbook"),
1999 .callback = G_CALLBACK (cb_file_save)
2001 { .name = "FileSaveAs",
2002 .icon = "document-save-as",
2003 .label = GNM_N_STOCK_SAVE_AS,
2004 .label_context = GNM_STOCK_LABEL_CONTEXT,
2005 .accelerator = "<control><shift>s",
2006 .tooltip = N_("Save the current workbook with a different name"),
2007 .callback = G_CALLBACK (cb_file_save_as)
2009 { .name = "FileSend",
2010 .icon = "gnumeric-link-email",
2011 .label = N_("Sen_d To..."),
2012 .tooltip = N_("Send the current file via email"),
2013 .callback = G_CALLBACK (cb_file_sendto)
2015 { .name = "FilePageSetup",
2016 .icon = "document-page-setup",
2017 .label = N_("Page Set_up..."),
2018 .tooltip = N_("Setup the page settings for your current printer"),
2019 .callback = G_CALLBACK (cb_file_page_setup)
2021 { .name = "FilePrintPreview",
2022 .icon = "document-print-preview",
2023 .label = N_("Print Pre_view"),
2024 .tooltip = N_("Print preview"),
2025 .callback = G_CALLBACK (cb_file_print_preview)
2027 { .name = "FilePrint",
2028 .icon = "document-print",
2029 .label = N_("Print"),
2030 .accelerator = "<control>p",
2031 .tooltip = N_("Print the current file"),
2032 .callback = G_CALLBACK (cb_file_print)
2034 { .name = "FilePrintArea",
2035 .label = N_("Print Area & Breaks")
2037 { .name = "FileHistoryFull",
2038 .label = N_("Full _History..."),
2039 .tooltip = N_("Access previously used file"),
2040 .callback = G_CALLBACK (cb_file_history_full)
2042 { .name = "FileClose",
2043 .icon = "window-close",
2044 .label = N_("_Close"),
2045 .accelerator = "<control>w",
2046 .tooltip = N_("Close the current file"),
2047 .callback = G_CALLBACK (cb_file_close)
2049 { .name = "FileQuit",
2050 .icon = "application-exit",
2051 .label = N_("_Quit"),
2052 .accelerator = "<control>q",
2053 .tooltip = N_("Quit the application"),
2054 .callback = G_CALLBACK (cb_file_quit)
2056 /* ---------------------------------------- */
2057 { .name = "MenuEdit",
2058 .label = N_("_Edit")
2060 { .name = "MenuEditClear",
2061 .icon = "edit-clear",
2062 .label = N_("C_lear")
2064 { .name = "MenuEditDelete",
2065 .icon = "edit-delete",
2066 .label = N_("_Delete")
2068 { .name = "MenuEditItems",
2069 .label = N_("_Modify")
2071 { .name = "MenuEditSheet",
2072 .label = N_("S_heet")
2074 { .name = "MenuEditSelect",
2075 .label = N_("_Select")
2078 { .name = "EditCopy",
2079 .icon = "edit-copy",
2080 .label = N_("_Copy"),
2081 .accelerator = "<control>c",
2082 .tooltip = N_("Copy the selection"),
2083 .callback = G_CALLBACK (cb_edit_copy)
2086 /* ---------------------------------------- */
2087 { .name = "MenuView",
2088 .label = N_("_View")
2090 { .name = "MenuViewWindows",
2091 .label = N_("_Windows")
2093 { .name = "MenuViewToolbars",
2094 .label = N_("_Toolbars")
2096 /* ---------------------------------------- */
2097 { .name = "MenuInsert",
2098 .label = N_("_Insert"),
2099 .callback = G_CALLBACK (cb_insert_menu)
2101 { .name = "MenuInsertObject",
2102 .label = N_("_Object")
2104 { .name = "MenuInsertSpecial",
2105 .label = N_("S_pecial")
2107 { .name = "MenuInsertFormulaWrap",
2108 .icon = "gnumeric-formulaguru",
2109 .label = N_("Func_tion Wrapper")
2111 { .name = "InsertNames",
2112 .label = N_("_Name..."),
2113 .accelerator = "F3",
2114 .tooltip = N_("Insert a defined name"),
2115 .callback = G_CALLBACK (cb_paste_names)
2117 /* ---------------------------------------- */
2118 { .name = "MenuFormat",
2119 .label = N_("F_ormat")
2121 { .name = "MenuFormatCells",
2122 .label = N_("_Cells")
2124 { .name = "MenuFormatText",
2125 .label = N_("_Text")
2127 { .name = "MenuFormatTextUnderline",
2128 .label = N_("_Underline")
2130 { .name = "MenuFormatColumn",
2131 .label = N_("C_olumn")
2133 { .name = "MenuFormatRow",
2134 .label = N_("_Row")
2136 { .name = "MenuFormatSheet",
2137 .label = N_("_Sheet")
2139 /* ---------------------------------------- */
2140 { .name = "MenuTools",
2141 .label = N_("_Tools")
2143 { .name = "MenuToolsScenarios",
2144 .label = N_("Sce_narios")
2146 /* ---------------------------------------- */
2147 { .name = "MenuStatistics",
2148 .label = N_("_Statistics")
2150 { .name = "MenuStatisticsDescriptive",
2151 .label = N_("_Descriptive Statistics")
2153 { .name = "MenuToolFrequencies",
2154 .label = N_("Fre_quency Tables")
2156 { .name = "MenuStatisticsTimeSeries",
2157 .label = N_("De_pendent Observations")
2159 { .name = "MenuToolForecast",
2160 .label = N_("F_orecast")
2162 { .name = "MenuStatisticsOneSample",
2163 .label = N_("_One Sample Tests")
2165 { .name = "MenuToolOneMedian",
2166 .label = N_("Claims About a Me_dian")
2168 { .name = "MenuStatisticsTwoSamples",
2169 .label = N_("_Two Sample Tests")
2171 { .name = "MenuToolTwoMedians",
2172 .label = N_("Claims About Two Me_dians")
2174 { .name = "MenuToolTTest",
2175 .label = N_("Claims About Two _Means")
2177 { .name = "MenuStatisticsMultipleSamples",
2178 .label = N_("_Multiple Sample Tests")
2180 { .name = "MenuANOVA",
2181 .label = N_("_ANOVA")
2183 { .name = "MenuContingencyTests",
2184 .label = N_("Contin_gency Table")
2186 /* ---------------------------------------- */
2187 { .name = "MenuData",
2188 .label = N_("_Data")
2190 { .name = "MenuFilter",
2191 .label = N_("_Filter")
2193 { .name = "MenuEditFill",
2194 .label = N_("F_ill")
2196 { .name = "MenuRandomGenerator",
2197 .label = N_("_Random Generators")
2199 { .name = "MenuOutline",
2200 .label = N_("_Group and Outline")
2202 { .name = "MenuExternalData",
2203 .label = N_("Import _Data")
2205 { .name = "MenuExportData",
2206 .label = N_("E_xport Data")
2208 { .name = "MenuSlicer",
2209 .label = N_("Data S_licer")
2211 /* ---------------------------------------- */
2212 { .name = "MenuHelp",
2213 .label = N_("_Help")
2216 { .name = "HelpDocs",
2217 .icon = "help-browser",
2218 .label = N_("_Contents"),
2219 .accelerator = "F1",
2220 .tooltip = N_("Open a viewer for Gnumeric's documentation"),
2221 .callback = G_CALLBACK (cb_help_docs)
2223 { .name = "HelpFunctions",
2224 .icon = "gnumeric-formulaguru",
2225 .label = N_("_Functions"),
2226 .tooltip = N_("Functions help"),
2227 .callback = G_CALLBACK (cb_help_function)
2229 { .name = "HelpWeb",
2230 .label = N_("Gnumeric on the _Web"),
2231 .tooltip = N_("Browse to Gnumeric's website"),
2232 .callback = G_CALLBACK (cb_help_web)
2234 { .name = "HelpIRC",
2235 .label = N_("_Live Assistance"),
2236 .tooltip = N_("See if anyone is available to answer questions"),
2237 .callback = G_CALLBACK (cb_help_irc)
2239 { .name = "HelpBug",
2240 .label = N_("Report a _Problem"),
2241 .tooltip = N_("Report problem"),
2242 .callback = G_CALLBACK (cb_help_bug)
2244 { .name = "HelpAbout",
2245 .icon = "help-about",
2246 .label = N_("_About"),
2247 .tooltip = N_("About this application"),
2248 .callback = G_CALLBACK (cb_help_about)
2252 /* actions that are sensitive only in data sheets */
2253 static GnmActionEntry const data_only_actions[] = {
2254 { .name = "EditCut",
2255 .icon = "edit-cut",
2256 .label = N_("Cu_t"),
2257 .accelerator = "<control>x",
2258 .tooltip = N_("Cut the selection"),
2259 .callback = G_CALLBACK (cb_edit_cut)
2261 { .name = "EditPaste",
2262 .icon = "edit-paste",
2263 .label = N_("_Paste"),
2264 .accelerator = "<control>v",
2265 .tooltip = N_("Paste the clipboard"),
2266 .callback = G_CALLBACK (cb_edit_paste)
2270 #define FULLSCREEN_ACCEL "F11"
2272 static GnmActionEntry const semi_permanent_actions[] = {
2273 /* Edit -> Sheet */
2274 { .name = "SheetReorder",
2275 .label = N_("_Manage Sheets..."),
2276 .tooltip = N_("Manage the sheets in this workbook"),
2277 .callback = G_CALLBACK (cb_sheet_order)
2279 { .name = "InsertSheet",
2280 .label = N_("_Insert"),
2281 .tooltip = N_("Insert a new sheet"),
2282 .callback = G_CALLBACK (wbcg_insert_sheet)
2284 /* ICK A DUPLICATE : we have no way to override a label on one proxy */
2285 { .name = "SheetInsert",
2286 .label = N_("_Sheet"),
2287 .tooltip = N_("Insert a new sheet"),
2288 .callback = G_CALLBACK (wbcg_insert_sheet)
2290 { .name = "InsertSheetAtEnd",
2291 .label = N_("_Append"),
2292 .tooltip = N_("Append a new sheet"),
2293 .callback = G_CALLBACK (wbcg_append_sheet)
2295 { .name = "EditDuplicateSheet",
2296 .label = N_("_Duplicate"),
2297 .tooltip = N_("Make a copy of the current sheet"),
2298 .callback = G_CALLBACK (wbcg_clone_sheet)
2300 { .name = "SheetRemove",
2301 .label = N_("_Remove"),
2302 .tooltip = N_("Irrevocably remove an entire sheet"),
2303 .callback = G_CALLBACK (cb_sheet_remove)
2305 { .name = "SheetChangeName",
2306 .label = N_("Re_name..."),
2307 .tooltip = N_("Rename the current sheet"),
2308 .callback = G_CALLBACK (cb_sheet_name)
2310 { .name = "SheetResize",
2311 .label = N_("Resize..."),
2312 .tooltip = N_("Change the size of the current sheet"),
2313 .callback = G_CALLBACK (cb_sheet_resize)
2316 /* View */
2317 { .name = "ViewNew",
2318 .icon = "document-new",
2319 .label = N_("_New View..."),
2320 .tooltip = N_("Create a new view of the workbook"),
2321 .callback = G_CALLBACK (cb_view_new)
2324 /* Format */
2325 { .name = "FormatWorkbook",
2326 .icon = "document-properties",
2327 .label = N_("View _Properties..."),
2328 .tooltip = N_("Modify the view properties"),
2329 .callback = G_CALLBACK (cb_workbook_attr)
2332 { .name = "ViewStatusbar",
2333 .toggle = TRUE,
2334 .label = N_("View _Statusbar"),
2335 .tooltip = N_("Toggle visibility of statusbar"),
2336 .callback = G_CALLBACK (cb_view_statusbar),
2337 .is_active = TRUE
2340 { .name = "ViewFullScreen",
2341 .toggle = TRUE,
2342 .icon = "view-fullscreen",
2343 .label = N_("F_ull Screen"),
2344 .accelerator = FULLSCREEN_ACCEL,
2345 .tooltip = N_("Switch to or from full screen mode"),
2346 .callback = G_CALLBACK (cb_view_fullscreen)
2350 #define ZOOM_IN_ACCEL NULL
2351 #define ZOOM_OUT_ACCEL NULL
2353 static GnmActionEntry const actions[] = {
2354 /* File */
2355 { .name = "FileMetaData",
2356 .icon = "document-properties",
2357 .label = N_("Document Proper_ties..."),
2358 .tooltip = N_("Edit document properties"),
2359 .callback = G_CALLBACK (cb_doc_meta_data)
2362 /* File->PrintArea */
2363 { .name = "FilePrintAreaSet",
2364 .label = N_("Set Print Area"),
2365 .tooltip = N_("Use the current selection as print area"),
2366 .callback = G_CALLBACK (cb_file_print_area_set)
2368 { .name = "FilePrintAreaClear",
2369 .label = N_("Clear Print Area"),
2370 .tooltip = N_("Undefine the print area"),
2371 .callback = G_CALLBACK (cb_file_print_area_clear)
2373 { .name = "FilePrintAreaShow",
2374 .label = N_("Show Print Area"),
2375 .tooltip = N_("Select the print area"),
2376 .callback = G_CALLBACK (cb_file_print_area_show)
2378 { .name = "FilePrintAreaToggleColPageBreak",
2379 .label = N_("Set Column Page Break"),
2380 .tooltip = N_("Split the page to the left of this column"),
2381 .callback = G_CALLBACK (cb_file_print_area_toggle_col)
2383 { .name = "FilePrintAreaToggleRowPageBreak",
2384 .label = N_("Set Row Page Break"),
2385 .tooltip = N_("Split the page above this row"),
2386 .callback = G_CALLBACK (cb_file_print_area_toggle_row)
2388 { .name = "FilePrintAreaClearAllPageBreak",
2389 .label = N_("Clear All Page Breaks"),
2390 .tooltip = N_("Remove all manual pagebreaks from this sheet"),
2391 .callback = G_CALLBACK (cb_file_print_area_clear_pagebreaks)
2394 /* Edit -> Clear */
2395 { .name = "EditClearAll",
2396 .icon = "edit-clear",
2397 .label = N_("_All"),
2398 .tooltip = N_("Clear the selected cells' formats, comments, and contents"),
2399 .callback = G_CALLBACK (cb_edit_clear_all)
2401 { .name = "EditClearFormats",
2402 .label = N_("_Formats & Hyperlinks"),
2403 .tooltip = N_("Clear the selected cells' formats and hyperlinks"),
2404 .callback = G_CALLBACK (cb_edit_clear_formats)
2406 { .name = "EditClearComments",
2407 .icon = "gnumeric-comment-delete",
2408 .label = N_("Co_mments"),
2409 .tooltip = N_("Delete the selected cells' comments"),
2410 .callback = G_CALLBACK (cb_edit_clear_comments)
2412 { .name = "EditClearContent",
2413 .icon = "edit-clear",
2414 .label = N_("_Contents"),
2415 .tooltip = N_("Clear the selected cells' contents"),
2416 .callback = G_CALLBACK (cb_edit_clear_content)
2418 { .name = "EditClearAllFiltered",
2419 .icon = "edit-clear",
2420 .label = N_("A_ll Filtered Rows"),
2421 .tooltip = N_("Clear the selected cells' formats, comments, and contents in the filtered rows"),
2422 .callback = G_CALLBACK (cb_edit_clear_all_filtered)
2424 { .name = "EditClearFormatsFiltered",
2425 .label = N_("F_ormats & Hyperlinks in Filtered Rows"),
2426 .tooltip = N_("Clear the selected cells' formats and hyperlinks in the filtered rows"),
2427 .callback = G_CALLBACK (cb_edit_clear_formats_filtered)
2429 { .name = "EditClearCommentsFiltered",
2430 .icon = "gnumeric-comment-delete",
2431 .label = N_("Comme_nts in Filtered Rows"),
2432 .tooltip = N_("Delete the selected cells' comments in the filtered rows"),
2433 .callback = G_CALLBACK (cb_edit_clear_comments_filtered)
2435 { .name = "EditClearContentFiltered",
2436 .icon = "edit-clear",
2437 .label = N_("Content_s of Filtered Rows"),
2438 .tooltip = N_("Clear the selected cells' contents in the filtered rows"),
2439 .callback = G_CALLBACK (cb_edit_clear_content_filtered)
2442 /* Edit -> Delete */
2443 /*Translators: Delete "Rows"*/
2444 { .name = "EditDeleteRows",
2445 .icon = "gnumeric-row-delete",
2446 .label = N_("_Rows"),
2447 .tooltip = N_("Delete the row(s) containing the selected cells"),
2448 .callback = G_CALLBACK (cb_edit_delete_rows)
2450 /*Translators: Delete "Columns"*/
2451 { .name = "EditDeleteColumns",
2452 .icon = "gnumeric-column-delete",
2453 .label = N_("_Columns"),
2454 .tooltip = N_("Delete the column(s) containing the selected cells"),
2455 .callback = G_CALLBACK (cb_edit_delete_columns)
2457 { .name = "EditDeleteCells",
2458 .label = N_("C_ells..."),
2459 .accelerator = "<control>minus",
2460 .tooltip = N_("Delete the selected cells, shifting others into their place"),
2461 .callback = G_CALLBACK (cb_edit_delete_cells)
2463 { .name = "EditClearHyperlinks",
2464 .icon = "gnumeric-link-delete",
2465 .label = N_("_Hyperlinks"),
2466 .tooltip = N_("Delete the selected cells' hyperlinks"),
2467 .callback = G_CALLBACK (cb_edit_delete_links)
2469 /* A duplicate that should not go into the menus, used only for the accelerator */
2470 { .name = "EditDeleteCellsXL",
2471 .label = N_("C_ells..."),
2472 .accelerator = "<control>KP_Subtract",
2473 .tooltip = N_("Delete the selected cells, shifting others into their place"),
2474 .callback = G_CALLBACK (cb_edit_delete_cells)
2477 /* Edit -> Select */
2479 /* Note : The accelerators involving space are just for display
2480 * purposes. We actually handle this in
2481 * gnm-pane.c:gnm_pane_key_mode_sheet
2482 * with the rest of the key movement and rangeselection.
2483 * Otherwise input methods would steal them */
2484 { .name = "EditSelectAll",
2485 .label = N_("_All"),
2486 .accelerator = "<control><shift>space",
2487 .tooltip = N_("Select all cells in the spreadsheet"),
2488 .callback = G_CALLBACK (cb_edit_select_all)
2490 { .name = "EditSelectColumn",
2491 .label = N_("_Column"),
2492 .accelerator = "<control>space",
2493 .tooltip = N_("Select an entire column"),
2494 .callback = G_CALLBACK (cb_edit_select_col)
2496 { .name = "EditSelectRow",
2497 .label = N_("_Row"),
2498 .accelerator = "<shift>space",
2499 .tooltip = N_("Select an entire row"),
2500 .callback = G_CALLBACK (cb_edit_select_row)
2503 { .name = "EditSelectArray",
2504 .label = N_("Arra_y"),
2505 .accelerator = "<control>slash",
2506 .tooltip = N_("Select an array of cells"),
2507 .callback = G_CALLBACK (cb_edit_select_array)
2509 { .name = "EditSelectDepends",
2510 .label = N_("_Depends"),
2511 .accelerator = "<control>bracketright",
2512 .tooltip = N_("Select all the cells that depend on the current edit cell"),
2513 .callback = G_CALLBACK (cb_edit_select_depends)
2515 { .name = "EditSelectInputs",
2516 .label = N_("_Inputs"),
2517 .accelerator = "<control>bracketleft",
2518 .tooltip = N_("Select all the cells are used by the current edit cell"),
2519 .callback = G_CALLBACK (cb_edit_select_inputs)
2522 { .name = "EditSelectObject",
2523 .label = N_("Next _Object"),
2524 .accelerator = "<control>Tab",
2525 .tooltip = N_("Select the next sheet object"),
2526 .callback = G_CALLBACK (cb_edit_select_object)
2529 { .name = "EditGotoTop",
2530 .icon = "go-top",
2531 .label = N_("Go to Top"),
2532 .tooltip = N_("Go to the top of the data"),
2533 .callback = G_CALLBACK (cb_edit_goto_top)
2535 { .name = "EditGotoBottom",
2536 .icon = "go-bottom",
2537 .label = N_("Go to Bottom"),
2538 .tooltip = N_("Go to the bottom of the data"),
2539 .callback = G_CALLBACK (cb_edit_goto_bottom)
2541 { .name = "EditGotoFirst",
2542 .icon = "go-first",
2543 .label = N_("Go to First"),
2544 .tooltip = N_("Go to the first data cell"),
2545 .callback = G_CALLBACK (cb_edit_goto_first)
2547 { .name = "EditGotoLast",
2548 .icon = "go-last",
2549 .label = N_("Go to Last"),
2550 .tooltip = N_("Go to the last data cell"),
2551 .callback = G_CALLBACK (cb_edit_goto_last)
2553 { .name = "EditGoto",
2554 .icon = "go-jump",
2555 .label = N_("_Go to Cell..."),
2556 .accelerator = "<control>g",
2557 .tooltip = N_("Jump to a specified cell"),
2558 .callback = G_CALLBACK (cb_edit_goto)
2560 /* This is a navigational aid that is not supposed to appear */
2561 /* in the menu */
2562 { .name = "EditGotoCellIndicator",
2563 .label = N_("Go to Current Cell Indicator"),
2564 .accelerator = "<shift><control>g",
2565 .tooltip = N_("Go to Current Cell Indicator"),
2566 .callback = G_CALLBACK (cb_edit_goto_cell_indicator)
2569 /* Edit */
2570 { .name = "Repeat",
2571 .label = N_("Repeat"),
2572 .accelerator = "F4",
2573 .tooltip = N_("Repeat the previous action"),
2574 .callback = G_CALLBACK (cb_repeat)
2576 { .name = "EditPasteSpecial",
2577 .icon = "edit-paste",
2578 .label = N_("P_aste Special..."),
2579 .accelerator = "<shift><control>v",
2580 .tooltip = N_("Paste with optional filters and transformations"),
2581 .callback = G_CALLBACK (cb_edit_paste_special)
2584 { .name = "EditComment",
2585 .icon = "gnumeric-comment-edit",
2586 .label = N_("Co_mment..."),
2587 .tooltip = N_("Edit the selected cell's comment"),
2588 .callback = G_CALLBACK (cb_insert_comment)
2590 { .name = "EditHyperlink",
2591 .icon = "gnumeric-link-edit",
2592 .label = N_("Hyper_link..."),
2593 .accelerator = "<control>K",
2594 .tooltip = N_("Edit the selected cell's hyperlink"),
2595 .callback = G_CALLBACK (cb_insert_hyperlink)
2597 #if 0
2598 { .name = "EditGenerateName",
2599 .label = N_("_Auto generate names..."),
2600 .tooltip = N_("Use the current selection to create names"),
2601 .callback = G_CALLBACK (cb_auto_generate__named_expr)
2603 #endif
2605 { .name = "EditFind",
2606 .icon = "edit-find",
2607 .label = N_("S_earch..."),
2608 .accelerator = "<control>f",
2609 .tooltip = N_("Search for something"),
2610 .callback = G_CALLBACK (cb_edit_search)
2612 { .name = "EditReplace",
2613 .icon = "edit-find-replace",
2614 .label = N_("Search _& Replace..."),
2615 .accelerator = "<control>h",
2616 .tooltip = N_("Search for something and replace it with something else"),
2617 .callback = G_CALLBACK (cb_edit_search_replace)
2620 { .name = "EditRecalc",
2621 .label = N_("Recalculate"),
2622 .accelerator = "F9",
2623 .tooltip = N_("Recalculate the spreadsheet"),
2624 .callback = G_CALLBACK (cb_edit_recalc)
2627 { .name = "EditPreferences",
2628 .icon = "preferences-system",
2629 .label = N_("Preferences..."),
2630 .tooltip = N_("Change Gnumeric Preferences"),
2631 .callback = G_CALLBACK (cb_file_preferences)
2634 /* View */
2635 { .name = "ViewFreezeThawPanes",
2636 .label = N_("_Freeze Panes"),
2637 .tooltip = N_("Freeze the top left of the sheet"),
2638 .callback = G_CALLBACK (cb_view_freeze_panes)
2640 { .name = "ViewZoom",
2641 .icon = "zoom-fit-best", /* dubious */
2642 .label = N_("_Zoom..."),
2643 .tooltip = N_("Zoom the spreadsheet in or out"),
2644 .callback = G_CALLBACK (cb_view_zoom)
2646 { .name = "ViewZoomIn",
2647 .icon = "zoom-in",
2648 .label = N_("Zoom _In"),
2649 .accelerator = ZOOM_IN_ACCEL,
2650 .tooltip = N_("Increase the zoom to make things larger"),
2651 .callback = G_CALLBACK (cb_view_zoom_in)
2653 { .name = "ViewZoomOut",
2654 .icon = "zoom-out",
2655 .label = N_("Zoom _Out"),
2656 .accelerator = ZOOM_OUT_ACCEL,
2657 .tooltip = N_("Decrease the zoom to make things smaller"),
2658 .callback = G_CALLBACK (cb_view_zoom_out)
2661 /* Insert */
2662 { .name = "InsertCells",
2663 .label = N_("C_ells..."),
2664 .accelerator = "<control>plus",
2665 .tooltip = N_("Insert new cells"),
2666 .callback = G_CALLBACK (cb_insert_cells)
2668 /* A duplicate that should not go into the menus, used only for the accelerator */
2669 { .name = "InsertCellsXL",
2670 .label = N_("C_ells..."),
2671 .accelerator = "<control>KP_Add",
2672 .tooltip = N_("Insert new cells"),
2673 .callback = G_CALLBACK (cb_insert_cells)
2675 /*Translators: Insert "Columns"*/
2676 { .name = "InsertColumns",
2677 .icon = "gnumeric-column-add",
2678 .label = N_("_Columns"),
2679 .tooltip = N_("Insert new columns"),
2680 .callback = G_CALLBACK (cb_insert_cols)
2682 /*Translators: Insert "Rows"*/
2683 { .name = "InsertRows",
2684 .icon = "gnumeric-row-add",
2685 .label = N_("_Rows"),
2686 .tooltip = N_("Insert new rows"),
2687 .callback = G_CALLBACK (cb_insert_rows)
2690 { .name = "ChartGuru",
2691 .icon = "gnumeric-graphguru",
2692 .label = N_("C_hart..."),
2693 .tooltip = N_("Insert a Chart"),
2694 .callback = G_CALLBACK (cb_launch_chart_guru)
2696 { .name = "NewGOComponent",
2697 .icon = "New Goffice_Component",
2698 .label = N_("_New..."),
2699 .tooltip = N_("Insert a new Goffice component object"),
2700 .callback = G_CALLBACK (cb_launch_go_component_new)
2702 { .name = "GOComponentFromFile",
2703 .icon = "New Goffice_Component from a file",
2704 .label = N_("_From File..."),
2705 .tooltip = N_("Insert a new Goffice component object from a file"),
2706 .callback = G_CALLBACK (cb_launch_go_component_from_file)
2708 { .name = "InsertImage",
2709 .icon = "insert-image",
2710 .label = N_("_Image..."),
2711 .tooltip = N_("Insert an image"),
2712 .callback = G_CALLBACK (cb_insert_image)
2715 { .name = "InsertComment",
2716 .icon = "gnumeric-comment-add",
2717 .label = N_("Co_mment..."),
2718 .tooltip = N_("Insert a comment"),
2719 .callback = G_CALLBACK (cb_insert_comment)
2721 { .name = "InsertHyperlink",
2722 .icon = "gnumeric-link-add",
2723 .label = N_("Hyper_link..."),
2724 .accelerator = "<control>K",
2725 .tooltip = N_("Insert a Hyperlink"),
2726 .callback = G_CALLBACK (cb_insert_hyperlink)
2728 { .name = "InsertSortDecreasing",
2729 .icon = "view-sort-descending",
2730 .label = N_("Sort (_Descending)"),
2731 .tooltip = N_("Wrap with SORT (descending)"),
2732 .callback = G_CALLBACK (cb_insert_sort_descending)
2734 { .name = "InsertSortIncreasing",
2735 .icon = "view-sort-ascending",
2736 .label = N_("Sort (_Ascending)"),
2737 .tooltip = N_("Wrap with SORT (ascending)"),
2738 .callback = G_CALLBACK (cb_insert_sort_ascending)
2741 /* Insert -> Special */
2742 { .name = "InsertCurrentDate",
2743 .label = N_("Current _Date"),
2744 .accelerator = "<control>semicolon",
2745 .tooltip = N_("Insert the current date into the selected cell(s)"),
2746 .callback = G_CALLBACK (cb_insert_current_date)
2749 { .name = "InsertCurrentTime",
2750 .label = N_("Current _Time"),
2751 .accelerator = "<control>colon",
2752 .tooltip = N_("Insert the current time into the selected cell(s)"),
2753 .callback = G_CALLBACK (cb_insert_current_time)
2756 { .name = "InsertCurrentDateTime",
2757 .label = N_("Current D_ate and Time"),
2758 .accelerator = "<control>period",
2759 .tooltip = N_("Insert the current date and time into the selected cell(s)"),
2760 .callback = G_CALLBACK (cb_insert_current_date_time)
2763 /* Insert -> Name */
2764 { .name = "EditNames",
2765 .label = N_("_Names..."),
2766 .accelerator = "<control>F3",
2767 .tooltip = N_("Edit defined names for expressions"),
2768 .callback = G_CALLBACK (cb_define_name)
2771 /* Format */
2772 { .name = "FormatAuto",
2773 .label = N_("_Autoformat..."),
2774 .tooltip = N_("Format a region of cells according to a pre-defined template"),
2775 .callback = G_CALLBACK (cb_autoformat)
2777 { .name = "SheetDirection",
2778 .icon = "format-text-direction-ltr",
2779 .label = N_("Direction"),
2780 .tooltip = N_("Toggle sheet direction, left-to-right vs right-to-left"),
2781 .callback = G_CALLBACK (cb_direction)
2784 /* Format -> Cells */
2785 { .name = "FormatCells",
2786 .label = N_("_Format..."),
2787 .accelerator = "<control>1",
2788 .tooltip = N_("Modify the formatting of the selected cells"),
2789 .callback = G_CALLBACK (cb_format_cells)
2791 { .name = "FormatCellsCond",
2792 .label = N_("_Conditional Formatting..."),
2793 .tooltip = N_("Modify the conditional formatting of the selected cells"),
2794 .callback = G_CALLBACK (cb_format_cells_cond)
2796 { .name = "FormatCellsFitHeight",
2797 .icon = "gnumeric-row-size",
2798 .label = N_("Auto Fit _Height"),
2799 .tooltip = N_("Ensure rows are just tall enough to display content of selection"),
2800 .callback = G_CALLBACK (cb_format_cells_auto_fit_height)
2802 { .name = "FormatCellsFitWidth",
2803 .icon = "gnumeric-column-size",
2804 .label = N_("Auto Fit _Width"),
2805 .tooltip = N_("Ensure columns are just wide enough to display content of selection"),
2806 .callback = G_CALLBACK (cb_format_cells_auto_fit_width)
2810 /* Format -> Col */
2811 { .name = "ColumnSize",
2812 .icon = "gnumeric-column-size",
2813 .label = N_("_Width..."),
2814 .tooltip = N_("Change width of the selected columns"),
2815 .callback = G_CALLBACK (cb_set_column_width)
2817 { .name = "ColumnAutoSize",
2818 .icon = "gnumeric-column-size",
2819 .label = N_("_Auto Fit Width"),
2820 .tooltip = N_("Ensure columns are just wide enough to display their content"),
2821 .callback = G_CALLBACK (cb_format_column_auto_fit)
2823 { .name = "ColumnHide",
2824 .icon = "gnumeric-column-hide",
2825 .label = N_("_Hide"),
2826 .accelerator = "<control>0",
2827 .tooltip = N_("Hide the selected columns"),
2828 .callback = G_CALLBACK (cb_format_column_hide)
2830 { .name = "ColumnUnhide",
2831 .icon = "gnumeric-column-unhide",
2832 .label = N_("_Unhide"),
2833 .accelerator = "<control>parenright",
2834 .tooltip = N_("Make any hidden columns in the selection visible"),
2835 .callback = G_CALLBACK (cb_format_column_unhide)
2837 { .name = "ColumnDefaultSize",
2838 .icon = "gnumeric-column-size",
2839 .label = N_("_Standard Width"),
2840 .tooltip = N_("Change the default column width"),
2841 .callback = G_CALLBACK (cb_format_column_std_width)
2844 /* Format -> Row */
2845 { .name = "RowSize",
2846 .icon = "gnumeric-row-size",
2847 .label = N_("H_eight..."),
2848 .tooltip = N_("Change height of the selected rows"),
2849 .callback = G_CALLBACK (cb_set_row_height)
2851 { .name = "RowAutoSize",
2852 .icon = "gnumeric-row-size",
2853 .label = N_("_Auto Fit Height"),
2854 .tooltip = N_("Ensure rows are just tall enough to display their content"),
2855 .callback = G_CALLBACK (cb_format_row_auto_fit)
2857 { .name = "RowHide",
2858 .icon = "gnumeric-row-hide",
2859 .label = N_("_Hide"),
2860 .accelerator = "<control>9",
2861 .tooltip = N_("Hide the selected rows"),
2862 .callback = G_CALLBACK (cb_format_row_hide)
2864 { .name = "RowUnhide",
2865 .icon = "gnumeric-row-unhide",
2866 .label = N_("_Unhide"),
2867 .accelerator = "<control>parenleft",
2868 .tooltip = N_("Make any hidden rows in the selection visible"),
2869 .callback = G_CALLBACK (cb_format_row_unhide)
2871 { .name = "RowDefaultSize",
2872 .icon = "gnumeric-row-size",
2873 .label = N_("_Standard Height"),
2874 .tooltip = N_("Change the default row height"),
2875 .callback = G_CALLBACK (cb_format_row_std_height)
2878 /* Tools */
2879 { .name = "ToolsPlugins",
2880 .label = N_("_Plug-ins..."),
2881 .tooltip = N_("Manage available plugin modules"),
2882 .callback = G_CALLBACK (cb_tools_plugins)
2884 { .name = "ToolsAutoCorrect",
2885 .label = N_("Auto _Correct..."),
2886 .tooltip = N_("Automatically perform simple spell checking"),
2887 .callback = G_CALLBACK (cb_tools_autocorrect)
2889 { .name = "ToolsAutoSave",
2890 .label = N_("_Auto Save..."),
2891 .tooltip = N_("Automatically save the current document at regular intervals"),
2892 .callback = G_CALLBACK (cb_tools_auto_save)
2894 { .name = "ToolsGoalSeek",
2895 .label = N_("_Goal Seek..."),
2896 .tooltip = N_("Iteratively recalculate to find a target value"),
2897 .callback = G_CALLBACK (cb_tools_goal_seek)
2899 { .name = "ToolsSolver",
2900 .label = N_("_Solver..."),
2901 .tooltip = N_("Iteratively recalculate with constraints to approach a target value"),
2902 .callback = G_CALLBACK (cb_tools_solver)
2904 { .name = "ToolsSimulation",
2905 .label = N_("Si_mulation..."),
2906 .tooltip = N_("Test decision alternatives by using Monte Carlo "
2907 "simulation to find out probable outputs and risks related to them"),
2908 .callback = G_CALLBACK (cb_tools_simulation)
2910 { .name = "ToolsCompare",
2911 .label = N_("Compare Sheets..."),
2912 .tooltip = N_("Find differences between two sheets"),
2913 .callback = G_CALLBACK (cb_tools_compare)
2916 /* Tools -> Scenarios */
2917 { .name = "ToolsScenarios",
2918 .label = N_("_View..."),
2919 .tooltip = N_("View, delete and report different scenarios"),
2920 .callback = G_CALLBACK (cb_tools_scenarios)
2922 { .name = "ToolsScenarioAdd",
2923 .label = N_("_Add..."),
2924 .tooltip = N_("Add a new scenario"),
2925 .callback = G_CALLBACK (cb_tools_scenario_add)
2928 /* Statistics */
2930 { .name = "ToolsSampling",
2931 .label = N_("_Sampling..."),
2932 .tooltip = N_("Periodic and random samples"),
2933 .callback = G_CALLBACK (cb_tools_sampling)
2936 /* Statistics -> Descriptive*/
2938 { .name = "ToolsCorrelation",
2939 .label = N_("_Correlation..."),
2940 .tooltip = N_("Pearson Correlation"),
2941 .callback = G_CALLBACK (cb_tools_correlation)
2943 { .name = "ToolsCovariance",
2944 .label = N_("Co_variance..."),
2945 .tooltip = N_("Covariance"),
2946 .callback = G_CALLBACK (cb_tools_covariance)
2948 { .name = "ToolsDescStatistics",
2949 .label = N_("_Descriptive Statistics..."),
2950 .tooltip = N_("Various summary statistics"),
2951 .callback = G_CALLBACK (cb_tools_desc_statistics)
2954 /* Statistics -> Descriptive -> Frequencies */
2956 { .name = "ToolsFrequency",
2957 .label = N_("Fre_quency Tables..."),
2958 .tooltip = N_("Frequency tables for non-numeric data"),
2959 .callback = G_CALLBACK (cb_tools_frequency)
2961 { .name = "ToolsHistogram",
2962 .label = N_("_Histogram..."),
2963 .tooltip = N_("Various frequency tables for numeric data"),
2964 .callback = G_CALLBACK (cb_tools_histogram)
2966 { .name = "ToolsRanking",
2967 .label = N_("Ranks And _Percentiles..."),
2968 .tooltip = N_("Ranks, placements and percentiles"),
2969 .callback = G_CALLBACK (cb_tools_ranking)
2972 /* Statistics -> DependentObservations */
2974 { .name = "ToolsFourier",
2975 .label = N_("_Fourier Analysis..."),
2976 .tooltip = N_("Fourier Analysis"),
2977 .callback = G_CALLBACK (cb_tools_fourier)
2979 { .name = "ToolsPrincipalComponents",
2980 .label =
2981 N_("Principal Components Analysis..."),
2982 .tooltip = N_("Principal Components Analysis"),
2983 .callback = G_CALLBACK (cb_tools_principal_components)
2985 /* Statistics -> DependentObservations -> Forecast*/
2987 { .name = "ToolsExpSmoothing",
2988 .label = N_("_Exponential Smoothing..."),
2989 .tooltip = N_("Exponential smoothing..."),
2990 .callback = G_CALLBACK (cb_tools_exp_smoothing)
2992 { .name = "ToolsAverage",
2993 .label = N_("_Moving Average..."),
2994 .tooltip = N_("Moving average..."),
2995 .callback = G_CALLBACK (cb_tools_average)
2997 { .name = "ToolsRegression",
2998 .label = N_("_Regression..."),
2999 .tooltip = N_("Regression Analysis"),
3000 .callback = G_CALLBACK (cb_tools_regression)
3002 { .name = "ToolsKaplanMeier",
3003 .label = N_("_Kaplan-Meier Estimates..."),
3004 .tooltip = N_("Creation of Kaplan-Meier Survival Curves"),
3005 .callback = G_CALLBACK (cb_tools_kaplan_meier)
3008 /* Statistics -> OneSample */
3010 { .name = "ToolsNormalityTests",
3011 .label = N_("_Normality Tests..."),
3012 .tooltip = N_("Testing a sample for normality"),
3013 .callback = G_CALLBACK (cb_tools_normality_tests)
3015 { .name = "ToolsOneMeanTest",
3016 .label = N_("Claims About a _Mean..."),
3017 .tooltip = N_("Testing the value of a mean"),
3018 .callback = G_CALLBACK (cb_tools_one_mean_test)
3021 /* Statistics -> OneSample -> OneMedian*/
3023 { .name = "ToolsOneMedianSignTest",
3024 .label = N_("_Sign Test..."),
3025 .tooltip = N_("Testing the value of a median"),
3026 .callback = G_CALLBACK (cb_tools_sign_test_one_median)
3028 { .name = "ToolsOneMedianWilcoxonSignedRank",
3029 .label = N_("_Wilcoxon Signed Rank Test..."),
3030 .tooltip = N_("Testing the value of a median"),
3031 .callback = G_CALLBACK (cb_tools_wilcoxon_signed_rank_one_median)
3034 /* Statistics -> TwoSamples */
3036 { .name = "ToolsFTest",
3037 .label = N_("Claims About Two _Variances"),
3038 .tooltip = N_("Comparing two population variances"),
3039 .callback = G_CALLBACK (cb_tools_ftest)
3042 /* Statistics -> TwoSamples -> Two Means*/
3044 { .name = "ToolTTestPaired",
3045 .label = N_("_Paired Samples..."),
3046 .tooltip = N_("Comparing two population means for two paired samples"),
3047 .callback = G_CALLBACK (cb_tools_ttest_paired)
3050 { .name = "ToolTTestEqualVar",
3051 .label = N_("Unpaired Samples, _Equal Variances..."),
3052 .tooltip = N_("Comparing two population means for two unpaired samples from populations with equal variances"),
3053 .callback = G_CALLBACK (cb_tools_ttest_equal_var)
3056 { .name = "ToolTTestUnequalVar",
3057 .label = N_("Unpaired Samples, _Unequal Variances..."),
3058 .tooltip = N_("Comparing two population means for two unpaired samples from populations with unequal variances"),
3059 .callback = G_CALLBACK (cb_tools_ttest_unequal_var)
3062 { .name = "ToolZTest",
3063 .label = N_("Unpaired Samples, _Known Variances..."),
3064 .tooltip = N_("Comparing two population means from populations with known variances"),
3065 .callback = G_CALLBACK (cb_tools_ztest)
3068 /* Statistics -> TwoSamples -> Two Medians*/
3070 { .name = "ToolsTwoMedianSignTest",
3071 .label = N_("_Sign Test..."),
3072 .tooltip = N_("Comparing the values of two medians of paired observations"),
3073 .callback = G_CALLBACK (cb_tools_sign_test_two_medians)
3075 { .name = "ToolsTwoMedianWilcoxonSignedRank",
3076 .label = N_("_Wilcoxon Signed Rank Test..."),
3077 .tooltip = N_("Comparing the values of two medians of paired observations"),
3078 .callback = G_CALLBACK (cb_tools_wilcoxon_signed_rank_two_medians)
3080 { .name = "ToolsTwoMedianWilcoxonMannWhitney",
3081 .label = N_("Wilcoxon-_Mann-Whitney Test..."),
3082 .tooltip = N_("Comparing the values of two medians of unpaired observations"),
3083 .callback = G_CALLBACK (cb_tools_wilcoxon_mann_whitney)
3086 /* Statistics -> MultipleSamples */
3088 /* Statistics -> MultipleSamples -> ANOVA*/
3090 { .name = "ToolsANOVAoneFactor",
3091 .label = N_("_One Factor..."),
3092 .tooltip = N_("One Factor Analysis of Variance..."),
3093 .callback = G_CALLBACK (cb_tools_anova_one_factor)
3095 { .name = "ToolsANOVAtwoFactor",
3096 .label = N_("_Two Factor..."),
3097 .tooltip = N_("Two Factor Analysis of Variance..."),
3098 .callback = G_CALLBACK (cb_tools_anova_two_factor)
3101 /* Statistics -> MultipleSamples -> ContingencyTable*/
3103 { .name = "ToolsHomogeneity",
3104 .label = N_("Test of _Homogeneity..."),
3105 .tooltip = N_("Chi Squared Test of Homogeneity..."),
3106 .callback = G_CALLBACK (cb_tools_chi_square_homogeneity)
3108 { .name = "ToolsIndependence",
3109 .label = N_("Test of _Independence..."),
3110 .tooltip = N_("Chi Squared Test of Independence..."),
3111 .callback = G_CALLBACK (cb_tools_chi_square_independence)
3114 /* Data */
3115 { .name = "DataSort",
3116 .icon = "view-sort-ascending",
3117 .label = N_("_Sort..."),
3118 .tooltip = N_("Sort the selected region"),
3119 .callback = G_CALLBACK (cb_data_sort)
3121 { .name = "DataShuffle",
3122 .label = N_("Sh_uffle..."),
3123 .tooltip = N_("Shuffle cells, rows or columns"),
3124 .callback = G_CALLBACK (cb_data_shuffle)
3126 { .name = "DataValidate",
3127 .label = N_("_Validate..."),
3128 .tooltip = N_("Validate input with preset criteria"),
3129 .callback = G_CALLBACK (cb_data_validate)
3131 { .name = "DataTextToColumns",
3132 .label = N_("T_ext to Columns..."),
3133 .tooltip = N_("Parse the text in the selection into data"),
3134 .callback = G_CALLBACK (cb_data_text_to_columns)
3136 { .name = "DataConsolidate",
3137 .label = N_("_Consolidate..."),
3138 .tooltip = N_("Consolidate regions using a function"),
3139 .callback = G_CALLBACK (cb_data_consolidate)
3141 { .name = "DataTable",
3142 .label = N_("_Table..."),
3143 .tooltip = N_("Create a Data Table to evaluate a function with multiple inputs"),
3144 .callback = G_CALLBACK (cb_data_table)
3146 { .name = "DataExport",
3147 .label = N_("E_xport into Other Format..."),
3148 .tooltip = N_("Export the current workbook or sheet"),
3149 .callback = G_CALLBACK (cb_data_export)
3151 { .name = "DataExportText",
3152 .label = N_("Export as _Text File..."),
3153 .tooltip = N_("Export the current sheet as a text file"),
3154 .callback = G_CALLBACK (cb_data_export_text)
3156 { .name = "DataExportCSV",
3157 .label = N_("Export as _CSV File..."),
3158 .tooltip = N_("Export the current sheet as a csv file"),
3159 .callback = G_CALLBACK (cb_data_export_csv)
3161 { .name = "DataExportRepeat",
3162 .label = N_("Repeat Export"),
3163 .accelerator = "<control>E",
3164 .tooltip = N_("Repeat the last data export"),
3165 .callback = G_CALLBACK (cb_data_export_repeat)
3168 /* Data -> Fill */
3169 { .name = "EditFillAutofill",
3170 .label = N_("Auto_fill"),
3171 .tooltip = N_("Automatically fill the current selection"),
3172 .callback = G_CALLBACK (cb_edit_fill_autofill)
3174 { .name = "ToolsMerge",
3175 .label = N_("_Merge..."),
3176 .tooltip = N_("Merges columnar data into a sheet creating duplicate sheets for each row"),
3177 .callback = G_CALLBACK (cb_tools_merge)
3179 { .name = "ToolsTabulate",
3180 .label = N_("_Tabulate Dependency..."),
3181 .tooltip = N_("Make a table of a cell's value as a function of other cells"),
3182 .callback = G_CALLBACK (cb_tools_tabulate)
3184 { .name = "EditFillSeries",
3185 .label = N_("_Series..."),
3186 .tooltip = N_("Fill according to a linear or exponential series"),
3187 .callback = G_CALLBACK (cb_edit_fill_series)
3189 { .name = "RandomGeneratorUncorrelated",
3190 .label = N_("_Uncorrelated..."),
3191 .tooltip = N_("Generate random numbers of a selection of distributions"),
3192 .callback = G_CALLBACK (cb_tools_random_generator_uncorrelated)
3194 { .name = "RandomGeneratorCorrelated",
3195 .label = N_("_Correlated..."),
3196 .tooltip = N_("Generate variates for correlated normal distributed random variables"),
3197 .callback = G_CALLBACK (cb_tools_random_generator_correlated)
3199 { .name = "CopyDown",
3200 .label = N_("Fill Downwards"),
3201 .accelerator = "<control>D",
3202 .tooltip = N_("Copy the content from the top row to the cells below"),
3203 .callback = G_CALLBACK (cb_copydown)
3205 { .name = "CopyRight",
3206 .label = N_("Fill to Right"),
3207 .accelerator = "<control>R",
3208 .tooltip = N_("Copy the content from the left column to the cells on the right"),
3209 .callback = G_CALLBACK (cb_copyright)
3213 /* Data -> Outline */
3214 { .name = "DataOutlineHideDetail",
3215 .icon = "gnumeric-detail-hide",
3216 .label = N_("_Hide Detail"),
3217 .tooltip = N_("Collapse an outline group"),
3218 .callback = G_CALLBACK (cb_data_hide_detail)
3220 { .name = "DataOutlineShowDetail",
3221 .icon = "gnumeric-detail-show",
3222 .label = N_("_Show Detail"),
3223 .tooltip = N_("Uncollapse an outline group"),
3224 .callback = G_CALLBACK (cb_data_show_detail)
3226 { .name = "DataOutlineGroup",
3227 .icon = "gnumeric-group",
3228 .label = N_("_Group..."),
3229 .accelerator = "<shift><alt>Right",
3230 .tooltip = N_("Add an outline group"),
3231 .callback = G_CALLBACK (cb_data_group)
3233 { .name = "DataOutlineUngroup",
3234 .icon = "gnumeric-ungroup",
3235 .label = N_("_Ungroup..."),
3236 .accelerator = "<shift><alt>Left",
3237 .tooltip = N_("Remove an outline group"),
3238 .callback = G_CALLBACK (cb_data_ungroup)
3241 /* Data -> Filter */
3242 { .name = "DataAutoFilter",
3243 .icon = "gnumeric-autofilter",
3244 .label = N_("Add _Auto Filter"),
3245 .tooltip = N_("Add or remove a filter"),
3246 .callback = G_CALLBACK (cb_auto_filter)
3248 { .name = "DataFilterShowAll",
3249 .label = N_("_Clear Advanced Filter"),
3250 .tooltip = N_("Show all rows hidden by an advanced filter"),
3251 .callback = G_CALLBACK (cb_show_all)
3253 { .name = "DataFilterAdvancedfilter",
3254 .label = N_("Advanced _Filter..."),
3255 .tooltip = N_("Filter data with given criteria"),
3256 .callback = G_CALLBACK (cb_data_filter)
3258 /* Data -> External */
3259 { .name = "DataImportText",
3260 .label = N_("Import _Text File..."),
3261 .tooltip = N_("Import data from a text file"),
3262 .callback = G_CALLBACK (cb_data_import_text)
3264 { .name = "DataImportOther",
3265 .label = N_("Import _Other File..."),
3266 .tooltip = N_("Import data from a file"),
3267 .callback = G_CALLBACK (cb_data_import_other)
3270 /* Data -> Data Slicer */
3271 /* label and tip are context dependent, see wbcg_menu_state_update */
3272 { .name = "DataSlicer",
3273 .label = N_("Add _Data Slicer"),
3274 .tooltip = N_("Create a data slicer"),
3275 .callback = G_CALLBACK (cb_data_slicer_create)
3277 { .name = "DataSlicerRefresh",
3278 .label = N_("_Refresh"),
3279 .tooltip = N_("Regenerate a data slicer from the source data"),
3280 .callback = G_CALLBACK (cb_data_slicer_refresh)
3282 { .name = "DataSlicerEdit",
3283 .label = N_("_Edit Data Slicer..."),
3284 .tooltip = N_("Adjust a data slicer"),
3285 .callback = G_CALLBACK (cb_data_slicer_edit)
3288 /* Standard Toolbar */
3289 { .name = "AutoSum",
3290 .icon = "gnumeric-autosum",
3291 .label = N_("Sum"),
3292 .accelerator = "<alt>equal",
3293 .tooltip = N_("Sum into the current cell"),
3294 .callback = G_CALLBACK (cb_autosum)
3296 { .name = "InsertFormula",
3297 .icon = "gnumeric-formulaguru",
3298 .label = N_("_Function..."),
3299 .tooltip = N_("Edit a function in the current cell"),
3300 .callback = G_CALLBACK (cb_formula_guru)
3303 { .name = "SortAscending",
3304 .icon = "view-sort-ascending",
3305 .label = N_("Sort Ascending"),
3306 .tooltip = N_("Sort the selected region in ascending order based on the first column selected"),
3307 .callback = G_CALLBACK (cb_sort_ascending)
3309 { .name = "SortDescending",
3310 .icon = "view-sort-descending",
3311 .label = N_("Sort Descending"),
3312 .tooltip = N_("Sort the selected region in descending order based on the first column selected"),
3313 .callback = G_CALLBACK (cb_sort_descending)
3316 /* Object Toolbar */
3317 { .name = "CreateFrame",
3318 .icon = "gnumeric-object-frame",
3319 .label = N_("Frame"),
3320 .tooltip = N_("Create a frame"),
3321 .callback = G_CALLBACK (cmd_create_frame)
3323 { .name = "CreateCheckbox",
3324 .icon = "gnumeric-object-checkbox",
3325 .label = N_("Checkbox"),
3326 .tooltip = N_("Create a checkbox"),
3327 .callback = G_CALLBACK (cmd_create_checkbox)
3329 { .name = "CreateScrollbar",
3330 .icon = "gnumeric-object-scrollbar",
3331 .label = N_("Scrollbar"),
3332 .tooltip = N_("Create a scrollbar"),
3333 .callback = G_CALLBACK (cmd_create_scrollbar)
3335 { .name = "CreateSlider",
3336 .icon = "gnumeric-object-slider",
3337 .label = N_("Slider"),
3338 .tooltip = N_("Create a slider"),
3339 .callback = G_CALLBACK (cmd_create_slider)
3341 { .name = "CreateSpinButton",
3342 .icon = "gnumeric-object-spinbutton",
3343 .label = N_("SpinButton"),
3344 .tooltip = N_("Create a spin button"),
3345 .callback = G_CALLBACK (cmd_create_spinbutton)
3347 { .name = "CreateList",
3348 .icon = "gnumeric-object-list",
3349 .label = N_("List"),
3350 .tooltip = N_("Create a list"),
3351 .callback = G_CALLBACK (cmd_create_list)
3353 { .name = "CreateCombo",
3354 .icon = "gnumeric-object-combo",
3355 .label = N_("Combo Box"),
3356 .tooltip = N_("Create a combo box"),
3357 .callback = G_CALLBACK (cmd_create_combo)
3359 { .name = "CreateLine",
3360 .icon = "gnumeric-object-line",
3361 .label = N_("Line"),
3362 .tooltip = N_("Create a line object"),
3363 .callback = G_CALLBACK (cmd_create_line)
3365 { .name = "CreateArrow",
3366 .icon = "gnumeric-object-arrow",
3367 .label = N_("Arrow"),
3368 .tooltip = N_("Create an arrow object"),
3369 .callback = G_CALLBACK (cmd_create_arrow)
3371 { .name = "CreateRectangle",
3372 .icon = "gnumeric-object-rectangle",
3373 .label = N_("Rectangle"),
3374 .tooltip = N_("Create a rectangle object"),
3375 .callback = G_CALLBACK (cmd_create_rectangle)
3377 { .name = "CreateEllipse",
3378 .icon = "gnumeric-object-ellipse",
3379 .label = N_("Ellipse"),
3380 .tooltip = N_("Create an ellipse object"),
3381 .callback = G_CALLBACK (cmd_create_ellipse)
3383 { .name = "CreateButton",
3384 .icon = "gnumeric-object-button",
3385 .label = N_("Button"),
3386 .tooltip = N_("Create a button"),
3387 .callback = G_CALLBACK (cmd_create_button)
3389 { .name = "CreateRadioButton",
3390 .icon = "gnumeric-object-radiobutton",
3391 .label = N_("RadioButton"),
3392 .tooltip = N_("Create a radio button"),
3393 .callback = G_CALLBACK (cmd_create_radiobutton)
3396 /* Format toolbar */
3397 { .name = "FormatMergeCells",
3398 .icon = "gnumeric-cells-merge",
3399 .label = N_("Merge"),
3400 .tooltip = N_("Merge a range of cells"),
3401 .callback = G_CALLBACK (cb_merge_cells)
3403 { .name = "FormatUnmergeCells",
3404 .icon = "gnumeric-cells-split",
3405 .label = N_("Unmerge"),
3406 .tooltip = N_("Split merged ranges of cells"),
3407 .callback = G_CALLBACK (cb_unmerge_cells)
3410 { .name = "FormatAsGeneral",
3411 .label = N_("General"),
3412 .accelerator = "<control>asciitilde",
3413 .tooltip = N_("Format the selection as General"),
3414 .callback = G_CALLBACK (cb_format_as_general)
3416 { .name = "FormatAsNumber",
3417 .label = N_("Number"),
3418 .accelerator = "<control>exclam",
3419 .tooltip = N_("Format the selection as numbers"),
3420 .callback = G_CALLBACK (cb_format_as_number)
3422 { .name = "FormatAsCurrency",
3423 .label = N_("Currency"),
3424 .accelerator = "<control>dollar",
3425 .tooltip = N_("Format the selection as currency"),
3426 .callback = G_CALLBACK (cb_format_as_currency)
3428 { .name = "FormatAsAccounting",
3429 .icon = "gnumeric-format-accounting",
3430 .label = N_("Accounting"),
3431 .tooltip = N_("Format the selection as accounting"),
3432 .callback = G_CALLBACK (cb_format_as_accounting)
3434 { .name = "FormatAsPercentage",
3435 .icon = "gnumeric-format-percentage",
3436 .label = N_("Percentage"),
3437 .accelerator = "<control>percent",
3438 .tooltip = N_("Format the selection as percentage"),
3439 .callback = G_CALLBACK (cb_format_as_percentage)
3441 { .name = "FormatAsScientific",
3442 .label = N_("Scientific"),
3443 .accelerator = "<control>asciicircum",
3444 .tooltip = N_("Format the selection as scientific"),
3445 .callback = G_CALLBACK (cb_format_as_scientific)
3447 { .name = "FormatAsDate",
3448 .label = N_("Date"),
3449 .accelerator = "<control>numbersign",
3450 .tooltip = N_("Format the selection as date"),
3451 .callback = G_CALLBACK (cb_format_as_date)
3453 { .name = "FormatAsTime",
3454 .label = N_("Time"),
3455 .accelerator = "<control>at",
3456 .tooltip = N_("Format the selection as time"),
3457 .callback = G_CALLBACK (cb_format_as_time)
3459 { .name = "FormatAddBorders",
3460 .label = N_("AddBorders"),
3461 .accelerator = "<control>ampersand",
3462 .tooltip = N_("Add a border around the selection"),
3463 .callback = G_CALLBACK (cb_format_add_borders)
3465 { .name = "FormatClearBorders",
3466 .label = N_("ClearBorders"),
3467 .accelerator = "<control>underscore",
3468 .tooltip = N_("Clear the border around the selection"),
3469 .callback = G_CALLBACK (cb_format_clear_borders)
3472 { .name = "FormatWithThousands",
3473 .icon = "gnumeric-format-thousand-separator",
3474 .label = N_("Thousands Separator"),
3475 .tooltip = N_("Set the format of the selected cells to include a thousands separator"),
3476 .callback = G_CALLBACK (cb_format_with_thousands)
3478 { .name = "FormatIncreasePrecision",
3479 .icon = "gnumeric-format-precision-increase",
3480 .label = N_("Increase Precision"),
3481 .tooltip = N_("Increase the number of decimals displayed"),
3482 .callback = G_CALLBACK (cb_format_inc_precision)
3484 { .name = "FormatDecreasePrecision",
3485 .icon = "gnumeric-format-precision-decrease",
3486 .label = N_("Decrease Precision"),
3487 .tooltip = N_("Decrease the number of decimals displayed"),
3488 .callback = G_CALLBACK (cb_format_dec_precision)
3491 /* Gtk marks these accelerators as invalid because they use Tab
3492 * enable them manually in gnm-pane.c */
3493 { .name = "FormatDecreaseIndent",
3494 .icon = "format-indent-less",
3495 .accelerator = "<control><alt><shift>Tab",
3496 .tooltip = N_("Decrease the indent, and align the contents to the left"),
3497 .callback = G_CALLBACK (cb_format_dec_indent)
3499 { .name = "FormatIncreaseIndent",
3500 .icon = "format-indent-more",
3501 .accelerator = "<control><alt>Tab",
3502 .tooltip = N_("Increase the indent, and align the contents to the left"),
3503 .callback = G_CALLBACK (cb_format_inc_indent)
3506 /* ---------------------------------------- */
3508 { .name = "SheetDisplayOutlines",
3509 .toggle = TRUE,
3510 .label = N_("Display _Outlines"),
3511 .accelerator = "<control>8",
3512 .tooltip = N_("Toggle whether or not to display outline groups"),
3513 .callback = G_CALLBACK (cb_sheet_pref_display_outlines)
3515 { .name = "SheetOutlineBelow",
3516 .toggle = TRUE,
3517 .label = N_("Outlines _Below"),
3518 .tooltip = N_("Toggle whether to display row outlines on top or bottom"),
3519 .callback = G_CALLBACK (cb_sheet_pref_outline_symbols_below)
3521 { .name = "SheetOutlineRight",
3522 .toggle = TRUE,
3523 .label = N_("Outlines _Right"),
3524 .tooltip = N_("Toggle whether to display column outlines on the left or right"),
3525 .callback = G_CALLBACK (cb_sheet_pref_outline_symbols_right)
3527 { .name = "SheetDisplayFormulas",
3528 .toggle = TRUE,
3529 .icon = "gnumeric-formulaguru",
3530 .label = N_("Display _Formul\303\246"),
3531 .accelerator = "<control>quoteleft",
3532 .tooltip = N_("Display the value of a formula or the formula itself"),
3533 .callback = G_CALLBACK (cb_sheet_pref_display_formulas)
3535 { .name = "SheetHideZeros",
3536 .toggle = TRUE,
3537 .label = N_("_Hide Zeros"),
3538 .tooltip = N_("Toggle whether or not to display zeros as blanks"),
3539 .callback = G_CALLBACK (cb_sheet_pref_hide_zero)
3541 { .name = "SheetHideGridlines",
3542 .toggle = TRUE,
3543 .label = N_("Hide _Gridlines"),
3544 .tooltip = N_("Toggle whether or not to display gridlines"),
3545 .callback = G_CALLBACK (cb_sheet_pref_hide_grid)
3547 { .name = "SheetHideColHeader",
3548 .toggle = TRUE,
3549 .label = N_("Hide _Column Headers"),
3550 .tooltip = N_("Toggle whether or not to display column headers"),
3551 .callback = G_CALLBACK (cb_sheet_pref_hide_col_header)
3553 { .name = "SheetHideRowHeader",
3554 .toggle = TRUE,
3555 .label = N_("Hide _Row Headers"),
3556 .tooltip = N_("Toggle whether or not to display row headers"),
3557 .callback = G_CALLBACK (cb_sheet_pref_hide_row_header)
3560 /* TODO : Make this a sub menu when we have more convention types */
3561 { .name = "SheetUseR1C1",
3562 .toggle = TRUE,
3563 .label = N_("Use R1C1 N_otation "),
3564 .tooltip = N_("Display addresses as R1C1 or A1"),
3565 .callback = G_CALLBACK (cb_sheet_pref_use_r1c1)
3568 { .name = "AlignLeft",
3569 .toggle = TRUE,
3570 .icon = "format-justify-left",
3571 .label = N_("_Left Align"),
3572 .tooltip = N_("Align left"),
3573 .callback = G_CALLBACK (cb_align_left)
3575 { .name = "AlignCenter",
3576 .toggle = TRUE,
3577 .icon = "format-justify-center",
3578 .label = N_("_Center"),
3579 .tooltip = N_("Center horizontally"),
3580 .callback = G_CALLBACK (cb_align_center)
3582 { .name = "AlignRight",
3583 .toggle = TRUE,
3584 .icon = "format-justify-right",
3585 .label = N_("_Right Align"),
3586 .tooltip = N_("Align right"),
3587 .callback = G_CALLBACK (cb_align_right)
3589 { .name = "CenterAcrossSelection",
3590 .toggle = TRUE,
3591 .icon = "gnumeric-center-across-selection",
3592 .label = N_("_Center Across Selection"),
3593 .tooltip = N_("Center horizontally across the selection"),
3594 .callback = G_CALLBACK (cb_center_across_selection)
3596 { .name = "MergeAndCenter",
3597 .toggle = TRUE,
3598 .label = N_("_Merge and Center"),
3599 .tooltip = N_("Merge the selection into 1 cell, and center horizontally."),
3600 .callback = G_CALLBACK (cb_merge_and_center)
3602 #warning "Add justify"
3603 #warning "h/v distributed?"
3605 #warning "Get vertical alignment icons"
3606 { .name = "AlignTop",
3607 .toggle = TRUE,
3608 .label = N_("Align _Top"),
3609 .tooltip = N_("Align Top"),
3610 .callback = G_CALLBACK (cb_align_top)
3612 { .name = "AlignVCenter",
3613 .toggle = TRUE,
3614 .label = N_("_Vertically Center"),
3615 .tooltip = N_("Vertically Center"),
3616 .callback = G_CALLBACK (cb_align_vcenter)
3618 { .name = "AlignBottom",
3619 .toggle = TRUE,
3620 .label = N_("Align _Bottom"),
3621 .tooltip = N_("Align Bottom"),
3622 .callback = G_CALLBACK (cb_align_bottom)
3626 static GnmActionEntry const font_actions[] = {
3627 { .name = "FontBold",
3628 .toggle = TRUE,
3629 .icon = "format-text-bold",
3630 .label = N_("_Bold"),
3631 .accelerator = "<control>b", /* ALSO "<control>2" */
3632 .tooltip = N_("Bold"),
3633 .callback = G_CALLBACK (cb_font_bold),
3634 .is_active = FALSE },
3635 { .name = "FontItalic",
3636 .toggle = TRUE,
3637 .icon = "format-text-italic",
3638 .label = N_("_Italic"),
3639 .accelerator = "<control>i", /* ALSO "<control>3" */
3640 .tooltip = N_("Italic"),
3641 .callback = G_CALLBACK (cb_font_italic),
3642 .is_active = FALSE },
3643 { .name = "FontUnderline",
3644 .toggle = TRUE,
3645 .icon = "format-text-underline",
3646 .label = N_("_Underline"),
3647 .accelerator = "<control>u", /* ALSO "<control>4" */
3648 .tooltip = N_("Underline"),
3649 .callback = G_CALLBACK (cb_font_underline),
3650 .is_active = FALSE },
3651 { .name = "FontDoubleUnderline",
3652 .toggle = TRUE,
3653 .icon = "stock_text_underlined-double", /* from icon theme */
3654 .label = N_("_Double Underline"),
3655 .accelerator = "<control><shift>d",
3656 .tooltip = N_("Double Underline"),
3657 .callback = G_CALLBACK (cb_font_double_underline),
3658 .is_active = FALSE },
3659 { .name = "FontSingleLowUnderline",
3660 .toggle = TRUE,
3661 .label = N_("_Single Low Underline"),
3662 .accelerator = "<control><shift>l",
3663 .tooltip = N_("Single Low Underline"),
3664 .callback = G_CALLBACK (cb_font_underline_low),
3665 .is_active = FALSE },
3666 { .name = "FontDoubleLowUnderline",
3667 .toggle = TRUE,
3668 .label = N_("Double _Low Underline"),
3669 .tooltip = N_("Double Low Underline"),
3670 .callback = G_CALLBACK (cb_font_double_underline_low),
3671 .is_active = FALSE },
3672 { .name = "FontStrikeThrough",
3673 .toggle = TRUE,
3674 .icon = "format-text-strikethrough",
3675 .label = N_("_Strikethrough"),
3676 .accelerator = "<control>5",
3677 .tooltip = N_("Strikethrough"),
3678 .callback = G_CALLBACK (cb_font_strikethrough),
3679 .is_active = FALSE },
3680 { .name = "FontSuperscript",
3681 .toggle = TRUE,
3682 .icon = "gnumeric-superscript",
3683 .label = N_("Su_perscript"),
3684 .accelerator = "<control>asciicircum",
3685 .tooltip = N_("Superscript"),
3686 .callback = G_CALLBACK (cb_font_superscript),
3687 .is_active = FALSE },
3688 { .name = "FontSubscript",
3689 .toggle = TRUE,
3690 .icon = "gnumeric-subscript",
3691 .label = N_("Subscrip_t"),
3692 .accelerator = "<control>underscore",
3693 .tooltip = N_("Subscript"),
3694 .callback = G_CALLBACK (cb_font_subscript), .is_active = FALSE }
3697 /****************************************************************************/
3699 static GOActionComboPixmapsElement const halignment_combo_info[] = {
3700 { N_("Align left"), "format-justify-left", GNM_HALIGN_LEFT },
3701 { N_("Center horizontally"), "format-justify-center", GNM_HALIGN_CENTER },
3702 { N_("Align right"), "format-justify-right", GNM_HALIGN_RIGHT },
3703 { N_("Fill horizontally"), "gnumeric-format-halign-fill", GNM_HALIGN_FILL },
3704 { N_("Justify horizontally"), "format-justify-fill", GNM_HALIGN_JUSTIFY },
3705 { N_("Distributed"), "gnumeric-format-halign-distributed", GNM_HALIGN_DISTRIBUTED },
3706 { N_("Center horizontally across the selection"),
3707 "gnumeric-center-across-selection", GNM_HALIGN_CENTER_ACROSS_SELECTION },
3708 { N_("Align numbers right, and text left"),
3709 "gnumeric-format-halign-general", GNM_HALIGN_GENERAL },
3710 { NULL, NULL }
3712 static GOActionComboPixmapsElement const valignment_combo_info[] = {
3713 { N_("Align top"), "gnumeric-format-valign-top", GNM_VALIGN_TOP },
3714 { N_("Center vertically"), "gnumeric-format-valign-center", GNM_VALIGN_CENTER },
3715 { N_("Align bottom"), "gnumeric-format-valign-bottom", GNM_VALIGN_BOTTOM },
3716 { N_("Justify"), "gnumeric-format-valign-justify", GNM_VALIGN_JUSTIFY },
3717 { N_("Align distributed"), "gnumeric-format-valign-distributed", GNM_VALIGN_DISTRIBUTED },
3718 { NULL, NULL}
3721 static void
3722 cb_halignment_activated (GOActionComboPixmaps *a, WBCGtk *wbcg)
3724 wbcg_set_selection_halign (wbcg,
3725 go_action_combo_pixmaps_get_selected (a, NULL));
3727 static void
3728 cb_valignment_activated (GOActionComboPixmaps *a, WBCGtk *wbcg)
3730 wbcg_set_selection_valign (wbcg,
3731 go_action_combo_pixmaps_get_selected (a, NULL));
3734 static void
3735 wbc_gtk_init_alignments (WBCGtk *wbcg)
3737 wbcg->halignment = go_action_combo_pixmaps_new ("HAlignmentSelector",
3738 halignment_combo_info, 3, 1);
3739 g_object_set (G_OBJECT (wbcg->halignment),
3740 "label", _("Horizontal Alignment"),
3741 "tooltip", _("Horizontal Alignment"),
3742 NULL);
3743 g_signal_connect (G_OBJECT (wbcg->halignment),
3744 "activate",
3745 G_CALLBACK (cb_halignment_activated), wbcg);
3746 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->halignment));
3748 wbcg->valignment = go_action_combo_pixmaps_new ("VAlignmentSelector",
3749 valignment_combo_info, 1, 3);
3750 g_object_set (G_OBJECT (wbcg->valignment),
3751 "label", _("Vertical Alignment"),
3752 "tooltip", _("Vertical Alignment"),
3753 NULL);
3754 g_signal_connect (G_OBJECT (wbcg->valignment),
3755 "activate",
3756 G_CALLBACK (cb_valignment_activated), wbcg);
3757 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->valignment));
3760 /****************************************************************************/
3762 static void
3763 cb_custom_color_created (GOActionComboColor *caction, GtkWidget *dialog, WBCGtk *wbcg)
3765 wbc_gtk_attach_guru (wbcg, dialog);
3766 wbcg_set_transient (wbcg, GTK_WINDOW (dialog));
3769 static void
3770 cb_fore_color_changed (GOActionComboColor *a, WBCGtk *wbcg)
3772 WorkbookControl *wbc = GNM_WBC (wbcg);
3773 GnmStyle *mstyle;
3774 GOColor c;
3775 gboolean is_default;
3777 if (wbcg->updating_ui)
3778 return;
3779 c = go_action_combo_color_get_color (a, &is_default);
3781 if (wbcg_is_editing (wbcg)) {
3782 wbcg_edit_add_markup (wbcg, go_color_to_pango (c, TRUE));
3783 return;
3786 mstyle = gnm_style_new ();
3787 gnm_style_set_font_color (mstyle, is_default
3788 ? style_color_auto_font ()
3789 : gnm_color_new_go (c));
3790 cmd_selection_format (wbc, mstyle, NULL, _("Set Foreground Color"));
3793 static void
3794 wbc_gtk_init_color_fore (WBCGtk *gtk)
3796 GnmColor *sc_auto_font = style_color_auto_font ();
3797 GOColor default_color = sc_auto_font->go_color;
3798 style_color_unref (sc_auto_font);
3800 gtk->fore_color = go_action_combo_color_new ("ColorFore", "gnumeric-font",
3801 _("Automatic"), default_color, NULL); /* set group to view */
3802 go_action_combo_color_set_allow_alpha (gtk->fore_color, TRUE);
3803 g_object_set (G_OBJECT (gtk->fore_color),
3804 "label", _("Foreground"),
3805 "tooltip", _("Foreground"),
3806 NULL);
3807 g_signal_connect (G_OBJECT (gtk->fore_color),
3808 "combo-activate",
3809 G_CALLBACK (cb_fore_color_changed), gtk);
3810 g_signal_connect (G_OBJECT (gtk->fore_color),
3811 "display-custom-dialog",
3812 G_CALLBACK (cb_custom_color_created), gtk);
3813 gnm_action_group_add_action (gtk->font_actions,
3814 GTK_ACTION (gtk->fore_color));
3817 static void
3818 cb_back_color_changed (GOActionComboColor *a, WBCGtk *wbcg)
3820 WorkbookControl *wbc = GNM_WBC (wbcg);
3821 GnmStyle *mstyle;
3822 GOColor c;
3823 gboolean is_default;
3825 if (wbcg->updating_ui)
3826 return;
3828 c = go_action_combo_color_get_color (a, &is_default);
3830 mstyle = gnm_style_new ();
3831 if (!is_default) {
3832 /* We need to have a pattern of at least solid to draw a background colour */
3833 if (!gnm_style_is_element_set (mstyle, MSTYLE_PATTERN) ||
3834 gnm_style_get_pattern (mstyle) < 1)
3835 gnm_style_set_pattern (mstyle, 1);
3837 gnm_style_set_back_color (mstyle, gnm_color_new_go (c));
3838 } else
3839 gnm_style_set_pattern (mstyle, 0); /* Set background to NONE */
3840 cmd_selection_format (wbc, mstyle, NULL, _("Set Background Color"));
3843 static void
3844 wbc_gtk_init_color_back (WBCGtk *gtk)
3846 gtk->back_color = go_action_combo_color_new ("ColorBack", "gnumeric-bucket",
3847 _("Clear Background"), 0, NULL);
3848 g_object_set (G_OBJECT (gtk->back_color),
3849 "label", _("Background"),
3850 "tooltip", _("Background"),
3851 NULL);
3852 g_object_connect (G_OBJECT (gtk->back_color),
3853 "signal::combo-activate", G_CALLBACK (cb_back_color_changed), gtk,
3854 "signal::display-custom-dialog", G_CALLBACK (cb_custom_color_created), gtk,
3855 NULL);
3856 gnm_action_group_add_action (gtk->actions, GTK_ACTION (gtk->back_color));
3859 /****************************************************************************/
3861 static GOActionComboPixmapsElement const border_combo_info[] = {
3862 { N_("Left"), "gnumeric-format-border-left", 11 },
3863 { N_("Clear Borders"), "gnumeric-format-border-none", 12 },
3864 { N_("Right"), "gnumeric-format-border-right", 13 },
3866 { N_("All Borders"), "gnumeric-format-border-all", 21 },
3867 { N_("Outside Borders"), "gnumeric-format-border-outside", 22 },
3868 { N_("Thick Outside Borders"), "gnumeric-format-border-thick-outside", 23 },
3870 { N_("Bottom"), "gnumeric-format-border-bottom", 31 },
3871 { N_("Double Bottom"), "gnumeric-format-border-double-bottom", 32 },
3872 { N_("Thick Bottom"), "gnumeric-format-border-thick-bottom", 33 },
3874 { N_("Top and Bottom"), "gnumeric-format-border-top-n-bottom", 41 },
3875 { N_("Top and Double Bottom"), "gnumeric-format-border-top-n-double-bottom", 42 },
3876 { N_("Top and Thick Bottom"), "gnumeric-format-border-top-n-thick-bottom", 43 },
3878 { NULL, NULL}
3881 static void
3882 cb_border_activated (GOActionComboPixmaps *a, WorkbookControl *wbc)
3884 Sheet *sheet = wb_control_cur_sheet (wbc);
3885 GnmBorder *borders[GNM_STYLE_BORDER_EDGE_MAX];
3886 int i;
3887 int index = go_action_combo_pixmaps_get_selected (a, NULL);
3889 /* Init the list */
3890 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; i++)
3891 borders[i] = NULL;
3893 switch (index) {
3894 case 11 : /* left */
3895 borders[GNM_STYLE_BORDER_LEFT] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3896 sheet_style_get_auto_pattern_color (sheet),
3897 gnm_style_border_get_orientation (GNM_STYLE_BORDER_LEFT));
3898 break;
3900 case 12 : /* none */
3901 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; i++)
3902 borders[i] = gnm_style_border_ref (gnm_style_border_none ());
3903 break;
3905 case 13 : /* right */
3906 borders[GNM_STYLE_BORDER_RIGHT] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3907 sheet_style_get_auto_pattern_color (sheet),
3908 gnm_style_border_get_orientation (GNM_STYLE_BORDER_RIGHT));
3909 break;
3911 case 21 : /* all */
3912 for (i = GNM_STYLE_BORDER_HORIZ; i <= GNM_STYLE_BORDER_VERT; ++i)
3913 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3914 sheet_style_get_auto_pattern_color (sheet),
3915 gnm_style_border_get_orientation (i));
3916 /* fall through */
3918 case 22 : /* outside */
3919 for (i = GNM_STYLE_BORDER_TOP; i <= GNM_STYLE_BORDER_RIGHT; ++i)
3920 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3921 sheet_style_get_auto_pattern_color (sheet),
3922 gnm_style_border_get_orientation (i));
3923 break;
3925 case 23 : /* thick_outside */
3926 for (i = GNM_STYLE_BORDER_TOP; i <= GNM_STYLE_BORDER_RIGHT; ++i)
3927 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THICK,
3928 sheet_style_get_auto_pattern_color (sheet),
3929 gnm_style_border_get_orientation (i));
3930 break;
3932 case 41 : /* top_n_bottom */
3933 case 42 : /* top_n_double_bottom */
3934 case 43 : /* top_n_thick_bottom */
3935 borders[GNM_STYLE_BORDER_TOP] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3936 sheet_style_get_auto_pattern_color (sheet),
3937 gnm_style_border_get_orientation (GNM_STYLE_BORDER_TOP));
3938 /* Fall through */
3940 case 31 : /* bottom */
3941 case 32 : /* double_bottom */
3942 case 33 : /* thick_bottom */
3944 int const tmp = index % 10;
3945 GnmStyleBorderType const t =
3946 (tmp == 1) ? GNM_STYLE_BORDER_THIN :
3947 (tmp == 2) ? GNM_STYLE_BORDER_DOUBLE
3948 : GNM_STYLE_BORDER_THICK;
3950 borders[GNM_STYLE_BORDER_BOTTOM] = gnm_style_border_fetch (t,
3951 sheet_style_get_auto_pattern_color (sheet),
3952 gnm_style_border_get_orientation (GNM_STYLE_BORDER_BOTTOM));
3953 break;
3956 default:
3957 g_warning ("Unknown border preset selected (%d)", index);
3958 return;
3961 cmd_selection_format (wbc, NULL, borders, _("Set Borders"));
3964 static void
3965 wbc_gtk_init_borders (WBCGtk *wbcg)
3967 wbcg->borders = go_action_combo_pixmaps_new ("BorderSelector", border_combo_info, 3, 4);
3968 g_object_set (G_OBJECT (wbcg->borders),
3969 "label", _("Borders"),
3970 "tooltip", _("Borders"),
3971 NULL);
3972 #if 0
3973 go_combo_pixmaps_select (wbcg->borders, 1); /* default to none */
3974 #endif
3975 g_signal_connect (G_OBJECT (wbcg->borders),
3976 "combo-activate",
3977 G_CALLBACK (cb_border_activated), wbcg);
3978 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->borders));
3981 /****************************************************************************/
3983 static void
3984 cb_chain_sensitivity (GtkAction *src, G_GNUC_UNUSED GParamSpec *pspec,
3985 GtkAction *action)
3987 gboolean old_val = gtk_action_get_sensitive (action);
3988 gboolean new_val = gtk_action_get_sensitive (src);
3989 if ((new_val != 0) == (old_val != 0))
3990 return;
3991 if (new_val)
3992 gtk_action_connect_accelerator (action);
3993 else
3994 gtk_action_disconnect_accelerator (action);
3995 g_object_set (action, "sensitive", new_val, NULL);
3999 static void
4000 create_undo_redo (GOActionComboStack **haction, char const *hname,
4001 GCallback hcb,
4002 GtkAction **vaction, char const *vname,
4003 GCallback vcb,
4004 WBCGtk *gtk,
4005 char const *tooltip,
4006 char const *icon_name,
4007 char const *accel, const char *alt_accel)
4009 *haction = g_object_new
4010 (go_action_combo_stack_get_type (),
4011 "name", hname,
4012 "tooltip", tooltip,
4013 "icon-name", icon_name,
4014 "sensitive", FALSE,
4015 "visible-vertical", FALSE,
4016 NULL);
4017 gtk_action_group_add_action_with_accel
4018 (gtk->semi_permanent_actions,
4019 GTK_ACTION (*haction),
4020 accel);
4021 g_signal_connect (G_OBJECT (*haction), "activate", hcb, gtk);
4023 *vaction = g_object_new
4024 (GTK_TYPE_ACTION,
4025 "name", vname,
4026 "tooltip", tooltip,
4027 "icon-name", icon_name,
4028 "sensitive", FALSE,
4029 "visible-horizontal", FALSE,
4030 NULL);
4031 gtk_action_group_add_action_with_accel
4032 (gtk->semi_permanent_actions,
4033 GTK_ACTION (*vaction),
4034 alt_accel);
4035 g_signal_connect_swapped (G_OBJECT (*vaction), "activate", vcb, gtk);
4037 g_signal_connect (G_OBJECT (*haction), "notify::sensitive",
4038 G_CALLBACK (cb_chain_sensitivity), *vaction);
4042 static void
4043 cb_undo_activated (GOActionComboStack *a, WorkbookControl *wbc)
4045 unsigned n = workbook_find_command (wb_control_get_workbook (wbc), TRUE,
4046 go_action_combo_stack_selection (a));
4047 while (n-- > 0)
4048 command_undo (wbc);
4051 static void
4052 cb_redo_activated (GOActionComboStack *a, WorkbookControl *wbc)
4054 unsigned n = workbook_find_command (wb_control_get_workbook (wbc), FALSE,
4055 go_action_combo_stack_selection (a));
4056 while (n-- > 0)
4057 command_redo (wbc);
4060 static void
4061 wbc_gtk_init_undo_redo (WBCGtk *gtk)
4063 create_undo_redo (
4064 &gtk->redo_haction, "Redo", G_CALLBACK (cb_redo_activated),
4065 &gtk->redo_vaction, "VRedo", G_CALLBACK (command_redo),
4066 gtk, _("Redo the undone action"),
4067 "edit-redo", "<control>y", "<control><shift>z");
4068 create_undo_redo (
4069 &gtk->undo_haction, "Undo", G_CALLBACK (cb_undo_activated),
4070 &gtk->undo_vaction, "VUndo", G_CALLBACK (command_undo),
4071 gtk, _("Undo the last action"),
4072 "edit-undo", "<control>z", NULL);
4075 /****************************************************************************/
4077 static GNM_ACTION_DEF (cb_zoom_activated)
4079 WorkbookControl *wbc = (WorkbookControl *)wbcg;
4080 Sheet *sheet = wb_control_cur_sheet (wbc);
4081 char const *new_zoom;
4082 int factor;
4083 char *end;
4085 if (sheet == NULL || wbcg->updating_ui || wbcg->snotebook == NULL)
4086 return;
4088 new_zoom = go_action_combo_text_get_entry (wbcg->zoom_haction);
4090 errno = 0; /* strtol sets errno, but does not clear it. */
4091 factor = strtol (new_zoom, &end, 10);
4092 if (new_zoom != end && errno != ERANGE && factor == (gnm_float)factor)
4093 /* The GSList of sheet passed to cmd_zoom will be freed by cmd_zoom,
4094 * and the sheet will force an update of the zoom combo to keep the
4095 * display consistent
4097 cmd_zoom (wbc, g_slist_append (NULL, sheet), factor / 100.);
4100 static GNM_ACTION_DEF (cb_vzoom_activated)
4102 dialog_zoom (wbcg, wbcg_cur_sheet (wbcg));
4105 static void
4106 wbc_gtk_init_zoom (WBCGtk *wbcg)
4108 #warning TODO : Add zoom to selection
4109 static char const * const preset_zoom [] = {
4110 "200%",
4111 "150%",
4112 "100%",
4113 "75%",
4114 "50%",
4115 "25%",
4116 NULL
4118 int i;
4120 /* ----- horizontal ----- */
4122 wbcg->zoom_haction =
4123 g_object_new (go_action_combo_text_get_type (),
4124 "name", "Zoom",
4125 "label", _("_Zoom"),
4126 "visible-vertical", FALSE,
4127 "tooltip", _("Zoom"),
4128 "stock-id", "zoom-in",
4129 NULL);
4130 go_action_combo_text_set_width (wbcg->zoom_haction, "10000%");
4131 for (i = 0; preset_zoom[i] != NULL ; ++i)
4132 go_action_combo_text_add_item (wbcg->zoom_haction,
4133 preset_zoom[i]);
4135 g_signal_connect (G_OBJECT (wbcg->zoom_haction),
4136 "activate",
4137 G_CALLBACK (cb_zoom_activated), wbcg);
4138 gnm_action_group_add_action (wbcg->actions,
4139 GTK_ACTION (wbcg->zoom_haction));
4141 /* ----- vertical ----- */
4143 wbcg->zoom_vaction =
4144 g_object_new (GTK_TYPE_ACTION,
4145 "name", "VZoom",
4146 "tooltip", _("Zoom"),
4147 "icon-name", "zoom-in",
4148 "visible-horizontal", FALSE,
4149 NULL);
4150 g_signal_connect (G_OBJECT (wbcg->zoom_vaction),
4151 "activate",
4152 G_CALLBACK (cb_vzoom_activated), wbcg);
4153 gnm_action_group_add_action (wbcg->actions,
4154 GTK_ACTION (wbcg->zoom_vaction));
4156 /* ----- chain ----- */
4158 g_signal_connect (G_OBJECT (wbcg->zoom_haction), "notify::sensitive",
4159 G_CALLBACK (cb_chain_sensitivity), wbcg->zoom_vaction);
4162 /****************************************************************************/
4164 typedef struct { GtkAction base; } GnmFontAction;
4165 typedef struct { GtkActionClass base; } GnmFontActionClass;
4167 static PangoFontDescription *
4168 gnm_font_action_get_font_desc (GtkAction *act)
4170 PangoFontDescription *desc =
4171 g_object_get_data (G_OBJECT (act), "font-data");
4172 return desc;
4175 void
4176 wbcg_font_action_set_font_desc (GtkAction *act, PangoFontDescription *desc)
4178 PangoFontDescription *old_desc;
4179 GSList *p;
4181 old_desc = g_object_get_data (G_OBJECT (act), "font-data");
4182 if (!old_desc) {
4183 old_desc = pango_font_description_new ();
4184 g_object_set_data_full (G_OBJECT (act),
4185 "font-data", old_desc,
4186 (GDestroyNotify)pango_font_description_free);
4188 pango_font_description_merge (old_desc, desc, TRUE);
4190 for (p = gtk_action_get_proxies (act); p; p = p->next) {
4191 GtkWidget *w = p->data;
4192 GtkWidget *child;
4193 GtkFontChooser *chooser;
4195 if (!GTK_IS_BIN (w))
4196 continue;
4198 child = gtk_bin_get_child (GTK_BIN (w));
4199 if (!GTK_IS_FONT_CHOOSER (child))
4200 continue;
4202 chooser = GTK_FONT_CHOOSER (child);
4203 gtk_font_chooser_set_font_desc (chooser, old_desc);
4207 static void
4208 cb_font_set (GtkFontChooser *chooser, GtkAction *act)
4210 PangoFontDescription *desc = gtk_font_chooser_get_font_desc (chooser);
4211 wbcg_font_action_set_font_desc (act, desc);
4212 pango_font_description_free (desc);
4213 gtk_action_activate (act);
4216 static void
4217 cb_font_button_screen_changed (GtkWidget *widget)
4219 /* Doesn't look right */
4220 #if 0
4221 GdkScreen *screen = gtk_widget_get_screen (widget);
4223 if (screen) {
4224 int w = gnm_widget_measure_string (widget,
4225 "XXMonospace | 99XX");
4226 gtk_widget_set_size_request (widget, w, -1);
4228 #endif
4231 /* Filter to ignore non-scalable fonts. */
4232 static gboolean
4233 cb_font_filter (G_GNUC_UNUSED const PangoFontFamily *family,
4234 const PangoFontFace *face_,
4235 gpointer user)
4237 PangoFontFace *face = (PangoFontFace*)face_;
4238 int n_sizes;
4239 int *sizes = NULL;
4240 static int debug = -1;
4242 pango_font_face_list_sizes (face, &sizes, &n_sizes);
4243 g_free (sizes);
4245 if (debug == -1)
4246 debug = gnm_debug_flag ("fonts");
4248 if (n_sizes > 0 && debug) {
4249 PangoFontDescription *desc = pango_font_face_describe (face);
4250 char *s = pango_font_description_to_string (desc);
4251 g_printerr ("Ignoring bitmap face %s\n", s);
4252 g_free (s);
4253 pango_font_description_free (desc);
4256 return n_sizes == 0;
4259 static GtkWidget *
4260 gnm_font_action_create_tool_item (GtkAction *action)
4262 GtkWidget *item = g_object_new
4263 (GTK_TYPE_TOOL_ITEM,
4264 NULL);
4265 GtkWidget *but = g_object_new
4266 (gnm_font_button_get_type(),
4267 "dialog-type", GO_TYPE_FONT_SEL_DIALOG,
4268 "show-preview-entry", TRUE,
4269 "show-style", FALSE,
4270 "relief", gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (item)),
4271 "focus-on-click", FALSE,
4272 NULL);
4273 if (0) gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (but),
4274 cb_font_filter,
4275 NULL,
4276 NULL);
4277 gtk_widget_show_all (but);
4278 gtk_container_add (GTK_CONTAINER (item), but);
4279 g_signal_connect (but,
4280 "font-set", G_CALLBACK (cb_font_set),
4281 action);
4282 g_signal_connect (but,
4283 "screen-changed",
4284 G_CALLBACK (cb_font_button_screen_changed),
4285 action);
4286 return item;
4289 static void
4290 gnm_font_action_class_init (GObjectClass *gobject_class)
4292 GtkActionClass *act = GTK_ACTION_CLASS (gobject_class);
4294 act->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
4295 act->create_tool_item = gnm_font_action_create_tool_item;
4298 static
4299 GSF_CLASS (GnmFontAction, gnm_font_action,
4300 gnm_font_action_class_init, NULL, GTK_TYPE_ACTION)
4301 #if 0
4303 #endif
4304 #define GNM_FONT_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), gnm_font_action_get_type(), GnmFontAction))
4306 static void
4307 cb_font_changed (GtkAction *act, WBCGtk *gtk)
4309 PangoFontDescription *desc = gnm_font_action_get_font_desc (act);
4310 const char *family = pango_font_description_get_family (desc);
4311 int size = pango_font_description_get_size (desc);
4314 * Ignore events during destruction. This is an attempt at avoiding
4315 * https://bugzilla.redhat.com/show_bug.cgi?id=803904 for which we
4316 * blame gtk.
4318 if (gtk->snotebook == NULL)
4319 return;
4321 if (wbcg_is_editing (WBC_GTK (gtk))) {
4322 wbcg_edit_add_markup (WBC_GTK (gtk),
4323 pango_attr_family_new (family));
4324 wbcg_edit_add_markup (WBC_GTK (gtk),
4325 pango_attr_size_new (size));
4326 } else {
4327 GnmStyle *style = gnm_style_new ();
4328 char *font_name = pango_font_description_to_string (desc);
4329 char *title = g_strdup_printf (_("Setting Font %s"), font_name);
4330 g_free (font_name);
4332 gnm_style_set_font_name (style, family);
4333 gnm_style_set_font_size (style, size / (double)PANGO_SCALE);
4335 cmd_selection_format (GNM_WBC (gtk), style, NULL, title);
4336 g_free (title);
4340 static void
4341 cb_font_name_vaction_response (GtkDialog *dialog,
4342 gint response_id,
4343 GtkAction *act)
4345 WBCGtk *wbcg = g_object_get_data (G_OBJECT (act), "wbcg");
4347 if (response_id == GTK_RESPONSE_OK) {
4348 PangoFontDescription *desc = gtk_font_chooser_get_font_desc
4349 (GTK_FONT_CHOOSER (dialog));
4350 wbcg_font_action_set_font_desc (act, desc);
4351 pango_font_description_free (desc);
4352 cb_font_changed (act, wbcg);
4355 gtk_widget_destroy (GTK_WIDGET (dialog));
4359 static void
4360 cb_font_name_vaction_clicked (GtkAction *act, WBCGtk *wbcg)
4362 GtkFontChooser *font_dialog;
4363 const char *key = "font-name-dialog";
4365 if (gnm_dialog_raise_if_exists (wbcg, key))
4366 return;
4368 font_dialog = g_object_new (GO_TYPE_FONT_SEL_DIALOG, NULL);
4369 gtk_font_chooser_set_font_desc (font_dialog,
4370 gnm_font_action_get_font_desc (act));
4371 g_signal_connect (font_dialog, "response",
4372 G_CALLBACK (cb_font_name_vaction_response),
4373 act);
4375 gtk_window_present (GTK_WINDOW (font_dialog));
4377 gnm_keyed_dialog (wbcg, GTK_WINDOW (font_dialog), key);
4380 static GtkAction *
4381 wbc_gtk_init_font_name (WBCGtk *gtk, gboolean horiz)
4383 GtkAction *act = g_object_new
4384 (horiz ? gnm_font_action_get_type () : GTK_TYPE_ACTION,
4385 "visible-vertical", !horiz,
4386 "visible-horizontal", horiz,
4387 "name", (horiz ? "FontName" : "VFontName"),
4388 "tooltip", _("Change font"),
4389 "icon-name", "gnumeric-font",
4390 NULL);
4392 g_object_set_data (G_OBJECT (act), "wbcg", gtk);
4394 g_signal_connect (G_OBJECT (act),
4395 "activate",
4396 (horiz
4397 ? G_CALLBACK (cb_font_changed)
4398 : G_CALLBACK (cb_font_name_vaction_clicked)),
4399 gtk);
4401 gnm_action_group_add_action (gtk->font_actions, act);
4403 return act;
4406 /****************************************************************************/
4408 static void
4409 list_actions (GtkActionGroup *group)
4411 GList *actions, *l;
4413 if (!group)
4414 return;
4416 actions = gtk_action_group_list_actions (group);
4417 for (l = actions; l; l = l->next) {
4418 GtkAction *act = l->data;
4419 const char *name = gtk_action_get_name (act);
4420 g_printerr ("Action %s\n", name);
4423 g_list_free (actions);
4426 void
4427 wbc_gtk_init_actions (WBCGtk *wbcg)
4429 static struct {
4430 char const *name;
4431 gboolean is_font;
4432 unsigned offset;
4433 } const toggles[] = {
4434 { "FontBold", TRUE, G_STRUCT_OFFSET (WBCGtk, font.bold) },
4435 { "FontItalic", TRUE, G_STRUCT_OFFSET (WBCGtk, font.italic) },
4436 { "FontUnderline", TRUE, G_STRUCT_OFFSET (WBCGtk, font.underline) },
4437 { "FontDoubleUnderline", TRUE, G_STRUCT_OFFSET (WBCGtk, font.d_underline) },
4438 { "FontSingleLowUnderline",TRUE, G_STRUCT_OFFSET (WBCGtk, font.sl_underline) },
4439 { "FontDoubleLowUnderline",TRUE, G_STRUCT_OFFSET (WBCGtk, font.dl_underline) },
4440 { "FontSuperscript", TRUE, G_STRUCT_OFFSET (WBCGtk, font.superscript) },
4441 { "FontSubscript", TRUE, G_STRUCT_OFFSET (WBCGtk, font.subscript) },
4442 { "FontStrikeThrough", TRUE, G_STRUCT_OFFSET (WBCGtk, font.strikethrough) },
4444 { "AlignLeft", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.left) },
4445 { "AlignCenter", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.center) },
4446 { "AlignRight", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.right) },
4447 { "CenterAcrossSelection", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.center_across_selection) },
4448 { "AlignTop", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.top) },
4449 { "AlignVCenter", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.center) },
4450 { "AlignBottom", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.bottom) }
4452 unsigned i;
4454 wbcg->permanent_actions = gtk_action_group_new ("PermanentActions");
4455 wbcg->actions = gtk_action_group_new ("Actions");
4456 wbcg->font_actions = gtk_action_group_new ("FontActions");
4457 wbcg->data_only_actions = gtk_action_group_new ("DataOnlyActions");
4458 wbcg->semi_permanent_actions = gtk_action_group_new ("SemiPermanentActions");
4460 gnm_action_group_add_actions (wbcg->permanent_actions,
4461 permanent_actions, G_N_ELEMENTS (permanent_actions), wbcg);
4462 gnm_action_group_add_actions (wbcg->actions,
4463 actions, G_N_ELEMENTS (actions), wbcg);
4464 gnm_action_group_add_actions (wbcg->font_actions,
4465 font_actions, G_N_ELEMENTS (font_actions), wbcg);
4466 gnm_action_group_add_actions (wbcg->data_only_actions,
4467 data_only_actions, G_N_ELEMENTS (data_only_actions), wbcg);
4468 gnm_action_group_add_actions (wbcg->semi_permanent_actions,
4469 semi_permanent_actions, G_N_ELEMENTS (semi_permanent_actions), wbcg);
4471 wbc_gtk_init_alignments (wbcg);
4472 wbc_gtk_init_color_fore (wbcg);
4473 wbc_gtk_init_color_back (wbcg);
4474 wbc_gtk_init_borders (wbcg);
4475 wbc_gtk_init_undo_redo (wbcg);
4476 wbc_gtk_init_zoom (wbcg);
4477 wbcg->font_name_haction = wbc_gtk_init_font_name (wbcg, TRUE);
4478 wbcg->font_name_vaction = wbc_gtk_init_font_name (wbcg, FALSE);
4480 for (i = G_N_ELEMENTS (toggles); i-- > 0 ; ) {
4481 GtkAction *act = wbcg_find_action (wbcg, toggles[i].name);
4482 G_STRUCT_MEMBER (GtkToggleAction *, wbcg, toggles[i].offset) =
4483 (GtkToggleAction*) (act);
4486 if (gnm_debug_flag ("actions")) {
4487 list_actions (wbcg->permanent_actions);
4488 list_actions (wbcg->actions);
4489 list_actions (wbcg->font_actions);
4490 list_actions (wbcg->data_only_actions);
4491 list_actions (wbcg->semi_permanent_actions);
4492 list_actions (wbcg->file_history.actions);
4493 list_actions (wbcg->toolbar.actions);
4494 list_actions (wbcg->windows.actions);
4495 list_actions (wbcg->templates.actions);