Update Spanish translation
[gnumeric.git] / src / stf-export.c
blob8740f608018561532198e16871629624608764e6
1 /*
2 * stf-export.c : Structured Text Format Exporter (STF-E)
3 * Engine to construct CSV files
5 * Copyright (C) Almer. S. Tigelaar.
6 * EMail: almer1@dds.nl or almer-t@bigfoot.com
8 * Based on the csv-io.c plugin by:
9 * Miguel de Icaza <miguel@gnu.org>
10 * Jody Goldberg <jody@gnome.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses/>.
26 #include <gnumeric-config.h>
27 #include <gnumeric.h>
28 #include <gnm-i18n.h>
29 #include <stf-export.h>
31 #include <gnumeric-conf.h>
32 #include <sheet.h>
33 #include <workbook.h>
34 #include <cell.h>
35 #include <value.h>
36 #include <gutils.h>
37 #include <gnm-format.h>
38 #include <gnm-datetime.h>
39 #include <gsf/gsf-output-iconv.h>
40 #include <gsf/gsf-output-memory.h>
41 #include <gsf/gsf-impl-utils.h>
42 #include <goffice/goffice.h>
44 #include <string.h>
45 #include <locale.h>
47 struct _GnmStfExport {
48 GsfOutputCsv csv;
50 GSList *sheet_list;
51 char *charset;
52 char *locale;
53 GnmStfTransliterateMode transliterate_mode;
54 GnmStfFormatMode format;
57 static GObjectClass *parent_class;
59 typedef struct {
60 GsfOutputCsvClass base_class;
61 } GnmStfExportClass;
63 enum {
64 PROP_0,
65 PROP_CHARSET,
66 PROP_LOCALE,
67 PROP_TRANSLITERATE_MODE,
68 PROP_FORMAT
71 /* ------------------------------------------------------------------------- */
73 static void
74 cb_sheet_destroyed (GnmStfExport *stfe, gpointer deadsheet)
76 g_return_if_fail (GNM_IS_STF_EXPORT (stfe));
78 stfe->sheet_list = g_slist_remove (stfe->sheet_list, deadsheet);
81 /**
82 * gnm_stf_export_options_sheet_list_clear:
83 * @stfe: an export options struct
85 * Clears the sheet list.
86 **/
87 void
88 gnm_stf_export_options_sheet_list_clear (GnmStfExport *stfe)
90 GSList *l;
92 g_return_if_fail (GNM_IS_STF_EXPORT (stfe));
95 for (l = stfe->sheet_list; l; l = l->next) {
96 Sheet *sheet = l->data;
98 g_object_weak_unref (G_OBJECT (sheet),
99 (GWeakNotify) cb_sheet_destroyed,
100 stfe);
103 g_slist_free (stfe->sheet_list);
104 stfe->sheet_list = NULL;
109 * gnm_stf_export_options_sheet_list_add:
110 * @stfe: an export options struct
111 * @sheet: a gnumeric sheet
113 * Appends a @sheet to the list of sheets to be exported
115 void
116 gnm_stf_export_options_sheet_list_add (GnmStfExport *stfe, Sheet *sheet)
118 g_return_if_fail (GNM_IS_STF_EXPORT (stfe));
119 g_return_if_fail (IS_SHEET (sheet));
121 g_object_weak_ref (G_OBJECT (sheet),
122 (GWeakNotify) cb_sheet_destroyed,
123 stfe);
124 stfe->sheet_list = g_slist_append (stfe->sheet_list, sheet);
129 * gnm_stf_export_options_sheet_list_get:
130 * @stfe: #GnmStfExport
132 * Returns: (element-type Sheet) (transfer none): the list of #Sheet instances
133 * added to @stfe using gnm_stf_export_options_sheet_list_add().
135 GSList *
136 gnm_stf_export_options_sheet_list_get (const GnmStfExport *stfe)
138 g_return_val_if_fail (GNM_IS_STF_EXPORT (stfe), NULL);
140 return stfe->sheet_list;
143 /* ------------------------------------------------------------------------- */
146 static char *
147 try_auto_float (GnmValue *value, const GOFormat *format,
148 GODateConventions const *date_conv)
150 gboolean is_date;
151 int is_time;
153 if (!VALUE_IS_FLOAT (value))
154 return NULL;
156 format = gnm_format_specialize (format, value);
157 is_date = go_format_is_date (format) > 0;
158 is_time = go_format_is_time (format);
160 if (is_date || is_time > 0)
161 return NULL;
163 return format_value (go_format_general (), value, -1, date_conv);
167 static char *
168 try_auto_date (GnmValue *value, const GOFormat *format,
169 GODateConventions const *date_conv)
171 gnm_float v, vr, vs;
172 GOFormat *actual;
173 char *res;
174 gboolean needs_date, needs_time, needs_frac_sec;
175 gboolean is_date;
176 int is_time;
177 GString *xlfmt;
178 GDate date;
180 format = gnm_format_specialize (format, value);
181 is_date = go_format_is_date (format) > 0;
182 is_time = go_format_is_time (format);
184 if (!is_date && is_time <= 0)
185 return NULL;
187 /* We don't want to coerce strings. */
188 if (!VALUE_IS_FLOAT (value))
189 return NULL;
191 /* Verify that the date is valid. */
192 if (!datetime_value_to_g (&date, value, date_conv))
193 return NULL;
195 v = value_get_as_float (value);
196 vr = gnm_fake_round (v);
197 vs = (24 * 60 * 60) * gnm_abs (v - vr);
199 needs_date = is_time < 2 && (is_date || gnm_abs (v) >= 1);
200 needs_time = is_time > 0 || gnm_abs (v - vr) > 1e-9;
201 needs_frac_sec = needs_time && gnm_abs (vs - gnm_fake_round (vs)) >= 0.5e-3;
203 xlfmt = g_string_new (NULL);
204 if (needs_date) g_string_append (xlfmt, "yyyy/mm/dd");
205 if (needs_time) {
206 if (needs_date)
207 g_string_append_c (xlfmt, ' ');
208 if (is_time == 2)
209 g_string_append (xlfmt, "[h]:mm:ss");
210 else
211 g_string_append (xlfmt, "hh:mm:ss");
212 if (needs_frac_sec)
213 g_string_append (xlfmt, ".000");
215 actual = go_format_new_from_XL (xlfmt->str);
216 g_string_free (xlfmt, TRUE);
217 res = format_value (actual, value, -1, date_conv);
218 go_format_unref (actual);
220 return res;
224 * stf_export_cell:
225 * @stfe: an export options struct
226 * @cell: the cell to write to the file
228 * Return value: return TRUE on success, FALSE otherwise.
230 static gboolean
231 stf_export_cell (GnmStfExport *stfe, GnmCell *cell)
233 char const *text = NULL;
234 char *tmp = NULL;
235 gboolean ok;
236 g_return_val_if_fail (stfe != NULL, FALSE);
238 if (cell) {
239 switch (stfe->format) {
240 case GNM_STF_FORMAT_PRESERVE:
241 text = tmp = gnm_cell_get_rendered_text (cell);
242 break;
243 default:
244 case GNM_STF_FORMAT_AUTO:
245 if (cell->value) {
246 GODateConventions const *date_conv =
247 sheet_date_conv (cell->base.sheet);
248 GOFormat const *format = gnm_cell_get_format (cell);
249 text = tmp = try_auto_date (cell->value, format, date_conv);
250 if (!text)
251 text = tmp = try_auto_float (cell->value, format, date_conv);
252 if (!text)
253 text = value_peek_string (cell->value);
255 break;
256 case GNM_STF_FORMAT_RAW:
257 if (cell->value)
258 text = value_peek_string (cell->value);
259 break;
263 ok = gsf_output_csv_write_field (GSF_OUTPUT_CSV (stfe),
264 text ? text : "",
265 -1);
266 g_free (tmp);
268 return ok;
272 * stf_export_sheet:
273 * @stfe: an export options struct
274 * @sheet: the sheet to export
276 * Writes the @sheet to the callback function
278 * Return value: returns TRUE on success, FALSE otherwise
280 static gboolean
281 stf_export_sheet (GnmStfExport *stfe, Sheet *sheet)
283 int col, row;
284 GnmRange r;
285 GnmRangeRef *range;
287 g_return_val_if_fail (stfe != NULL, FALSE);
288 g_return_val_if_fail (IS_SHEET (sheet), FALSE);
290 range = g_object_get_data (G_OBJECT (sheet->workbook), "ssconvert-range");
291 if (range) {
292 Sheet *start_sheet, *end_sheet;
293 GnmEvalPos ep;
295 gnm_rangeref_normalize (range,
296 eval_pos_init_sheet (&ep, sheet),
297 &start_sheet, &end_sheet,
298 &r);
300 if (start_sheet != sheet)
301 return TRUE;
302 } else
303 r = sheet_get_extent (sheet, FALSE, TRUE);
305 for (row = r.start.row; row <= r.end.row; row++) {
306 for (col = r.start.col; col <= r.end.col; col++) {
307 GnmCell *cell = sheet_cell_get (sheet, col, row);
308 if (!stf_export_cell (stfe, cell))
309 return FALSE;
311 if (!gsf_output_csv_write_eol (GSF_OUTPUT_CSV (stfe)))
312 return FALSE;
315 return TRUE;
319 * gnm_stf_export:
320 * @export_options: an export options struct
322 * Exports the sheets given in @stfe
324 * Return value: TRUE on success, FALSE otherwise
326 gboolean
327 gnm_stf_export (GnmStfExport *stfe)
329 GSList *ptr;
330 GsfOutput *sink;
331 gboolean result = TRUE;
332 char *old_locale = NULL;
334 g_return_val_if_fail (GNM_IS_STF_EXPORT (stfe), FALSE);
335 g_return_val_if_fail (stfe->sheet_list != NULL, FALSE);
336 g_object_get (G_OBJECT (stfe), "sink", &sink, NULL);
337 g_return_val_if_fail (sink != NULL, FALSE);
339 if (stfe->charset &&
340 strcmp (stfe->charset, "UTF-8") != 0) {
341 char *charset;
342 GsfOutput *converter;
344 switch (stfe->transliterate_mode) {
345 default:
346 case GNM_STF_TRANSLITERATE_MODE_ESCAPE:
347 charset = g_strdup (stfe->charset);
348 break;
349 case GNM_STF_TRANSLITERATE_MODE_TRANS:
350 charset = g_strconcat (stfe->charset,
351 "//TRANSLIT",
352 NULL);
353 break;
355 converter = gsf_output_iconv_new (sink, charset, "UTF-8");
356 g_free (charset);
358 if (converter) {
359 g_object_set (G_OBJECT (stfe), "sink", converter, NULL);
360 g_object_unref (converter);
361 } else {
362 g_warning ("Failed to create converter.");
363 result = FALSE;
367 if (stfe->locale) {
368 old_locale = g_strdup (go_setlocale (LC_ALL, NULL));
369 go_setlocale (LC_ALL, stfe->locale);
372 for (ptr = stfe->sheet_list; ptr != NULL ; ptr = ptr->next) {
373 Sheet *sheet = ptr->data;
374 if (!stf_export_sheet (stfe, sheet)) {
375 result = FALSE;
376 break;
380 if (old_locale) /* go_setlocale clears the cache, */
381 /*so we don't want to call it with NULL*/
382 go_setlocale (LC_ALL, old_locale);
383 g_free (old_locale);
386 g_object_set (G_OBJECT (stfe), "sink", sink, NULL);
387 g_object_unref (sink);
389 return result;
392 /* ------------------------------------------------------------------------- */
395 * gnm_stf_export_can_transliterate:
397 * Return value: %TRUE iff //TRANSLIT is supported
399 gboolean
400 gnm_stf_export_can_transliterate (void)
402 char const *text = "G\xc3\xbclzow";
403 char *encoded_text;
404 GError *error = NULL;
406 encoded_text = g_convert (text, -1,
407 "ASCII//TRANSLIT", "UTF-8",
408 NULL, NULL, &error);
409 g_free (encoded_text);
411 if (error == NULL)
412 return TRUE;
414 g_error_free (error);
415 return FALSE;
418 /* ------------------------------------------------------------------------- */
420 GType
421 gnm_stf_transliterate_mode_get_type (void)
423 static GType etype = 0;
424 if (etype == 0) {
425 static GEnumValue const values[] = {
426 { GNM_STF_TRANSLITERATE_MODE_TRANS, "GNM_STF_TRANSLITERATE_MODE_TRANS", "transliterate" },
427 { GNM_STF_TRANSLITERATE_MODE_ESCAPE, "GNM_STF_TRANSLITERATE_MODE_ESCAPE", "escape" },
428 { 0, NULL, NULL }
430 etype = g_enum_register_static ("GnmStfTransliterateMode", values);
432 return etype;
435 /* ------------------------------------------------------------------------- */
437 GType
438 gnm_stf_format_mode_get_type (void)
440 static GType etype = 0;
441 if (etype == 0) {
442 static GEnumValue const values[] = {
443 { GNM_STF_FORMAT_AUTO, "GNM_STF_FORMAT_AUTO", "automatic" },
444 { GNM_STF_FORMAT_RAW, "GNM_STF_FORMAT_RAW", "raw" },
445 { GNM_STF_FORMAT_PRESERVE, "GNM_STF_FORMAT_PRESERVE", "preserve" },
446 { 0, NULL, NULL }
448 etype = g_enum_register_static ("GnmStfFormatMode", values);
450 return etype;
453 /* ------------------------------------------------------------------------- */
455 static void
456 gnm_stf_export_init (G_GNUC_UNUSED GObject *obj)
460 /* ------------------------------------------------------------------------- */
462 static void
463 gnm_stf_export_finalize (GObject *obj)
465 GnmStfExport *stfe = (GnmStfExport *)obj;
467 gnm_stf_export_options_sheet_list_clear (stfe);
468 g_free (stfe->charset);
469 g_free (stfe->locale);
471 G_OBJECT_CLASS (parent_class)->finalize (obj);
474 /* ------------------------------------------------------------------------- */
476 static void
477 gnm_stf_export_get_property (GObject *object,
478 guint property_id,
479 GValue *value,
480 GParamSpec *pspec)
482 GnmStfExport *stfe = (GnmStfExport *)object;
484 switch (property_id) {
485 case PROP_CHARSET:
486 g_value_set_string (value, stfe->charset);
487 break;
488 case PROP_LOCALE:
489 g_value_set_string (value, stfe->locale);
490 break;
491 case PROP_TRANSLITERATE_MODE:
492 g_value_set_enum (value, stfe->transliterate_mode);
493 break;
494 case PROP_FORMAT:
495 g_value_set_enum (value, stfe->format);
496 break;
497 default:
498 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
499 break;
503 /* ------------------------------------------------------------------------- */
505 static void
506 gnm_stf_export_set_property (GObject *object,
507 guint property_id,
508 GValue const *value,
509 GParamSpec *pspec)
511 GnmStfExport *stfe = (GnmStfExport *)object;
512 char *scopy;
514 switch (property_id) {
515 case PROP_CHARSET:
516 scopy = g_value_dup_string (value);
517 g_free (stfe->charset);
518 stfe->charset = scopy;
519 break;
520 case PROP_LOCALE:
521 scopy = g_value_dup_string (value);
522 g_free (stfe->locale);
523 stfe->locale = scopy;
524 break;
525 case PROP_TRANSLITERATE_MODE:
526 stfe->transliterate_mode = g_value_get_enum (value);
527 break;
528 case PROP_FORMAT:
529 stfe->format = g_value_get_enum (value);
530 break;
531 default:
532 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
533 break;
537 /* ------------------------------------------------------------------------- */
539 static void
540 gnm_stf_export_class_init (GObjectClass *gobject_class)
542 parent_class = g_type_class_peek_parent (gobject_class);
544 gobject_class->finalize = gnm_stf_export_finalize;
545 gobject_class->get_property = gnm_stf_export_get_property;
546 gobject_class->set_property = gnm_stf_export_set_property;
548 g_object_class_install_property
549 (gobject_class,
550 PROP_CHARSET,
551 g_param_spec_string ("charset",
552 P_("Character set"),
553 P_("The character encoding of the output."),
554 NULL,
555 GSF_PARAM_STATIC |
556 G_PARAM_READWRITE));
557 g_object_class_install_property
558 (gobject_class,
559 PROP_LOCALE,
560 g_param_spec_string ("locale",
561 P_("Locale"),
562 P_("The locale to use for number and date formatting."),
563 NULL,
564 GSF_PARAM_STATIC |
565 G_PARAM_READWRITE));
566 g_object_class_install_property
567 (gobject_class,
568 PROP_TRANSLITERATE_MODE,
569 g_param_spec_enum ("transliterate-mode",
570 P_("Transliterate mode"),
571 P_("What to do with unrepresentable characters."),
572 GNM_STF_TRANSLITERATE_MODE_TYPE,
573 GNM_STF_TRANSLITERATE_MODE_ESCAPE,
574 GSF_PARAM_STATIC |
575 G_PARAM_READWRITE));
576 g_object_class_install_property
577 (gobject_class,
578 PROP_FORMAT,
579 g_param_spec_enum ("format",
580 P_("Format"),
581 P_("How should cells be formatted?"),
582 GNM_STF_FORMAT_MODE_TYPE,
583 GNM_STF_FORMAT_AUTO,
584 GSF_PARAM_STATIC |
585 G_PARAM_READWRITE));
588 /* ------------------------------------------------------------------------- */
590 GSF_CLASS (GnmStfExport, gnm_stf_export,
591 gnm_stf_export_class_init, gnm_stf_export_init, GSF_OUTPUT_CSV_TYPE)
593 /* ------------------------------------------------------------------------- */
594 /* ------------------------------------------------------------------------- */
597 #include <wbc-gtk.h>
598 #include <dialogs/dialog-stf-export.h>
599 #include <workbook-view.h>
602 * gnm_stf_get_stfe:
603 * @obj: #GObject with a #GnmStfExport attached as data.
605 * If none is found, a new one is created and attached to @obj.
606 * Returns: (transfer none): the #GnmStfExport.
608 GnmStfExport *
609 gnm_stf_get_stfe (GObject *obj)
611 GnmStfExport *stfe = g_object_get_data (obj, "stfe");
612 if (!stfe) {
613 const char * sep = gnm_conf_get_stf_export_separator ();
614 const char * string_indicator = gnm_conf_get_stf_export_stringindicator ();
615 const char * terminator = gnm_conf_get_stf_export_terminator ();
616 const char * locale = gnm_conf_get_stf_export_locale ();
617 const char * encoding = gnm_conf_get_stf_export_encoding ();
618 int quotingmode = gnm_conf_get_stf_export_quoting ();
619 int format = gnm_conf_get_stf_export_format ();
620 int transliteratemode = gnm_conf_get_stf_export_transliteration () ?
621 GNM_STF_TRANSLITERATE_MODE_TRANS : GNM_STF_TRANSLITERATE_MODE_ESCAPE;
622 GString *triggers = g_string_new (NULL);
624 if (strlen (locale) == 0)
625 locale = NULL;
626 if (strlen (encoding) == 0)
627 encoding = NULL;
629 /* Workaround GConf bug #641807. */
630 if (terminator == NULL || strlen (terminator) == 0)
631 terminator = "\n";
633 if (quotingmode == GSF_OUTPUT_CSV_QUOTING_MODE_AUTO) {
634 g_string_append (triggers, " \t");
635 g_string_append (triggers, terminator);
636 g_string_append (triggers, string_indicator);
637 g_string_append (triggers, sep);
640 stfe = g_object_new (GNM_STF_EXPORT_TYPE,
641 "quoting-triggers", triggers->str,
642 "separator", sep,
643 "quote", string_indicator,
644 "eol", terminator,
645 "charset", encoding,
646 "locale", locale,
647 "quoting-mode", quotingmode,
648 "transliterate-mode", transliteratemode,
649 "format", format,
650 NULL);
651 g_object_set_data_full (obj, "stfe", stfe, g_object_unref);
652 g_string_free (triggers, TRUE);
654 return stfe;
657 static void
658 gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs,
659 GOIOContext *context,
660 GoView const *view, GsfOutput *output)
662 WorkbookView *wbv = GNM_WORKBOOK_VIEW (view);
663 Workbook *wb = wb_view_get_workbook (wbv);
664 GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (wb));
665 GsfOutput *dummy_sink;
666 gboolean nosheets;
668 /* TODO: move this GUI dependent code out of this
669 * filesaver into gui-file.c. After this, remove includes (see above). */
670 if (GNM_IS_WBC_GTK (context->impl)) {
671 gboolean cancelled =
672 stf_export_dialog (WBC_GTK (context->impl), stfe, wb);
673 if (cancelled) {
674 go_io_error_unknown (context);
675 return;
679 nosheets = (stfe->sheet_list == NULL);
680 if (nosheets) {
681 GPtrArray *sel = gnm_file_saver_get_sheets (fs, wbv, TRUE);
682 unsigned ui;
683 for (ui = 0; ui < sel->len; ui++)
684 gnm_stf_export_options_sheet_list_add
685 (stfe, g_ptr_array_index (sel, ui));
686 g_ptr_array_unref (sel);
689 g_object_set (G_OBJECT (stfe), "sink", output, NULL);
690 if (gnm_stf_export (stfe) == FALSE)
691 go_cmd_context_error_import (GO_CMD_CONTEXT (context),
692 _("Error while trying to export file as text"));
694 /* We're not allowed to set a NULL sink, so use a dummy. */
695 dummy_sink = gsf_output_memory_new ();
696 g_object_set (G_OBJECT (stfe), "sink", dummy_sink, NULL);
697 g_object_unref (dummy_sink);
699 if (nosheets)
700 gnm_stf_export_options_sheet_list_clear (stfe);
703 struct cb_set_export_option {
704 GOFileSaver *fs;
705 Workbook const *wb;
708 static gboolean
709 cb_set_export_option (const char *key, const char *value,
710 GError **err, gpointer user_)
712 struct cb_set_export_option *user = user_;
713 Workbook const *wb = user->wb;
714 GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (wb));
715 const char *errtxt;
717 if (strcmp (key, "eol") == 0) {
718 const char *eol;
719 if (g_ascii_strcasecmp ("unix", value) == 0)
720 eol = "\n";
721 else if (g_ascii_strcasecmp ("mac", value) == 0)
722 eol = "\r";
723 else if (g_ascii_strcasecmp ("windows", value) == 0)
724 eol = "\r\n";
725 else {
726 errtxt = _("eol must be one of unix, mac, and windows");
727 goto error;
730 g_object_set (G_OBJECT (stfe), "eol", eol, NULL);
731 return FALSE;
734 if (strcmp (key, "charset") == 0 ||
735 strcmp (key, "locale") == 0 ||
736 strcmp (key, "quote") == 0 ||
737 strcmp (key, "separator") == 0 ||
738 strcmp (key, "format") == 0 ||
739 strcmp (key, "transliterate-mode") == 0 ||
740 strcmp (key, "quoting-mode") == 0 ||
741 strcmp (key, "quoting-on-whitespace") == 0)
742 return go_object_set_property
743 (G_OBJECT (stfe),
744 key, key, value,
745 err,
746 (_("Invalid value for option %s: \"%s\"")));
748 return gnm_file_saver_common_export_option (user->fs, wb,
749 key, value, err);
751 error:
752 if (err)
753 *err = g_error_new (go_error_invalid (), 0, "%s", errtxt);
755 return TRUE;
758 static gboolean
759 gnm_stf_fs_set_export_options (GOFileSaver *fs,
760 GODoc *doc,
761 const char *options,
762 GError **err,
763 G_GNUC_UNUSED gpointer user)
765 GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (doc));
766 struct cb_set_export_option data;
767 data.fs = fs;
768 data.wb = WORKBOOK (doc);
769 gnm_stf_export_options_sheet_list_clear (stfe);
770 return go_parse_key_value (options, err, cb_set_export_option, &data);
774 * gnm_stf_file_saver_create:
775 * @id:
777 * Returns: (transfer full): the newly allocated #GOFileSaver.
779 GOFileSaver *
780 gnm_stf_file_saver_create (gchar const *id)
782 GOFileSaver *fs = go_file_saver_new (id,
783 "txt",
784 _("Text (configurable)"),
785 GO_FILE_FL_WRITE_ONLY,
786 gnm_stf_file_saver_save);
787 go_file_saver_set_save_scope (fs, GO_FILE_SAVE_WORKBOOK);
788 g_object_set (G_OBJECT (fs), "sheet-selection", TRUE, NULL);
789 g_signal_connect (G_OBJECT (fs), "set-export-options",
790 G_CALLBACK (gnm_stf_fs_set_export_options),
791 NULL);
792 return GO_FILE_SAVER (fs);