5 * Jon K Hellan (hellan@acm.org)
6 * Zbigniew Chyla (cyba@gnome.pl)
7 * Andreas J. Guelzow (aguelzow@pyrshep.ca)
9 #include <gnumeric-config.h>
10 #include <glib/gi18n-lib.h>
16 #include <dialogs/dialogs.h>
18 #include <application.h>
19 #include <command-context.h>
20 #include <wbc-gtk-impl.h>
21 #include <workbook-view.h>
22 #include <workbook-priv.h>
23 #include <gnumeric-conf.h>
24 #include <application.h>
26 #include <goffice/goffice.h>
32 GOCharmapSel
*go_charmap_sel
;
33 GtkWidget
*charmap_label
;
35 } file_opener_format_changed_cb_data
;
40 file_opener_description_cmp (gconstpointer a
, gconstpointer b
)
42 GOFileOpener
const *fo_a
= a
, *fo_b
= b
;
44 return g_utf8_collate (go_file_opener_get_description (fo_a
),
45 go_file_opener_get_description (fo_b
));
49 file_saver_description_cmp (gconstpointer a
, gconstpointer b
)
51 GOFileSaver
const *fs_a
= a
, *fs_b
= b
;
53 return g_utf8_collate (go_file_saver_get_description (fs_a
),
54 go_file_saver_get_description (fs_b
));
58 make_format_chooser (GList
*list
, GtkComboBox
*combo
)
61 GtkComboBoxText
*bt
= GTK_COMBO_BOX_TEXT (combo
);
63 /* Make format chooser */
64 for (l
= list
; l
!= NULL
; l
= l
->next
) {
65 GObject
*obj
= l
->data
;
69 descr
= _("Automatically detected");
70 else if (GO_IS_FILE_OPENER (obj
))
71 descr
= go_file_opener_get_description (GO_FILE_OPENER (obj
));
73 descr
= go_file_saver_get_description (GO_FILE_SAVER (obj
));
75 gtk_combo_box_text_append_text (bt
, descr
);
79 /* Show view in a wbcg. Use current or new wbcg according to policy */
81 gui_wb_view_show (WBCGtk
*wbcg
, WorkbookView
*wbv
)
83 WBCGtk
*new_wbcg
= NULL
;
84 Workbook
*tmp_wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
86 if (go_doc_is_pristine (GO_DOC (tmp_wb
))) {
88 g_object_unref (tmp_wb
);
89 wb_control_set_view (GNM_WBC (wbcg
), wbv
, NULL
);
90 wb_control_init_state (GNM_WBC (wbcg
));
92 GdkScreen
*screen
= gtk_window_get_screen (wbcg_toplevel (wbcg
));
93 WorkbookControl
*new_wbc
=
94 workbook_control_new_wrapper (GNM_WBC (wbcg
),
96 new_wbcg
= WBC_GTK (new_wbc
);
98 wbcg_copy_toolbar_visibility (new_wbcg
, wbcg
);
101 sheet_update (wb_view_cur_sheet (wbv
));
107 * Returns: (transfer none): the new #WorkbookView for the file read.
110 gui_file_read (WBCGtk
*wbcg
, char const *uri
,
111 GOFileOpener
const *optional_format
, gchar
const *optional_encoding
)
113 GOIOContext
*io_context
;
116 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), FALSE
);
117 io_context
= go_io_context_new (GO_CMD_CONTEXT (wbcg
));
118 wbv
= workbook_view_new_from_uri (uri
, optional_format
, io_context
,
121 if (go_io_error_occurred (io_context
) ||
122 go_io_warning_occurred (io_context
))
123 go_io_error_display (io_context
);
125 g_object_unref (io_context
);
126 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), TRUE
);
129 gui_wb_view_show (wbcg
, wbv
);
130 workbook_update_history (wb_view_get_workbook (wbv
), GNM_FILE_SAVE_AS_STYLE_SAVE
);
132 /* Somehow fixes #625687. Don't know why. */
133 wbcg_focus_cur_scg (wbcg
);
140 gnm_gui_file_template (WBCGtk
*wbcg
, char const *uri
)
142 GOIOContext
*io_context
;
144 GOFileOpener
const *optional_format
= NULL
;
145 gchar
const *optional_encoding
= NULL
;
147 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), FALSE
);
148 io_context
= go_io_context_new (GO_CMD_CONTEXT (wbcg
));
149 wbv
= workbook_view_new_from_uri (uri
, optional_format
, io_context
,
152 if (go_io_error_occurred (io_context
) ||
153 go_io_warning_occurred (io_context
))
154 go_io_error_display (io_context
);
156 g_object_unref (io_context
);
157 go_cmd_context_set_sensitive (GO_CMD_CONTEXT (wbcg
), TRUE
);
160 Workbook
*wb
= wb_view_get_workbook (wbv
);
161 workbook_set_saveinfo (wb
, GO_FILE_FL_NEW
, NULL
);
162 gui_wb_view_show (wbcg
, wbv
);
169 file_opener_format_changed_cb (GtkComboBox
*format_combo
,
170 file_opener_format_changed_cb_data
*data
)
172 GOFileOpener
*fo
= g_list_nth_data (data
->openers
,
173 gtk_combo_box_get_active (format_combo
));
174 gboolean is_sensitive
= fo
!= NULL
&& go_file_opener_is_encoding_dependent (fo
);
176 gtk_widget_set_sensitive (GTK_WIDGET (data
->go_charmap_sel
), is_sensitive
);
177 gtk_widget_set_sensitive (data
->charmap_label
, is_sensitive
);
182 file_opener_find_by_id (GList
*openers
, char const *id
)
190 for (l
= openers
; l
!= NULL
; l
= l
->next
, i
++) {
191 if (GO_IS_FILE_OPENER (l
->data
) &&
192 strcmp (id
, go_file_opener_get_id(l
->data
)) == 0)
200 cb_advanced_clicked (GtkButton
*advanced
, GtkFileChooser
*fsel
)
202 GtkWidget
*extra
= g_object_get_data (G_OBJECT (advanced
), "extra");
204 gtk_button_set_use_underline (advanced
, TRUE
);
205 if (gtk_file_chooser_get_extra_widget (fsel
)) {
206 /* xgettext: If possible try to use the same mnemonic for
207 * Advanced and Simple */
208 gtk_button_set_label (advanced
, _("Advanc_ed"));
209 gtk_file_chooser_set_extra_widget (fsel
, NULL
);
211 gtk_button_set_label (advanced
, _("Simpl_e"));
212 gtk_file_chooser_set_extra_widget (fsel
, extra
);
217 * Suggests automatic file type recognition, but lets the user choose an
218 * import filter for selected file.
221 gui_file_open (WBCGtk
*wbcg
, GnmFileOpenStyle type
, char const *default_format
)
223 GList
*openers
= NULL
, *all_openers
, *l
;
224 GtkFileChooser
*fsel
;
225 GtkWidget
*advanced_button
;
226 GtkComboBox
*format_combo
;
227 GtkWidget
*go_charmap_sel
;
228 file_opener_format_changed_cb_data data
;
230 char const *title
= NULL
;
232 char const *encoding
= NULL
;
233 GOFileOpener
*fo
= NULL
;
234 Workbook
*workbook
= wb_control_get_workbook (GNM_WBC (wbcg
));
236 all_openers
= go_get_file_openers ();
238 if (default_format
!= NULL
) {
239 fo
= go_file_opener_for_id (default_format
);
243 openers
= g_list_prepend (NULL
, fo
);
245 for (l
= all_openers
; l
; l
= l
->next
)
246 if (l
->data
!= NULL
) {
247 GOFileOpener
*fo
= l
->data
;
248 GSList
const *mimes
= go_file_opener_get_mimes (fo
);
249 GSList
*fsavers
= NULL
, *fl
;
251 for (; mimes
; mimes
= mimes
->next
) {
252 GOFileSaver
*fs
= go_file_saver_for_mime_type
255 fsavers
= g_slist_prepend (fsavers
, fs
);
258 case GNM_FILE_OPEN_STYLE_OPEN
:
259 for (fl
= fsavers
; fl
; fl
= fl
->next
) {
260 GOFileSaver
*fs
= GO_FILE_SAVER (fl
->data
);
261 if ((go_file_saver_get_save_scope (fs
)
262 != GO_FILE_SAVE_RANGE
) &&
263 (go_file_saver_get_format_level (fs
)
264 == GO_FILE_FL_AUTO
)) {
265 openers
= g_list_prepend
271 case GNM_FILE_OPEN_STYLE_IMPORT
:
273 gboolean is_open
= FALSE
;
274 for (fl
= fsavers
; fl
; fl
= fl
->next
) {
275 GOFileSaver
*fs
= GO_FILE_SAVER
277 if ((go_file_saver_get_save_scope
279 != GO_FILE_SAVE_RANGE
) &&
280 (go_file_saver_get_format_level
282 == GO_FILE_FL_AUTO
)) {
288 openers
= g_list_prepend
293 g_slist_free (fsavers
);
295 openers
= g_list_sort (openers
, file_opener_description_cmp
);
296 /* NULL represents automatic file type recognition */
297 openers
= g_list_prepend (openers
, NULL
);
300 opener_default
= file_opener_find_by_id (openers
, default_format
);
302 if (opener_default
!= 0)
303 title
= (go_file_opener_get_description
304 (g_list_nth_data (openers
, opener_default
)));
307 case GNM_FILE_OPEN_STYLE_OPEN
:
308 title
= _("Open Spreadsheet File");
310 case GNM_FILE_OPEN_STYLE_IMPORT
:
311 title
= _("Import Data File");
314 data
.openers
= openers
;
316 /* Make charmap chooser */
317 go_charmap_sel
= go_charmap_sel_new (GO_CHARMAP_SEL_TO_UTF8
);
318 data
.go_charmap_sel
= GO_CHARMAP_SEL(go_charmap_sel
);
319 data
.charmap_label
= gtk_label_new_with_mnemonic (_("Character _encoding:"));
321 /* Make format chooser */
322 format_combo
= GTK_COMBO_BOX (gtk_combo_box_text_new ());
323 make_format_chooser (openers
, format_combo
);
324 g_signal_connect (G_OBJECT (format_combo
), "changed",
325 G_CALLBACK (file_opener_format_changed_cb
), &data
);
326 gtk_combo_box_set_active (format_combo
, opener_default
);
327 gtk_widget_set_sensitive (GTK_WIDGET (format_combo
), opener_default
== 0);
328 file_opener_format_changed_cb (format_combo
, &data
);
330 fsel
= GTK_FILE_CHOOSER
331 (g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG
,
332 "action", GTK_FILE_CHOOSER_ACTION_OPEN
,
335 "select-multiple", TRUE
,
338 advanced_button
= gtk_button_new_with_mnemonic (_("Advanc_ed"));
339 gtk_widget_show (advanced_button
);
340 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (fsel
))),
341 advanced_button
, FALSE
, TRUE
, 6);
342 gtk_dialog_add_buttons (GTK_DIALOG (fsel
),
343 GNM_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
344 GNM_STOCK_OPEN
, GTK_RESPONSE_OK
,
346 gtk_dialog_set_default_response (GTK_DIALOG (fsel
), GTK_RESPONSE_OK
);
348 /* Add Templates bookmark */
350 char *templates
= g_build_filename (gnm_sys_data_dir (), "templates", NULL
);
351 gtk_file_chooser_add_shortcut_folder (fsel
, templates
, NULL
);
355 /* Start in the same directory as the current workbook. */
356 gtk_file_chooser_select_uri (fsel
, go_doc_get_uri (GO_DOC (workbook
)));
357 gtk_file_chooser_unselect_all (fsel
);
361 GtkFileFilter
*filter
;
362 char const *filter_name
= NULL
;
364 filter
= gtk_file_filter_new ();
365 gtk_file_filter_set_name (filter
, _("All Files"));
366 gtk_file_filter_add_pattern (filter
, "*");
367 gtk_file_chooser_add_filter (fsel
, filter
);
369 filter
= gnm_app_create_opener_filter (openers
);
370 if (default_format
!= NULL
) {
371 if (0 == strcmp (default_format
,
372 "Gnumeric_stf:stf_assistant"))
373 filter_name
= _("Text Files");
375 if (filter_name
== NULL
)
377 case GNM_FILE_OPEN_STYLE_OPEN
:
378 filter_name
= _("Spreadsheets");
380 case GNM_FILE_OPEN_STYLE_IMPORT
:
381 filter_name
= _("Data Files");
384 gtk_file_filter_set_name (filter
, filter_name
);
385 gtk_file_chooser_add_filter (fsel
, filter
);
386 /* Make this filter the default */
387 gtk_file_chooser_set_filter (fsel
, filter
);
392 GtkWidget
*grid
= gtk_grid_new ();
395 "column-spacing", 12,
398 gtk_widget_set_hexpand (GTK_WIDGET (format_combo
), TRUE
);
399 gtk_grid_attach (GTK_GRID (grid
),
400 GTK_WIDGET (format_combo
),
402 label
= gtk_label_new_with_mnemonic (_("File _type:"));
403 gtk_grid_attach (GTK_GRID (grid
), label
, 0, 0, 1, 1);
404 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (format_combo
));
406 gtk_widget_set_hexpand (go_charmap_sel
, TRUE
);
407 gtk_grid_attach (GTK_GRID (grid
), go_charmap_sel
, 1, 1, 1, 1);
408 gtk_grid_attach (GTK_GRID (grid
), data
.charmap_label
, 0, 1, 1, 1);
409 gtk_label_set_mnemonic_widget (GTK_LABEL (data
.charmap_label
),
412 g_object_ref_sink (grid
);
413 g_object_set_data_full (G_OBJECT (advanced_button
), "extra",
414 grid
, g_object_unref
);
415 gtk_widget_show_all (grid
);
416 g_signal_connect (G_OBJECT (advanced_button
),
418 G_CALLBACK (cb_advanced_clicked
),
422 /* Show file selector */
423 if (!go_gtk_file_sel_dialog (wbcg_toplevel (wbcg
), GTK_WIDGET (fsel
)))
426 uris
= gtk_file_chooser_get_uris (fsel
);
427 encoding
= go_charmap_sel_get_encoding (GO_CHARMAP_SEL (go_charmap_sel
));
428 fo
= g_list_nth_data (openers
, gtk_combo_box_get_active (format_combo
));
431 gtk_widget_destroy (GTK_WIDGET (fsel
));
432 g_list_free (openers
);
435 char *uri
= uris
->data
;
438 /* Make sure dialog goes away right now. */
439 while (g_main_context_iteration (NULL
, FALSE
));
441 gui_file_read (wbcg
, uri
, fo
, encoding
);
445 g_slist_free_1 (hook
);
450 check_multiple_sheet_support_if_needed (GOFileSaver
*fs
,
452 WorkbookView
*wb_view
)
454 gboolean ret_val
= TRUE
;
456 if (go_file_saver_get_save_scope (fs
) != GO_FILE_SAVE_WORKBOOK
&&
457 gnm_conf_get_core_file_save_single_sheet ()) {
458 Workbook
*wb
= wb_view_get_workbook (wb_view
);
460 _("Selected file format doesn't support "
461 "saving multiple sheets in one file.\n"
462 "If you want to save all sheets, save them "
463 "in separate files or select different file format.\n"
464 "Do you want to save only current sheet?");
465 if (workbook_sheet_count (wb
) > 1) {
466 ret_val
= go_gtk_query_yes_no (parent
, TRUE
, "%s", msg
);
473 extension_check_disabled (GOFileSaver
*fs
)
475 GSList
*list
= gnm_conf_get_core_file_save_extension_check_disabled ();
476 char const *id
= go_file_saver_get_id (fs
);
478 return (NULL
!= g_slist_find_custom (list
, id
, go_str_compare
));
482 GtkFileChooser
*fsel
;
484 } file_saver_format_changed_cb_data
;
487 * Change or add the extension for the newly chosen saver to the file
488 * name in the file chooser.
491 file_saver_format_changed_cb (GtkComboBox
*format_combo
,
492 file_saver_format_changed_cb_data
*data
)
494 GOFileSaver
*fs
= g_list_nth_data (data
->savers
, gtk_combo_box_get_active (format_combo
));
495 char *uri
= gtk_file_chooser_get_uri (data
->fsel
);
496 char *basename
= NULL
, *newname
= NULL
, *dot
;
497 char const *ext
= go_file_saver_get_extension (fs
);
502 basename
= go_basename_from_uri (uri
);
506 dot
= strchr (basename
, '.');
510 newname
= g_strconcat (basename
, ".", ext
, NULL
);
511 gtk_file_chooser_set_current_name (data
->fsel
, newname
);
520 gui_file_save_as (WBCGtk
*wbcg
, WorkbookView
*wb_view
, GnmFileSaveAsStyle type
,
521 char const *default_format
)
523 GList
*savers
= NULL
, *l
;
524 GtkFileChooser
*fsel
;
525 GtkComboBox
*format_combo
;
527 file_saver_format_changed_cb_data data
;
528 gboolean success
= FALSE
;
533 char const *title
= (type
== GNM_FILE_SAVE_AS_STYLE_SAVE
) ? _("Save the current workbook as")
534 : _("Export the current workbook or sheet to");
536 g_return_val_if_fail (wbcg
!= NULL
, FALSE
);
538 wb
= wb_view_get_workbook (wb_view
);
539 wbcg2
= wbcg_find_for_workbook (wb
, wbcg
, NULL
, NULL
);
541 for (l
= go_get_file_savers (); l
; l
= l
->next
)
543 case GNM_FILE_SAVE_AS_STYLE_SAVE
:
544 if ((l
->data
== NULL
) ||
545 ((go_file_saver_get_save_scope (GO_FILE_SAVER (l
->data
))
546 != GO_FILE_SAVE_RANGE
) &&
547 (go_file_saver_get_format_level (GO_FILE_SAVER (l
->data
))
548 == GO_FILE_FL_AUTO
)))
549 savers
= g_list_prepend (savers
, l
->data
);
551 case GNM_FILE_SAVE_AS_STYLE_EXPORT
:
553 if ((l
->data
== NULL
) ||
554 ((go_file_saver_get_save_scope (GO_FILE_SAVER (l
->data
))
555 != GO_FILE_SAVE_RANGE
) &&
556 (go_file_saver_get_format_level (GO_FILE_SAVER (l
->data
))
557 != GO_FILE_FL_AUTO
)))
558 savers
= g_list_prepend (savers
, l
->data
);
561 data
.savers
= savers
= g_list_sort (savers
, file_saver_description_cmp
);
563 data
.fsel
= fsel
= GTK_FILE_CHOOSER
564 (g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG
,
565 "action", GTK_FILE_CHOOSER_ACTION_SAVE
,
569 gtk_dialog_add_buttons (GTK_DIALOG (fsel
),
570 GNM_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
571 GNM_STOCK_SAVE
, GTK_RESPONSE_OK
,
574 gtk_dialog_set_default_response (GTK_DIALOG (fsel
), GTK_RESPONSE_OK
);
578 GtkFileFilter
*filter
;
581 filter
= gtk_file_filter_new ();
582 gtk_file_filter_set_name (filter
, _("All Files"));
583 gtk_file_filter_add_pattern (filter
, "*");
584 gtk_file_chooser_add_filter (fsel
, filter
);
586 filter
= gtk_file_filter_new ();
587 gtk_file_filter_set_name (filter
, _("Spreadsheets"));
588 for (l
= savers
; l
; l
= l
->next
) {
589 GOFileSaver
*fs
= l
->data
;
590 char const *ext
= go_file_saver_get_extension (fs
);
591 char const *mime
= go_file_saver_get_mime_type (fs
);
594 gtk_file_filter_add_mime_type (filter
, mime
);
596 #warning "FIXME: do we get all extensions?"
597 /* Well, we don't get things we cannot save. */
599 char *pattern
= g_strconcat ("*.", ext
, NULL
);
600 gtk_file_filter_add_pattern (filter
, pattern
);
604 gtk_file_chooser_add_filter (fsel
, filter
);
605 /* Make this filter the default */
606 gtk_file_chooser_set_filter (fsel
, filter
);
610 GtkWidget
*box
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, 2);
611 GtkWidget
*label
= gtk_label_new_with_mnemonic (_("File _type:"));
612 format_combo
= GTK_COMBO_BOX (gtk_combo_box_text_new ());
613 make_format_chooser (savers
, format_combo
);
614 g_signal_connect (G_OBJECT (format_combo
), "changed",
615 G_CALLBACK (file_saver_format_changed_cb
), &data
);
617 gtk_box_pack_start (GTK_BOX (box
), label
, FALSE
, TRUE
, 6);
618 gtk_box_pack_start (GTK_BOX (box
), GTK_WIDGET (format_combo
), FALSE
, TRUE
, 6);
619 gtk_label_set_mnemonic_widget (GTK_LABEL (label
), GTK_WIDGET (format_combo
));
621 gtk_widget_show_all (box
);
622 gtk_file_chooser_set_extra_widget (fsel
, box
);
625 /* Set default file saver */
626 if (type
== GNM_FILE_SAVE_AS_STYLE_SAVE
) {
627 fs
= workbook_get_file_saver (wb
);
628 if (!fs
|| g_list_find (savers
, fs
) == NULL
)
629 fs
= go_file_saver_get_default ();
632 fs
= go_file_saver_for_id (default_format
);
634 fs
= workbook_get_file_exporter (wb
);
635 if (!fs
|| g_list_find (savers
, fs
) == NULL
)
636 fs
= go_file_saver_for_id ("Gnumeric_html:latex_table");
639 gtk_combo_box_set_active (format_combo
, g_list_index (savers
, fs
));
641 /* Set default file name */
642 if (type
== GNM_FILE_SAVE_AS_STYLE_EXPORT
) {
643 char *basename
, *dot
, *newname
;
644 char const *ext
= go_file_saver_get_extension (fs
);
646 wb_uri
= workbook_get_last_export_uri (wb
);
647 if (!wb_uri
|| fs
!= workbook_get_file_exporter (wb
))
648 wb_uri
= go_doc_get_uri (GO_DOC (wb
));
649 if (!wb_uri
) wb_uri
= _("Untitled");
650 if (!ext
) ext
= "txt";
652 basename
= go_basename_from_uri (wb_uri
);
653 dot
= strrchr (basename
, '.');
655 newname
= g_strconcat (basename
, ".", ext
, NULL
);
657 gtk_file_chooser_set_uri (fsel
, wb_uri
);
658 gtk_file_chooser_set_current_name (fsel
, newname
);
665 wb_uri
= go_doc_get_uri (GO_DOC (wb
));
666 if (!wb_uri
) wb_uri
= _("Untitled");
667 basename
= go_basename_from_uri (wb_uri
);
670 * If the file exists, the following is dominated by the
671 * final set_uri. If the file does not exist, we get the
672 * directory from the first set_uri and the basename set
673 * with set_current_name.
675 gtk_file_chooser_set_uri (fsel
, wb_uri
);
676 gtk_file_chooser_set_current_name (fsel
, basename
);
677 gtk_file_chooser_set_uri (fsel
, wb_uri
);
685 /* Show file selector */
686 if (!go_gtk_file_sel_dialog (wbcg_toplevel (wbcg
), GTK_WIDGET (fsel
)))
688 fs
= g_list_nth_data (savers
, gtk_combo_box_get_active (format_combo
));
691 uri
= gtk_file_chooser_get_uri (fsel
);
692 if (!go_url_check_extension (uri
,
693 go_file_saver_get_extension (fs
),
695 !extension_check_disabled (fs
) &&
696 !go_gtk_query_yes_no (GTK_WINDOW (fsel
),
698 _("The given file extension does not match the"
699 " chosen file type. Do you want to use this name"
710 if (go_gtk_url_is_writeable (GTK_WINDOW (fsel
), uri
,
711 gnm_conf_get_core_file_save_def_overwrite ()))
718 GtkWidget
*nb
= GTK_WIDGET (wbcg2
->notebook_area
);
720 gtk_widget_get_allocation (nb
, &a
);
721 wb_view_preferred_size (wb_view
, a
.width
, a
.height
);
724 success
= check_multiple_sheet_support_if_needed (fs
, GTK_WINDOW (fsel
), wb_view
);
726 /* Destroy early so no-one can repress the Save button. */
727 gtk_widget_destroy (GTK_WIDGET (fsel
));
729 if (workbook_view_save_as (wb_view
, fs
, uri
, GO_CMD_CONTEXT (wbcg
)))
730 workbook_update_history (wb
, type
);
737 gtk_widget_destroy (GTK_WIDGET (fsel
));
738 g_list_free (savers
);
744 warn_about_overwrite (WBCGtk
*wbcg
,
746 GDateTime
*known_modtime
)
750 char *shortname
, *filename
, *longname
, *duri
, *modtxt
;
751 Workbook
*wb
= wb_control_get_workbook (GNM_WBC (wbcg
));
753 GDateTime
*modtime_local
;
755 uri
= go_doc_get_uri (GO_DOC (wb
));
756 filename
= go_filename_from_uri (uri
);
758 shortname
= g_filename_display_basename (filename
);
760 shortname
= g_filename_display_basename (uri
);
763 duri
= g_uri_unescape_string (uri
, NULL
);
765 ? g_filename_display_name (duri
)
768 modtime_local
= g_date_time_to_local (modtime
);
769 modtxt
= g_date_time_format (modtime_local
, _("%F %T"));
770 g_date_time_unref (modtime_local
);
772 dialog
= gtk_message_dialog_new_with_markup
773 (wbcg_toplevel (wbcg
),
774 GTK_DIALOG_DESTROY_WITH_PARENT
,
777 _("The file you are about to save has changed on disk. If you continue, you will overwrite someone else's changes.\n\n"
780 "Last modified: <b>%s</b>\n"),
781 shortname
, longname
, modtxt
);
782 gtk_dialog_add_buttons (GTK_DIALOG (dialog
),
783 _("Overwrite"), GTK_RESPONSE_YES
,
784 _("Cancel"), GTK_RESPONSE_NO
,
792 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_NO
);
793 response
= go_gtk_dialog_run (GTK_DIALOG (dialog
),
794 wbcg_toplevel (wbcg
));
795 return response
== GTK_RESPONSE_YES
;
799 gui_file_save (WBCGtk
*wbcg
, WorkbookView
*wb_view
)
801 Workbook
*wb
= wb_view_get_workbook (wb_view
);
803 wbcg_find_for_workbook (wb
, wbcg
, NULL
, NULL
);
806 GtkWidget
*nb
= GTK_WIDGET (wbcg2
->notebook_area
);
808 gtk_widget_get_allocation (nb
, &a
);
809 wb_view_preferred_size (wb_view
, a
.width
, a
.height
);
812 if (wb
->file_format_level
< GO_FILE_FL_AUTO
)
813 return gui_file_save_as (wbcg
, wb_view
,
814 GNM_FILE_SAVE_AS_STYLE_SAVE
, NULL
);
817 const char *uri
= go_doc_get_uri (GO_DOC (wb
));
818 GDateTime
*known_modtime
= go_doc_get_modtime (GO_DOC (wb
));
819 GDateTime
*modtime
= go_file_get_modtime (uri
);
820 gboolean debug_modtime
= gnm_debug_flag ("modtime");
822 /* We need a ref because a Ctrl-Q at the wrong time will
823 cause the workbook to disappear at the end of the
827 if (modtime
&& known_modtime
) {
828 if (g_date_time_equal (known_modtime
, modtime
)) {
830 g_printerr ("Modtime match\n");
833 g_printerr ("Modtime mismatch\n");
834 ok
= warn_about_overwrite (wbcg
, modtime
, known_modtime
);
839 ok
= workbook_view_save (wb_view
, GO_CMD_CONTEXT (wbcg
));
841 workbook_update_history (wb
, GNM_FILE_SAVE_AS_STYLE_SAVE
);
845 g_date_time_unref (modtime
);
852 gui_file_export_repeat (WBCGtk
*wbcg
)
854 WorkbookView
*wb_view
= wb_control_view (GNM_WBC (wbcg
));
855 Workbook
*wb
= wb_view_get_workbook (wb_view
);
856 GOFileSaver
*fs
= workbook_get_file_exporter (wb
);
857 gchar
const *last_uri
= workbook_get_last_export_uri (wb
);
859 if (fs
!= NULL
&& last_uri
!= NULL
) {
863 if (go_file_saver_get_save_scope (fs
) != GO_FILE_SAVE_WORKBOOK
)
864 msg
= _("Do you want to export the <b>current sheet</b> of this "
865 "workbook to the location '<b>%s</b>' "
866 "using the '<b>%s</b>' exporter?");
868 msg
= _("Do you want to export this workbook to the "
869 "location '<b>%s</b>' "
870 "using the '<b>%s</b>' exporter?");
872 /* go_gtk_query_yes_no does not handle markup ... */
873 dialog
= gtk_message_dialog_new_with_markup (wbcg_toplevel (wbcg
),
874 GTK_DIALOG_DESTROY_WITH_PARENT
,
875 GTK_MESSAGE_QUESTION
,
878 go_file_saver_get_description (fs
));
879 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_YES
);
881 if (GTK_RESPONSE_YES
==
882 go_gtk_dialog_run (GTK_DIALOG (dialog
), wbcg_toplevel (wbcg
))) {
883 /* We need to copy wb->last_export_uri since it will be reset during saving */
884 gchar
*uri
= g_strdup (last_uri
);
885 if(workbook_view_save_as (wb_view
, fs
, uri
, GO_CMD_CONTEXT (wbcg
))) {
886 workbook_update_history (wb
, GNM_FILE_SAVE_AS_STYLE_EXPORT
);
894 go_gtk_notice_dialog (wbcg_toplevel (wbcg
), GTK_MESSAGE_ERROR
,
895 _("Unable to repeat export since no previous "
896 "export information has been saved in this "