GUI: Move .ui files from goffice resources to glib resources
[gnumeric.git] / src / wbc-gtk-actions.c
blobb4876b59b4d173e958a8b54c0441057b7438aee7
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /*
4 * wbcg-actions.c: The callbacks and tables for all the menus and stock toolbars
6 * Copyright (C) 2003-2006 Jody Goldberg (jody@gnome.org)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) version 3.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 * USA
24 #include <gnumeric-config.h>
25 #include "gnumeric.h"
27 #include "libgnumeric.h"
28 #include "application.h"
29 #include "gnm-commands-slicer.h"
30 #include "commands.h"
31 #include "clipboard.h"
32 #include "selection.h"
33 #include "search.h"
34 #include "ranges.h"
35 #include "cell.h"
36 #include "stf.h"
37 #include "value.h"
38 #include "gnm-format.h"
39 #include "sheet.h"
40 #include "sort.h"
41 #include "sheet-merge.h"
42 #include "sheet-filter.h"
43 #include "sheet-utils.h"
44 #include "sheet-style.h"
45 #include "style-border.h"
46 #include "style-color.h"
47 #include "tools/filter.h"
48 #include "sheet-control-gui-priv.h"
49 #include "sheet-view.h"
50 #include "cmd-edit.h"
51 #include "workbook.h"
52 #include "workbook-view.h"
53 #include "wbc-gtk-impl.h"
54 #include "workbook-cmd-format.h"
55 #include "dialogs/dialogs.h"
56 #include "sheet-object-image.h"
57 #include "sheet-object-widget.h"
58 #include "gnm-so-filled.h"
59 #include "gnm-so-line.h"
60 #include "sheet-object-graph.h"
61 #include "sheet-object-component.h"
62 #include "gui-util.h"
63 #include "gui-file.h"
64 #include "gnumeric-conf.h"
65 #include "expr.h"
66 #include "print.h"
67 #include "print-info.h"
68 #include "gnm-pane-impl.h"
69 #include "gutils.h"
70 #include "widgets/gnm-fontbutton.h"
72 #include <goffice/goffice.h>
73 #include <goffice/component/goffice-component.h>
75 #include <gtk/gtk.h>
76 #include <glib/gi18n-lib.h>
77 #include <gsf/gsf-input.h>
78 #include <string.h>
79 #include <glib/gstdio.h>
80 #include <errno.h>
82 static gboolean
83 cb_cleanup_sendto (gpointer path)
85 char *dir = g_path_get_dirname (path);
87 g_unlink (path);
88 g_free (path); /* the attachment */
90 g_rmdir (dir);
91 g_free (dir); /* the tempdir */
93 return FALSE;
97 static GNM_ACTION_DEF (cb_file_new)
99 GdkScreen *screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
100 Workbook *wb = workbook_new_with_sheets
101 (gnm_conf_get_core_workbook_n_sheet ());
102 WBCGtk *new_wbcg = wbc_gtk_new (NULL, wb, screen, NULL);
103 wbcg_copy_toolbar_visibility (new_wbcg, wbcg);
106 static GNM_ACTION_DEF (cb_file_open) { gui_file_open (wbcg, GNM_FILE_OPEN_STYLE_OPEN, NULL); }
107 static GNM_ACTION_DEF (cb_file_save) { gui_file_save (wbcg, wb_control_view (GNM_WBC (wbcg))); }
108 static GNM_ACTION_DEF (cb_file_save_as) { gui_file_save_as
109 (wbcg, wb_control_view (GNM_WBC (wbcg)),
110 GNM_FILE_SAVE_AS_STYLE_SAVE, NULL); }
112 static GNM_ACTION_DEF (cb_file_sendto) {
113 WorkbookControl *wbc = GNM_WBC (wbcg);
114 WorkbookView *wbv = wb_control_view (wbc);
115 GOCmdContext *gcc = GO_CMD_CONTEXT (wbcg);
116 gboolean problem = FALSE;
117 GOIOContext *io_context;
118 Workbook *wb;
119 GOFileSaver *fs;
121 wb = wb_control_get_workbook (wbc);
122 g_object_ref (wb);
123 fs = workbook_get_file_saver (wb);
124 if (fs == NULL)
125 fs = go_file_saver_get_default ();
127 io_context = go_io_context_new (gcc);
128 if (fs != NULL) {
129 char *template, *full_name, *uri;
130 char *basename = g_path_get_basename (go_doc_get_uri (GO_DOC (wb)));
132 template = g_build_filename (g_get_tmp_dir (),
133 ".gnm-sendto-XXXXXX", NULL);
134 problem = (g_mkdtemp_full (template, 0600) == NULL);
136 if (problem) {
137 g_free (template);
138 goto out;
141 full_name = g_build_filename (template, basename, NULL);
142 g_free (basename);
143 uri = go_filename_to_uri (full_name);
145 workbook_view_save_to_uri (wbv, fs, uri, io_context);
147 if (go_io_error_occurred (io_context) ||
148 go_io_warning_occurred (io_context))
149 go_io_error_display (io_context);
151 if (go_io_error_occurred (io_context)) {
152 problem = TRUE;
153 } else {
154 /* mutt does not handle urls with no destination
155 * so pick something to arbitrary */
156 GError *err;
157 GdkScreen *screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
158 char *url, *tmp = go_url_encode (full_name, 0);
159 url = g_strdup_printf ("mailto:someone?attach=%s", tmp);
160 g_free (tmp);
162 err = go_gtk_url_show (url, screen);
164 if (err != NULL) {
165 go_cmd_context_error (GO_CMD_CONTEXT (io_context), err);
166 g_error_free (err);
167 go_io_error_display (io_context);
168 problem = TRUE;
171 g_free (template);
172 g_free (uri);
174 if (problem) {
175 cb_cleanup_sendto (full_name);
176 } else {
178 * We wait a while before we clean up to ensure the file is
179 * loaded by the mailer.
181 g_timeout_add (1000 * 10, cb_cleanup_sendto, full_name);
183 } else {
184 go_cmd_context_error_export (GO_CMD_CONTEXT (io_context),
185 _("Default file saver is not available."));
186 go_io_error_display (io_context);
187 problem = TRUE;
190 out:
191 g_object_unref (io_context);
192 g_object_unref (wb);
194 /* What do we do with "problem"? */
197 static GNM_ACTION_DEF (cb_file_page_setup)
199 dialog_printer_setup (wbcg, wbcg_cur_sheet (wbcg));
202 static GNM_ACTION_DEF (cb_file_print_area_set)
204 Sheet *sheet = wbcg_cur_sheet (wbcg);
205 SheetView *sv = sheet_get_view (sheet, wb_control_view (GNM_WBC (wbcg)));
206 GnmParsePos pp;
207 char *message;
208 char * selection;
209 GnmRange const *r = selection_first_range (sv,
210 GO_CMD_CONTEXT (wbcg), _("Set Print Area"));
211 if (r != NULL) {
212 parse_pos_init_sheet (&pp, sheet);
213 selection = undo_range_name (sheet, r);
214 message = g_strdup_printf (_("Set Print Area to %s"), selection);
215 cmd_define_name (GNM_WBC (wbcg), "Print_Area", &pp,
216 gnm_expr_top_new_constant
217 (value_new_cellrange_r (NULL, r)),
218 message);
219 g_free (selection);
220 g_free (message);
224 static GNM_ACTION_DEF (cb_file_print_area_clear)
226 GnmParsePos pp;
227 Sheet *sheet = wbcg_cur_sheet (wbcg);
229 parse_pos_init_sheet (&pp, sheet);
230 cmd_define_name (GNM_WBC (wbcg), "Print_Area", &pp,
231 gnm_expr_top_new_constant
232 (value_new_error_REF (NULL)),
233 _("Clear Print Area"));
236 static GNM_ACTION_DEF (cb_file_print_area_show)
238 Sheet *sheet = wbcg_cur_sheet (wbcg);
239 GnmRange *r = sheet_get_nominal_printarea (sheet);
241 if (r != NULL) {
242 SheetView *sv = sheet_get_view (sheet,
243 wb_control_view (GNM_WBC (wbcg)));
244 wb_control_sheet_focus (GNM_WBC (wbcg), sheet);
245 sv_selection_reset (sv);
246 sv_selection_add_range (sv, r);
247 gnm_sheet_view_make_cell_visible (sv, r->start.col, r->start.row, FALSE);
248 g_free (r);
252 static GNM_ACTION_DEF (cb_file_print_area_toggle_col)
254 cmd_page_break_toggle (GNM_WBC (wbcg),
255 wbcg_cur_sheet (wbcg),
256 TRUE);
258 static GNM_ACTION_DEF (cb_file_print_area_toggle_row)
260 cmd_page_break_toggle (GNM_WBC (wbcg),
261 wbcg_cur_sheet (wbcg),
262 FALSE);
265 static GNM_ACTION_DEF (cb_file_print_area_clear_pagebreaks)
267 cmd_page_breaks_clear (GNM_WBC (wbcg), wbcg_cur_sheet (wbcg));
270 static GNM_ACTION_DEF (cb_file_print)
272 gnm_print_sheet (GNM_WBC (wbcg),
273 wbcg_cur_sheet (wbcg), FALSE, GNM_PRINT_SAVED_INFO, NULL);
276 static GNM_ACTION_DEF (cb_file_print_preview)
278 gnm_print_sheet (GNM_WBC (wbcg),
279 wbcg_cur_sheet (wbcg), TRUE, GNM_PRINT_ACTIVE_SHEET, NULL);
282 static GNM_ACTION_DEF (cb_doc_meta_data) { dialog_doc_metadata_new (wbcg, 0); }
283 static GNM_ACTION_DEF (cb_file_preferences) { dialog_preferences (wbcg, NULL); }
284 static GNM_ACTION_DEF (cb_file_history_full) { dialog_recent_used (wbcg); }
285 static GNM_ACTION_DEF (cb_file_close) { wbc_gtk_close (wbcg); }
287 static GNM_ACTION_DEF (cb_file_quit)
289 /* If we are still loading initial files, short circuit */
290 if (!gnm_app_initial_open_complete ()) {
291 g_object_set (gnm_app_get_app (), "shutting-down", TRUE, NULL);
292 return;
295 /* If we were editing when the quit request came in abort the edit. */
296 wbcg_edit_finish (wbcg, WBC_EDIT_REJECT, NULL);
298 dialog_quit (wbcg);
301 /****************************************************************************/
303 static GNM_ACTION_DEF (cb_edit_clear_all)
305 cmd_selection_clear (GNM_WBC (wbcg),
306 CLEAR_VALUES | CLEAR_FORMATS | CLEAR_OBJECTS | CLEAR_COMMENTS);
309 static GNM_ACTION_DEF (cb_edit_clear_formats)
310 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_FORMATS); }
311 static GNM_ACTION_DEF (cb_edit_clear_comments)
312 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_COMMENTS); }
313 static GNM_ACTION_DEF (cb_edit_clear_content)
314 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_VALUES); }
315 static GNM_ACTION_DEF (cb_edit_clear_all_filtered)
317 cmd_selection_clear (GNM_WBC (wbcg),
318 CLEAR_VALUES | CLEAR_FORMATS | CLEAR_OBJECTS | CLEAR_COMMENTS | CLEAR_FILTERED_ONLY);
321 static GNM_ACTION_DEF (cb_edit_clear_formats_filtered)
322 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_FORMATS | CLEAR_FILTERED_ONLY); }
323 static GNM_ACTION_DEF (cb_edit_clear_comments_filtered)
324 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_COMMENTS | CLEAR_FILTERED_ONLY); }
325 static GNM_ACTION_DEF (cb_edit_clear_content_filtered)
326 { cmd_selection_clear (GNM_WBC (wbcg), CLEAR_VALUES | CLEAR_FILTERED_ONLY); }
328 static GNM_ACTION_DEF (cb_edit_delete_rows)
330 WorkbookControl *wbc = GNM_WBC (wbcg);
331 SheetView *sv = wb_control_cur_sheet_view (wbc);
332 Sheet *sheet = wb_control_cur_sheet (wbc);
333 GnmRange const *sel;
334 int rows;
336 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Delete"))))
337 return;
338 rows = range_height (sel);
340 cmd_delete_rows (wbc, sheet, sel->start.row, rows);
342 static GNM_ACTION_DEF (cb_edit_delete_columns)
344 WorkbookControl *wbc = GNM_WBC (wbcg);
345 SheetView *sv = wb_control_cur_sheet_view (wbc);
346 Sheet *sheet = wb_control_cur_sheet (wbc);
347 GnmRange const *sel;
348 int cols;
350 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Delete"))))
351 return;
352 cols = range_width (sel);
354 cmd_delete_cols (wbc, sheet, sel->start.col, cols);
357 static GNM_ACTION_DEF (cb_edit_delete_cells)
359 dialog_delete_cells (wbcg);
361 static GNM_ACTION_DEF (cb_edit_delete_links)
363 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
364 GnmStyle *style = gnm_style_new ();
365 GSList *l;
366 int n_links = 0;
367 gchar const *format;
368 gchar *name;
369 WorkbookControl *wbc = GNM_WBC (wbcg);
370 Sheet *sheet = wb_control_cur_sheet (wbc);
372 for (l = scg_view (scg)->selections; l != NULL; l = l->next) {
373 GnmRange const *r = l->data;
374 GnmStyleList *styles;
376 styles = sheet_style_collect_hlinks (sheet, r);
377 n_links += g_slist_length (styles);
378 style_list_free (styles);
380 format = ngettext ("Remove %d Link", "Remove %d Links", n_links);
381 name = g_strdup_printf (format, n_links);
382 gnm_style_set_hlink (style, NULL);
383 cmd_selection_format (wbc, style, NULL, name);
384 g_free (name);
387 static GNM_ACTION_DEF (cb_edit_select_all)
389 scg_select_all (wbcg_cur_scg (wbcg));
391 static GNM_ACTION_DEF (cb_edit_select_row)
393 sv_select_cur_row (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
395 static GNM_ACTION_DEF (cb_edit_select_col)
397 sv_select_cur_col (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
399 static GNM_ACTION_DEF (cb_edit_select_array)
401 sv_select_cur_array (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
403 static GNM_ACTION_DEF (cb_edit_select_depends)
405 sv_select_cur_depends (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
407 static GNM_ACTION_DEF (cb_edit_select_inputs)
409 sv_select_cur_inputs (wb_control_cur_sheet_view (GNM_WBC (wbcg)));
411 static GNM_ACTION_DEF (cb_edit_select_object)
413 scg_object_select_next (wbcg_cur_scg (wbcg), FALSE);
416 static GNM_ACTION_DEF (cb_edit_cut)
418 if (!wbcg_is_editing (wbcg)) {
419 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
420 WorkbookControl *wbc = GNM_WBC (wbcg);
421 SheetView *sv = wb_control_cur_sheet_view (wbc);
422 if (scg != NULL && scg->selected_objects != NULL)
423 gnm_app_clipboard_cut_copy_obj (wbc, TRUE, sv,
424 go_hash_keys (scg->selected_objects));
425 else
426 gnm_sheet_view_selection_cut (sv, wbc);
427 } else
428 gtk_editable_cut_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
431 static GNM_ACTION_DEF (cb_edit_copy)
433 if (!wbcg_is_editing (wbcg)) {
434 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
435 WorkbookControl *wbc = GNM_WBC (wbcg);
436 SheetView *sv = wb_control_cur_sheet_view (wbc);
437 if (scg != NULL && scg->selected_objects != NULL)
438 gnm_app_clipboard_cut_copy_obj (wbc, FALSE, sv,
439 go_hash_keys (scg->selected_objects));
440 else
441 gnm_sheet_view_selection_copy (sv, wbc);
442 } else
443 gtk_editable_copy_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
446 static GNM_ACTION_DEF (cb_edit_paste)
448 if (!wbcg_is_editing (wbcg)) {
449 WorkbookControl *wbc = GNM_WBC (wbcg);
450 SheetView *sv = wb_control_cur_sheet_view (wbc);
451 cmd_paste_to_selection (wbc, sv, PASTE_DEFAULT);
452 } else
453 gtk_editable_paste_clipboard (GTK_EDITABLE (wbcg_get_entry (wbcg)));
456 static GNM_ACTION_DEF (cb_edit_paste_special)
458 dialog_paste_special (wbcg);
461 static GNM_ACTION_DEF (cb_sheet_remove)
463 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
464 if (scg)
465 scg_delete_sheet_if_possible (scg);
468 static void
469 common_cell_goto (WBCGtk *wbcg, Sheet *sheet, GnmCellPos const *pos)
471 SheetView *sv;
472 WorkbookView *wbv;
474 if (!sheet_is_visible (sheet))
475 return;
477 wbv = wb_control_view (GNM_WBC (wbcg));
478 sv = sheet_get_view (sheet, wbv);
479 wb_view_sheet_focus (wbv, sheet);
480 sv_selection_set (sv, pos,
481 pos->col, pos->row,
482 pos->col, pos->row);
483 gnm_sheet_view_make_cell_visible (sv, pos->col, pos->row, FALSE);
486 static int
487 cb_edit_search_replace_query (GnmSearchReplaceQuery q, GnmSearchReplace *sr, ...)
489 int res;
490 va_list pvar;
491 WBCGtk *wbcg = sr->user_data;
493 va_start (pvar, sr);
495 switch (q) {
496 case GNM_SRQ_FAIL: {
497 GnmCell *cell = va_arg (pvar, GnmCell *);
498 char const *old_text = va_arg (pvar, char const *);
499 char const *new_text = va_arg (pvar, char const *);
500 char *err = g_strdup_printf
501 (_("In cell %s, the current contents\n"
502 " %s\n"
503 "would have been replaced by\n"
504 " %s\n"
505 "which is invalid.\n\n"
506 "The replace has been aborted "
507 "and nothing has been changed."),
508 cell_name (cell),
509 old_text,
510 new_text);
512 go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR,
513 "%s", err);
514 g_free (err);
515 res = GTK_RESPONSE_NO;
516 break;
519 case GNM_SRQ_QUERY: {
520 GnmCell *cell = va_arg (pvar, GnmCell *);
521 char const *old_text = va_arg (pvar, char const *);
522 char const *new_text = va_arg (pvar, char const *);
523 Sheet *sheet = cell->base.sheet;
524 char *pos_name = g_strconcat (sheet->name_unquoted, "!",
525 cell_name (cell), NULL);
527 common_cell_goto (wbcg, sheet, &cell->pos);
529 res = dialog_search_replace_query (wbcg, sr, pos_name,
530 old_text, new_text);
531 g_free (pos_name);
532 break;
535 case GNM_SRQ_QUERY_COMMENT: {
536 Sheet *sheet = va_arg (pvar, Sheet *);
537 GnmCellPos *cp = va_arg (pvar, GnmCellPos *);
538 char const *old_text = va_arg (pvar, char const *);
539 char const *new_text = va_arg (pvar, char const *);
540 char *pos_name = g_strdup_printf (_("Comment in cell %s!%s"),
541 sheet->name_unquoted,
542 cellpos_as_string (cp));
543 common_cell_goto (wbcg, sheet, cp);
545 res = dialog_search_replace_query (wbcg, sr, pos_name,
546 old_text, new_text);
547 g_free (pos_name);
548 break;
551 default:
552 /* Shouldn't really happen. */
553 res = GTK_RESPONSE_CANCEL;
556 va_end (pvar);
557 return res;
560 static gboolean
561 cb_edit_search_replace_action (WBCGtk *wbcg,
562 GnmSearchReplace *sr)
564 WorkbookControl *wbc = GNM_WBC (wbcg);
566 sr->query_func = cb_edit_search_replace_query;
567 sr->user_data = wbcg;
569 return cmd_search_replace (wbc, sr);
573 static GNM_ACTION_DEF (cb_edit_search_replace) { dialog_search_replace (wbcg, cb_edit_search_replace_action); }
574 static GNM_ACTION_DEF (cb_edit_search) { dialog_search (wbcg); }
576 static GNM_ACTION_DEF (cb_edit_fill_autofill)
578 WorkbookControl *wbc = GNM_WBC (wbcg);
579 SheetView *sv = wb_control_cur_sheet_view (wbc);
580 Sheet *sheet = wb_control_cur_sheet (wbc);
582 GnmRange const *total = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Autofill"));
583 if (total) {
584 GnmRange src = *total;
585 gboolean do_loop;
586 GSList *merges, *ptr;
588 if (sheet_range_trim (sheet, &src, TRUE, TRUE))
589 return; /* Region totally empty */
591 /* trim is a bit overzealous, it forgets about merges */
592 do {
593 do_loop = FALSE;
594 merges = gnm_sheet_merge_get_overlap (sheet, &src);
595 for (ptr = merges ; ptr != NULL ; ptr = ptr->next) {
596 GnmRange const *r = ptr->data;
597 if (src.end.col < r->end.col) {
598 src.end.col = r->end.col;
599 do_loop = TRUE;
601 if (src.end.row < r->end.row) {
602 src.end.row = r->end.row;
603 do_loop = TRUE;
606 } while (do_loop);
608 /* Make it autofill in only one direction */
609 if ((total->end.col - src.end.col) >=
610 (total->end.row - src.end.row))
611 src.end.row = total->end.row;
612 else
613 src.end.col = total->end.col;
615 cmd_autofill (wbc, sheet, FALSE,
616 total->start.col, total->start.row,
617 src.end.col - total->start.col + 1,
618 src.end.row - total->start.row + 1,
619 total->end.col, total->end.row,
620 FALSE);
624 static GNM_ACTION_DEF (cb_edit_fill_series)
626 dialog_fill_series (wbcg);
629 static GNM_ACTION_DEF (cb_edit_goto_top)
631 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_top);
633 static GNM_ACTION_DEF (cb_edit_goto_bottom)
635 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_bottom);
637 static GNM_ACTION_DEF (cb_edit_goto_first)
639 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_first);
641 static GNM_ACTION_DEF (cb_edit_goto_last)
643 wb_control_navigate_to_cell (GNM_WBC (wbcg), navigator_last);
645 static GNM_ACTION_DEF (cb_edit_goto)
647 dialog_goto_cell (wbcg);
649 static GNM_ACTION_DEF (cb_edit_goto_cell_indicator)
651 if (GNM_IS_WBC_GTK (wbcg))
652 wbcg_focus_current_cell_indicator (WBC_GTK (wbcg));
655 static GNM_ACTION_DEF (cb_edit_recalc)
657 /* TODO:
658 * f9 - do any necessary calculations across all sheets
659 * shift-f9 - do any necessary calcs on current sheet only
660 * ctrl-alt-f9 - force a full recalc across all sheets
661 * ctrl-alt-shift-f9 - a full-monty super recalc
663 workbook_recalc_all (wb_control_get_workbook (GNM_WBC (wbcg)));
666 static GNM_ACTION_DEF (cb_repeat) { command_repeat (GNM_WBC (wbcg)); }
668 /****************************************************************************/
670 static GNM_ACTION_DEF (cb_direction)
672 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
673 cmd_toggle_rtl (GNM_WBC (wbcg), sheet);
676 static GNM_ACTION_DEF (cb_view_zoom_in)
678 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
679 int zoom = (int)(sheet->last_zoom_factor_used * 100. + .5) - 10;
680 if ((zoom % 15) != 0)
681 zoom = 15 * (int)(zoom/15);
682 zoom += 15;
683 if (zoom <= 390)
684 cmd_zoom (GNM_WBC (wbcg), g_slist_append (NULL, sheet),
685 (double) (zoom + 10) / 100);
687 static GNM_ACTION_DEF (cb_view_zoom_out)
689 Sheet *sheet = wb_control_cur_sheet (GNM_WBC (wbcg));
690 int zoom = (int)(sheet->last_zoom_factor_used * 100. + .5) - 10;
691 if ((zoom % 15) != 0)
692 zoom = 15 * (int)(zoom/15);
693 else
694 zoom -= 15;
695 if (0 <= zoom)
696 cmd_zoom (GNM_WBC (wbcg), g_slist_append (NULL, sheet),
697 (double) (zoom + 10) / 100);
700 static GNM_ACTION_DEF (cb_view_fullscreen)
702 if (wbcg->is_fullscreen)
703 gtk_window_unfullscreen (wbcg_toplevel (wbcg));
704 else
705 gtk_window_fullscreen (wbcg_toplevel (wbcg));
708 static GNM_ACTION_DEF (cb_view_zoom) { dialog_zoom (wbcg, wbcg_cur_sheet (wbcg)); }
709 static GNM_ACTION_DEF (cb_view_new) { dialog_new_view (wbcg); }
710 static GNM_ACTION_DEF (cb_view_freeze_panes)
712 WorkbookControl *wbc = GNM_WBC (wbcg);
713 SheetView *sv = wb_control_cur_sheet_view (wbc);
714 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
716 scg_mode_edit (scg);
717 if (scg->active_panes == 1) {
718 gboolean center = FALSE;
719 GnmPane const *pane = scg_pane (scg, 0);
720 GnmCellPos frozen_tl, unfrozen_tl;
722 frozen_tl = pane->first;
723 unfrozen_tl = sv->edit_pos;
725 if (unfrozen_tl.row == 0 && unfrozen_tl.col == 0) {
726 GnmRange const *first = selection_first_range (sv, NULL, NULL);
727 Sheet *sheet = sv_sheet (sv);
728 gboolean full_rows = range_is_full (first, sheet, TRUE);
729 gboolean full_cols = range_is_full (first, sheet, FALSE);
730 if (!full_rows || !full_cols) {
731 if (!full_rows && !full_cols) {
732 unfrozen_tl.row = first->end.row + 1;
733 unfrozen_tl.col = first->end.col + 1;
734 } else if (full_rows) {
735 unfrozen_tl.row = first->end.row + 1;
736 unfrozen_tl.col = 0;
737 } else {
738 unfrozen_tl.row = 0;
739 unfrozen_tl.col = first->end.col + 1;
744 /* If edit pos is out of visible range */
745 if (unfrozen_tl.col < pane->first.col ||
746 unfrozen_tl.col > pane->last_visible.col ||
747 unfrozen_tl.row < pane->first.row ||
748 unfrozen_tl.row > pane->last_visible.row)
749 center = TRUE;
751 if (unfrozen_tl.col == pane->first.col) {
752 /* or edit pos is in top left visible cell */
753 if (unfrozen_tl.row == pane->first.row)
754 center = TRUE;
755 else
756 unfrozen_tl.col = frozen_tl.col = 0;
757 } else if (unfrozen_tl.row == pane->first.row)
758 unfrozen_tl.row = frozen_tl.row = 0;
760 if (center) {
761 unfrozen_tl.col = (pane->first.col +
762 pane->last_visible.col) / 2;
763 unfrozen_tl.row = (pane->first.row +
764 pane->last_visible.row) / 2;
767 g_return_if_fail (unfrozen_tl.col > frozen_tl.col ||
768 unfrozen_tl.row > frozen_tl.row);
770 gnm_sheet_view_freeze_panes (sv, &frozen_tl, &unfrozen_tl);
771 } else
772 gnm_sheet_view_freeze_panes (sv, NULL, NULL);
775 /****************************************************************************/
777 static void
778 insert_date_time_common (WBCGtk *wbcg, gboolean do_date, gboolean do_time)
780 if (wbcg_edit_start (wbcg, FALSE, FALSE)) {
781 WorkbookControl *wbc = GNM_WBC (wbcg);
782 SheetView *sv = wb_control_cur_sheet_view (wbc);
783 Sheet *sheet = sv_sheet (sv);
784 GnmCell const *cell = sheet_cell_fetch (sheet,
785 sv->edit_pos.col,
786 sv->edit_pos.row);
787 GODateConventions const *date_conv = sheet_date_conv (sheet);
788 GnmValue *v = value_new_float
789 (go_date_timet_to_serial_raw (time (NULL), date_conv));
790 char *txt;
791 char *dtxt = NULL;
792 char *ttxt = NULL;
794 if (do_date) {
795 GOFormat *fmt = gnm_format_for_date_editing (cell);
796 dtxt = format_value (fmt, v, -1, date_conv);
797 go_format_unref (fmt);
800 if (do_time) {
801 GOFormat const *fmt = go_format_default_time ();
802 ttxt = format_value (fmt, v, -1, date_conv);
805 if (do_date && do_time) {
806 txt = g_strconcat (dtxt, " ", ttxt, NULL);
807 g_free (dtxt);
808 g_free (ttxt);
809 } else if (do_date)
810 txt = dtxt;
811 else
812 txt = ttxt;
814 wb_control_edit_line_set (wbc, txt);
816 value_release (v);
817 g_free (txt);
823 static GNM_ACTION_DEF (cb_insert_current_date_time)
825 insert_date_time_common (wbcg, TRUE, TRUE);
827 static GNM_ACTION_DEF (cb_insert_current_date)
829 insert_date_time_common (wbcg, TRUE, FALSE);
832 static GNM_ACTION_DEF (cb_insert_current_time)
834 insert_date_time_common (wbcg, FALSE, TRUE);
837 static GNM_ACTION_DEF (cb_define_name)
839 dialog_define_names (wbcg);
841 static GNM_ACTION_DEF (cb_paste_names)
843 dialog_paste_names (wbcg);
846 static GNM_ACTION_DEF (cb_insert_rows)
848 WorkbookControl *wbc = GNM_WBC (wbcg);
849 Sheet *sheet = wb_control_cur_sheet (wbc);
850 SheetView *sv = wb_control_cur_sheet_view (wbc);
851 GnmRange const *sel;
853 /* TODO : No need to check simplicty. XL applies for each non-discrete
854 * selected region, (use selection_apply). Arrays and Merged regions
855 * are permitted.
857 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Insert rows"))))
858 return;
859 cmd_insert_rows (wbc, sheet, sel->start.row, range_height (sel));
862 static GNM_ACTION_DEF (cb_insert_cols)
864 WorkbookControl *wbc = GNM_WBC (wbcg);
865 Sheet *sheet = wb_control_cur_sheet (wbc);
866 SheetView *sv = wb_control_cur_sheet_view (wbc);
867 GnmRange const *sel;
869 /* TODO : No need to check simplicty. XL applies for each non-discrete
870 * selected region, (use selection_apply). Arrays and Merged regions
871 * are permitted.
873 if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc),
874 _("Insert columns"))))
875 return;
876 cmd_insert_cols (wbc, sheet, sel->start.col, range_width (sel));
879 static GNM_ACTION_DEF (cb_insert_cells) { dialog_insert_cells (wbcg); }
881 static GNM_ACTION_DEF (cb_insert_comment)
883 WorkbookControl *wbc = GNM_WBC (wbcg);
884 Sheet *sheet = wb_control_cur_sheet (wbc);
885 SheetView *sv = wb_control_cur_sheet_view (wbc);
886 dialog_cell_comment (wbcg, sheet, &sv->edit_pos);
889 /****************************************************************************/
891 static GNM_ACTION_DEF (cb_sheet_name)
893 WorkbookControl *wbc = GNM_WBC (wbcg);
894 Sheet *sheet = wb_control_cur_sheet (wbc);
895 dialog_sheet_rename (wbcg, sheet);
898 static GNM_ACTION_DEF (cb_sheet_order) { dialog_sheet_order (wbcg); }
899 static GNM_ACTION_DEF (cb_sheet_resize) { dialog_sheet_resize (wbcg); }
900 static GNM_ACTION_DEF (cb_format_cells) { dialog_cell_format (wbcg, FD_CURRENT, 0); }
901 static GNM_ACTION_DEF (cb_format_cells_cond) { dialog_cell_format_cond (wbcg); }
902 static GNM_ACTION_DEF (cb_autoformat) { dialog_autoformat (wbcg); }
903 static GNM_ACTION_DEF (cb_workbook_attr) { dialog_workbook_attr (wbcg); }
904 static GNM_ACTION_DEF (cb_tools_plugins) { dialog_plugin_manager (wbcg); }
905 static GNM_ACTION_DEF (cb_tools_autocorrect) { dialog_preferences (wbcg, "Auto Correct"); }
906 static GNM_ACTION_DEF (cb_tools_auto_save) { dialog_autosave (wbcg); }
907 static GNM_ACTION_DEF (cb_tools_goal_seek) { dialog_goal_seek (wbcg, wbcg_cur_sheet (wbcg)); }
908 static GNM_ACTION_DEF (cb_tools_tabulate) { dialog_tabulate (wbcg, wbcg_cur_sheet (wbcg)); }
909 static GNM_ACTION_DEF (cb_tools_merge) { dialog_merge (wbcg); }
911 static GNM_ACTION_DEF (cb_tools_solver) { dialog_solver (wbcg, wbcg_cur_sheet (wbcg)); }
913 static GNM_ACTION_DEF (cb_tools_scenario_add) { dialog_scenario_add (wbcg); }
914 static GNM_ACTION_DEF (cb_tools_scenarios) { dialog_scenarios (wbcg); }
915 static GNM_ACTION_DEF (cb_tools_simulation) { dialog_simulation (wbcg, wbcg_cur_sheet (wbcg)); }
916 static GNM_ACTION_DEF (cb_tools_compare) { dialog_sheet_compare (wbcg); }
917 static GNM_ACTION_DEF (cb_tools_anova_one_factor) { dialog_anova_single_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
918 static GNM_ACTION_DEF (cb_tools_anova_two_factor) { dialog_anova_two_factor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
919 static GNM_ACTION_DEF (cb_tools_chi_square_independence) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), TRUE); }
920 static GNM_ACTION_DEF (cb_tools_chi_square_homogeneity) { dialog_chi_square_tool (wbcg, wbcg_cur_sheet (wbcg), FALSE); }
921 static GNM_ACTION_DEF (cb_tools_correlation) { dialog_correlation_tool (wbcg, wbcg_cur_sheet (wbcg)); }
922 static GNM_ACTION_DEF (cb_tools_covariance) { dialog_covariance_tool (wbcg, wbcg_cur_sheet (wbcg)); }
923 static GNM_ACTION_DEF (cb_tools_desc_statistics) { dialog_descriptive_stat_tool (wbcg, wbcg_cur_sheet (wbcg)); }
924 static GNM_ACTION_DEF (cb_tools_exp_smoothing) { dialog_exp_smoothing_tool (wbcg, wbcg_cur_sheet (wbcg)); }
925 static GNM_ACTION_DEF (cb_tools_average) { dialog_average_tool (wbcg, wbcg_cur_sheet (wbcg)); }
926 static GNM_ACTION_DEF (cb_tools_fourier) { dialog_fourier_tool (wbcg, wbcg_cur_sheet (wbcg)); }
927 static GNM_ACTION_DEF (cb_tools_frequency) { dialog_frequency_tool (wbcg, wbcg_cur_sheet (wbcg)); }
928 static GNM_ACTION_DEF (cb_tools_histogram) { dialog_histogram_tool (wbcg, wbcg_cur_sheet (wbcg)); }
929 static GNM_ACTION_DEF (cb_tools_kaplan_meier) { dialog_kaplan_meier_tool (wbcg, wbcg_cur_sheet (wbcg)); }
930 static GNM_ACTION_DEF (cb_tools_normality_tests){ dialog_normality_tool (wbcg, wbcg_cur_sheet (wbcg)); }
931 static GNM_ACTION_DEF (cb_tools_one_mean_test) { dialog_one_mean_test_tool (wbcg, wbcg_cur_sheet (wbcg)); }
932 static GNM_ACTION_DEF (cb_tools_principal_components) { dialog_principal_components_tool (wbcg, wbcg_cur_sheet (wbcg)); }
933 static GNM_ACTION_DEF (cb_tools_ranking) { dialog_ranking_tool (wbcg, wbcg_cur_sheet (wbcg)); }
934 static GNM_ACTION_DEF (cb_tools_regression) { dialog_regression_tool (wbcg, wbcg_cur_sheet (wbcg)); }
935 static GNM_ACTION_DEF (cb_tools_sampling) { dialog_sampling_tool (wbcg, wbcg_cur_sheet (wbcg)); }
936 static GNM_ACTION_DEF (cb_tools_sign_test_one_median) { dialog_sign_test_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST); }
937 static GNM_ACTION_DEF (cb_tools_sign_test_two_medians) { dialog_sign_test_two_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST); }
938 static GNM_ACTION_DEF (cb_tools_wilcoxon_signed_rank_one_median) { dialog_sign_test_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST_WILCOXON); }
939 static GNM_ACTION_DEF (cb_tools_wilcoxon_signed_rank_two_medians) { dialog_sign_test_two_tool (wbcg, wbcg_cur_sheet (wbcg), SIGNTEST_WILCOXON); }
940 static GNM_ACTION_DEF (cb_tools_wilcoxon_mann_whitney) { dialog_wilcoxon_m_w_tool (wbcg, wbcg_cur_sheet (wbcg)); }
941 static GNM_ACTION_DEF (cb_tools_ttest_paired) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_PAIRED); }
942 static GNM_ACTION_DEF (cb_tools_ttest_equal_var) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_UNPAIRED_EQUALVARIANCES); }
943 static GNM_ACTION_DEF (cb_tools_ttest_unequal_var) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_UNPAIRED_UNEQUALVARIANCES); }
944 static GNM_ACTION_DEF (cb_tools_ztest) { dialog_ttest_tool (wbcg, wbcg_cur_sheet (wbcg), TTEST_ZTEST); }
945 static GNM_ACTION_DEF (cb_tools_ftest) { dialog_ftest_tool (wbcg, wbcg_cur_sheet (wbcg)); }
946 static GNM_ACTION_DEF (cb_tools_random_generator_uncorrelated) { dialog_random_tool (wbcg, wbcg_cur_sheet (wbcg)); }
947 static GNM_ACTION_DEF (cb_tools_random_generator_correlated) { dialog_random_cor_tool (wbcg, wbcg_cur_sheet (wbcg)); }
948 static GNM_ACTION_DEF (cb_data_sort) { dialog_cell_sort (wbcg); }
949 static GNM_ACTION_DEF (cb_data_shuffle) { dialog_shuffle (wbcg); }
950 static GNM_ACTION_DEF (cb_data_import_text) { gui_file_open
951 (wbcg, GNM_FILE_OPEN_STYLE_IMPORT, "Gnumeric_stf:stf_assistant"); }
952 static GNM_ACTION_DEF (cb_data_import_other) { gui_file_open
953 (wbcg, GNM_FILE_OPEN_STYLE_IMPORT, NULL); }
955 static GNM_ACTION_DEF (cb_auto_filter) { cmd_autofilter_add_remove (GNM_WBC (wbcg)); }
956 static GNM_ACTION_DEF (cb_show_all) { filter_show_all (GNM_WBC (wbcg)); }
957 static GNM_ACTION_DEF (cb_data_filter) { dialog_advanced_filter (wbcg); }
958 static GNM_ACTION_DEF (cb_data_validate) { dialog_cell_format (wbcg, FD_VALIDATION,
959 (1 << FD_VALIDATION) | (1 << FD_INPUT_MSG)); }
960 static GNM_ACTION_DEF (cb_data_text_to_columns) { stf_text_to_columns (GNM_WBC (wbcg), GO_CMD_CONTEXT (wbcg)); }
961 static GNM_ACTION_DEF (cb_data_consolidate) { dialog_consolidate (wbcg); }
962 static GNM_ACTION_DEF (cb_data_table) { dialog_data_table (wbcg); }
963 static GNM_ACTION_DEF (cb_data_slicer_create) { dialog_data_slicer (wbcg, TRUE); }
964 static GNM_ACTION_DEF (cb_data_slicer_refresh) { cmd_slicer_refresh (GNM_WBC (wbcg)); }
965 static GNM_ACTION_DEF (cb_data_slicer_edit) { dialog_data_slicer (wbcg, FALSE); }
966 static GNM_ACTION_DEF (cb_data_export) { gui_file_save_as
967 (wbcg, wb_control_view (GNM_WBC (wbcg)),
968 GNM_FILE_SAVE_AS_STYLE_EXPORT, NULL); }
969 static GNM_ACTION_DEF (cb_data_export_text) { gui_file_save_as
970 (wbcg, wb_control_view (GNM_WBC (wbcg)),
971 GNM_FILE_SAVE_AS_STYLE_EXPORT, "Gnumeric_stf:stf_assistant"); }
972 static GNM_ACTION_DEF (cb_data_export_csv) { gui_file_save_as
973 (wbcg, wb_control_view (GNM_WBC (wbcg)),
974 GNM_FILE_SAVE_AS_STYLE_EXPORT, "Gnumeric_stf:stf_csv"); }
975 static GNM_ACTION_DEF (cb_data_export_repeat) { gui_file_export_repeat (wbcg); }
977 static void
978 hide_show_detail_real (WBCGtk *wbcg, gboolean is_cols, gboolean show)
980 WorkbookControl *wbc = GNM_WBC (wbcg);
981 SheetView *sv = wb_control_cur_sheet_view (wbc);
982 char const *operation = show ? _("Show Detail") : _("Hide Detail");
983 GnmRange const *r = selection_first_range (sv, GO_CMD_CONTEXT (wbc),
984 operation);
986 /* This operation can only be performed on a whole existing group */
987 if (sheet_colrow_can_group (sv_sheet (sv), r, is_cols)) {
988 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbc), operation,
989 _("can only be performed on an existing group"));
990 return;
993 cmd_selection_colrow_hide (wbc, is_cols, show);
996 static void
997 hide_show_detail (WBCGtk *wbcg, gboolean show)
999 WorkbookControl *wbc = GNM_WBC (wbcg);
1000 SheetView *sv = wb_control_cur_sheet_view (wbc);
1001 Sheet const *sheet = sv_sheet (sv);
1002 char const *operation = show ? _("Show Detail") : _("Hide Detail");
1003 GnmRange const *r = selection_first_range (sv,
1004 GO_CMD_CONTEXT (wbc), operation);
1005 gboolean is_cols;
1007 /* We only operate on a single selection */
1008 if (r == NULL)
1009 return;
1011 /* Do we need to ask the user what he/she wants to group/ungroup? */
1012 if (range_is_full (r, sheet, TRUE) ^ range_is_full (r, sheet, FALSE))
1013 is_cols = !range_is_full (r, sheet, TRUE);
1014 else {
1015 dialog_col_row (wbcg, operation,
1016 (ColRowCallback_t) hide_show_detail_real,
1017 GINT_TO_POINTER (show));
1018 return;
1021 hide_show_detail_real (wbcg, is_cols, show);
1024 static void
1025 group_ungroup_colrow (WBCGtk *wbcg, gboolean group)
1027 WorkbookControl *wbc = GNM_WBC (wbcg);
1028 SheetView *sv = wb_control_cur_sheet_view (wbc);
1029 Sheet const *sheet = sv_sheet (sv);
1030 char const *operation = group ? _("Group") : _("Ungroup");
1031 GnmRange const *r = selection_first_range (sv,
1032 GO_CMD_CONTEXT (wbc), operation);
1033 gboolean is_cols;
1035 /* We only operate on a single selection */
1036 if (r == NULL)
1037 return;
1039 /* Do we need to ask the user what he/she wants to group/ungroup? */
1040 if (range_is_full (r, sheet, TRUE) ^ range_is_full (r, sheet, FALSE))
1041 is_cols = !range_is_full (r, sheet, TRUE);
1042 else {
1043 dialog_col_row (wbcg, operation,
1044 (ColRowCallback_t) cmd_selection_group,
1045 GINT_TO_POINTER (group));
1046 return;
1049 cmd_selection_group (wbc, is_cols, group);
1052 static GNM_ACTION_DEF (cb_data_hide_detail) { hide_show_detail (wbcg, FALSE); }
1053 static GNM_ACTION_DEF (cb_data_show_detail) { hide_show_detail (wbcg, TRUE); }
1054 static GNM_ACTION_DEF (cb_data_group) { group_ungroup_colrow (wbcg, TRUE); }
1055 static GNM_ACTION_DEF (cb_data_ungroup) { group_ungroup_colrow (wbcg, FALSE); }
1057 static GNM_ACTION_DEF (cb_help_function) { dialog_function_select_help (wbcg); }
1058 static GNM_ACTION_DEF (cb_help_docs)
1060 char *argv[] = { NULL, NULL, NULL };
1061 GError *err = NULL;
1063 #ifndef G_OS_WIN32
1064 argv[0] = (char *)"yelp";
1065 argv[1] = (char *)"help:gnumeric";
1066 g_spawn_async (NULL, argv, NULL,
1067 G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL
1068 | G_SPAWN_STDERR_TO_DEV_NULL,
1069 NULL, NULL, NULL, &err);
1070 #else
1071 /* TODO : Should really start in same directory as the gspawn-* helpers
1072 * are installed in case they are not in the path */
1073 argv[0] = (char *)"hh";
1074 argv[1] = g_build_filename (gnm_sys_data_dir (), "doc", "C",
1075 "gnumeric.chm", NULL);
1076 g_spawn_async (NULL, argv, NULL,
1077 G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL
1078 | G_SPAWN_STDERR_TO_DEV_NULL,
1079 NULL, NULL, NULL, &err);
1080 g_free (argv[1]);
1081 #endif
1082 if (NULL != err) {
1083 GOErrorInfo *ei = go_error_info_new_printf
1084 (_("Unable to start the help browser (%s).\n"
1085 "The system error message is: \n\n%s"),
1086 argv[0], err->message);
1087 go_cmd_context_error_info (GO_CMD_CONTEXT (wbcg), ei);
1088 g_error_free (err);
1089 g_free (ei);
1093 static void
1094 show_url (WBCGtk *wbcg, const char *url)
1096 GError *err;
1097 GdkScreen *screen;
1099 screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
1100 err = go_gtk_url_show (url, screen);
1101 if (err != NULL) {
1102 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), err);
1103 g_error_free (err);
1108 static GNM_ACTION_DEF (cb_help_web)
1110 show_url (wbcg, "http://www.gnumeric.org/");
1113 static GNM_ACTION_DEF (cb_help_irc)
1115 show_url (wbcg, "irc://irc.gnome.org/gnumeric");
1118 static GNM_ACTION_DEF (cb_help_bug)
1120 show_url (wbcg, "http://bugzilla.gnome.org/enter_bug.cgi?product=Gnumeric");
1123 static GNM_ACTION_DEF (cb_help_about) { dialog_about (wbcg); }
1125 static GNM_ACTION_DEF (cb_autosum)
1127 GtkEntry *entry;
1128 gchar const *txt;
1130 if (wbcg_is_editing (wbcg))
1131 return;
1133 entry = wbcg_get_entry (wbcg);
1134 txt = gtk_entry_get_text (entry);
1135 if (strncmp (txt, "=sum(", 5)) {
1136 if (!wbcg_edit_start (wbcg, TRUE, TRUE))
1137 return; /* attempt to edit failed */
1138 gtk_entry_set_text (entry, "=sum()");
1139 gtk_editable_set_position (GTK_EDITABLE (entry), 5);
1140 } else {
1141 if (!wbcg_edit_start (wbcg, FALSE, TRUE))
1142 return; /* attempt to edit failed */
1145 * FIXME : This is crap!
1146 * When the function druid is more complete use that.
1148 gtk_editable_set_position (GTK_EDITABLE (entry),
1149 gtk_entry_get_text_length (entry)-1);
1153 static GNM_ACTION_DEF (cb_insert_image)
1155 char *uri = go_gtk_select_image (wbcg_toplevel (wbcg), NULL);
1157 if (uri) {
1158 GError *err = NULL;
1159 GsfInput *input = go_file_open (uri, &err);
1161 if (input != NULL) {
1162 unsigned len = gsf_input_size (input);
1163 guint8 const *data = gsf_input_read (input, len, NULL);
1164 SheetObjectImage *soi = g_object_new (GNM_SO_IMAGE_TYPE, NULL);
1165 sheet_object_image_set_image (soi, "", data, len);
1166 wbcg_insert_object (wbcg, GNM_SO (soi));
1167 g_object_unref (input);
1168 } else
1169 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), err);
1171 g_free (uri);
1175 static GNM_ACTION_DEF (cb_insert_hyperlink) { dialog_hyperlink (wbcg, GNM_SHEET_CONTROL (wbcg_cur_scg (wbcg))); }
1176 static GNM_ACTION_DEF (cb_formula_guru) { dialog_formula_guru (wbcg, NULL); }
1177 static GNM_ACTION_DEF (cb_insert_sort_ascending) { workbook_cmd_wrap_sort (GNM_WBC (wbcg), 1);}
1178 static GNM_ACTION_DEF (cb_insert_sort_descending){ workbook_cmd_wrap_sort (GNM_WBC (wbcg), 0);}
1180 static void
1181 sort_by_rows (WBCGtk *wbcg, gboolean descending)
1183 SheetView *sv;
1184 GnmRange *sel;
1185 GnmRange tmp_ns ={{0,0},{0,0}}, tmp_s ={{0,0},{0,0}};
1186 GnmSortData *data;
1187 GnmSortClause *clause;
1188 int numclause, i;
1189 GSList *l;
1190 int cnt_singletons = 0, cnt_non_singletons = 0;
1191 gboolean top_to_bottom = TRUE;
1192 gboolean not_acceptable = FALSE;
1194 g_return_if_fail (GNM_IS_WBC_GTK (wbcg));
1196 sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
1197 for (l = sv->selections; l != NULL; l = l->next) {
1198 GnmRange const *r = l->data;
1199 if (range_is_singleton (r)) {
1200 cnt_singletons++;
1201 tmp_s = *r;
1202 } else {
1203 cnt_non_singletons++;
1204 tmp_ns = *r;
1208 not_acceptable = (cnt_non_singletons > 1 ||
1209 (cnt_non_singletons == 0 && cnt_singletons > 1));
1211 if (!not_acceptable && cnt_singletons > 0 && cnt_non_singletons == 1) {
1212 gboolean first = TRUE;
1213 for (l = sv->selections; l != NULL; l = l->next) {
1214 GnmRange const *r = l->data;
1215 gboolean t_b = FALSE, l_r = FALSE;
1217 if (!range_is_singleton (r))
1218 continue;
1219 t_b = r->start.col >= tmp_ns.start.col &&
1220 r->end.col <= tmp_ns.end.col;
1221 l_r = r->start.row >= tmp_ns.start.row &&
1222 r->end.row <= tmp_ns.end.row;
1223 if (!t_b && !l_r) {
1224 not_acceptable = TRUE;
1225 break;
1227 if (!t_b || !l_r) {
1228 if (first) {
1229 first = FALSE;
1230 top_to_bottom = t_b;
1231 } else {
1232 if ((top_to_bottom && !t_b) ||
1233 (!top_to_bottom && !l_r)) {
1234 not_acceptable = TRUE;
1235 break;
1242 if (not_acceptable) {
1243 GError *msg = g_error_new (go_error_invalid(), 0,
1244 _("%s does not support multiple ranges"),
1245 _("Sort"));
1246 go_cmd_context_error (GO_CMD_CONTEXT (wbcg), msg);
1247 g_error_free (msg);
1248 return;
1251 if (cnt_singletons == 1 && cnt_non_singletons == 0) {
1252 Sheet *sheet = sv_sheet (sv);
1254 sel = g_new0 (GnmRange, 1);
1255 range_init_full_sheet (sel, sheet);
1256 sel->start.row = tmp_s.start.row;
1257 range_clip_to_finite (sel, sheet);
1258 numclause = 1;
1259 clause = g_new0 (GnmSortClause, 1);
1260 clause[0].offset = tmp_s.start.col - sel->start.col;
1261 clause[0].asc = descending;
1262 clause[0].cs = gnm_conf_get_core_sort_default_by_case ();
1263 clause[0].val = TRUE;
1264 } else if (cnt_singletons == 0) {
1265 sel = gnm_range_dup (&tmp_ns);
1266 range_clip_to_finite (sel, sv_sheet (sv));
1268 numclause = range_width (sel);
1269 clause = g_new0 (GnmSortClause, numclause);
1270 for (i = 0; i < numclause; i++) {
1271 clause[i].offset = i;
1272 clause[i].asc = descending;
1273 clause[i].cs = gnm_conf_get_core_sort_default_by_case ();
1274 clause[i].val = TRUE;
1276 } else /* cnt_singletons > 0 && cnt_non_singletons == 1*/ {
1277 sel = gnm_range_dup (&tmp_ns);
1278 range_clip_to_finite (sel, sv_sheet (sv));
1279 numclause = cnt_singletons;
1280 clause = g_new0 (GnmSortClause, numclause);
1281 i = numclause - 1;
1282 for (l = sv->selections; l != NULL; l = l->next) {
1283 GnmRange const *r = l->data;
1284 if (!range_is_singleton (r))
1285 continue;
1286 if (i >= 0) {
1287 clause[i].offset = (top_to_bottom) ?
1288 r->start.col - sel->start.col
1289 : r->start.row - sel->start.row;
1290 clause[i].asc = descending;
1291 clause[i].cs = gnm_conf_get_core_sort_default_by_case ();
1292 clause[i].val = TRUE;
1294 i--;
1298 data = g_new (GnmSortData, 1);
1299 data->sheet = sv_sheet (sv);
1300 data->range = sel;
1301 data->num_clause = numclause;
1302 data->clauses = clause;
1303 data->locale = NULL;
1305 data->retain_formats = gnm_conf_get_core_sort_default_retain_formats ();
1307 /* Hard code sorting by row. I would prefer not to, but user testing
1308 * indicates
1309 * - that the button should always does the same things
1310 * - that the icon matches the behavior
1311 * - XL does this.
1314 /* Note that if the user specified rows by singleton selection we switch */
1315 /* to column sorting */
1316 data->top = top_to_bottom;
1318 if (sheet_range_has_heading (data->sheet, data->range, data->top, FALSE))
1319 data->range->start.row += 1;
1321 cmd_sort (GNM_WBC (wbcg), data);
1323 static GNM_ACTION_DEF (cb_sort_ascending) { sort_by_rows (wbcg, FALSE); }
1324 static GNM_ACTION_DEF (cb_sort_descending) { sort_by_rows (wbcg, TRUE); }
1326 static void
1327 cb_add_graph (GogGraph *graph, gpointer wbcg)
1329 GnmGraphDataClosure *data = (GnmGraphDataClosure *) g_object_get_data (G_OBJECT (graph), "data-closure");
1330 if (data) {
1331 if (data->new_sheet) {
1332 WorkbookControl *wbc = GNM_WBC (wbcg);
1333 Sheet *sheet = wb_control_cur_sheet (wbc);
1334 WorkbookSheetState *old_state = workbook_sheet_state_new (wb_control_get_workbook (wbc));
1335 Sheet *new_sheet = workbook_sheet_add_with_type (
1336 wb_control_get_workbook (wbc),
1337 GNM_SHEET_OBJECT, -1,
1338 gnm_sheet_get_max_cols (sheet),
1339 gnm_sheet_get_max_rows (sheet));
1340 SheetObject *sog = sheet_object_graph_new (graph);
1341 print_info_set_paper_orientation (new_sheet->print_info, GTK_PAGE_ORIENTATION_LANDSCAPE);
1342 sheet_object_set_sheet (sog, new_sheet);
1343 wb_view_sheet_focus (wb_control_view (wbc), new_sheet);
1344 cmd_reorganize_sheets (wbc, old_state, sheet);
1345 g_object_unref (sog);
1346 return;
1349 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_graph_new (graph));
1352 static GNM_ACTION_DEF (cb_launch_chart_guru)
1354 GClosure *closure = g_cclosure_new (G_CALLBACK (cb_add_graph),
1355 wbcg, NULL);
1356 sheet_object_graph_guru (wbcg, NULL, closure);
1357 g_closure_sink (closure);
1360 static void
1361 cb_add_component_new (GOComponent *component, gpointer wbcg)
1363 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
1366 static void
1367 component_changed_cb (GOComponent *component, gpointer data)
1369 cb_add_component_new (component, data);
1372 static GNM_ACTION_DEF (cb_launch_go_component_new)
1374 gchar const *mime_type;
1375 gint result;
1376 GtkWidget *dialog = go_component_mime_dialog_new ();
1377 result = gtk_dialog_run (GTK_DIALOG (dialog));
1378 if (result == GTK_RESPONSE_OK) {
1379 mime_type = go_component_mime_dialog_get_mime_type ((GOComponentMimeDialog *) dialog);
1380 if (mime_type) {
1381 GtkWindow *win;
1382 GOComponent *component = go_component_new_by_mime_type (mime_type);
1383 if (component) {
1384 g_signal_connect (G_OBJECT (component), "changed", G_CALLBACK (component_changed_cb), wbcg);
1385 win = go_component_edit (component);
1386 gtk_window_set_transient_for (win, GTK_WINDOW (wbcg_toplevel (wbcg)));
1387 g_object_set_data_full (G_OBJECT (win), "component", component, g_object_unref);
1391 gtk_widget_destroy (dialog);
1394 static GNM_ACTION_DEF (cb_launch_go_component_from_file)
1396 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Choose object file"),
1397 GTK_WINDOW (wbcg_toplevel (wbcg)),
1398 GTK_FILE_CHOOSER_ACTION_OPEN,
1399 GNM_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1400 GNM_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1401 NULL);
1402 go_components_add_filter (GTK_FILE_CHOOSER (dlg));
1403 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
1404 char *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg));
1405 GOComponent *component;
1406 component = go_component_new_from_uri (uri);
1407 g_free (uri);
1408 if (component) {
1409 wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
1410 g_object_unref (component);
1413 gtk_widget_destroy (dlg);
1416 static void
1417 create_object (WBCGtk *wbcg, GType t,
1418 char const *first_property_name,
1419 ...)
1421 va_list args;
1422 va_start (args, first_property_name);
1423 wbcg_insert_object (wbcg, (SheetObject *)
1424 g_object_new_valist (t, first_property_name, args));
1425 va_end (args);
1428 static GNM_ACTION_DEF (cmd_create_frame)
1429 { create_object (wbcg, sheet_widget_frame_get_type(), NULL); }
1430 static GNM_ACTION_DEF (cmd_create_button)
1431 { create_object (wbcg, sheet_widget_button_get_type(), NULL); }
1432 static GNM_ACTION_DEF (cmd_create_radiobutton)
1433 { create_object (wbcg, sheet_widget_radio_button_get_type(), NULL); }
1434 static GNM_ACTION_DEF (cmd_create_scrollbar)
1435 { create_object (wbcg, sheet_widget_scrollbar_get_type(), NULL); }
1436 static GNM_ACTION_DEF (cmd_create_slider)
1437 { create_object (wbcg, sheet_widget_slider_get_type(), NULL); }
1438 static GNM_ACTION_DEF (cmd_create_spinbutton)
1439 { create_object (wbcg, sheet_widget_spinbutton_get_type(), NULL); }
1440 static GNM_ACTION_DEF (cmd_create_checkbox)
1441 { create_object (wbcg, sheet_widget_checkbox_get_type(), NULL); }
1442 static GNM_ACTION_DEF (cmd_create_list)
1443 { create_object (wbcg, sheet_widget_list_get_type(), NULL); }
1444 static GNM_ACTION_DEF (cmd_create_combo)
1445 { create_object (wbcg, sheet_widget_combo_get_type(), NULL); }
1446 static GNM_ACTION_DEF (cmd_create_line)
1447 { create_object (wbcg, GNM_SO_LINE_TYPE, NULL); }
1448 static GNM_ACTION_DEF (cmd_create_arrow) {
1449 GOArrow arrow;
1450 go_arrow_init_kite (&arrow, 8., 10., 3.);
1451 create_object (wbcg, GNM_SO_LINE_TYPE, "end-arrow", &arrow, NULL);
1453 static GNM_ACTION_DEF (cmd_create_rectangle)
1454 { create_object (wbcg, GNM_SO_FILLED_TYPE, NULL); }
1455 static GNM_ACTION_DEF (cmd_create_ellipse)
1456 { create_object (wbcg, GNM_SO_FILLED_TYPE, "is-oval", TRUE, NULL); }
1458 /*****************************************************************************/
1459 static void
1460 wbcg_set_selection_halign (WBCGtk *wbcg, GnmHAlign halign)
1462 WorkbookControl *wbc = GNM_WBC (wbcg);
1463 WorkbookView *wb_view;
1464 GnmStyle *style;
1466 if (wbcg->updating_ui)
1467 return;
1469 /* This is a toggle button. If we are already enabled
1470 * then revert to general */
1471 wb_view = wb_control_view (wbc);
1472 if (gnm_style_get_align_h (wb_view->current_style) == halign)
1473 halign = GNM_HALIGN_GENERAL;
1475 style = gnm_style_new ();
1476 gnm_style_set_align_h (style, halign);
1477 cmd_selection_format (wbc, style, NULL, _("Set Horizontal Alignment"));
1479 static GNM_ACTION_DEF (cb_align_left)
1480 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_LEFT); }
1481 static GNM_ACTION_DEF (cb_align_right)
1482 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_RIGHT); }
1483 static GNM_ACTION_DEF (cb_align_center)
1484 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_CENTER); }
1485 static GNM_ACTION_DEF (cb_center_across_selection)
1486 { wbcg_set_selection_halign (wbcg, GNM_HALIGN_CENTER_ACROSS_SELECTION); }
1488 /*****************************************************************************/
1490 static void
1491 wbcg_set_selection_valign (WBCGtk *wbcg, GnmVAlign valign)
1493 WorkbookControl *wbc = GNM_WBC (wbcg);
1494 WorkbookView *wb_view;
1495 GnmStyle *style;
1497 if (wbcg->updating_ui)
1498 return;
1500 /* This is a toggle button. If we are already enabled
1501 * then revert to general */
1502 wb_view = wb_control_view (wbc);
1503 if (gnm_style_get_align_v (wb_view->current_style) == valign) {
1504 if (valign == GNM_VALIGN_BOTTOM)
1505 return;
1506 valign = GNM_VALIGN_BOTTOM;
1509 style = gnm_style_new ();
1510 gnm_style_set_align_v (style, valign);
1511 cmd_selection_format (wbc, style, NULL, _("Set Vertical Alignment"));
1513 static GNM_ACTION_DEF (cb_align_top)
1514 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_TOP); }
1515 static GNM_ACTION_DEF (cb_align_vcenter)
1516 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_CENTER); }
1517 static GNM_ACTION_DEF (cb_align_bottom)
1518 { wbcg_set_selection_valign (wbcg, GNM_VALIGN_BOTTOM); }
1520 /*****************************************************************************/
1522 static GNM_ACTION_DEF (cb_merge_and_center)
1524 WorkbookControl *wbc = GNM_WBC (wbcg);
1525 GSList *range_list = selection_get_ranges (
1526 wb_control_cur_sheet_view (wbc), FALSE);
1527 cmd_merge_cells (wbc, wb_control_cur_sheet (wbc), range_list, TRUE);
1528 range_fragment_free (range_list);
1531 static GNM_ACTION_DEF (cb_merge_cells)
1533 WorkbookControl *wbc = GNM_WBC (wbcg);
1534 GSList *range_list = selection_get_ranges (
1535 wb_control_cur_sheet_view (wbc), FALSE);
1536 cmd_merge_cells (wbc, wb_control_cur_sheet (wbc), range_list, FALSE);
1537 range_fragment_free (range_list);
1540 static GNM_ACTION_DEF (cb_unmerge_cells)
1542 WorkbookControl *wbc = GNM_WBC (wbcg);
1543 GSList *range_list = selection_get_ranges (
1544 wb_control_cur_sheet_view (wbc), FALSE);
1545 cmd_unmerge_cells (wbc, wb_control_cur_sheet (wbc), range_list);
1546 range_fragment_free (range_list);
1549 static GNM_ACTION_DEF (cb_view_statusbar)
1551 wbcg_toggle_visibility (wbcg, GTK_TOGGLE_ACTION (a));
1554 /*****************************************************************************/
1556 static void
1557 toggle_font_attr (WBCGtk *wbcg, GtkToggleAction *act,
1558 GnmStyleElement t, unsigned true_val, unsigned false_val)
1560 WorkbookControl *wbc = GNM_WBC (wbcg);
1561 GnmStyle *new_style;
1562 unsigned val;
1564 /* If the user did not initiate this action ignore it.
1565 * This happens whenever the ui updates and the current cell makes a
1566 * change to the toolbar indicators.
1568 if (wbcg->updating_ui)
1569 return;
1571 val = gtk_toggle_action_get_active (act) ? true_val : false_val;
1572 if (wbcg_is_editing (wbcg)) {
1573 PangoAttribute *attr = NULL;
1574 switch (t) {
1575 default:
1576 case MSTYLE_FONT_BOLD:
1577 attr = pango_attr_weight_new (val ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
1578 break;
1579 case MSTYLE_FONT_ITALIC:
1580 attr = pango_attr_style_new (val ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
1581 break;
1582 case MSTYLE_FONT_UNDERLINE:
1583 attr = pango_attr_underline_new
1584 (gnm_translate_underline_to_pango (val));
1585 break;
1586 case MSTYLE_FONT_STRIKETHROUGH:
1587 attr = pango_attr_strikethrough_new (val);
1588 break;
1589 case MSTYLE_FONT_SCRIPT:
1590 switch (val) {
1591 default:
1592 case GO_FONT_SCRIPT_STANDARD:
1593 wbcg_edit_add_markup
1594 (wbcg, go_pango_attr_superscript_new (FALSE));
1595 attr = go_pango_attr_subscript_new (FALSE);
1596 break;
1597 case GO_FONT_SCRIPT_SUPER:
1598 attr = go_pango_attr_superscript_new (TRUE);
1599 break;
1600 case GO_FONT_SCRIPT_SUB:
1601 attr = go_pango_attr_subscript_new (TRUE);
1602 break;
1604 break;
1606 wbcg_edit_add_markup (wbcg, attr);
1607 return;
1610 new_style = gnm_style_new ();
1611 switch (t) {
1612 default:
1613 case MSTYLE_FONT_BOLD: gnm_style_set_font_bold (new_style, val); break;
1614 case MSTYLE_FONT_ITALIC: gnm_style_set_font_italic (new_style, val); break;
1615 case MSTYLE_FONT_UNDERLINE: gnm_style_set_font_uline (new_style, val); break;
1616 case MSTYLE_FONT_STRIKETHROUGH: gnm_style_set_font_strike (new_style, val); break;
1617 case MSTYLE_FONT_SCRIPT: gnm_style_set_font_script (new_style, val); break;
1620 cmd_selection_format_toggle_font_style (wbc, new_style, t);
1623 static void cb_font_bold (GtkToggleAction *act, WBCGtk *wbcg)
1624 { toggle_font_attr (wbcg, act, MSTYLE_FONT_BOLD, TRUE, FALSE); }
1625 static void cb_font_italic (GtkToggleAction *act, WBCGtk *wbcg)
1626 { toggle_font_attr (wbcg, act, MSTYLE_FONT_ITALIC, TRUE, FALSE); }
1627 static void cb_font_underline (GtkToggleAction *act, WBCGtk *wbcg)
1628 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_SINGLE, UNDERLINE_NONE); }
1629 static void cb_font_double_underline (GtkToggleAction *act, WBCGtk *wbcg)
1630 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_DOUBLE, UNDERLINE_NONE); }
1631 static void cb_font_underline_low (GtkToggleAction *act, WBCGtk *wbcg)
1632 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_SINGLE_LOW, UNDERLINE_NONE); }
1633 static void cb_font_double_underline_low (GtkToggleAction *act, WBCGtk *wbcg)
1634 { toggle_font_attr (wbcg, act, MSTYLE_FONT_UNDERLINE, UNDERLINE_DOUBLE_LOW, UNDERLINE_NONE); }
1635 static void cb_font_strikethrough (GtkToggleAction *act, WBCGtk *wbcg)
1636 { toggle_font_attr (wbcg, act, MSTYLE_FONT_STRIKETHROUGH, TRUE, FALSE); }
1637 static void cb_font_subscript (GtkToggleAction *act, WBCGtk *wbcg)
1638 { toggle_font_attr (wbcg, act, MSTYLE_FONT_SCRIPT, GO_FONT_SCRIPT_SUB, GO_FONT_SCRIPT_STANDARD); }
1639 static void cb_font_superscript (GtkToggleAction *act, WBCGtk *wbcg)
1640 { toggle_font_attr (wbcg, act, MSTYLE_FONT_SCRIPT, GO_FONT_SCRIPT_SUPER, GO_FONT_SCRIPT_STANDARD); }
1642 static void
1643 apply_number_format (WBCGtk *wbcg,
1644 GOFormat *format,
1645 char const *descriptor)
1647 GnmStyle *mstyle = gnm_style_new ();
1648 gnm_style_set_format (mstyle, format);
1649 cmd_selection_format (GNM_WBC (wbcg), mstyle, NULL, descriptor);
1652 static GNM_ACTION_DEF (cb_format_as_general)
1654 apply_number_format (wbcg,
1655 go_format_general (),
1656 _("Format as General"));
1659 static GNM_ACTION_DEF (cb_format_as_number)
1661 GOFormat *fmt = go_format_new_from_XL ("0");
1662 apply_number_format (wbcg, fmt, _("Format as Number"));
1663 go_format_unref (fmt);
1666 static GNM_ACTION_DEF (cb_format_as_currency)
1668 GOFormatDetails *details = go_format_details_new (GO_FORMAT_CURRENCY);
1669 GString *str = g_string_new (NULL);
1670 GOFormat *fmt;
1672 details->currency = go_format_locale_currency ();
1673 details->num_decimals = 2;
1674 go_format_generate_str (str, details);
1675 go_format_details_free (details);
1677 fmt = go_format_new_from_XL (str->str);
1678 g_string_free (str, TRUE);
1679 apply_number_format (wbcg, fmt, _("Format as Currency"));
1680 go_format_unref (fmt);
1683 static GNM_ACTION_DEF (cb_format_as_accounting)
1685 apply_number_format (wbcg,
1686 go_format_default_accounting (),
1687 _("Format as Accounting"));
1690 static GNM_ACTION_DEF (cb_format_as_percentage)
1692 GOFormat *fmt = go_format_new_from_XL ("0%");
1693 apply_number_format (wbcg, fmt, _("Format as Percentage"));
1694 go_format_unref (fmt);
1697 static GNM_ACTION_DEF (cb_format_as_scientific)
1699 GOFormat *fmt = go_format_new_from_XL ("0.00E+00");
1700 apply_number_format (wbcg, fmt, _("Format as Percentage"));
1701 go_format_unref (fmt);
1704 static GNM_ACTION_DEF (cb_format_as_time)
1706 apply_number_format (wbcg,
1707 go_format_default_time (),
1708 _("Format as Time"));
1711 static GNM_ACTION_DEF (cb_format_as_date)
1713 apply_number_format (wbcg,
1714 go_format_default_date (),
1715 _("Format as Date"));
1718 /* Adds borders to all the selected regions on the sheet.
1719 * FIXME: This is a little more simplistic then it should be, it always
1720 * removes and/or overwrites any borders. What we should do is
1721 * 1) When adding -> don't add a border if the border is thicker than 'THIN'
1722 * 2) When removing -> don't remove unless the border is 'THIN'
1724 static void
1725 mutate_borders (WBCGtk *wbcg, gboolean add)
1727 GnmBorder *borders [GNM_STYLE_BORDER_EDGE_MAX];
1728 int i;
1730 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; ++i)
1731 if (i <= GNM_STYLE_BORDER_RIGHT)
1732 borders[i] = gnm_style_border_fetch (
1733 add ? GNM_STYLE_BORDER_THIN : GNM_STYLE_BORDER_NONE,
1734 style_color_black (), gnm_style_border_get_orientation (i));
1735 else
1736 borders[i] = NULL;
1738 cmd_selection_format (GNM_WBC (wbcg), NULL, borders,
1739 add ? _("Add Borders") : _("Remove borders"));
1742 static GNM_ACTION_DEF (cb_format_add_borders) { mutate_borders (wbcg, TRUE); }
1743 static GNM_ACTION_DEF (cb_format_clear_borders) { mutate_borders (wbcg, FALSE); }
1745 static void
1746 modify_format (WBCGtk *wbcg,
1747 GOFormat *(*format_modify_fn) (GOFormat const *format),
1748 char const *descriptor)
1750 WorkbookControl *wbc = GNM_WBC (wbcg);
1751 WorkbookView const *wbv;
1752 GOFormat *new_fmt;
1754 wbv = wb_control_view (wbc);
1755 g_return_if_fail (wbv != NULL);
1756 g_return_if_fail (wbv->current_style != NULL);
1758 new_fmt = (*format_modify_fn) (gnm_style_get_format (wbv->current_style));
1759 if (new_fmt != NULL) {
1760 GnmStyle *style = gnm_style_new ();
1761 gnm_style_set_format (style, new_fmt);
1762 cmd_selection_format (wbc, style, NULL, descriptor);
1763 go_format_unref (new_fmt);
1767 static GnmValue *
1768 cb_calc_decs (GnmCellIter const *iter, gpointer user)
1770 int *pdecs = user;
1771 int decs = 0;
1772 GnmCell *cell = iter->cell;
1773 char *text;
1774 const char *p;
1775 GString const *dec = go_locale_get_decimal ();
1777 if (!cell || !cell->value || !VALUE_IS_NUMBER (cell->value))
1778 return NULL;
1781 * If we are displaying an equation, we don't want to look into
1782 * the rendered text.
1784 if (gnm_cell_has_expr (cell) && cell->base.sheet->display_formulas)
1785 return NULL;
1787 text = gnm_cell_get_rendered_text (cell);
1788 p = strstr (text, dec->str);
1789 if (p) {
1790 p += dec->len;
1792 while (g_ascii_isdigit (*p))
1793 decs++, p++;
1796 *pdecs = MAX (*pdecs, decs);
1798 g_free (text);
1800 return NULL;
1803 static void
1804 inc_dec (WBCGtk *wbcg,
1805 int dir,
1806 GOFormat *(*format_modify_fn) (GOFormat const *format),
1807 char const *descriptor)
1809 WorkbookControl *wbc = GNM_WBC (wbcg);
1810 WorkbookView *wbv = wb_control_view (wbc);
1811 GOFormat const *fmt = gnm_style_get_format (wbv->current_style);
1812 SheetView *sv;
1813 GOFormat *new_fmt;
1814 GnmStyle *style;
1815 GSList *l;
1816 int decs = -2;
1817 GString *new_fmt_str;
1819 if (!go_format_is_general (fmt)) {
1820 modify_format (wbcg, format_modify_fn, descriptor);
1821 return;
1824 sv = wb_view_cur_sheet_view (wbv);
1825 if (!sv)
1826 return;
1828 for (l = sv->selections; l ; l = l->next) {
1829 GnmRange const *r = l->data;
1830 sheet_foreach_cell_in_range (sv_sheet (sv),
1831 CELL_ITER_IGNORE_BLANK |
1832 CELL_ITER_IGNORE_HIDDEN,
1833 r, cb_calc_decs, &decs);
1836 new_fmt_str = g_string_new ("0");
1837 if (decs + dir > 0) {
1838 g_string_append_c (new_fmt_str, '.');
1839 go_string_append_c_n (new_fmt_str, '0', decs + dir);
1841 new_fmt = go_format_new_from_XL (new_fmt_str->str);
1842 g_string_free (new_fmt_str, TRUE);
1844 style = gnm_style_new ();
1845 gnm_style_set_format (style, new_fmt);
1846 cmd_selection_format (wbc, style, NULL, descriptor);
1847 go_format_unref (new_fmt);
1850 static GNM_ACTION_DEF (cb_format_inc_precision)
1851 { inc_dec (wbcg, 1,
1852 &go_format_inc_precision, _("Increase precision")); }
1853 static GNM_ACTION_DEF (cb_format_dec_precision)
1854 { inc_dec (wbcg, -1,
1855 &go_format_dec_precision, _("Decrease precision")); }
1856 static GNM_ACTION_DEF (cb_format_with_thousands)
1857 { modify_format (wbcg, &go_format_toggle_1000sep, _("Toggle thousands separator")); }
1859 static GNM_ACTION_DEF (cb_format_dec_indent) { workbook_cmd_dec_indent (GNM_WBC (wbcg)); }
1860 static GNM_ACTION_DEF (cb_format_inc_indent) { workbook_cmd_inc_indent (GNM_WBC (wbcg)); }
1862 static GNM_ACTION_DEF (cb_copydown)
1864 WorkbookControl *wbc = GNM_WBC (wbcg);
1865 cmd_copyrel (wbc, 0, -1, _("Copy down"));
1868 static GNM_ACTION_DEF (cb_copyright)
1870 WorkbookControl *wbc = GNM_WBC (wbcg);
1871 /* xgettext: copy from the cell to the left into current cell --
1872 this has nothing whatsoever to do with copyright. */
1873 cmd_copyrel (wbc, -1, 0, _("Copy right"));
1876 static GNM_ACTION_DEF (cb_format_cells_auto_fit_height)
1878 WorkbookControl *wbc = GNM_WBC (wbcg);
1879 workbook_cmd_autofit_selection
1880 (wbc, wb_control_cur_sheet (wbc), FALSE);
1883 static GNM_ACTION_DEF (cb_format_cells_auto_fit_width)
1885 WorkbookControl *wbc = GNM_WBC (wbcg);
1886 workbook_cmd_autofit_selection
1887 (wbc, wb_control_cur_sheet (wbc), TRUE);
1890 static GNM_ACTION_DEF (cb_format_column_auto_fit)
1892 WorkbookControl *wbc = GNM_WBC (wbcg);
1893 workbook_cmd_resize_selected_colrow (wbc,
1894 wb_control_cur_sheet (wbc), TRUE, -1);
1896 static GNM_ACTION_DEF (cb_set_column_width)
1898 dialog_col_width (wbcg, FALSE);
1900 static GNM_ACTION_DEF (cb_format_column_std_width)
1902 dialog_col_width (wbcg, TRUE);
1904 static GNM_ACTION_DEF (cb_format_column_hide)
1906 cmd_selection_colrow_hide (GNM_WBC (wbcg), TRUE, FALSE);
1908 static GNM_ACTION_DEF (cb_format_column_unhide)
1910 cmd_selection_colrow_hide (GNM_WBC (wbcg), TRUE, TRUE);
1913 static GNM_ACTION_DEF (cb_format_row_auto_fit)
1915 WorkbookControl *wbc = GNM_WBC (wbcg);
1916 workbook_cmd_resize_selected_colrow (wbc,
1917 wb_control_cur_sheet (wbc), FALSE, -1);
1919 static GNM_ACTION_DEF (cb_set_row_height)
1921 dialog_row_height (wbcg, FALSE);
1923 static GNM_ACTION_DEF (cb_format_row_std_height)
1925 dialog_row_height (wbcg, TRUE);
1927 static GNM_ACTION_DEF (cb_format_row_hide)
1929 cmd_selection_colrow_hide (GNM_WBC (wbcg), FALSE, FALSE);
1931 static GNM_ACTION_DEF (cb_format_row_unhide)
1933 cmd_selection_colrow_hide (GNM_WBC (wbcg), FALSE, TRUE);
1936 static GNM_ACTION_DEF (cb_file_menu)
1938 wbc_gtk_load_templates (wbcg);
1941 static GNM_ACTION_DEF (cb_insert_menu)
1943 GtkAction *action = wbcg_find_action (wbcg, "MenuInsertObject");
1944 SheetControlGUI *scg = wbcg_cur_scg (wbcg);
1945 gtk_action_set_sensitive (action, go_components_get_mime_types () != NULL && scg && scg_sheet (scg)->sheet_type == GNM_SHEET_DATA);
1948 #define TOGGLE_HANDLER(flag,property) \
1949 static GNM_ACTION_DEF (cb_sheet_pref_ ## flag ) \
1951 g_return_if_fail (GNM_IS_WBC_GTK (wbcg)); \
1953 if (!wbcg->updating_ui) { \
1954 Sheet *sheet = wbcg_cur_sheet (wbcg); \
1955 go_object_toggle (sheet, property); \
1956 sheet_update (sheet); \
1960 TOGGLE_HANDLER (display_formulas, "display-formulas")
1961 TOGGLE_HANDLER (hide_zero, "display-zeros")
1962 TOGGLE_HANDLER (hide_grid, "display-grid")
1963 TOGGLE_HANDLER (hide_col_header, "display-column-header")
1964 TOGGLE_HANDLER (hide_row_header, "display-row-header")
1965 TOGGLE_HANDLER (display_outlines, "display-outlines")
1966 TOGGLE_HANDLER (outline_symbols_below, "display-outlines-below")
1967 TOGGLE_HANDLER (outline_symbols_right, "display-outlines-right")
1968 TOGGLE_HANDLER (use_r1c1, "use-r1c1")
1970 /* Actions that are always sensitive */
1971 static GnmActionEntry const permanent_actions[] = {
1972 { .name = "MenuFile",
1973 .label = N_("_File"),
1974 .callback = G_CALLBACK (cb_file_menu)
1976 { .name = "MenuFileNewFromTemplate",
1977 .icon = "document-new",
1978 .label = N_("New From Template")
1980 { .name = "FileNew",
1981 .icon = "document-new",
1982 .label = N_("_New"),
1983 .accelerator = "<control>n",
1984 .tooltip = N_("Create a new workbook"),
1985 .callback = G_CALLBACK (cb_file_new)
1987 { .name = "FileOpen",
1988 .icon = "document-open",
1989 .label = GNM_N_STOCK_OPEN,
1990 .label_context = GNM_STOCK_LABEL_CONTEXT,
1991 .accelerator = "<control>o",
1992 .tooltip = N_("Open a file"),
1993 .callback = G_CALLBACK (cb_file_open)
1995 { .name = "FileSave",
1996 .icon = "document-save",
1997 .label = GNM_N_STOCK_SAVE,
1998 .label_context = GNM_STOCK_LABEL_CONTEXT,
1999 .accelerator = "<control>s",
2000 .tooltip = N_("Save the current workbook"),
2001 .callback = G_CALLBACK (cb_file_save)
2003 { .name = "FileSaveAs",
2004 .icon = "document-save-as",
2005 .label = GNM_N_STOCK_SAVE_AS,
2006 .label_context = GNM_STOCK_LABEL_CONTEXT,
2007 .accelerator = "<control><shift>s",
2008 .tooltip = N_("Save the current workbook with a different name"),
2009 .callback = G_CALLBACK (cb_file_save_as)
2011 { .name = "FileSend",
2012 .icon = "gnumeric-link-email",
2013 .label = N_("Sen_d To..."),
2014 .tooltip = N_("Send the current file via email"),
2015 .callback = G_CALLBACK (cb_file_sendto)
2017 { .name = "FilePageSetup",
2018 .icon = "document-page-setup",
2019 .label = N_("Page Set_up..."),
2020 .tooltip = N_("Setup the page settings for your current printer"),
2021 .callback = G_CALLBACK (cb_file_page_setup)
2023 { .name = "FilePrintPreview",
2024 .icon = "document-print-preview",
2025 .label = N_("Print Pre_view"),
2026 .tooltip = N_("Print preview"),
2027 .callback = G_CALLBACK (cb_file_print_preview)
2029 { .name = "FilePrint",
2030 .icon = "document-print",
2031 .label = N_("Print"),
2032 .accelerator = "<control>p",
2033 .tooltip = N_("Print the current file"),
2034 .callback = G_CALLBACK (cb_file_print)
2036 { .name = "FilePrintArea",
2037 .label = N_("Print Area & Breaks")
2039 { .name = "FileHistoryFull",
2040 .label = N_("Full _History..."),
2041 .tooltip = N_("Access previously used file"),
2042 .callback = G_CALLBACK (cb_file_history_full)
2044 { .name = "FileClose",
2045 .icon = "window-close",
2046 .label = N_("_Close"),
2047 .accelerator = "<control>w",
2048 .tooltip = N_("Close the current file"),
2049 .callback = G_CALLBACK (cb_file_close)
2051 { .name = "FileQuit",
2052 .icon = "application-exit",
2053 .label = N_("_Quit"),
2054 .accelerator = "<control>q",
2055 .tooltip = N_("Quit the application"),
2056 .callback = G_CALLBACK (cb_file_quit)
2058 /* ---------------------------------------- */
2059 { .name = "MenuEdit",
2060 .label = N_("_Edit")
2062 { .name = "MenuEditClear",
2063 .icon = "edit-clear",
2064 .label = N_("C_lear")
2066 { .name = "MenuEditDelete",
2067 .icon = "edit-delete",
2068 .label = N_("_Delete")
2070 { .name = "MenuEditItems",
2071 .label = N_("_Modify")
2073 { .name = "MenuEditSheet",
2074 .label = N_("S_heet")
2076 { .name = "MenuEditSelect",
2077 .label = N_("_Select")
2080 { .name = "EditCopy",
2081 .icon = "edit-copy",
2082 .label = N_("_Copy"),
2083 .accelerator = "<control>c",
2084 .tooltip = N_("Copy the selection"),
2085 .callback = G_CALLBACK (cb_edit_copy)
2088 /* ---------------------------------------- */
2089 { .name = "MenuView",
2090 .label = N_("_View")
2092 { .name = "MenuViewWindows",
2093 .label = N_("_Windows")
2095 { .name = "MenuViewToolbars",
2096 .label = N_("_Toolbars")
2098 /* ---------------------------------------- */
2099 { .name = "MenuInsert",
2100 .label = N_("_Insert"),
2101 .callback = G_CALLBACK (cb_insert_menu)
2103 { .name = "MenuInsertObject",
2104 .label = N_("_Object")
2106 { .name = "MenuInsertSpecial",
2107 .label = N_("S_pecial")
2109 { .name = "MenuInsertFormulaWrap",
2110 .icon = "gnumeric-formulaguru",
2111 .label = N_("Func_tion Wrapper")
2113 { .name = "InsertNames",
2114 .label = N_("_Name..."),
2115 .accelerator = "F3",
2116 .tooltip = N_("Insert a defined name"),
2117 .callback = G_CALLBACK (cb_paste_names)
2119 /* ---------------------------------------- */
2120 { .name = "MenuFormat",
2121 .label = N_("F_ormat")
2123 { .name = "MenuFormatCells",
2124 .label = N_("_Cells")
2126 { .name = "MenuFormatText",
2127 .label = N_("_Text")
2129 { .name = "MenuFormatTextUnderline",
2130 .label = N_("_Underline")
2132 { .name = "MenuFormatColumn",
2133 .label = N_("C_olumn")
2135 { .name = "MenuFormatRow",
2136 .label = N_("_Row")
2138 { .name = "MenuFormatSheet",
2139 .label = N_("_Sheet")
2141 /* ---------------------------------------- */
2142 { .name = "MenuTools",
2143 .label = N_("_Tools")
2145 { .name = "MenuToolsScenarios",
2146 .label = N_("Sce_narios")
2148 /* ---------------------------------------- */
2149 { .name = "MenuStatistics",
2150 .label = N_("_Statistics")
2152 { .name = "MenuStatisticsDescriptive",
2153 .label = N_("_Descriptive Statistics")
2155 { .name = "MenuToolFrequencies",
2156 .label = N_("Fre_quency Tables")
2158 { .name = "MenuStatisticsTimeSeries",
2159 .label = N_("De_pendent Observations")
2161 { .name = "MenuToolForecast",
2162 .label = N_("F_orecast")
2164 { .name = "MenuStatisticsOneSample",
2165 .label = N_("_One Sample Tests")
2167 { .name = "MenuToolOneMedian",
2168 .label = N_("Claims About a Me_dian")
2170 { .name = "MenuStatisticsTwoSamples",
2171 .label = N_("_Two Sample Tests")
2173 { .name = "MenuToolTwoMedians",
2174 .label = N_("Claims About Two Me_dians")
2176 { .name = "MenuToolTTest",
2177 .label = N_("Claims About Two _Means")
2179 { .name = "MenuStatisticsMultipleSamples",
2180 .label = N_("_Multiple Sample Tests")
2182 { .name = "MenuANOVA",
2183 .label = N_("_ANOVA")
2185 { .name = "MenuContingencyTests",
2186 .label = N_("Contin_gency Table")
2188 /* ---------------------------------------- */
2189 { .name = "MenuData",
2190 .label = N_("_Data")
2192 { .name = "MenuFilter",
2193 .label = N_("_Filter")
2195 { .name = "MenuEditFill",
2196 .label = N_("F_ill")
2198 { .name = "MenuRandomGenerator",
2199 .label = N_("_Random Generators")
2201 { .name = "MenuOutline",
2202 .label = N_("_Group and Outline")
2204 { .name = "MenuExternalData",
2205 .label = N_("Import _Data")
2207 { .name = "MenuExportData",
2208 .label = N_("E_xport Data")
2210 { .name = "MenuSlicer",
2211 .label = N_("Data S_licer")
2213 /* ---------------------------------------- */
2214 { .name = "MenuHelp",
2215 .label = N_("_Help")
2218 { .name = "HelpDocs",
2219 .icon = "help-browser",
2220 .label = N_("_Contents"),
2221 .accelerator = "F1",
2222 .tooltip = N_("Open a viewer for Gnumeric's documentation"),
2223 .callback = G_CALLBACK (cb_help_docs)
2225 { .name = "HelpFunctions",
2226 .icon = "gnumeric-formulaguru",
2227 .label = N_("_Functions"),
2228 .tooltip = N_("Functions help"),
2229 .callback = G_CALLBACK (cb_help_function)
2231 { .name = "HelpWeb",
2232 .label = N_("Gnumeric on the _Web"),
2233 .tooltip = N_("Browse to Gnumeric's website"),
2234 .callback = G_CALLBACK (cb_help_web)
2236 { .name = "HelpIRC",
2237 .label = N_("_Live Assistance"),
2238 .tooltip = N_("See if anyone is available to answer questions"),
2239 .callback = G_CALLBACK (cb_help_irc)
2241 { .name = "HelpBug",
2242 .label = N_("Report a _Problem"),
2243 .tooltip = N_("Report problem"),
2244 .callback = G_CALLBACK (cb_help_bug)
2246 { .name = "HelpAbout",
2247 .icon = "help-about",
2248 .label = N_("_About"),
2249 .tooltip = N_("About this application"),
2250 .callback = G_CALLBACK (cb_help_about)
2254 /* actions that are sensitive only in data sheets */
2255 static GnmActionEntry const data_only_actions[] = {
2256 { .name = "EditCut",
2257 .icon = "edit-cut",
2258 .label = N_("Cu_t"),
2259 .accelerator = "<control>x",
2260 .tooltip = N_("Cut the selection"),
2261 .callback = G_CALLBACK (cb_edit_cut)
2263 { .name = "EditPaste",
2264 .icon = "edit-paste",
2265 .label = N_("_Paste"),
2266 .accelerator = "<control>v",
2267 .tooltip = N_("Paste the clipboard"),
2268 .callback = G_CALLBACK (cb_edit_paste)
2272 #define FULLSCREEN_ACCEL "F11"
2274 static GnmActionEntry const semi_permanent_actions[] = {
2275 /* Edit -> Sheet */
2276 { .name = "SheetReorder",
2277 .label = N_("_Manage Sheets..."),
2278 .tooltip = N_("Manage the sheets in this workbook"),
2279 .callback = G_CALLBACK (cb_sheet_order)
2281 { .name = "InsertSheet",
2282 .label = N_("_Insert"),
2283 .tooltip = N_("Insert a new sheet"),
2284 .callback = G_CALLBACK (wbcg_insert_sheet)
2286 /* ICK A DUPLICATE : we have no way to override a label on one proxy */
2287 { .name = "SheetInsert",
2288 .label = N_("_Sheet"),
2289 .tooltip = N_("Insert a new sheet"),
2290 .callback = G_CALLBACK (wbcg_insert_sheet)
2292 { .name = "InsertSheetAtEnd",
2293 .label = N_("_Append"),
2294 .tooltip = N_("Append a new sheet"),
2295 .callback = G_CALLBACK (wbcg_append_sheet)
2297 { .name = "EditDuplicateSheet",
2298 .label = N_("_Duplicate"),
2299 .tooltip = N_("Make a copy of the current sheet"),
2300 .callback = G_CALLBACK (wbcg_clone_sheet)
2302 { .name = "SheetRemove",
2303 .label = N_("_Remove"),
2304 .tooltip = N_("Irrevocably remove an entire sheet"),
2305 .callback = G_CALLBACK (cb_sheet_remove)
2307 { .name = "SheetChangeName",
2308 .label = N_("Re_name..."),
2309 .tooltip = N_("Rename the current sheet"),
2310 .callback = G_CALLBACK (cb_sheet_name)
2312 { .name = "SheetResize",
2313 .label = N_("Resize..."),
2314 .tooltip = N_("Change the size of the current sheet"),
2315 .callback = G_CALLBACK (cb_sheet_resize)
2318 /* View */
2319 { .name = "ViewNew",
2320 .icon = "document-new",
2321 .label = N_("_New View..."),
2322 .tooltip = N_("Create a new view of the workbook"),
2323 .callback = G_CALLBACK (cb_view_new)
2326 /* Format */
2327 { .name = "FormatWorkbook",
2328 .icon = "document-properties",
2329 .label = N_("View _Properties..."),
2330 .tooltip = N_("Modify the view properties"),
2331 .callback = G_CALLBACK (cb_workbook_attr)
2334 { .name = "ViewStatusbar",
2335 .toggle = TRUE,
2336 .label = N_("View _Statusbar"),
2337 .tooltip = N_("Toggle visibility of statusbar"),
2338 .callback = G_CALLBACK (cb_view_statusbar),
2339 .is_active = TRUE
2342 { .name = "ViewFullScreen",
2343 .toggle = TRUE,
2344 .icon = "view-fullscreen",
2345 .label = N_("F_ull Screen"),
2346 .accelerator = FULLSCREEN_ACCEL,
2347 .tooltip = N_("Switch to or from full screen mode"),
2348 .callback = G_CALLBACK (cb_view_fullscreen)
2352 #define ZOOM_IN_ACCEL NULL
2353 #define ZOOM_OUT_ACCEL NULL
2355 static GnmActionEntry const actions[] = {
2356 /* File */
2357 { .name = "FileMetaData",
2358 .icon = "document-properties",
2359 .label = N_("Document Proper_ties..."),
2360 .tooltip = N_("Edit document properties"),
2361 .callback = G_CALLBACK (cb_doc_meta_data)
2364 /* File->PrintArea */
2365 { .name = "FilePrintAreaSet",
2366 .label = N_("Set Print Area"),
2367 .tooltip = N_("Use the current selection as print area"),
2368 .callback = G_CALLBACK (cb_file_print_area_set)
2370 { .name = "FilePrintAreaClear",
2371 .label = N_("Clear Print Area"),
2372 .tooltip = N_("Undefine the print area"),
2373 .callback = G_CALLBACK (cb_file_print_area_clear)
2375 { .name = "FilePrintAreaShow",
2376 .label = N_("Show Print Area"),
2377 .tooltip = N_("Select the print area"),
2378 .callback = G_CALLBACK (cb_file_print_area_show)
2380 { .name = "FilePrintAreaToggleColPageBreak",
2381 .label = N_("Set Column Page Break"),
2382 .tooltip = N_("Split the page to the left of this column"),
2383 .callback = G_CALLBACK (cb_file_print_area_toggle_col)
2385 { .name = "FilePrintAreaToggleRowPageBreak",
2386 .label = N_("Set Row Page Break"),
2387 .tooltip = N_("Split the page above this row"),
2388 .callback = G_CALLBACK (cb_file_print_area_toggle_row)
2390 { .name = "FilePrintAreaClearAllPageBreak",
2391 .label = N_("Clear All Page Breaks"),
2392 .tooltip = N_("Remove all manual pagebreaks from this sheet"),
2393 .callback = G_CALLBACK (cb_file_print_area_clear_pagebreaks)
2396 /* Edit -> Clear */
2397 { .name = "EditClearAll",
2398 .icon = "edit-clear",
2399 .label = N_("_All"),
2400 .tooltip = N_("Clear the selected cells' formats, comments, and contents"),
2401 .callback = G_CALLBACK (cb_edit_clear_all)
2403 { .name = "EditClearFormats",
2404 .label = N_("_Formats & Hyperlinks"),
2405 .tooltip = N_("Clear the selected cells' formats and hyperlinks"),
2406 .callback = G_CALLBACK (cb_edit_clear_formats)
2408 { .name = "EditClearComments",
2409 .icon = "gnumeric-comment-delete",
2410 .label = N_("Co_mments"),
2411 .tooltip = N_("Delete the selected cells' comments"),
2412 .callback = G_CALLBACK (cb_edit_clear_comments)
2414 { .name = "EditClearContent",
2415 .icon = "edit-clear",
2416 .label = N_("_Contents"),
2417 .tooltip = N_("Clear the selected cells' contents"),
2418 .callback = G_CALLBACK (cb_edit_clear_content)
2420 { .name = "EditClearAllFiltered",
2421 .icon = "edit-clear",
2422 .label = N_("A_ll Filtered Rows"),
2423 .tooltip = N_("Clear the selected cells' formats, comments, and contents in the filtered rows"),
2424 .callback = G_CALLBACK (cb_edit_clear_all_filtered)
2426 { .name = "EditClearFormatsFiltered",
2427 .label = N_("F_ormats & Hyperlinks in Filtered Rows"),
2428 .tooltip = N_("Clear the selected cells' formats and hyperlinks in the filtered rows"),
2429 .callback = G_CALLBACK (cb_edit_clear_formats_filtered)
2431 { .name = "EditClearCommentsFiltered",
2432 .icon = "gnumeric-comment-delete",
2433 .label = N_("Comme_nts in Filtered Rows"),
2434 .tooltip = N_("Delete the selected cells' comments in the filtered rows"),
2435 .callback = G_CALLBACK (cb_edit_clear_comments_filtered)
2437 { .name = "EditClearContentFiltered",
2438 .icon = "edit-clear",
2439 .label = N_("Content_s of Filtered Rows"),
2440 .tooltip = N_("Clear the selected cells' contents in the filtered rows"),
2441 .callback = G_CALLBACK (cb_edit_clear_content_filtered)
2444 /* Edit -> Delete */
2445 /*Translators: Delete "Rows"*/
2446 { .name = "EditDeleteRows",
2447 .icon = "gnumeric-row-delete",
2448 .label = N_("_Rows"),
2449 .tooltip = N_("Delete the row(s) containing the selected cells"),
2450 .callback = G_CALLBACK (cb_edit_delete_rows)
2452 /*Translators: Delete "Columns"*/
2453 { .name = "EditDeleteColumns",
2454 .icon = "gnumeric-column-delete",
2455 .label = N_("_Columns"),
2456 .tooltip = N_("Delete the column(s) containing the selected cells"),
2457 .callback = G_CALLBACK (cb_edit_delete_columns)
2459 { .name = "EditDeleteCells",
2460 .label = N_("C_ells..."),
2461 .accelerator = "<control>minus",
2462 .tooltip = N_("Delete the selected cells, shifting others into their place"),
2463 .callback = G_CALLBACK (cb_edit_delete_cells)
2465 { .name = "EditClearHyperlinks",
2466 .icon = "gnumeric-link-delete",
2467 .label = N_("_Hyperlinks"),
2468 .tooltip = N_("Delete the selected cells' hyperlinks"),
2469 .callback = G_CALLBACK (cb_edit_delete_links)
2471 /* A duplicate that should not go into the menus, used only for the accelerator */
2472 { .name = "EditDeleteCellsXL",
2473 .label = N_("C_ells..."),
2474 .accelerator = "<control>KP_Subtract",
2475 .tooltip = N_("Delete the selected cells, shifting others into their place"),
2476 .callback = G_CALLBACK (cb_edit_delete_cells)
2479 /* Edit -> Select */
2481 /* Note : The accelerators involving space are just for display
2482 * purposes. We actually handle this in
2483 * gnm-pane.c:gnm_pane_key_mode_sheet
2484 * with the rest of the key movement and rangeselection.
2485 * Otherwise input methods would steal them */
2486 { .name = "EditSelectAll",
2487 .label = N_("_All"),
2488 .accelerator = "<control><shift>space",
2489 .tooltip = N_("Select all cells in the spreadsheet"),
2490 .callback = G_CALLBACK (cb_edit_select_all)
2492 { .name = "EditSelectColumn",
2493 .label = N_("_Column"),
2494 .accelerator = "<control>space",
2495 .tooltip = N_("Select an entire column"),
2496 .callback = G_CALLBACK (cb_edit_select_col)
2498 { .name = "EditSelectRow",
2499 .label = N_("_Row"),
2500 .accelerator = "<shift>space",
2501 .tooltip = N_("Select an entire row"),
2502 .callback = G_CALLBACK (cb_edit_select_row)
2505 { .name = "EditSelectArray",
2506 .label = N_("Arra_y"),
2507 .accelerator = "<control>slash",
2508 .tooltip = N_("Select an array of cells"),
2509 .callback = G_CALLBACK (cb_edit_select_array)
2511 { .name = "EditSelectDepends",
2512 .label = N_("_Depends"),
2513 .accelerator = "<control>bracketright",
2514 .tooltip = N_("Select all the cells that depend on the current edit cell"),
2515 .callback = G_CALLBACK (cb_edit_select_depends)
2517 { .name = "EditSelectInputs",
2518 .label = N_("_Inputs"),
2519 .accelerator = "<control>bracketleft",
2520 .tooltip = N_("Select all the cells are used by the current edit cell"),
2521 .callback = G_CALLBACK (cb_edit_select_inputs)
2524 { .name = "EditSelectObject",
2525 .label = N_("Next _Object"),
2526 .accelerator = "<control>Tab",
2527 .tooltip = N_("Select the next sheet object"),
2528 .callback = G_CALLBACK (cb_edit_select_object)
2531 { .name = "EditGotoTop",
2532 .icon = "go-top",
2533 .label = N_("Go to Top"),
2534 .tooltip = N_("Go to the top of the data"),
2535 .callback = G_CALLBACK (cb_edit_goto_top)
2537 { .name = "EditGotoBottom",
2538 .icon = "go-bottom",
2539 .label = N_("Go to Bottom"),
2540 .tooltip = N_("Go to the bottom of the data"),
2541 .callback = G_CALLBACK (cb_edit_goto_bottom)
2543 { .name = "EditGotoFirst",
2544 .icon = "go-first",
2545 .label = N_("Go to First"),
2546 .tooltip = N_("Go to the first data cell"),
2547 .callback = G_CALLBACK (cb_edit_goto_first)
2549 { .name = "EditGotoLast",
2550 .icon = "go-last",
2551 .label = N_("Go to Last"),
2552 .tooltip = N_("Go to the last data cell"),
2553 .callback = G_CALLBACK (cb_edit_goto_last)
2555 { .name = "EditGoto",
2556 .icon = "go-jump",
2557 .label = N_("_Go to Cell..."),
2558 .accelerator = "<control>g",
2559 .tooltip = N_("Jump to a specified cell"),
2560 .callback = G_CALLBACK (cb_edit_goto)
2562 /* This is a navigational aid that is not supposed to appear */
2563 /* in the menu */
2564 { .name = "EditGotoCellIndicator",
2565 .label = N_("Go to Current Cell Indicator"),
2566 .accelerator = "<shift><control>g",
2567 .tooltip = N_("Go to Current Cell Indicator"),
2568 .callback = G_CALLBACK (cb_edit_goto_cell_indicator)
2571 /* Edit */
2572 { .name = "Repeat",
2573 .label = N_("Repeat"),
2574 .accelerator = "F4",
2575 .tooltip = N_("Repeat the previous action"),
2576 .callback = G_CALLBACK (cb_repeat)
2578 { .name = "EditPasteSpecial",
2579 .icon = "edit-paste",
2580 .label = N_("P_aste Special..."),
2581 .accelerator = "<shift><control>v",
2582 .tooltip = N_("Paste with optional filters and transformations"),
2583 .callback = G_CALLBACK (cb_edit_paste_special)
2586 { .name = "EditComment",
2587 .icon = "gnumeric-comment-edit",
2588 .label = N_("Co_mment..."),
2589 .tooltip = N_("Edit the selected cell's comment"),
2590 .callback = G_CALLBACK (cb_insert_comment)
2592 { .name = "EditHyperlink",
2593 .icon = "gnumeric-link-edit",
2594 .label = N_("Hyper_link..."),
2595 .accelerator = "<control>K",
2596 .tooltip = N_("Edit the selected cell's hyperlink"),
2597 .callback = G_CALLBACK (cb_insert_hyperlink)
2599 #if 0
2600 { .name = "EditGenerateName",
2601 .label = N_("_Auto generate names..."),
2602 .tooltip = N_("Use the current selection to create names"),
2603 .callback = G_CALLBACK (cb_auto_generate__named_expr)
2605 #endif
2607 { .name = "EditFind",
2608 .icon = "edit-find",
2609 .label = N_("S_earch..."),
2610 .accelerator = "<control>f",
2611 .tooltip = N_("Search for something"),
2612 .callback = G_CALLBACK (cb_edit_search)
2614 { .name = "EditReplace",
2615 .icon = "edit-find-replace",
2616 .label = N_("Search _& Replace..."),
2617 .accelerator = "<control>h",
2618 .tooltip = N_("Search for something and replace it with something else"),
2619 .callback = G_CALLBACK (cb_edit_search_replace)
2622 { .name = "EditRecalc",
2623 .label = N_("Recalculate"),
2624 .accelerator = "F9",
2625 .tooltip = N_("Recalculate the spreadsheet"),
2626 .callback = G_CALLBACK (cb_edit_recalc)
2629 { .name = "EditPreferences",
2630 .icon = "preferences-system",
2631 .label = N_("Preferences..."),
2632 .tooltip = N_("Change Gnumeric Preferences"),
2633 .callback = G_CALLBACK (cb_file_preferences)
2636 /* View */
2637 { .name = "ViewFreezeThawPanes",
2638 .label = N_("_Freeze Panes"),
2639 .tooltip = N_("Freeze the top left of the sheet"),
2640 .callback = G_CALLBACK (cb_view_freeze_panes)
2642 { .name = "ViewZoom",
2643 .icon = "zoom-fit-best", /* dubious */
2644 .label = N_("_Zoom..."),
2645 .tooltip = N_("Zoom the spreadsheet in or out"),
2646 .callback = G_CALLBACK (cb_view_zoom)
2648 { .name = "ViewZoomIn",
2649 .icon = "zoom-in",
2650 .label = N_("Zoom _In"),
2651 .accelerator = ZOOM_IN_ACCEL,
2652 .tooltip = N_("Increase the zoom to make things larger"),
2653 .callback = G_CALLBACK (cb_view_zoom_in)
2655 { .name = "ViewZoomOut",
2656 .icon = "zoom-out",
2657 .label = N_("Zoom _Out"),
2658 .accelerator = ZOOM_OUT_ACCEL,
2659 .tooltip = N_("Decrease the zoom to make things smaller"),
2660 .callback = G_CALLBACK (cb_view_zoom_out)
2663 /* Insert */
2664 { .name = "InsertCells",
2665 .label = N_("C_ells..."),
2666 .accelerator = "<control>plus",
2667 .tooltip = N_("Insert new cells"),
2668 .callback = G_CALLBACK (cb_insert_cells)
2670 /* A duplicate that should not go into the menus, used only for the accelerator */
2671 { .name = "InsertCellsXL",
2672 .label = N_("C_ells..."),
2673 .accelerator = "<control>KP_Add",
2674 .tooltip = N_("Insert new cells"),
2675 .callback = G_CALLBACK (cb_insert_cells)
2677 /*Translators: Insert "Columns"*/
2678 { .name = "InsertColumns",
2679 .icon = "gnumeric-column-add",
2680 .label = N_("_Columns"),
2681 .tooltip = N_("Insert new columns"),
2682 .callback = G_CALLBACK (cb_insert_cols)
2684 /*Translators: Insert "Rows"*/
2685 { .name = "InsertRows",
2686 .icon = "gnumeric-row-add",
2687 .label = N_("_Rows"),
2688 .tooltip = N_("Insert new rows"),
2689 .callback = G_CALLBACK (cb_insert_rows)
2692 { .name = "ChartGuru",
2693 .icon = "gnumeric-graphguru",
2694 .label = N_("C_hart..."),
2695 .tooltip = N_("Insert a Chart"),
2696 .callback = G_CALLBACK (cb_launch_chart_guru)
2698 { .name = "NewGOComponent",
2699 .icon = "New Goffice_Component",
2700 .label = N_("_New..."),
2701 .tooltip = N_("Insert a new Goffice component object"),
2702 .callback = G_CALLBACK (cb_launch_go_component_new)
2704 { .name = "GOComponentFromFile",
2705 .icon = "New Goffice_Component from a file",
2706 .label = N_("_From File..."),
2707 .tooltip = N_("Insert a new Goffice component object from a file"),
2708 .callback = G_CALLBACK (cb_launch_go_component_from_file)
2710 { .name = "InsertImage",
2711 .icon = "insert-image",
2712 .label = N_("_Image..."),
2713 .tooltip = N_("Insert an image"),
2714 .callback = G_CALLBACK (cb_insert_image)
2717 { .name = "InsertComment",
2718 .icon = "gnumeric-comment-add",
2719 .label = N_("Co_mment..."),
2720 .tooltip = N_("Insert a comment"),
2721 .callback = G_CALLBACK (cb_insert_comment)
2723 { .name = "InsertHyperlink",
2724 .icon = "gnumeric-link-add",
2725 .label = N_("Hyper_link..."),
2726 .accelerator = "<control>K",
2727 .tooltip = N_("Insert a Hyperlink"),
2728 .callback = G_CALLBACK (cb_insert_hyperlink)
2730 { .name = "InsertSortDecreasing",
2731 .icon = "view-sort-descending",
2732 .label = N_("Sort (_Descending)"),
2733 .tooltip = N_("Wrap with SORT (descending)"),
2734 .callback = G_CALLBACK (cb_insert_sort_descending)
2736 { .name = "InsertSortIncreasing",
2737 .icon = "view-sort-ascending",
2738 .label = N_("Sort (_Ascending)"),
2739 .tooltip = N_("Wrap with SORT (ascending)"),
2740 .callback = G_CALLBACK (cb_insert_sort_ascending)
2743 /* Insert -> Special */
2744 { .name = "InsertCurrentDate",
2745 .label = N_("Current _Date"),
2746 .accelerator = "<control>semicolon",
2747 .tooltip = N_("Insert the current date into the selected cell(s)"),
2748 .callback = G_CALLBACK (cb_insert_current_date)
2751 { .name = "InsertCurrentTime",
2752 .label = N_("Current _Time"),
2753 .accelerator = "<control>colon",
2754 .tooltip = N_("Insert the current time into the selected cell(s)"),
2755 .callback = G_CALLBACK (cb_insert_current_time)
2758 { .name = "InsertCurrentDateTime",
2759 .label = N_("Current D_ate and Time"),
2760 .accelerator = "<control>period",
2761 .tooltip = N_("Insert the current date and time into the selected cell(s)"),
2762 .callback = G_CALLBACK (cb_insert_current_date_time)
2765 /* Insert -> Name */
2766 { .name = "EditNames",
2767 .label = N_("_Names..."),
2768 .accelerator = "<control>F3",
2769 .tooltip = N_("Edit defined names for expressions"),
2770 .callback = G_CALLBACK (cb_define_name)
2773 /* Format */
2774 { .name = "FormatAuto",
2775 .label = N_("_Autoformat..."),
2776 .tooltip = N_("Format a region of cells according to a pre-defined template"),
2777 .callback = G_CALLBACK (cb_autoformat)
2779 { .name = "SheetDirection",
2780 .icon = "format-text-direction-ltr",
2781 .label = N_("Direction"),
2782 .tooltip = N_("Toggle sheet direction, left-to-right vs right-to-left"),
2783 .callback = G_CALLBACK (cb_direction)
2786 /* Format -> Cells */
2787 { .name = "FormatCells",
2788 .label = N_("_Format..."),
2789 .accelerator = "<control>1",
2790 .tooltip = N_("Modify the formatting of the selected cells"),
2791 .callback = G_CALLBACK (cb_format_cells)
2793 { .name = "FormatCellsCond",
2794 .label = N_("_Conditional Formatting..."),
2795 .tooltip = N_("Modify the conditional formatting of the selected cells"),
2796 .callback = G_CALLBACK (cb_format_cells_cond)
2798 { .name = "FormatCellsFitHeight",
2799 .icon = "gnumeric-row-size",
2800 .label = N_("Auto Fit _Height"),
2801 .tooltip = N_("Ensure rows are just tall enough to display content of selection"),
2802 .callback = G_CALLBACK (cb_format_cells_auto_fit_height)
2804 { .name = "FormatCellsFitWidth",
2805 .icon = "gnumeric-column-size",
2806 .label = N_("Auto Fit _Width"),
2807 .tooltip = N_("Ensure columns are just wide enough to display content of selection"),
2808 .callback = G_CALLBACK (cb_format_cells_auto_fit_width)
2812 /* Format -> Col */
2813 { .name = "ColumnSize",
2814 .icon = "gnumeric-column-size",
2815 .label = N_("_Width..."),
2816 .tooltip = N_("Change width of the selected columns"),
2817 .callback = G_CALLBACK (cb_set_column_width)
2819 { .name = "ColumnAutoSize",
2820 .icon = "gnumeric-column-size",
2821 .label = N_("_Auto Fit Width"),
2822 .tooltip = N_("Ensure columns are just wide enough to display their content"),
2823 .callback = G_CALLBACK (cb_format_column_auto_fit)
2825 { .name = "ColumnHide",
2826 .icon = "gnumeric-column-hide",
2827 .label = N_("_Hide"),
2828 .accelerator = "<control>0",
2829 .tooltip = N_("Hide the selected columns"),
2830 .callback = G_CALLBACK (cb_format_column_hide)
2832 { .name = "ColumnUnhide",
2833 .icon = "gnumeric-column-unhide",
2834 .label = N_("_Unhide"),
2835 .accelerator = "<control>parenright",
2836 .tooltip = N_("Make any hidden columns in the selection visible"),
2837 .callback = G_CALLBACK (cb_format_column_unhide)
2839 { .name = "ColumnDefaultSize",
2840 .icon = "gnumeric-column-size",
2841 .label = N_("_Standard Width"),
2842 .tooltip = N_("Change the default column width"),
2843 .callback = G_CALLBACK (cb_format_column_std_width)
2846 /* Format -> Row */
2847 { .name = "RowSize",
2848 .icon = "gnumeric-row-size",
2849 .label = N_("H_eight..."),
2850 .tooltip = N_("Change height of the selected rows"),
2851 .callback = G_CALLBACK (cb_set_row_height)
2853 { .name = "RowAutoSize",
2854 .icon = "gnumeric-row-size",
2855 .label = N_("_Auto Fit Height"),
2856 .tooltip = N_("Ensure rows are just tall enough to display their content"),
2857 .callback = G_CALLBACK (cb_format_row_auto_fit)
2859 { .name = "RowHide",
2860 .icon = "gnumeric-row-hide",
2861 .label = N_("_Hide"),
2862 .accelerator = "<control>9",
2863 .tooltip = N_("Hide the selected rows"),
2864 .callback = G_CALLBACK (cb_format_row_hide)
2866 { .name = "RowUnhide",
2867 .icon = "gnumeric-row-unhide",
2868 .label = N_("_Unhide"),
2869 .accelerator = "<control>parenleft",
2870 .tooltip = N_("Make any hidden rows in the selection visible"),
2871 .callback = G_CALLBACK (cb_format_row_unhide)
2873 { .name = "RowDefaultSize",
2874 .icon = "gnumeric-row-size",
2875 .label = N_("_Standard Height"),
2876 .tooltip = N_("Change the default row height"),
2877 .callback = G_CALLBACK (cb_format_row_std_height)
2880 /* Tools */
2881 { .name = "ToolsPlugins",
2882 .label = N_("_Plug-ins..."),
2883 .tooltip = N_("Manage available plugin modules"),
2884 .callback = G_CALLBACK (cb_tools_plugins)
2886 { .name = "ToolsAutoCorrect",
2887 .label = N_("Auto _Correct..."),
2888 .tooltip = N_("Automatically perform simple spell checking"),
2889 .callback = G_CALLBACK (cb_tools_autocorrect)
2891 { .name = "ToolsAutoSave",
2892 .label = N_("_Auto Save..."),
2893 .tooltip = N_("Automatically save the current document at regular intervals"),
2894 .callback = G_CALLBACK (cb_tools_auto_save)
2896 { .name = "ToolsGoalSeek",
2897 .label = N_("_Goal Seek..."),
2898 .tooltip = N_("Iteratively recalculate to find a target value"),
2899 .callback = G_CALLBACK (cb_tools_goal_seek)
2901 { .name = "ToolsSolver",
2902 .label = N_("_Solver..."),
2903 .tooltip = N_("Iteratively recalculate with constraints to approach a target value"),
2904 .callback = G_CALLBACK (cb_tools_solver)
2906 { .name = "ToolsSimulation",
2907 .label = N_("Si_mulation..."),
2908 .tooltip = N_("Test decision alternatives by using Monte Carlo "
2909 "simulation to find out probable outputs and risks related to them"),
2910 .callback = G_CALLBACK (cb_tools_simulation)
2912 { .name = "ToolsCompare",
2913 .label = N_("Compare Sheets..."),
2914 .tooltip = N_("Find differences between two sheets"),
2915 .callback = G_CALLBACK (cb_tools_compare)
2918 /* Tools -> Scenarios */
2919 { .name = "ToolsScenarios",
2920 .label = N_("_View..."),
2921 .tooltip = N_("View, delete and report different scenarios"),
2922 .callback = G_CALLBACK (cb_tools_scenarios)
2924 { .name = "ToolsScenarioAdd",
2925 .label = N_("_Add..."),
2926 .tooltip = N_("Add a new scenario"),
2927 .callback = G_CALLBACK (cb_tools_scenario_add)
2930 /* Statistics */
2932 { .name = "ToolsSampling",
2933 .label = N_("_Sampling..."),
2934 .tooltip = N_("Periodic and random samples"),
2935 .callback = G_CALLBACK (cb_tools_sampling)
2938 /* Statistics -> Descriptive*/
2940 { .name = "ToolsCorrelation",
2941 .label = N_("_Correlation..."),
2942 .tooltip = N_("Pearson Correlation"),
2943 .callback = G_CALLBACK (cb_tools_correlation)
2945 { .name = "ToolsCovariance",
2946 .label = N_("Co_variance..."),
2947 .tooltip = N_("Covariance"),
2948 .callback = G_CALLBACK (cb_tools_covariance)
2950 { .name = "ToolsDescStatistics",
2951 .label = N_("_Descriptive Statistics..."),
2952 .tooltip = N_("Various summary statistics"),
2953 .callback = G_CALLBACK (cb_tools_desc_statistics)
2956 /* Statistics -> Descriptive -> Frequencies */
2958 { .name = "ToolsFrequency",
2959 .label = N_("Fre_quency Tables..."),
2960 .tooltip = N_("Frequency tables for non-numeric data"),
2961 .callback = G_CALLBACK (cb_tools_frequency)
2963 { .name = "ToolsHistogram",
2964 .label = N_("_Histogram..."),
2965 .tooltip = N_("Various frequency tables for numeric data"),
2966 .callback = G_CALLBACK (cb_tools_histogram)
2968 { .name = "ToolsRanking",
2969 .label = N_("Ranks And _Percentiles..."),
2970 .tooltip = N_("Ranks, placements and percentiles"),
2971 .callback = G_CALLBACK (cb_tools_ranking)
2974 /* Statistics -> DependentObservations */
2976 { .name = "ToolsFourier",
2977 .label = N_("_Fourier Analysis..."),
2978 .tooltip = N_("Fourier Analysis"),
2979 .callback = G_CALLBACK (cb_tools_fourier)
2981 { .name = "ToolsPrincipalComponents",
2982 .label =
2983 N_("Principal Components Analysis..."),
2984 .tooltip = N_("Principal Components Analysis"),
2985 .callback = G_CALLBACK (cb_tools_principal_components)
2987 /* Statistics -> DependentObservations -> Forecast*/
2989 { .name = "ToolsExpSmoothing",
2990 .label = N_("_Exponential Smoothing..."),
2991 .tooltip = N_("Exponential smoothing..."),
2992 .callback = G_CALLBACK (cb_tools_exp_smoothing)
2994 { .name = "ToolsAverage",
2995 .label = N_("_Moving Average..."),
2996 .tooltip = N_("Moving average..."),
2997 .callback = G_CALLBACK (cb_tools_average)
2999 { .name = "ToolsRegression",
3000 .label = N_("_Regression..."),
3001 .tooltip = N_("Regression Analysis"),
3002 .callback = G_CALLBACK (cb_tools_regression)
3004 { .name = "ToolsKaplanMeier",
3005 .label = N_("_Kaplan-Meier Estimates..."),
3006 .tooltip = N_("Creation of Kaplan-Meier Survival Curves"),
3007 .callback = G_CALLBACK (cb_tools_kaplan_meier)
3010 /* Statistics -> OneSample */
3012 { .name = "ToolsNormalityTests",
3013 .label = N_("_Normality Tests..."),
3014 .tooltip = N_("Testing a sample for normality"),
3015 .callback = G_CALLBACK (cb_tools_normality_tests)
3017 { .name = "ToolsOneMeanTest",
3018 .label = N_("Claims About a _Mean..."),
3019 .tooltip = N_("Testing the value of a mean"),
3020 .callback = G_CALLBACK (cb_tools_one_mean_test)
3023 /* Statistics -> OneSample -> OneMedian*/
3025 { .name = "ToolsOneMedianSignTest",
3026 .label = N_("_Sign Test..."),
3027 .tooltip = N_("Testing the value of a median"),
3028 .callback = G_CALLBACK (cb_tools_sign_test_one_median)
3030 { .name = "ToolsOneMedianWilcoxonSignedRank",
3031 .label = N_("_Wilcoxon Signed Rank Test..."),
3032 .tooltip = N_("Testing the value of a median"),
3033 .callback = G_CALLBACK (cb_tools_wilcoxon_signed_rank_one_median)
3036 /* Statistics -> TwoSamples */
3038 { .name = "ToolsFTest",
3039 .label = N_("Claims About Two _Variances"),
3040 .tooltip = N_("Comparing two population variances"),
3041 .callback = G_CALLBACK (cb_tools_ftest)
3044 /* Statistics -> TwoSamples -> Two Means*/
3046 { .name = "ToolTTestPaired",
3047 .label = N_("_Paired Samples..."),
3048 .tooltip = N_("Comparing two population means for two paired samples"),
3049 .callback = G_CALLBACK (cb_tools_ttest_paired)
3052 { .name = "ToolTTestEqualVar",
3053 .label = N_("Unpaired Samples, _Equal Variances..."),
3054 .tooltip = N_("Comparing two population means for two unpaired samples from populations with equal variances"),
3055 .callback = G_CALLBACK (cb_tools_ttest_equal_var)
3058 { .name = "ToolTTestUnequalVar",
3059 .label = N_("Unpaired Samples, _Unequal Variances..."),
3060 .tooltip = N_("Comparing two population means for two unpaired samples from populations with unequal variances"),
3061 .callback = G_CALLBACK (cb_tools_ttest_unequal_var)
3064 { .name = "ToolZTest",
3065 .label = N_("Unpaired Samples, _Known Variances..."),
3066 .tooltip = N_("Comparing two population means from populations with known variances"),
3067 .callback = G_CALLBACK (cb_tools_ztest)
3070 /* Statistics -> TwoSamples -> Two Medians*/
3072 { .name = "ToolsTwoMedianSignTest",
3073 .label = N_("_Sign Test..."),
3074 .tooltip = N_("Comparing the values of two medians of paired observations"),
3075 .callback = G_CALLBACK (cb_tools_sign_test_two_medians)
3077 { .name = "ToolsTwoMedianWilcoxonSignedRank",
3078 .label = N_("_Wilcoxon Signed Rank Test..."),
3079 .tooltip = N_("Comparing the values of two medians of paired observations"),
3080 .callback = G_CALLBACK (cb_tools_wilcoxon_signed_rank_two_medians)
3082 { .name = "ToolsTwoMedianWilcoxonMannWhitney",
3083 .label = N_("Wilcoxon-_Mann-Whitney Test..."),
3084 .tooltip = N_("Comparing the values of two medians of unpaired observations"),
3085 .callback = G_CALLBACK (cb_tools_wilcoxon_mann_whitney)
3088 /* Statistics -> MultipleSamples */
3090 /* Statistics -> MultipleSamples -> ANOVA*/
3092 { .name = "ToolsANOVAoneFactor",
3093 .label = N_("_One Factor..."),
3094 .tooltip = N_("One Factor Analysis of Variance..."),
3095 .callback = G_CALLBACK (cb_tools_anova_one_factor)
3097 { .name = "ToolsANOVAtwoFactor",
3098 .label = N_("_Two Factor..."),
3099 .tooltip = N_("Two Factor Analysis of Variance..."),
3100 .callback = G_CALLBACK (cb_tools_anova_two_factor)
3103 /* Statistics -> MultipleSamples -> ContingencyTable*/
3105 { .name = "ToolsHomogeneity",
3106 .label = N_("Test of _Homogeneity..."),
3107 .tooltip = N_("Chi Squared Test of Homogeneity..."),
3108 .callback = G_CALLBACK (cb_tools_chi_square_homogeneity)
3110 { .name = "ToolsIndependence",
3111 .label = N_("Test of _Independence..."),
3112 .tooltip = N_("Chi Squared Test of Independence..."),
3113 .callback = G_CALLBACK (cb_tools_chi_square_independence)
3116 /* Data */
3117 { .name = "DataSort",
3118 .icon = "view-sort-ascending",
3119 .label = N_("_Sort..."),
3120 .tooltip = N_("Sort the selected region"),
3121 .callback = G_CALLBACK (cb_data_sort)
3123 { .name = "DataShuffle",
3124 .label = N_("Sh_uffle..."),
3125 .tooltip = N_("Shuffle cells, rows or columns"),
3126 .callback = G_CALLBACK (cb_data_shuffle)
3128 { .name = "DataValidate",
3129 .label = N_("_Validate..."),
3130 .tooltip = N_("Validate input with preset criteria"),
3131 .callback = G_CALLBACK (cb_data_validate)
3133 { .name = "DataTextToColumns",
3134 .label = N_("T_ext to Columns..."),
3135 .tooltip = N_("Parse the text in the selection into data"),
3136 .callback = G_CALLBACK (cb_data_text_to_columns)
3138 { .name = "DataConsolidate",
3139 .label = N_("_Consolidate..."),
3140 .tooltip = N_("Consolidate regions using a function"),
3141 .callback = G_CALLBACK (cb_data_consolidate)
3143 { .name = "DataTable",
3144 .label = N_("_Table..."),
3145 .tooltip = N_("Create a Data Table to evaluate a function with multiple inputs"),
3146 .callback = G_CALLBACK (cb_data_table)
3148 { .name = "DataExport",
3149 .label = N_("E_xport into Other Format..."),
3150 .tooltip = N_("Export the current workbook or sheet"),
3151 .callback = G_CALLBACK (cb_data_export)
3153 { .name = "DataExportText",
3154 .label = N_("Export as _Text File..."),
3155 .tooltip = N_("Export the current sheet as a text file"),
3156 .callback = G_CALLBACK (cb_data_export_text)
3158 { .name = "DataExportCSV",
3159 .label = N_("Export as _CSV File..."),
3160 .tooltip = N_("Export the current sheet as a csv file"),
3161 .callback = G_CALLBACK (cb_data_export_csv)
3163 { .name = "DataExportRepeat",
3164 .label = N_("Repeat Export"),
3165 .accelerator = "<control>E",
3166 .tooltip = N_("Repeat the last data export"),
3167 .callback = G_CALLBACK (cb_data_export_repeat)
3170 /* Data -> Fill */
3171 { .name = "EditFillAutofill",
3172 .label = N_("Auto_fill"),
3173 .tooltip = N_("Automatically fill the current selection"),
3174 .callback = G_CALLBACK (cb_edit_fill_autofill)
3176 { .name = "ToolsMerge",
3177 .label = N_("_Merge..."),
3178 .tooltip = N_("Merges columnar data into a sheet creating duplicate sheets for each row"),
3179 .callback = G_CALLBACK (cb_tools_merge)
3181 { .name = "ToolsTabulate",
3182 .label = N_("_Tabulate Dependency..."),
3183 .tooltip = N_("Make a table of a cell's value as a function of other cells"),
3184 .callback = G_CALLBACK (cb_tools_tabulate)
3186 { .name = "EditFillSeries",
3187 .label = N_("_Series..."),
3188 .tooltip = N_("Fill according to a linear or exponential series"),
3189 .callback = G_CALLBACK (cb_edit_fill_series)
3191 { .name = "RandomGeneratorUncorrelated",
3192 .label = N_("_Uncorrelated..."),
3193 .tooltip = N_("Generate random numbers of a selection of distributions"),
3194 .callback = G_CALLBACK (cb_tools_random_generator_uncorrelated)
3196 { .name = "RandomGeneratorCorrelated",
3197 .label = N_("_Correlated..."),
3198 .tooltip = N_("Generate variates for correlated normal distributed random variables"),
3199 .callback = G_CALLBACK (cb_tools_random_generator_correlated)
3201 { .name = "CopyDown",
3202 .label = N_("Fill Downwards"),
3203 .accelerator = "<control>D",
3204 .tooltip = N_("Copy the content from the top row to the cells below"),
3205 .callback = G_CALLBACK (cb_copydown)
3207 { .name = "CopyRight",
3208 .label = N_("Fill to Right"),
3209 .accelerator = "<control>R",
3210 .tooltip = N_("Copy the content from the left column to the cells on the right"),
3211 .callback = G_CALLBACK (cb_copyright)
3215 /* Data -> Outline */
3216 { .name = "DataOutlineHideDetail",
3217 .icon = "gnumeric-detail-hide",
3218 .label = N_("_Hide Detail"),
3219 .tooltip = N_("Collapse an outline group"),
3220 .callback = G_CALLBACK (cb_data_hide_detail)
3222 { .name = "DataOutlineShowDetail",
3223 .icon = "gnumeric-detail-show",
3224 .label = N_("_Show Detail"),
3225 .tooltip = N_("Uncollapse an outline group"),
3226 .callback = G_CALLBACK (cb_data_show_detail)
3228 { .name = "DataOutlineGroup",
3229 .icon = "gnumeric-group",
3230 .label = N_("_Group..."),
3231 .accelerator = "<shift><alt>Right",
3232 .tooltip = N_("Add an outline group"),
3233 .callback = G_CALLBACK (cb_data_group)
3235 { .name = "DataOutlineUngroup",
3236 .icon = "gnumeric-ungroup",
3237 .label = N_("_Ungroup..."),
3238 .accelerator = "<shift><alt>Left",
3239 .tooltip = N_("Remove an outline group"),
3240 .callback = G_CALLBACK (cb_data_ungroup)
3243 /* Data -> Filter */
3244 { .name = "DataAutoFilter",
3245 .icon = "gnumeric-autofilter",
3246 .label = N_("Add _Auto Filter"),
3247 .tooltip = N_("Add or remove a filter"),
3248 .callback = G_CALLBACK (cb_auto_filter)
3250 { .name = "DataFilterShowAll",
3251 .label = N_("_Clear Advanced Filter"),
3252 .tooltip = N_("Show all rows hidden by an advanced filter"),
3253 .callback = G_CALLBACK (cb_show_all)
3255 { .name = "DataFilterAdvancedfilter",
3256 .label = N_("Advanced _Filter..."),
3257 .tooltip = N_("Filter data with given criteria"),
3258 .callback = G_CALLBACK (cb_data_filter)
3260 /* Data -> External */
3261 { .name = "DataImportText",
3262 .label = N_("Import _Text File..."),
3263 .tooltip = N_("Import data from a text file"),
3264 .callback = G_CALLBACK (cb_data_import_text)
3266 { .name = "DataImportOther",
3267 .label = N_("Import _Other File..."),
3268 .tooltip = N_("Import data from a file"),
3269 .callback = G_CALLBACK (cb_data_import_other)
3272 /* Data -> Data Slicer */
3273 /* label and tip are context dependent, see wbcg_menu_state_update */
3274 { .name = "DataSlicer",
3275 .label = N_("Add _Data Slicer"),
3276 .tooltip = N_("Create a data slicer"),
3277 .callback = G_CALLBACK (cb_data_slicer_create)
3279 { .name = "DataSlicerRefresh",
3280 .label = N_("_Refresh"),
3281 .tooltip = N_("Regenerate a data slicer from the source data"),
3282 .callback = G_CALLBACK (cb_data_slicer_refresh)
3284 { .name = "DataSlicerEdit",
3285 .label = N_("_Edit Data Slicer..."),
3286 .tooltip = N_("Adjust a data slicer"),
3287 .callback = G_CALLBACK (cb_data_slicer_edit)
3290 /* Standard Toolbar */
3291 { .name = "AutoSum",
3292 .icon = "gnumeric-autosum",
3293 .label = N_("Sum"),
3294 .accelerator = "<alt>equal",
3295 .tooltip = N_("Sum into the current cell"),
3296 .callback = G_CALLBACK (cb_autosum)
3298 { .name = "InsertFormula",
3299 .icon = "gnumeric-formulaguru",
3300 .label = N_("_Function..."),
3301 .tooltip = N_("Edit a function in the current cell"),
3302 .callback = G_CALLBACK (cb_formula_guru)
3305 { .name = "SortAscending",
3306 .icon = "view-sort-ascending",
3307 .label = N_("Sort Ascending"),
3308 .tooltip = N_("Sort the selected region in ascending order based on the first column selected"),
3309 .callback = G_CALLBACK (cb_sort_ascending)
3311 { .name = "SortDescending",
3312 .icon = "view-sort-descending",
3313 .label = N_("Sort Descending"),
3314 .tooltip = N_("Sort the selected region in descending order based on the first column selected"),
3315 .callback = G_CALLBACK (cb_sort_descending)
3318 /* Object Toolbar */
3319 { .name = "CreateFrame",
3320 .icon = "gnumeric-object-frame",
3321 .label = N_("Frame"),
3322 .tooltip = N_("Create a frame"),
3323 .callback = G_CALLBACK (cmd_create_frame)
3325 { .name = "CreateCheckbox",
3326 .icon = "gnumeric-object-checkbox",
3327 .label = N_("Checkbox"),
3328 .tooltip = N_("Create a checkbox"),
3329 .callback = G_CALLBACK (cmd_create_checkbox)
3331 { .name = "CreateScrollbar",
3332 .icon = "gnumeric-object-scrollbar",
3333 .label = N_("Scrollbar"),
3334 .tooltip = N_("Create a scrollbar"),
3335 .callback = G_CALLBACK (cmd_create_scrollbar)
3337 { .name = "CreateSlider",
3338 .icon = "gnumeric-object-slider",
3339 .label = N_("Slider"),
3340 .tooltip = N_("Create a slider"),
3341 .callback = G_CALLBACK (cmd_create_slider)
3343 { .name = "CreateSpinButton",
3344 .icon = "gnumeric-object-spinbutton",
3345 .label = N_("SpinButton"),
3346 .tooltip = N_("Create a spin button"),
3347 .callback = G_CALLBACK (cmd_create_spinbutton)
3349 { .name = "CreateList",
3350 .icon = "gnumeric-object-list",
3351 .label = N_("List"),
3352 .tooltip = N_("Create a list"),
3353 .callback = G_CALLBACK (cmd_create_list)
3355 { .name = "CreateCombo",
3356 .icon = "gnumeric-object-combo",
3357 .label = N_("Combo Box"),
3358 .tooltip = N_("Create a combo box"),
3359 .callback = G_CALLBACK (cmd_create_combo)
3361 { .name = "CreateLine",
3362 .icon = "gnumeric-object-line",
3363 .label = N_("Line"),
3364 .tooltip = N_("Create a line object"),
3365 .callback = G_CALLBACK (cmd_create_line)
3367 { .name = "CreateArrow",
3368 .icon = "gnumeric-object-arrow",
3369 .label = N_("Arrow"),
3370 .tooltip = N_("Create an arrow object"),
3371 .callback = G_CALLBACK (cmd_create_arrow)
3373 { .name = "CreateRectangle",
3374 .icon = "gnumeric-object-rectangle",
3375 .label = N_("Rectangle"),
3376 .tooltip = N_("Create a rectangle object"),
3377 .callback = G_CALLBACK (cmd_create_rectangle)
3379 { .name = "CreateEllipse",
3380 .icon = "gnumeric-object-ellipse",
3381 .label = N_("Ellipse"),
3382 .tooltip = N_("Create an ellipse object"),
3383 .callback = G_CALLBACK (cmd_create_ellipse)
3385 { .name = "CreateButton",
3386 .icon = "gnumeric-object-button",
3387 .label = N_("Button"),
3388 .tooltip = N_("Create a button"),
3389 .callback = G_CALLBACK (cmd_create_button)
3391 { .name = "CreateRadioButton",
3392 .icon = "gnumeric-object-radiobutton",
3393 .label = N_("RadioButton"),
3394 .tooltip = N_("Create a radio button"),
3395 .callback = G_CALLBACK (cmd_create_radiobutton)
3398 /* Format toolbar */
3399 { .name = "FormatMergeCells",
3400 .icon = "gnumeric-cells-merge",
3401 .label = N_("Merge"),
3402 .tooltip = N_("Merge a range of cells"),
3403 .callback = G_CALLBACK (cb_merge_cells)
3405 { .name = "FormatUnmergeCells",
3406 .icon = "gnumeric-cells-split",
3407 .label = N_("Unmerge"),
3408 .tooltip = N_("Split merged ranges of cells"),
3409 .callback = G_CALLBACK (cb_unmerge_cells)
3412 { .name = "FormatAsGeneral",
3413 .label = N_("General"),
3414 .accelerator = "<control>asciitilde",
3415 .tooltip = N_("Format the selection as General"),
3416 .callback = G_CALLBACK (cb_format_as_general)
3418 { .name = "FormatAsNumber",
3419 .label = N_("Number"),
3420 .accelerator = "<control>exclam",
3421 .tooltip = N_("Format the selection as numbers"),
3422 .callback = G_CALLBACK (cb_format_as_number)
3424 { .name = "FormatAsCurrency",
3425 .label = N_("Currency"),
3426 .accelerator = "<control>dollar",
3427 .tooltip = N_("Format the selection as currency"),
3428 .callback = G_CALLBACK (cb_format_as_currency)
3430 { .name = "FormatAsAccounting",
3431 .icon = "gnumeric-format-accounting",
3432 .label = N_("Accounting"),
3433 .tooltip = N_("Format the selection as accounting"),
3434 .callback = G_CALLBACK (cb_format_as_accounting)
3436 { .name = "FormatAsPercentage",
3437 .icon = "gnumeric-format-percentage",
3438 .label = N_("Percentage"),
3439 .accelerator = "<control>percent",
3440 .tooltip = N_("Format the selection as percentage"),
3441 .callback = G_CALLBACK (cb_format_as_percentage)
3443 { .name = "FormatAsScientific",
3444 .label = N_("Scientific"),
3445 .accelerator = "<control>asciicircum",
3446 .tooltip = N_("Format the selection as scientific"),
3447 .callback = G_CALLBACK (cb_format_as_scientific)
3449 { .name = "FormatAsDate",
3450 .label = N_("Date"),
3451 .accelerator = "<control>numbersign",
3452 .tooltip = N_("Format the selection as date"),
3453 .callback = G_CALLBACK (cb_format_as_date)
3455 { .name = "FormatAsTime",
3456 .label = N_("Time"),
3457 .accelerator = "<control>at",
3458 .tooltip = N_("Format the selection as time"),
3459 .callback = G_CALLBACK (cb_format_as_time)
3461 { .name = "FormatAddBorders",
3462 .label = N_("AddBorders"),
3463 .accelerator = "<control>ampersand",
3464 .tooltip = N_("Add a border around the selection"),
3465 .callback = G_CALLBACK (cb_format_add_borders)
3467 { .name = "FormatClearBorders",
3468 .label = N_("ClearBorders"),
3469 .accelerator = "<control>underscore",
3470 .tooltip = N_("Clear the border around the selection"),
3471 .callback = G_CALLBACK (cb_format_clear_borders)
3474 { .name = "FormatWithThousands",
3475 .icon = "gnumeric-format-thousand-separator",
3476 .label = N_("Thousands Separator"),
3477 .tooltip = N_("Set the format of the selected cells to include a thousands separator"),
3478 .callback = G_CALLBACK (cb_format_with_thousands)
3480 { .name = "FormatIncreasePrecision",
3481 .icon = "gnumeric-format-precision-increase",
3482 .label = N_("Increase Precision"),
3483 .tooltip = N_("Increase the number of decimals displayed"),
3484 .callback = G_CALLBACK (cb_format_inc_precision)
3486 { .name = "FormatDecreasePrecision",
3487 .icon = "gnumeric-format-precision-decrease",
3488 .label = N_("Decrease Precision"),
3489 .tooltip = N_("Decrease the number of decimals displayed"),
3490 .callback = G_CALLBACK (cb_format_dec_precision)
3493 /* Gtk marks these accelerators as invalid because they use Tab
3494 * enable them manually in gnm-pane.c */
3495 { .name = "FormatDecreaseIndent",
3496 .icon = "format-indent-less",
3497 .accelerator = "<control><alt><shift>Tab",
3498 .tooltip = N_("Decrease the indent, and align the contents to the left"),
3499 .callback = G_CALLBACK (cb_format_dec_indent)
3501 { .name = "FormatIncreaseIndent",
3502 .icon = "format-indent-more",
3503 .accelerator = "<control><alt>Tab",
3504 .tooltip = N_("Increase the indent, and align the contents to the left"),
3505 .callback = G_CALLBACK (cb_format_inc_indent)
3508 /* ---------------------------------------- */
3510 { .name = "SheetDisplayOutlines",
3511 .toggle = TRUE,
3512 .label = N_("Display _Outlines"),
3513 .accelerator = "<control>8",
3514 .tooltip = N_("Toggle whether or not to display outline groups"),
3515 .callback = G_CALLBACK (cb_sheet_pref_display_outlines)
3517 { .name = "SheetOutlineBelow",
3518 .toggle = TRUE,
3519 .label = N_("Outlines _Below"),
3520 .tooltip = N_("Toggle whether to display row outlines on top or bottom"),
3521 .callback = G_CALLBACK (cb_sheet_pref_outline_symbols_below)
3523 { .name = "SheetOutlineRight",
3524 .toggle = TRUE,
3525 .label = N_("Outlines _Right"),
3526 .tooltip = N_("Toggle whether to display column outlines on the left or right"),
3527 .callback = G_CALLBACK (cb_sheet_pref_outline_symbols_right)
3529 { .name = "SheetDisplayFormulas",
3530 .toggle = TRUE,
3531 .icon = "gnumeric-formulaguru",
3532 .label = N_("Display _Formul\303\246"),
3533 .accelerator = "<control>quoteleft",
3534 .tooltip = N_("Display the value of a formula or the formula itself"),
3535 .callback = G_CALLBACK (cb_sheet_pref_display_formulas)
3537 { .name = "SheetHideZeros",
3538 .toggle = TRUE,
3539 .label = N_("_Hide Zeros"),
3540 .tooltip = N_("Toggle whether or not to display zeros as blanks"),
3541 .callback = G_CALLBACK (cb_sheet_pref_hide_zero)
3543 { .name = "SheetHideGridlines",
3544 .toggle = TRUE,
3545 .label = N_("Hide _Gridlines"),
3546 .tooltip = N_("Toggle whether or not to display gridlines"),
3547 .callback = G_CALLBACK (cb_sheet_pref_hide_grid)
3549 { .name = "SheetHideColHeader",
3550 .toggle = TRUE,
3551 .label = N_("Hide _Column Headers"),
3552 .tooltip = N_("Toggle whether or not to display column headers"),
3553 .callback = G_CALLBACK (cb_sheet_pref_hide_col_header)
3555 { .name = "SheetHideRowHeader",
3556 .toggle = TRUE,
3557 .label = N_("Hide _Row Headers"),
3558 .tooltip = N_("Toggle whether or not to display row headers"),
3559 .callback = G_CALLBACK (cb_sheet_pref_hide_row_header)
3562 /* TODO : Make this a sub menu when we have more convention types */
3563 { .name = "SheetUseR1C1",
3564 .toggle = TRUE,
3565 .label = N_("Use R1C1 N_otation "),
3566 .tooltip = N_("Display addresses as R1C1 or A1"),
3567 .callback = G_CALLBACK (cb_sheet_pref_use_r1c1)
3570 { .name = "AlignLeft",
3571 .toggle = TRUE,
3572 .icon = "format-justify-left",
3573 .label = N_("_Left Align"),
3574 .tooltip = N_("Align left"),
3575 .callback = G_CALLBACK (cb_align_left)
3577 { .name = "AlignCenter",
3578 .toggle = TRUE,
3579 .icon = "format-justify-center",
3580 .label = N_("_Center"),
3581 .tooltip = N_("Center horizontally"),
3582 .callback = G_CALLBACK (cb_align_center)
3584 { .name = "AlignRight",
3585 .toggle = TRUE,
3586 .icon = "format-justify-right",
3587 .label = N_("_Right Align"),
3588 .tooltip = N_("Align right"),
3589 .callback = G_CALLBACK (cb_align_right)
3591 { .name = "CenterAcrossSelection",
3592 .toggle = TRUE,
3593 .icon = "gnumeric-center-across-selection",
3594 .label = N_("_Center Across Selection"),
3595 .tooltip = N_("Center horizontally across the selection"),
3596 .callback = G_CALLBACK (cb_center_across_selection)
3598 { .name = "MergeAndCenter",
3599 .toggle = TRUE,
3600 .label = N_("_Merge and Center"),
3601 .tooltip = N_("Merge the selection into 1 cell, and center horizontally."),
3602 .callback = G_CALLBACK (cb_merge_and_center)
3604 #warning "Add justify"
3605 #warning "h/v distributed?"
3607 #warning "Get vertical alignment icons"
3608 { .name = "AlignTop",
3609 .toggle = TRUE,
3610 .label = N_("Align _Top"),
3611 .tooltip = N_("Align Top"),
3612 .callback = G_CALLBACK (cb_align_top)
3614 { .name = "AlignVCenter",
3615 .toggle = TRUE,
3616 .label = N_("_Vertically Center"),
3617 .tooltip = N_("Vertically Center"),
3618 .callback = G_CALLBACK (cb_align_vcenter)
3620 { .name = "AlignBottom",
3621 .toggle = TRUE,
3622 .label = N_("Align _Bottom"),
3623 .tooltip = N_("Align Bottom"),
3624 .callback = G_CALLBACK (cb_align_bottom)
3628 static GnmActionEntry const font_actions[] = {
3629 { .name = "FontBold",
3630 .toggle = TRUE,
3631 .icon = "format-text-bold",
3632 .label = N_("_Bold"),
3633 .accelerator = "<control>b", /* ALSO "<control>2" */
3634 .tooltip = N_("Bold"),
3635 .callback = G_CALLBACK (cb_font_bold),
3636 .is_active = FALSE },
3637 { .name = "FontItalic",
3638 .toggle = TRUE,
3639 .icon = "format-text-italic",
3640 .label = N_("_Italic"),
3641 .accelerator = "<control>i", /* ALSO "<control>3" */
3642 .tooltip = N_("Italic"),
3643 .callback = G_CALLBACK (cb_font_italic),
3644 .is_active = FALSE },
3645 { .name = "FontUnderline",
3646 .toggle = TRUE,
3647 .icon = "format-text-underline",
3648 .label = N_("_Underline"),
3649 .accelerator = "<control>u", /* ALSO "<control>4" */
3650 .tooltip = N_("Underline"),
3651 .callback = G_CALLBACK (cb_font_underline),
3652 .is_active = FALSE },
3653 { .name = "FontDoubleUnderline",
3654 .toggle = TRUE,
3655 .icon = "stock_text_underlined-double", /* from icon theme */
3656 .label = N_("_Double Underline"),
3657 .accelerator = "<control><shift>d",
3658 .tooltip = N_("Double Underline"),
3659 .callback = G_CALLBACK (cb_font_double_underline),
3660 .is_active = FALSE },
3661 { .name = "FontSingleLowUnderline",
3662 .toggle = TRUE,
3663 .label = N_("_Single Low Underline"),
3664 .accelerator = "<control><shift>l",
3665 .tooltip = N_("Single Low Underline"),
3666 .callback = G_CALLBACK (cb_font_underline_low),
3667 .is_active = FALSE },
3668 { .name = "FontDoubleLowUnderline",
3669 .toggle = TRUE,
3670 .label = N_("Double _Low Underline"),
3671 .tooltip = N_("Double Low Underline"),
3672 .callback = G_CALLBACK (cb_font_double_underline_low),
3673 .is_active = FALSE },
3674 { .name = "FontStrikeThrough",
3675 .toggle = TRUE,
3676 .icon = "format-text-strikethrough",
3677 .label = N_("_Strikethrough"),
3678 .accelerator = "<control>5",
3679 .tooltip = N_("Strikethrough"),
3680 .callback = G_CALLBACK (cb_font_strikethrough),
3681 .is_active = FALSE },
3682 { .name = "FontSuperscript",
3683 .toggle = TRUE,
3684 .icon = "gnumeric-superscript",
3685 .label = N_("Su_perscript"),
3686 .accelerator = "<control>asciicircum",
3687 .tooltip = N_("Superscript"),
3688 .callback = G_CALLBACK (cb_font_superscript),
3689 .is_active = FALSE },
3690 { .name = "FontSubscript",
3691 .toggle = TRUE,
3692 .icon = "gnumeric-subscript",
3693 .label = N_("Subscrip_t"),
3694 .accelerator = "<control>underscore",
3695 .tooltip = N_("Subscript"),
3696 .callback = G_CALLBACK (cb_font_subscript), .is_active = FALSE }
3699 /****************************************************************************/
3701 static GOActionComboPixmapsElement const halignment_combo_info[] = {
3702 { N_("Align left"), "format-justify-left", GNM_HALIGN_LEFT },
3703 { N_("Center horizontally"), "format-justify-center", GNM_HALIGN_CENTER },
3704 { N_("Align right"), "format-justify-right", GNM_HALIGN_RIGHT },
3705 { N_("Fill horizontally"), "gnumeric-format-halign-fill", GNM_HALIGN_FILL },
3706 { N_("Justify horizontally"), "format-justify-fill", GNM_HALIGN_JUSTIFY },
3707 { N_("Distributed"), "gnumeric-format-halign-distributed", GNM_HALIGN_DISTRIBUTED },
3708 { N_("Center horizontally across the selection"),
3709 "gnumeric-center-across-selection", GNM_HALIGN_CENTER_ACROSS_SELECTION },
3710 { N_("Align numbers right, and text left"),
3711 "gnumeric-format-halign-general", GNM_HALIGN_GENERAL },
3712 { NULL, NULL }
3714 static GOActionComboPixmapsElement const valignment_combo_info[] = {
3715 { N_("Align top"), "gnumeric-format-valign-top", GNM_VALIGN_TOP },
3716 { N_("Center vertically"), "gnumeric-format-valign-center", GNM_VALIGN_CENTER },
3717 { N_("Align bottom"), "gnumeric-format-valign-bottom", GNM_VALIGN_BOTTOM },
3718 { N_("Justify"), "gnumeric-format-valign-justify", GNM_VALIGN_JUSTIFY },
3719 { N_("Align distributed"), "gnumeric-format-valign-distributed", GNM_VALIGN_DISTRIBUTED },
3720 { NULL, NULL}
3723 static void
3724 cb_halignment_activated (GOActionComboPixmaps *a, WBCGtk *wbcg)
3726 wbcg_set_selection_halign (wbcg,
3727 go_action_combo_pixmaps_get_selected (a, NULL));
3729 static void
3730 cb_valignment_activated (GOActionComboPixmaps *a, WBCGtk *wbcg)
3732 wbcg_set_selection_valign (wbcg,
3733 go_action_combo_pixmaps_get_selected (a, NULL));
3736 static void
3737 wbc_gtk_init_alignments (WBCGtk *wbcg)
3739 wbcg->halignment = go_action_combo_pixmaps_new ("HAlignmentSelector",
3740 halignment_combo_info, 3, 1);
3741 g_object_set (G_OBJECT (wbcg->halignment),
3742 "label", _("Horizontal Alignment"),
3743 "tooltip", _("Horizontal Alignment"),
3744 NULL);
3745 g_signal_connect (G_OBJECT (wbcg->halignment),
3746 "activate",
3747 G_CALLBACK (cb_halignment_activated), wbcg);
3748 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->halignment));
3750 wbcg->valignment = go_action_combo_pixmaps_new ("VAlignmentSelector",
3751 valignment_combo_info, 1, 3);
3752 g_object_set (G_OBJECT (wbcg->valignment),
3753 "label", _("Vertical Alignment"),
3754 "tooltip", _("Vertical Alignment"),
3755 NULL);
3756 g_signal_connect (G_OBJECT (wbcg->valignment),
3757 "activate",
3758 G_CALLBACK (cb_valignment_activated), wbcg);
3759 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->valignment));
3762 /****************************************************************************/
3764 static void
3765 cb_custom_color_created (GOActionComboColor *caction, GtkWidget *dialog, WBCGtk *wbcg)
3767 wbc_gtk_attach_guru (wbcg, dialog);
3768 wbcg_set_transient (wbcg, GTK_WINDOW (dialog));
3771 static void
3772 cb_fore_color_changed (GOActionComboColor *a, WBCGtk *wbcg)
3774 WorkbookControl *wbc = GNM_WBC (wbcg);
3775 GnmStyle *mstyle;
3776 GOColor c;
3777 gboolean is_default;
3779 if (wbcg->updating_ui)
3780 return;
3781 c = go_action_combo_color_get_color (a, &is_default);
3783 if (wbcg_is_editing (wbcg)) {
3784 wbcg_edit_add_markup (wbcg, go_color_to_pango (c, TRUE));
3785 return;
3788 mstyle = gnm_style_new ();
3789 gnm_style_set_font_color (mstyle, is_default
3790 ? style_color_auto_font ()
3791 : gnm_color_new_go (c));
3792 cmd_selection_format (wbc, mstyle, NULL, _("Set Foreground Color"));
3795 static void
3796 wbc_gtk_init_color_fore (WBCGtk *gtk)
3798 GnmColor *sc_auto_font = style_color_auto_font ();
3799 GOColor default_color = sc_auto_font->go_color;
3800 style_color_unref (sc_auto_font);
3802 gtk->fore_color = go_action_combo_color_new ("ColorFore", "gnumeric-font",
3803 _("Automatic"), default_color, NULL); /* set group to view */
3804 go_action_combo_color_set_allow_alpha (gtk->fore_color, TRUE);
3805 g_object_set (G_OBJECT (gtk->fore_color),
3806 "label", _("Foreground"),
3807 "tooltip", _("Foreground"),
3808 NULL);
3809 g_signal_connect (G_OBJECT (gtk->fore_color),
3810 "combo-activate",
3811 G_CALLBACK (cb_fore_color_changed), gtk);
3812 g_signal_connect (G_OBJECT (gtk->fore_color),
3813 "display-custom-dialog",
3814 G_CALLBACK (cb_custom_color_created), gtk);
3815 gnm_action_group_add_action (gtk->font_actions,
3816 GTK_ACTION (gtk->fore_color));
3819 static void
3820 cb_back_color_changed (GOActionComboColor *a, WBCGtk *wbcg)
3822 WorkbookControl *wbc = GNM_WBC (wbcg);
3823 GnmStyle *mstyle;
3824 GOColor c;
3825 gboolean is_default;
3827 if (wbcg->updating_ui)
3828 return;
3830 c = go_action_combo_color_get_color (a, &is_default);
3832 mstyle = gnm_style_new ();
3833 if (!is_default) {
3834 /* We need to have a pattern of at least solid to draw a background colour */
3835 if (!gnm_style_is_element_set (mstyle, MSTYLE_PATTERN) ||
3836 gnm_style_get_pattern (mstyle) < 1)
3837 gnm_style_set_pattern (mstyle, 1);
3839 gnm_style_set_back_color (mstyle, gnm_color_new_go (c));
3840 } else
3841 gnm_style_set_pattern (mstyle, 0); /* Set background to NONE */
3842 cmd_selection_format (wbc, mstyle, NULL, _("Set Background Color"));
3845 static void
3846 wbc_gtk_init_color_back (WBCGtk *gtk)
3848 gtk->back_color = go_action_combo_color_new ("ColorBack", "gnumeric-bucket",
3849 _("Clear Background"), 0, NULL);
3850 g_object_set (G_OBJECT (gtk->back_color),
3851 "label", _("Background"),
3852 "tooltip", _("Background"),
3853 NULL);
3854 g_object_connect (G_OBJECT (gtk->back_color),
3855 "signal::combo-activate", G_CALLBACK (cb_back_color_changed), gtk,
3856 "signal::display-custom-dialog", G_CALLBACK (cb_custom_color_created), gtk,
3857 NULL);
3858 gnm_action_group_add_action (gtk->actions, GTK_ACTION (gtk->back_color));
3861 /****************************************************************************/
3863 static GOActionComboPixmapsElement const border_combo_info[] = {
3864 { N_("Left"), "gnumeric-format-border-left", 11 },
3865 { N_("Clear Borders"), "gnumeric-format-border-none", 12 },
3866 { N_("Right"), "gnumeric-format-border-right", 13 },
3868 { N_("All Borders"), "gnumeric-format-border-all", 21 },
3869 { N_("Outside Borders"), "gnumeric-format-border-outside", 22 },
3870 { N_("Thick Outside Borders"), "gnumeric-format-border-thick-outside", 23 },
3872 { N_("Bottom"), "gnumeric-format-border-bottom", 31 },
3873 { N_("Double Bottom"), "gnumeric-format-border-double-bottom", 32 },
3874 { N_("Thick Bottom"), "gnumeric-format-border-thick-bottom", 33 },
3876 { N_("Top and Bottom"), "gnumeric-format-border-top-n-bottom", 41 },
3877 { N_("Top and Double Bottom"), "gnumeric-format-border-top-n-double-bottom", 42 },
3878 { N_("Top and Thick Bottom"), "gnumeric-format-border-top-n-thick-bottom", 43 },
3880 { NULL, NULL}
3883 static void
3884 cb_border_activated (GOActionComboPixmaps *a, WorkbookControl *wbc)
3886 Sheet *sheet = wb_control_cur_sheet (wbc);
3887 GnmBorder *borders[GNM_STYLE_BORDER_EDGE_MAX];
3888 int i;
3889 int index = go_action_combo_pixmaps_get_selected (a, NULL);
3891 /* Init the list */
3892 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; i++)
3893 borders[i] = NULL;
3895 switch (index) {
3896 case 11 : /* left */
3897 borders[GNM_STYLE_BORDER_LEFT] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3898 sheet_style_get_auto_pattern_color (sheet),
3899 gnm_style_border_get_orientation (GNM_STYLE_BORDER_LEFT));
3900 break;
3902 case 12 : /* none */
3903 for (i = GNM_STYLE_BORDER_TOP; i < GNM_STYLE_BORDER_EDGE_MAX; i++)
3904 borders[i] = gnm_style_border_ref (gnm_style_border_none ());
3905 break;
3907 case 13 : /* right */
3908 borders[GNM_STYLE_BORDER_RIGHT] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3909 sheet_style_get_auto_pattern_color (sheet),
3910 gnm_style_border_get_orientation (GNM_STYLE_BORDER_RIGHT));
3911 break;
3913 case 21 : /* all */
3914 for (i = GNM_STYLE_BORDER_HORIZ; i <= GNM_STYLE_BORDER_VERT; ++i)
3915 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3916 sheet_style_get_auto_pattern_color (sheet),
3917 gnm_style_border_get_orientation (i));
3918 /* fall through */
3920 case 22 : /* outside */
3921 for (i = GNM_STYLE_BORDER_TOP; i <= GNM_STYLE_BORDER_RIGHT; ++i)
3922 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3923 sheet_style_get_auto_pattern_color (sheet),
3924 gnm_style_border_get_orientation (i));
3925 break;
3927 case 23 : /* thick_outside */
3928 for (i = GNM_STYLE_BORDER_TOP; i <= GNM_STYLE_BORDER_RIGHT; ++i)
3929 borders[i] = gnm_style_border_fetch (GNM_STYLE_BORDER_THICK,
3930 sheet_style_get_auto_pattern_color (sheet),
3931 gnm_style_border_get_orientation (i));
3932 break;
3934 case 41 : /* top_n_bottom */
3935 case 42 : /* top_n_double_bottom */
3936 case 43 : /* top_n_thick_bottom */
3937 borders[GNM_STYLE_BORDER_TOP] = gnm_style_border_fetch (GNM_STYLE_BORDER_THIN,
3938 sheet_style_get_auto_pattern_color (sheet),
3939 gnm_style_border_get_orientation (GNM_STYLE_BORDER_TOP));
3940 /* Fall through */
3942 case 31 : /* bottom */
3943 case 32 : /* double_bottom */
3944 case 33 : /* thick_bottom */
3946 int const tmp = index % 10;
3947 GnmStyleBorderType const t =
3948 (tmp == 1) ? GNM_STYLE_BORDER_THIN :
3949 (tmp == 2) ? GNM_STYLE_BORDER_DOUBLE
3950 : GNM_STYLE_BORDER_THICK;
3952 borders[GNM_STYLE_BORDER_BOTTOM] = gnm_style_border_fetch (t,
3953 sheet_style_get_auto_pattern_color (sheet),
3954 gnm_style_border_get_orientation (GNM_STYLE_BORDER_BOTTOM));
3955 break;
3958 default:
3959 g_warning ("Unknown border preset selected (%d)", index);
3960 return;
3963 cmd_selection_format (wbc, NULL, borders, _("Set Borders"));
3966 static void
3967 wbc_gtk_init_borders (WBCGtk *wbcg)
3969 wbcg->borders = go_action_combo_pixmaps_new ("BorderSelector", border_combo_info, 3, 4);
3970 g_object_set (G_OBJECT (wbcg->borders),
3971 "label", _("Borders"),
3972 "tooltip", _("Borders"),
3973 NULL);
3974 #if 0
3975 go_combo_pixmaps_select (wbcg->borders, 1); /* default to none */
3976 #endif
3977 g_signal_connect (G_OBJECT (wbcg->borders),
3978 "combo-activate",
3979 G_CALLBACK (cb_border_activated), wbcg);
3980 gnm_action_group_add_action (wbcg->actions, GTK_ACTION (wbcg->borders));
3983 /****************************************************************************/
3985 static void
3986 cb_chain_sensitivity (GtkAction *src, G_GNUC_UNUSED GParamSpec *pspec,
3987 GtkAction *action)
3989 gboolean old_val = gtk_action_get_sensitive (action);
3990 gboolean new_val = gtk_action_get_sensitive (src);
3991 if ((new_val != 0) == (old_val != 0))
3992 return;
3993 if (new_val)
3994 gtk_action_connect_accelerator (action);
3995 else
3996 gtk_action_disconnect_accelerator (action);
3997 g_object_set (action, "sensitive", new_val, NULL);
4001 static void
4002 create_undo_redo (GOActionComboStack **haction, char const *hname,
4003 GCallback hcb,
4004 GtkAction **vaction, char const *vname,
4005 GCallback vcb,
4006 WBCGtk *gtk,
4007 char const *tooltip,
4008 char const *icon_name,
4009 char const *accel, const char *alt_accel)
4011 *haction = g_object_new
4012 (go_action_combo_stack_get_type (),
4013 "name", hname,
4014 "tooltip", tooltip,
4015 "icon-name", icon_name,
4016 "sensitive", FALSE,
4017 "visible-vertical", FALSE,
4018 NULL);
4019 gtk_action_group_add_action_with_accel
4020 (gtk->semi_permanent_actions,
4021 GTK_ACTION (*haction),
4022 accel);
4023 g_signal_connect (G_OBJECT (*haction), "activate", hcb, gtk);
4025 *vaction = g_object_new
4026 (GTK_TYPE_ACTION,
4027 "name", vname,
4028 "tooltip", tooltip,
4029 "icon-name", icon_name,
4030 "sensitive", FALSE,
4031 "visible-horizontal", FALSE,
4032 NULL);
4033 gtk_action_group_add_action_with_accel
4034 (gtk->semi_permanent_actions,
4035 GTK_ACTION (*vaction),
4036 alt_accel);
4037 g_signal_connect_swapped (G_OBJECT (*vaction), "activate", vcb, gtk);
4039 g_signal_connect (G_OBJECT (*haction), "notify::sensitive",
4040 G_CALLBACK (cb_chain_sensitivity), *vaction);
4044 static void
4045 cb_undo_activated (GOActionComboStack *a, WorkbookControl *wbc)
4047 unsigned n = workbook_find_command (wb_control_get_workbook (wbc), TRUE,
4048 go_action_combo_stack_selection (a));
4049 while (n-- > 0)
4050 command_undo (wbc);
4053 static void
4054 cb_redo_activated (GOActionComboStack *a, WorkbookControl *wbc)
4056 unsigned n = workbook_find_command (wb_control_get_workbook (wbc), FALSE,
4057 go_action_combo_stack_selection (a));
4058 while (n-- > 0)
4059 command_redo (wbc);
4062 static void
4063 wbc_gtk_init_undo_redo (WBCGtk *gtk)
4065 create_undo_redo (
4066 &gtk->redo_haction, "Redo", G_CALLBACK (cb_redo_activated),
4067 &gtk->redo_vaction, "VRedo", G_CALLBACK (command_redo),
4068 gtk, _("Redo the undone action"),
4069 "edit-redo", "<control>y", "<control><shift>z");
4070 create_undo_redo (
4071 &gtk->undo_haction, "Undo", G_CALLBACK (cb_undo_activated),
4072 &gtk->undo_vaction, "VUndo", G_CALLBACK (command_undo),
4073 gtk, _("Undo the last action"),
4074 "edit-undo", "<control>z", NULL);
4077 /****************************************************************************/
4079 static GNM_ACTION_DEF (cb_zoom_activated)
4081 WorkbookControl *wbc = (WorkbookControl *)wbcg;
4082 Sheet *sheet = wb_control_cur_sheet (wbc);
4083 char const *new_zoom;
4084 int factor;
4085 char *end;
4087 if (sheet == NULL || wbcg->updating_ui || wbcg->snotebook == NULL)
4088 return;
4090 new_zoom = go_action_combo_text_get_entry (wbcg->zoom_haction);
4092 errno = 0; /* strtol sets errno, but does not clear it. */
4093 factor = strtol (new_zoom, &end, 10);
4094 if (new_zoom != end && errno != ERANGE && factor == (gnm_float)factor)
4095 /* The GSList of sheet passed to cmd_zoom will be freed by cmd_zoom,
4096 * and the sheet will force an update of the zoom combo to keep the
4097 * display consistent
4099 cmd_zoom (wbc, g_slist_append (NULL, sheet), factor / 100.);
4102 static GNM_ACTION_DEF (cb_vzoom_activated)
4104 dialog_zoom (wbcg, wbcg_cur_sheet (wbcg));
4107 static void
4108 wbc_gtk_init_zoom (WBCGtk *wbcg)
4110 #warning TODO : Add zoom to selection
4111 static char const * const preset_zoom [] = {
4112 "200%",
4113 "150%",
4114 "100%",
4115 "75%",
4116 "50%",
4117 "25%",
4118 NULL
4120 int i;
4122 /* ----- horizontal ----- */
4124 wbcg->zoom_haction =
4125 g_object_new (go_action_combo_text_get_type (),
4126 "name", "Zoom",
4127 "label", _("_Zoom"),
4128 "visible-vertical", FALSE,
4129 "tooltip", _("Zoom"),
4130 "stock-id", "zoom-in",
4131 NULL);
4132 go_action_combo_text_set_width (wbcg->zoom_haction, "10000%");
4133 for (i = 0; preset_zoom[i] != NULL ; ++i)
4134 go_action_combo_text_add_item (wbcg->zoom_haction,
4135 preset_zoom[i]);
4137 g_signal_connect (G_OBJECT (wbcg->zoom_haction),
4138 "activate",
4139 G_CALLBACK (cb_zoom_activated), wbcg);
4140 gnm_action_group_add_action (wbcg->actions,
4141 GTK_ACTION (wbcg->zoom_haction));
4143 /* ----- vertical ----- */
4145 wbcg->zoom_vaction =
4146 g_object_new (GTK_TYPE_ACTION,
4147 "name", "VZoom",
4148 "tooltip", _("Zoom"),
4149 "icon-name", "zoom-in",
4150 "visible-horizontal", FALSE,
4151 NULL);
4152 g_signal_connect (G_OBJECT (wbcg->zoom_vaction),
4153 "activate",
4154 G_CALLBACK (cb_vzoom_activated), wbcg);
4155 gnm_action_group_add_action (wbcg->actions,
4156 GTK_ACTION (wbcg->zoom_vaction));
4158 /* ----- chain ----- */
4160 g_signal_connect (G_OBJECT (wbcg->zoom_haction), "notify::sensitive",
4161 G_CALLBACK (cb_chain_sensitivity), wbcg->zoom_vaction);
4164 /****************************************************************************/
4166 typedef struct { GtkAction base; } GnmFontAction;
4167 typedef struct { GtkActionClass base; } GnmFontActionClass;
4169 static PangoFontDescription *
4170 gnm_font_action_get_font_desc (GtkAction *act)
4172 PangoFontDescription *desc =
4173 g_object_get_data (G_OBJECT (act), "font-data");
4174 return desc;
4177 void
4178 wbcg_font_action_set_font_desc (GtkAction *act, PangoFontDescription *desc)
4180 PangoFontDescription *old_desc;
4181 GSList *p;
4183 old_desc = g_object_get_data (G_OBJECT (act), "font-data");
4184 if (!old_desc) {
4185 old_desc = pango_font_description_new ();
4186 g_object_set_data_full (G_OBJECT (act),
4187 "font-data", old_desc,
4188 (GDestroyNotify)pango_font_description_free);
4190 pango_font_description_merge (old_desc, desc, TRUE);
4192 for (p = gtk_action_get_proxies (act); p; p = p->next) {
4193 GtkWidget *w = p->data;
4194 GtkWidget *child;
4195 GtkFontChooser *chooser;
4197 if (!GTK_IS_BIN (w))
4198 continue;
4200 child = gtk_bin_get_child (GTK_BIN (w));
4201 if (!GTK_IS_FONT_CHOOSER (child))
4202 continue;
4204 chooser = GTK_FONT_CHOOSER (child);
4205 gtk_font_chooser_set_font_desc (chooser, old_desc);
4209 static void
4210 cb_font_set (GtkFontChooser *chooser, GtkAction *act)
4212 PangoFontDescription *desc = gtk_font_chooser_get_font_desc (chooser);
4213 wbcg_font_action_set_font_desc (act, desc);
4214 pango_font_description_free (desc);
4215 gtk_action_activate (act);
4218 static void
4219 cb_font_button_screen_changed (GtkWidget *widget)
4221 /* Doesn't look right */
4222 #if 0
4223 GdkScreen *screen = gtk_widget_get_screen (widget);
4225 if (screen) {
4226 int w = gnm_widget_measure_string (widget,
4227 "XXMonospace | 99XX");
4228 gtk_widget_set_size_request (widget, w, -1);
4230 #endif
4233 /* Filter to ignore non-scalable fonts. */
4234 static gboolean
4235 cb_font_filter (G_GNUC_UNUSED const PangoFontFamily *family,
4236 const PangoFontFace *face_,
4237 gpointer user)
4239 PangoFontFace *face = (PangoFontFace*)face_;
4240 int n_sizes;
4241 int *sizes = NULL;
4242 static int debug = -1;
4244 pango_font_face_list_sizes (face, &sizes, &n_sizes);
4245 g_free (sizes);
4247 if (debug == -1)
4248 debug = gnm_debug_flag ("fonts");
4250 if (n_sizes > 0 && debug) {
4251 PangoFontDescription *desc = pango_font_face_describe (face);
4252 char *s = pango_font_description_to_string (desc);
4253 g_printerr ("Ignoring bitmap face %s\n", s);
4254 g_free (s);
4255 pango_font_description_free (desc);
4258 return n_sizes == 0;
4261 static GtkWidget *
4262 gnm_font_action_create_tool_item (GtkAction *action)
4264 GtkWidget *item = g_object_new
4265 (GTK_TYPE_TOOL_ITEM,
4266 NULL);
4267 GtkWidget *but = g_object_new
4268 (gnm_font_button_get_type(),
4269 "dialog-type", GO_TYPE_FONT_SEL_DIALOG,
4270 "show-preview-entry", TRUE,
4271 "show-style", FALSE,
4272 "relief", gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (item)),
4273 "focus-on-click", FALSE,
4274 NULL);
4275 if (0) gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (but),
4276 cb_font_filter,
4277 NULL,
4278 NULL);
4279 gtk_widget_show_all (but);
4280 gtk_container_add (GTK_CONTAINER (item), but);
4281 g_signal_connect (but,
4282 "font-set", G_CALLBACK (cb_font_set),
4283 action);
4284 g_signal_connect (but,
4285 "screen-changed",
4286 G_CALLBACK (cb_font_button_screen_changed),
4287 action);
4288 return item;
4291 static void
4292 gnm_font_action_class_init (GObjectClass *gobject_class)
4294 GtkActionClass *act = GTK_ACTION_CLASS (gobject_class);
4296 act->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
4297 act->create_tool_item = gnm_font_action_create_tool_item;
4300 static
4301 GSF_CLASS (GnmFontAction, gnm_font_action,
4302 gnm_font_action_class_init, NULL, GTK_TYPE_ACTION)
4303 #if 0
4305 #endif
4306 #define GNM_FONT_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), gnm_font_action_get_type(), GnmFontAction))
4308 static void
4309 cb_font_changed (GtkAction *act, WBCGtk *gtk)
4311 PangoFontDescription *desc = gnm_font_action_get_font_desc (act);
4312 const char *family = pango_font_description_get_family (desc);
4313 int size = pango_font_description_get_size (desc);
4316 * Ignore events during destruction. This is an attempt at avoiding
4317 * https://bugzilla.redhat.com/show_bug.cgi?id=803904 for which we
4318 * blame gtk.
4320 if (gtk->snotebook == NULL)
4321 return;
4323 if (wbcg_is_editing (WBC_GTK (gtk))) {
4324 wbcg_edit_add_markup (WBC_GTK (gtk),
4325 pango_attr_family_new (family));
4326 wbcg_edit_add_markup (WBC_GTK (gtk),
4327 pango_attr_size_new (size));
4328 } else {
4329 GnmStyle *style = gnm_style_new ();
4330 char *font_name = pango_font_description_to_string (desc);
4331 char *title = g_strdup_printf (_("Setting Font %s"), font_name);
4332 g_free (font_name);
4334 gnm_style_set_font_name (style, family);
4335 gnm_style_set_font_size (style, size / (double)PANGO_SCALE);
4337 cmd_selection_format (GNM_WBC (gtk), style, NULL, title);
4338 g_free (title);
4342 static void
4343 cb_font_name_vaction_response (GtkDialog *dialog,
4344 gint response_id,
4345 GtkAction *act)
4347 WBCGtk *wbcg = g_object_get_data (G_OBJECT (act), "wbcg");
4349 if (response_id == GTK_RESPONSE_OK) {
4350 PangoFontDescription *desc = gtk_font_chooser_get_font_desc
4351 (GTK_FONT_CHOOSER (dialog));
4352 wbcg_font_action_set_font_desc (act, desc);
4353 pango_font_description_free (desc);
4354 cb_font_changed (act, wbcg);
4357 gtk_widget_destroy (GTK_WIDGET (dialog));
4361 static void
4362 cb_font_name_vaction_clicked (GtkAction *act, WBCGtk *wbcg)
4364 GtkFontChooser *font_dialog;
4365 const char *key = "font-name-dialog";
4367 if (gnm_dialog_raise_if_exists (wbcg, key))
4368 return;
4370 font_dialog = g_object_new (GO_TYPE_FONT_SEL_DIALOG, NULL);
4371 gtk_font_chooser_set_font_desc (font_dialog,
4372 gnm_font_action_get_font_desc (act));
4373 g_signal_connect (font_dialog, "response",
4374 G_CALLBACK (cb_font_name_vaction_response),
4375 act);
4377 gtk_window_present (GTK_WINDOW (font_dialog));
4379 gnm_keyed_dialog (wbcg, GTK_WINDOW (font_dialog), key);
4382 static GtkAction *
4383 wbc_gtk_init_font_name (WBCGtk *gtk, gboolean horiz)
4385 GtkAction *act = g_object_new
4386 (horiz ? gnm_font_action_get_type () : GTK_TYPE_ACTION,
4387 "visible-vertical", !horiz,
4388 "visible-horizontal", horiz,
4389 "name", (horiz ? "FontName" : "VFontName"),
4390 "tooltip", _("Change font"),
4391 "icon-name", "gnumeric-font",
4392 NULL);
4394 g_object_set_data (G_OBJECT (act), "wbcg", gtk);
4396 g_signal_connect (G_OBJECT (act),
4397 "activate",
4398 (horiz
4399 ? G_CALLBACK (cb_font_changed)
4400 : G_CALLBACK (cb_font_name_vaction_clicked)),
4401 gtk);
4403 gnm_action_group_add_action (gtk->font_actions, act);
4405 return act;
4408 /****************************************************************************/
4410 static void
4411 list_actions (GtkActionGroup *group)
4413 GList *actions, *l;
4415 if (!group)
4416 return;
4418 actions = gtk_action_group_list_actions (group);
4419 for (l = actions; l; l = l->next) {
4420 GtkAction *act = l->data;
4421 const char *name = gtk_action_get_name (act);
4422 g_printerr ("Action %s\n", name);
4425 g_list_free (actions);
4428 void
4429 wbc_gtk_init_actions (WBCGtk *wbcg)
4431 static struct {
4432 char const *name;
4433 gboolean is_font;
4434 unsigned offset;
4435 } const toggles[] = {
4436 { "FontBold", TRUE, G_STRUCT_OFFSET (WBCGtk, font.bold) },
4437 { "FontItalic", TRUE, G_STRUCT_OFFSET (WBCGtk, font.italic) },
4438 { "FontUnderline", TRUE, G_STRUCT_OFFSET (WBCGtk, font.underline) },
4439 { "FontDoubleUnderline", TRUE, G_STRUCT_OFFSET (WBCGtk, font.d_underline) },
4440 { "FontSingleLowUnderline",TRUE, G_STRUCT_OFFSET (WBCGtk, font.sl_underline) },
4441 { "FontDoubleLowUnderline",TRUE, G_STRUCT_OFFSET (WBCGtk, font.dl_underline) },
4442 { "FontSuperscript", TRUE, G_STRUCT_OFFSET (WBCGtk, font.superscript) },
4443 { "FontSubscript", TRUE, G_STRUCT_OFFSET (WBCGtk, font.subscript) },
4444 { "FontStrikeThrough", TRUE, G_STRUCT_OFFSET (WBCGtk, font.strikethrough) },
4446 { "AlignLeft", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.left) },
4447 { "AlignCenter", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.center) },
4448 { "AlignRight", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.right) },
4449 { "CenterAcrossSelection", FALSE, G_STRUCT_OFFSET (WBCGtk, h_align.center_across_selection) },
4450 { "AlignTop", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.top) },
4451 { "AlignVCenter", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.center) },
4452 { "AlignBottom", FALSE, G_STRUCT_OFFSET (WBCGtk, v_align.bottom) }
4454 unsigned i;
4456 wbcg->permanent_actions = gtk_action_group_new ("PermanentActions");
4457 wbcg->actions = gtk_action_group_new ("Actions");
4458 wbcg->font_actions = gtk_action_group_new ("FontActions");
4459 wbcg->data_only_actions = gtk_action_group_new ("DataOnlyActions");
4460 wbcg->semi_permanent_actions = gtk_action_group_new ("SemiPermanentActions");
4462 gnm_action_group_add_actions (wbcg->permanent_actions,
4463 permanent_actions, G_N_ELEMENTS (permanent_actions), wbcg);
4464 gnm_action_group_add_actions (wbcg->actions,
4465 actions, G_N_ELEMENTS (actions), wbcg);
4466 gnm_action_group_add_actions (wbcg->font_actions,
4467 font_actions, G_N_ELEMENTS (font_actions), wbcg);
4468 gnm_action_group_add_actions (wbcg->data_only_actions,
4469 data_only_actions, G_N_ELEMENTS (data_only_actions), wbcg);
4470 gnm_action_group_add_actions (wbcg->semi_permanent_actions,
4471 semi_permanent_actions, G_N_ELEMENTS (semi_permanent_actions), wbcg);
4473 wbc_gtk_init_alignments (wbcg);
4474 wbc_gtk_init_color_fore (wbcg);
4475 wbc_gtk_init_color_back (wbcg);
4476 wbc_gtk_init_borders (wbcg);
4477 wbc_gtk_init_undo_redo (wbcg);
4478 wbc_gtk_init_zoom (wbcg);
4479 wbcg->font_name_haction = wbc_gtk_init_font_name (wbcg, TRUE);
4480 wbcg->font_name_vaction = wbc_gtk_init_font_name (wbcg, FALSE);
4482 for (i = G_N_ELEMENTS (toggles); i-- > 0 ; ) {
4483 GtkAction *act = wbcg_find_action (wbcg, toggles[i].name);
4484 G_STRUCT_MEMBER (GtkToggleAction *, wbcg, toggles[i].offset) =
4485 (GtkToggleAction*) (act);
4488 if (gnm_debug_flag ("actions")) {
4489 list_actions (wbcg->permanent_actions);
4490 list_actions (wbcg->actions);
4491 list_actions (wbcg->font_actions);
4492 list_actions (wbcg->data_only_actions);
4493 list_actions (wbcg->semi_permanent_actions);
4494 list_actions (wbcg->file_history.actions);
4495 list_actions (wbcg->toolbar.actions);
4496 list_actions (wbcg->windows.actions);
4497 list_actions (wbcg->templates.actions);