1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Jon K Hellan (hellan@acm.org)
7 * Zbigniew Chyla (cyba@gnome.pl)
8 * Andreas J. Guelzow (aguelzow@pyrshep.ca)
10 #include <gnumeric-config.h>
11 #include <glib/gi18n-lib.h>
19 #include "application.h"
20 #include "command-context.h"
21 #include "wbc-gtk-impl.h"
22 #include "workbook-view.h"
23 #include "workbook-priv.h"
24 #include "gnumeric-conf.h"
25 #include "application.h"
27 #include <goffice/goffice.h>
34 GOCharmapSel
*go_charmap_sel
;
35 GtkWidget
*charmap_label
;
37 } file_opener_format_changed_cb_data
;
42 file_opener_description_cmp (gconstpointer a
, gconstpointer b
)
44 GOFileOpener
const *fo_a
= a
, *fo_b
= b
;
46 return g_utf8_collate (go_file_opener_get_description (fo_a
),
47 go_file_opener_get_description (fo_b
));
51 file_saver_description_cmp (gconstpointer a
, gconstpointer b
)
53 GOFileSaver
const *fs_a
= a
, *fs_b
= b
;
55 return g_utf8_collate (go_file_saver_get_description (fs_a
),
56 go_file_saver_get_description (fs_b
));
60 make_format_chooser (GList
*list
, GtkComboBox
*combo
)
63 GtkComboBoxText
*bt
= GTK_COMBO_BOX_TEXT (combo
);
65 /* Make format chooser */
66 for (l
= list
; l
!= NULL
; l
= l
->next
) {
67 GObject
*obj
= l
->data
;
71 descr
= _("Automatically detected");
72 else if (GO_IS_FILE_OPENER (obj
))
73 descr
= go_file_opener_get_description (GO_FILE_OPENER (obj
));
75 descr
= go_file_saver_get_description (GO_FILE_SAVER (obj
));
77 gtk_combo_box_text_append_text (bt
, descr
);
81 /* Show view in a wbcg. Use current or new wbcg according to policy */
83 gui_wb_view_show (WBCGtk
*wbcg
, WorkbookView
*wbv
)
85 WBCGtk
*new_wbcg
= NULL
;
86 Workbook
*tmp_wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
88 if (go_doc_is_pristine (GO_DOC (tmp_wb
))) {
90 g_object_unref (tmp_wb
);
91 wb_control_set_view (GNM_WBC (wbcg
), wbv
, NULL
);
92 wb_control_init_state (GNM_WBC (wbcg
));
94 GdkScreen
*screen
= gtk_window_get_screen (wbcg_toplevel (wbcg
));
95 WorkbookControl
*new_wbc
=
96 workbook_control_new_wrapper (GNM_WBC (wbcg
),
98 new_wbcg
= WBC_GTK (new_wbc
);
100 wbcg_copy_toolbar_visibility (new_wbcg
, wbcg
);
103 sheet_update (wb_view_cur_sheet (wbv
));
109 * Returns: (transfer none): the new #WorkbookView for the file read.
112 gui_file_read (WBCGtk
*wbcg
, char const *uri
,
113 GOFileOpener
const *optional_format
, gchar
const *optional_encoding
)
115 GOIOContext
*io_context
;
118 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), FALSE
);
119 io_context
= go_io_context_new (GO_CMD_CONTEXT (wbcg
));
120 wbv
= workbook_view_new_from_uri (uri
, optional_format
, io_context
,
123 if (go_io_error_occurred (io_context
) ||
124 go_io_warning_occurred (io_context
))
125 go_io_error_display (io_context
);
127 g_object_unref (io_context
);
128 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), TRUE
);
131 gui_wb_view_show (wbcg
, wbv
);
132 workbook_update_history (wb_view_get_workbook (wbv
), GNM_FILE_SAVE_AS_STYLE_SAVE
);
134 /* Somehow fixes #625687. Don't know why. */
135 wbcg_focus_cur_scg (wbcg
);
142 gnm_gui_file_template (WBCGtk
*wbcg
, char const *uri
)
144 GOIOContext
*io_context
;
146 GOFileOpener
const *optional_format
= NULL
;
147 gchar
const *optional_encoding
= NULL
;
149 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), FALSE
);
150 io_context
= go_io_context_new (GO_CMD_CONTEXT (wbcg
));
151 wbv
= workbook_view_new_from_uri (uri
, optional_format
, io_context
,
154 if (go_io_error_occurred (io_context
) ||
155 go_io_warning_occurred (io_context
))
156 go_io_error_display (io_context
);
158 g_object_unref (io_context
);
159 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), TRUE
);
162 Workbook
*wb
= wb_view_get_workbook (wbv
);
163 workbook_set_saveinfo (wb
, GO_FILE_FL_NEW
, NULL
);
164 gui_wb_view_show (wbcg
, wbv
);
171 file_opener_format_changed_cb (GtkComboBox
*format_combo
,
172 file_opener_format_changed_cb_data
*data
)
174 GOFileOpener
*fo
= g_list_nth_data (data
->openers
,
175 gtk_combo_box_get_active (format_combo
));
176 gboolean is_sensitive
= fo
!= NULL
&& go_file_opener_is_encoding_dependent (fo
);
178 gtk_widget_set_sensitive (GTK_WIDGET (data
->go_charmap_sel
), is_sensitive
);
179 gtk_widget_set_sensitive (data
->charmap_label
, is_sensitive
);
184 file_opener_find_by_id (GList
*openers
, char const *id
)
192 for (l
= openers
; l
!= NULL
; l
= l
->next
, i
++) {
193 if (GO_IS_FILE_OPENER (l
->data
) &&
194 strcmp (id
, go_file_opener_get_id(l
->data
)) == 0)
202 cb_advanced_clicked (GtkButton
*advanced
, GtkFileChooser
*fsel
)
204 GtkWidget
*extra
= g_object_get_data (G_OBJECT (advanced
), "extra");
206 gtk_button_set_use_underline (advanced
, TRUE
);
207 if (gtk_file_chooser_get_extra_widget (fsel
)) {
208 /* xgettext: If possible try to use the same mnemonic for
209 * Advanced and Simple */
210 gtk_button_set_label (advanced
, _("Advanc_ed"));
211 gtk_file_chooser_set_extra_widget (fsel
, NULL
);
213 gtk_button_set_label (advanced
, _("Simpl_e"));
214 gtk_file_chooser_set_extra_widget (fsel
, extra
);
219 * Suggests automatic file type recognition, but lets the user choose an
220 * import filter for selected file.
223 gui_file_open (WBCGtk
*wbcg
, GnmFileOpenStyle type
, char const *default_format
)
225 GList
*openers
= NULL
, *all_openers
, *l
;
226 GtkFileChooser
*fsel
;
227 GtkWidget
*advanced_button
;
228 GtkComboBox
*format_combo
;
229 GtkWidget
*go_charmap_sel
;
230 file_opener_format_changed_cb_data data
;
232 char const *title
= NULL
;
234 char const *encoding
= NULL
;
235 GOFileOpener
*fo
= NULL
;
236 Workbook
*workbook
= wb_control_get_workbook (GNM_WBC (wbcg
));
238 all_openers
= go_get_file_openers ();
240 if (default_format
!= NULL
) {
241 fo
= go_file_opener_for_id (default_format
);
245 openers
= g_list_prepend (NULL
, fo
);
247 for (l
= all_openers
; l
; l
= l
->next
)
248 if (l
->data
!= NULL
) {
249 GOFileOpener
*fo
= l
->data
;
250 GSList
const *mimes
= go_file_opener_get_mimes (fo
);
251 GSList
*fsavers
= NULL
, *fl
;
253 for (; mimes
; mimes
= mimes
->next
) {
254 GOFileSaver
*fs
= go_file_saver_for_mime_type
257 fsavers
= g_slist_prepend (fsavers
, fs
);
260 case GNM_FILE_OPEN_STYLE_OPEN
:
261 for (fl
= fsavers
; fl
; fl
= fl
->next
) {
262 GOFileSaver
*fs
= GO_FILE_SAVER (fl
->data
);
263 if ((go_file_saver_get_save_scope (fs
)
264 != GO_FILE_SAVE_RANGE
) &&
265 (go_file_saver_get_format_level (fs
)
266 == GO_FILE_FL_AUTO
)) {
267 openers
= g_list_prepend
273 case GNM_FILE_OPEN_STYLE_IMPORT
:
275 gboolean is_open
= FALSE
;
276 for (fl
= fsavers
; fl
; fl
= fl
->next
) {
277 GOFileSaver
*fs
= GO_FILE_SAVER
279 if ((go_file_saver_get_save_scope
281 != GO_FILE_SAVE_RANGE
) &&
282 (go_file_saver_get_format_level
284 == GO_FILE_FL_AUTO
)) {
290 openers
= g_list_prepend
295 g_slist_free (fsavers
);
297 openers
= g_list_sort (openers
, file_opener_description_cmp
);
298 /* NULL represents automatic file type recognition */
299 openers
= g_list_prepend (openers
, NULL
);
302 opener_default
= file_opener_find_by_id (openers
, default_format
);
304 if (opener_default
!= 0)
305 title
= (go_file_opener_get_description
306 (g_list_nth_data (openers
, opener_default
)));
309 case GNM_FILE_OPEN_STYLE_OPEN
:
310 title
= _("Open Spreadsheet File");
312 case GNM_FILE_OPEN_STYLE_IMPORT
:
313 title
= _("Import Data File");
316 data
.openers
= openers
;
318 /* Make charmap chooser */
319 go_charmap_sel
= go_charmap_sel_new (GO_CHARMAP_SEL_TO_UTF8
);
320 data
.go_charmap_sel
= GO_CHARMAP_SEL(go_charmap_sel
);
321 data
.charmap_label
= gtk_label_new_with_mnemonic (_("Character _encoding:"));
323 /* Make format chooser */
324 format_combo
= GTK_COMBO_BOX (gtk_combo_box_text_new ());
325 make_format_chooser (openers
, format_combo
);
326 g_signal_connect (G_OBJECT (format_combo
), "changed",
327 G_CALLBACK (file_opener_format_changed_cb
), &data
);
328 gtk_combo_box_set_active (format_combo
, opener_default
);
329 gtk_widget_set_sensitive (GTK_WIDGET (format_combo
), opener_default
== 0);
330 file_opener_format_changed_cb (format_combo
, &data
);
332 fsel
= GTK_FILE_CHOOSER
333 (g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG
,
334 "action", GTK_FILE_CHOOSER_ACTION_OPEN
,
337 "select-multiple", TRUE
,
340 advanced_button
= gtk_button_new_with_mnemonic (_("Advanc_ed"));
341 gtk_widget_show (advanced_button
);
342 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (fsel
))),
343 advanced_button
, FALSE
, TRUE
, 6);
344 gtk_dialog_add_buttons (GTK_DIALOG (fsel
),
345 GNM_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
346 GNM_STOCK_OPEN
, GTK_RESPONSE_OK
,
348 gtk_dialog_set_default_response (GTK_DIALOG (fsel
), GTK_RESPONSE_OK
);
350 /* Add Templates bookmark */
352 char *templates
= g_build_filename (gnm_sys_data_dir (), "templates", NULL
);
353 gtk_file_chooser_add_shortcut_folder (fsel
, templates
, NULL
);
357 /* Start in the same directory as the current workbook. */
358 gtk_file_chooser_select_uri (fsel
, go_doc_get_uri (GO_DOC (workbook
)));
359 gtk_file_chooser_unselect_all (fsel
);
363 GtkFileFilter
*filter
;
364 char const *filter_name
= NULL
;
366 filter
= gtk_file_filter_new ();
367 gtk_file_filter_set_name (filter
, _("All Files"));
368 gtk_file_filter_add_pattern (filter
, "*");
369 gtk_file_chooser_add_filter (fsel
, filter
);
371 filter
= gnm_app_create_opener_filter (openers
);
372 if (default_format
!= NULL
) {
373 if (0 == strcmp (default_format
,
374 "Gnumeric_stf:stf_assistant"))
375 filter_name
= _("Text Files");
377 if (filter_name
== NULL
)
379 case GNM_FILE_OPEN_STYLE_OPEN
:
380 filter_name
= _("Spreadsheets");
382 case GNM_FILE_OPEN_STYLE_IMPORT
:
383 filter_name
= _("Data Files");
386 gtk_file_filter_set_name (filter
, filter_name
);
387 gtk_file_chooser_add_filter (fsel
, filter
);
388 /* Make this filter the default */
389 gtk_file_chooser_set_filter (fsel
, filter
);
394 GtkWidget
*grid
= gtk_grid_new ();
397 "column-spacing", 12,
400 gtk_widget_set_hexpand (GTK_WIDGET (format_combo
), TRUE
);
401 gtk_grid_attach (GTK_GRID (grid
),
402 GTK_WIDGET (format_combo
),
404 label
= gtk_label_new_with_mnemonic (_("File _type:"));
405 gtk_grid_attach (GTK_GRID (grid
), label
, 0, 0, 1, 1);
406 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (format_combo
));
408 gtk_widget_set_hexpand (go_charmap_sel
, TRUE
);
409 gtk_grid_attach (GTK_GRID (grid
), go_charmap_sel
, 1, 1, 1, 1);
410 gtk_grid_attach (GTK_GRID (grid
), data
.charmap_label
, 0, 1, 1, 1);
411 gtk_label_set_mnemonic_widget (GTK_LABEL (data
.charmap_label
),
414 g_object_ref_sink (grid
);
415 g_object_set_data_full (G_OBJECT (advanced_button
), "extra",
416 grid
, g_object_unref
);
417 gtk_widget_show_all (grid
);
418 g_signal_connect (G_OBJECT (advanced_button
),
420 G_CALLBACK (cb_advanced_clicked
),
424 /* Show file selector */
425 if (!go_gtk_file_sel_dialog (wbcg_toplevel (wbcg
), GTK_WIDGET (fsel
)))
428 uris
= gtk_file_chooser_get_uris (fsel
);
429 encoding
= go_charmap_sel_get_encoding (GO_CHARMAP_SEL (go_charmap_sel
));
430 fo
= g_list_nth_data (openers
, gtk_combo_box_get_active (format_combo
));
433 gtk_widget_destroy (GTK_WIDGET (fsel
));
434 g_list_free (openers
);
437 char *uri
= uris
->data
;
440 /* Make sure dialog goes away right now. */
441 while (g_main_context_iteration (NULL
, FALSE
));
443 gui_file_read (wbcg
, uri
, fo
, encoding
);
447 g_slist_free_1 (hook
);
452 check_multiple_sheet_support_if_needed (GOFileSaver
*fs
,
454 WorkbookView
*wb_view
)
456 gboolean ret_val
= TRUE
;
458 if (go_file_saver_get_save_scope (fs
) != GO_FILE_SAVE_WORKBOOK
&&
459 gnm_conf_get_core_file_save_single_sheet ()) {
460 Workbook
*wb
= wb_view_get_workbook (wb_view
);
462 _("Selected file format doesn't support "
463 "saving multiple sheets in one file.\n"
464 "If you want to save all sheets, save them "
465 "in separate files or select different file format.\n"
466 "Do you want to save only current sheet?");
467 if (workbook_sheet_count (wb
) > 1) {
468 ret_val
= go_gtk_query_yes_no (parent
, TRUE
, "%s", msg
);
475 extension_check_disabled (GOFileSaver
*fs
)
477 GSList
*list
= gnm_conf_get_core_file_save_extension_check_disabled ();
478 char const *id
= go_file_saver_get_id (fs
);
480 return (NULL
!= g_slist_find_custom (list
, id
, go_str_compare
));
484 GtkFileChooser
*fsel
;
486 } file_saver_format_changed_cb_data
;
489 * Change or add the extension for the newly chosen saver to the file
490 * name in the file chooser.
493 file_saver_format_changed_cb (GtkComboBox
*format_combo
,
494 file_saver_format_changed_cb_data
*data
)
496 GOFileSaver
*fs
= g_list_nth_data (data
->savers
, gtk_combo_box_get_active (format_combo
));
497 char *uri
= gtk_file_chooser_get_uri (data
->fsel
);
498 char *basename
= NULL
, *newname
= NULL
, *dot
;
499 char const *ext
= go_file_saver_get_extension (fs
);
504 basename
= go_basename_from_uri (uri
);
508 dot
= strchr (basename
, '.');
512 newname
= g_strconcat (basename
, ".", ext
, NULL
);
513 gtk_file_chooser_set_current_name (data
->fsel
, newname
);
522 gui_file_save_as (WBCGtk
*wbcg
, WorkbookView
*wb_view
, GnmFileSaveAsStyle type
,
523 char const *default_format
)
525 GList
*savers
= NULL
, *l
;
526 GtkFileChooser
*fsel
;
527 GtkComboBox
*format_combo
;
529 file_saver_format_changed_cb_data data
;
530 gboolean success
= FALSE
;
535 char const *title
= (type
== GNM_FILE_SAVE_AS_STYLE_SAVE
) ? _("Save the current workbook as")
536 : _("Export the current workbook or sheet to");
538 g_return_val_if_fail (wbcg
!= NULL
, FALSE
);
540 wb
= wb_view_get_workbook (wb_view
);
541 wbcg2
= wbcg_find_for_workbook (wb
, wbcg
, NULL
, NULL
);
543 for (l
= go_get_file_savers (); l
; l
= l
->next
)
545 case GNM_FILE_SAVE_AS_STYLE_SAVE
:
546 if ((l
->data
== NULL
) ||
547 ((go_file_saver_get_save_scope (GO_FILE_SAVER (l
->data
))
548 != GO_FILE_SAVE_RANGE
) &&
549 (go_file_saver_get_format_level (GO_FILE_SAVER (l
->data
))
550 == GO_FILE_FL_AUTO
)))
551 savers
= g_list_prepend (savers
, l
->data
);
553 case GNM_FILE_SAVE_AS_STYLE_EXPORT
:
555 if ((l
->data
== NULL
) ||
556 ((go_file_saver_get_save_scope (GO_FILE_SAVER (l
->data
))
557 != GO_FILE_SAVE_RANGE
) &&
558 (go_file_saver_get_format_level (GO_FILE_SAVER (l
->data
))
559 != GO_FILE_FL_AUTO
)))
560 savers
= g_list_prepend (savers
, l
->data
);
563 data
.savers
= savers
= g_list_sort (savers
, file_saver_description_cmp
);
565 data
.fsel
= fsel
= GTK_FILE_CHOOSER
566 (g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG
,
567 "action", GTK_FILE_CHOOSER_ACTION_SAVE
,
571 gtk_dialog_add_buttons (GTK_DIALOG (fsel
),
572 GNM_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
573 GNM_STOCK_SAVE
, GTK_RESPONSE_OK
,
576 gtk_dialog_set_default_response (GTK_DIALOG (fsel
), GTK_RESPONSE_OK
);
580 GtkFileFilter
*filter
;
583 filter
= gtk_file_filter_new ();
584 gtk_file_filter_set_name (filter
, _("All Files"));
585 gtk_file_filter_add_pattern (filter
, "*");
586 gtk_file_chooser_add_filter (fsel
, filter
);
588 filter
= gtk_file_filter_new ();
589 gtk_file_filter_set_name (filter
, _("Spreadsheets"));
590 for (l
= savers
; l
; l
= l
->next
) {
591 GOFileSaver
*fs
= l
->data
;
592 char const *ext
= go_file_saver_get_extension (fs
);
593 char const *mime
= go_file_saver_get_mime_type (fs
);
596 gtk_file_filter_add_mime_type (filter
, mime
);
598 #warning "FIXME: do we get all extensions?"
599 /* Well, we don't get things we cannot save. */
601 char *pattern
= g_strconcat ("*.", ext
, NULL
);
602 gtk_file_filter_add_pattern (filter
, pattern
);
606 gtk_file_chooser_add_filter (fsel
, filter
);
607 /* Make this filter the default */
608 gtk_file_chooser_set_filter (fsel
, filter
);
612 GtkWidget
*box
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 2);
613 GtkWidget
*label
= gtk_label_new_with_mnemonic (_("File _type:"));
614 format_combo
= GTK_COMBO_BOX (gtk_combo_box_text_new ());
615 make_format_chooser (savers
, format_combo
);
616 g_signal_connect (G_OBJECT (format_combo
), "changed",
617 G_CALLBACK (file_saver_format_changed_cb
), &data
);
619 gtk_box_pack_start (GTK_BOX (box
), label
, FALSE
, TRUE
, 6);
620 gtk_box_pack_start (GTK_BOX (box
), GTK_WIDGET (format_combo
), FALSE
, TRUE
, 6);
621 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (format_combo
));
623 gtk_widget_show_all (box
);
624 gtk_file_chooser_set_extra_widget (fsel
, box
);
627 /* Set default file saver */
628 if (type
== GNM_FILE_SAVE_AS_STYLE_SAVE
) {
629 fs
= workbook_get_file_saver (wb
);
630 if (!fs
|| g_list_find (savers
, fs
) == NULL
)
631 fs
= go_file_saver_get_default ();
634 fs
= go_file_saver_for_id (default_format
);
636 fs
= workbook_get_file_exporter (wb
);
637 if (!fs
|| g_list_find (savers
, fs
) == NULL
)
638 fs
= go_file_saver_for_id ("Gnumeric_html:latex_table");
641 gtk_combo_box_set_active (format_combo
, g_list_index (savers
, fs
));
643 /* Set default file name */
644 if (type
== GNM_FILE_SAVE_AS_STYLE_EXPORT
) {
645 char *basename
, *dot
, *newname
;
646 char const *ext
= go_file_saver_get_extension (fs
);
648 wb_uri
= workbook_get_last_export_uri (wb
);
649 if (!wb_uri
|| fs
!= workbook_get_file_exporter (wb
))
650 wb_uri
= go_doc_get_uri (GO_DOC (wb
));
651 if (!wb_uri
) wb_uri
= _("Untitled");
652 if (!ext
) ext
= "txt";
654 basename
= go_basename_from_uri (wb_uri
);
655 dot
= strrchr (basename
, '.');
657 newname
= g_strconcat (basename
, ".", ext
, NULL
);
659 gtk_file_chooser_set_uri (fsel
, wb_uri
);
660 gtk_file_chooser_set_current_name (fsel
, newname
);
667 wb_uri
= go_doc_get_uri (GO_DOC (wb
));
668 if (!wb_uri
) wb_uri
= _("Untitled");
669 basename
= go_basename_from_uri (wb_uri
);
672 * If the file exists, the following is dominated by the
673 * final set_uri. If the file does not exist, we get the
674 * directory from the first set_uri and the basename set
675 * with set_current_name.
677 gtk_file_chooser_set_uri (fsel
, wb_uri
);
678 gtk_file_chooser_set_current_name (fsel
, basename
);
679 gtk_file_chooser_set_uri (fsel
, wb_uri
);
687 /* Show file selector */
688 if (!go_gtk_file_sel_dialog (wbcg_toplevel (wbcg
), GTK_WIDGET (fsel
)))
690 fs
= g_list_nth_data (savers
, gtk_combo_box_get_active (format_combo
));
693 uri
= gtk_file_chooser_get_uri (fsel
);
694 if (!go_url_check_extension (uri
,
695 go_file_saver_get_extension (fs
),
697 !extension_check_disabled (fs
) &&
698 !go_gtk_query_yes_no (GTK_WINDOW (fsel
),
700 _("The given file extension does not match the"
701 " chosen file type. Do you want to use this name"
712 if (go_gtk_url_is_writeable (GTK_WINDOW (fsel
), uri
,
713 gnm_conf_get_core_file_save_def_overwrite ()))
720 GtkWidget
*nb
= GTK_WIDGET (wbcg2
->notebook_area
);
722 gtk_widget_get_allocation (nb
, &a
);
723 wb_view_preferred_size (wb_view
, a
.width
, a
.height
);
726 success
= check_multiple_sheet_support_if_needed (fs
, GTK_WINDOW (fsel
), wb_view
);
728 /* Destroy early so no-one can repress the Save button. */
729 gtk_widget_destroy (GTK_WIDGET (fsel
));
731 if (workbook_view_save_as (wb_view
, fs
, uri
, GO_CMD_CONTEXT (wbcg
)))
732 workbook_update_history (wb
, type
);
739 gtk_widget_destroy (GTK_WIDGET (fsel
));
740 g_list_free (savers
);
746 warn_about_overwrite (WBCGtk
*wbcg
,
748 GDateTime
*known_modtime
)
752 char *shortname
, *filename
, *longname
, *duri
, *modtxt
;
753 Workbook
*wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
755 GDateTime
*modtime_local
;
757 uri
= go_doc_get_uri (GO_DOC (wb
));
758 filename
= go_filename_from_uri (uri
);
760 shortname
= g_filename_display_basename (filename
);
762 shortname
= g_filename_display_basename (uri
);
765 duri
= g_uri_unescape_string (uri
, NULL
);
767 ? g_filename_display_name (duri
)
770 modtime_local
= g_date_time_to_local (modtime
);
771 modtxt
= g_date_time_format (modtime_local
, _("%F %T"));
772 g_date_time_unref (modtime_local
);
774 dialog
= gtk_message_dialog_new_with_markup
775 (wbcg_toplevel (wbcg
),
776 GTK_DIALOG_DESTROY_WITH_PARENT
,
779 _("The file you are about to save has changed on disk. If you continue, you will overwrite someone else's changes.\n\n"
782 "Last modified: <b>%s</b>\n"),
783 shortname
, longname
, modtxt
);
784 gtk_dialog_add_buttons (GTK_DIALOG (dialog
),
785 _("Overwrite"), GTK_RESPONSE_YES
,
786 _("Cancel"), GTK_RESPONSE_NO
,
794 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_NO
);
795 response
= go_gtk_dialog_run (GTK_DIALOG (dialog
),
796 wbcg_toplevel (wbcg
));
797 return response
== GTK_RESPONSE_YES
;
801 gui_file_save (WBCGtk
*wbcg
, WorkbookView
*wb_view
)
803 Workbook
*wb
= wb_view_get_workbook (wb_view
);
805 wbcg_find_for_workbook (wb
, wbcg
, NULL
, NULL
);
808 GtkWidget
*nb
= GTK_WIDGET (wbcg2
->notebook_area
);
810 gtk_widget_get_allocation (nb
, &a
);
811 wb_view_preferred_size (wb_view
, a
.width
, a
.height
);
814 if (wb
->file_format_level
< GO_FILE_FL_AUTO
)
815 return gui_file_save_as (wbcg
, wb_view
,
816 GNM_FILE_SAVE_AS_STYLE_SAVE
, NULL
);
819 const char *uri
= go_doc_get_uri (GO_DOC (wb
));
820 GDateTime
*known_modtime
= go_doc_get_modtime (GO_DOC (wb
));
821 GDateTime
*modtime
= go_file_get_modtime (uri
);
822 gboolean debug_modtime
= gnm_debug_flag ("modtime");
824 /* We need a ref because a Ctrl-Q at the wrong time will
825 cause the workbook to disappear at the end of the
829 if (modtime
&& known_modtime
) {
830 if (g_date_time_equal (known_modtime
, modtime
)) {
832 g_printerr ("Modtime match\n");
835 g_printerr ("Modtime mismatch\n");
836 ok
= warn_about_overwrite (wbcg
, modtime
, known_modtime
);
841 ok
= workbook_view_save (wb_view
, GO_CMD_CONTEXT (wbcg
));
843 workbook_update_history (wb
, GNM_FILE_SAVE_AS_STYLE_SAVE
);
847 g_date_time_unref (modtime
);
854 gui_file_export_repeat (WBCGtk
*wbcg
)
856 WorkbookView
*wb_view
= wb_control_view (GNM_WBC (wbcg
));
857 Workbook
*wb
= wb_view_get_workbook (wb_view
);
858 GOFileSaver
*fs
= workbook_get_file_exporter (wb
);
859 gchar
const *last_uri
= workbook_get_last_export_uri (wb
);
861 if (fs
!= NULL
&& last_uri
!= NULL
) {
865 if (go_file_saver_get_save_scope (fs
) != GO_FILE_SAVE_WORKBOOK
)
866 msg
= _("Do you want to export the <b>current sheet</b> of this "
867 "workbook to the location '<b>%s</b>' "
868 "using the '<b>%s</b>' exporter?");
870 msg
= _("Do you want to export this workbook to the "
871 "location '<b>%s</b>' "
872 "using the '<b>%s</b>' exporter?");
874 /* go_gtk_query_yes_no does not handle markup ... */
875 dialog
= gtk_message_dialog_new_with_markup (wbcg_toplevel (wbcg
),
876 GTK_DIALOG_DESTROY_WITH_PARENT
,
877 GTK_MESSAGE_QUESTION
,
880 go_file_saver_get_description (fs
));
881 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_YES
);
883 if (GTK_RESPONSE_YES
==
884 go_gtk_dialog_run (GTK_DIALOG (dialog
), wbcg_toplevel (wbcg
))) {
885 /* We need to copy wb->last_export_uri since it will be reset during saving */
886 gchar
*uri
= g_strdup (last_uri
);
887 if(workbook_view_save_as (wb_view
, fs
, uri
, GO_CMD_CONTEXT (wbcg
))) {
888 workbook_update_history (wb
, GNM_FILE_SAVE_AS_STYLE_EXPORT
);
896 go_gtk_notice_dialog (wbcg_toplevel (wbcg
), GTK_MESSAGE_ERROR
,
897 _("Unable to repeat export since no previous "
898 "export information has been saved in this "