[gnumeric] ssconvert: fix --export-file-per-sheet



commit 6f58b5e458fce639c2fdbbe401d1e05d6f8f7729
Author: Morten Welinder <terra gnome org>
Date:   Thu May 10 14:12:49 2018 -0400

    ssconvert: fix --export-file-per-sheet

 NEWS             |    1 +
 src/ssconvert.c  |  144 ++++++++++++++++++++++++++++++++++++++---------------
 src/stf-export.c |   19 ++++++--
 src/stf.c        |   14 +++--
 4 files changed, 127 insertions(+), 51 deletions(-)
---
diff --git a/NEWS b/NEWS
index 1d0770d..0e9e87a 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Morten:
        * Plug leaks.
        * Introspection fixes.
        * Work around gtk+ breakage re. link colors.
+       * Fix problems with ssconvert --export-file-per-sheet.  [#694408]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.41
diff --git a/src/ssconvert.c b/src/ssconvert.c
index 6bcfe78..8ab3595 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -40,6 +40,9 @@
 #include <sys/resource.h>
 #endif
 
+#define SHEET_SELECTION_KEY "sheet-selection"
+
+
 static gboolean ssconvert_show_version = FALSE;
 static gboolean ssconvert_verbose = FALSE;
 static gboolean ssconvert_list_exporters = FALSE;
@@ -183,12 +186,12 @@ static const GOptionEntry ssconvert_options [] = {
        { NULL }
 };
 
-static void
+static GnmRangeRef const *
 setup_range (GObject *obj, const char *key, Workbook *wb, const char *rtxt)
 {
        GnmParsePos pp;
        const char *end;
-       GnmRangeRef rr;
+       GnmRangeRef rr, *rrc;
 
        pp.wb = wb;
        pp.sheet = workbook_sheet_by_index (wb, 0);
@@ -201,9 +204,10 @@ setup_range (GObject *obj, const char *key, Workbook *wb, const char *rtxt)
                exit (1);
        }
 
-       g_object_set_data_full (obj, key,
-                               g_memdup (&rr, sizeof (rr)),
-                               g_free);
+       rrc = g_memdup (&rr, sizeof (rr));
+       g_object_set_data_full (obj, key, rrc, g_free);
+
+       return rrc;
 }
 
 static int
@@ -679,6 +683,10 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
        WorkbookView *wbv;
        GOIOContext *io_context = NULL;
        Workbook *wb = NULL;
+       GOFileSaveScope fsscope;
+       gboolean fs_sheet_selection;
+       GPtrArray *sheet_sel = NULL;
+       GnmRangeRef const *range = NULL;
 
        if (ssconvert_export_id != NULL) {
                fs = go_file_saver_for_id (ssconvert_export_id);
@@ -735,6 +743,30 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
 
        if (!fs)
                goto out;
+       fsscope = go_file_saver_get_save_scope (fs);
+       g_object_get (G_OBJECT (fs), "sheet-selection", &fs_sheet_selection, NULL);
+
+       if (ssconvert_one_file_per_sheet) {
+               gboolean ok;
+               switch (fsscope) {
+               case GO_FILE_SAVE_WORKBOOK:
+                       ok = fs_sheet_selection;
+                       break;
+               case GO_FILE_SAVE_SHEET:
+                       ok = TRUE;
+                       break;
+               case GO_FILE_SAVE_RANGE:
+               default:
+                       ok = FALSE;
+                       break;
+               }
+               if (!ok) {
+                       g_printerr (_("Selected exporter (%s) does not have the ability to split a workbook 
into sheets.\n"),
+                                   go_file_saver_get_id (fs));
+                       res = 1;
+                       goto out;
+               }
+       }
 
        io_context = go_io_context_new (cc);
        if (mergeargs == NULL) {
@@ -819,56 +851,81 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
        gnm_app_recalc ();
 
        if (ssconvert_range)
-               setup_range (G_OBJECT (wb),
-                            "ssconvert-range",
-                            wb,
-                            ssconvert_range);
-       else if (ssconvert_one_file_per_sheet ||
-                (workbook_sheet_count (wb) > 1 &&
-                 go_file_saver_get_save_scope (fs) != GO_FILE_SAVE_WORKBOOK)) {
-               if (ssconvert_one_file_per_sheet) {
-                       GSList *ptr, *sheets;
-                       char *template;
-
-                       res = 0;
-
-                       template = strchr (outarg, '%')
-                               ? g_strdup (outarg)
-                               : g_strconcat (outarg, ".%n", NULL);
-
-                       sheets = workbook_sheets (wb);
-                       for (ptr = sheets; ptr; ptr = ptr->next) {
-                               Sheet *sheet = ptr->data;
-                               char *tmpfile = resolve_template (template, sheet);
-                               int oldn = sheet->index_in_wb;
+               range = setup_range (G_OBJECT (wb),
+                                    "ssconvert-range",
+                                    wb,
+                                    ssconvert_range);
+
+       if (ssconvert_one_file_per_sheet ||
+           fsscope == GO_FILE_SAVE_SHEET ||
+           range) {
+               Sheet *def_sheet = NULL;
+
+               if (range && range->a.sheet)
+                       def_sheet = range->a.sheet;
+               else if (fsscope == GO_FILE_SAVE_SHEET || range)
+                       def_sheet = wb_view_cur_sheet (wbv);
+
+               sheet_sel = g_ptr_array_new ();
+               if (def_sheet)
+                       g_ptr_array_add (sheet_sel, def_sheet);
+               g_object_set_data (G_OBJECT (wb),
+                                  SHEET_SELECTION_KEY, sheet_sel);
+       }
 
+       if (ssconvert_one_file_per_sheet) {
+               GSList *ptr, *sheets;
+               char *template;
+
+               res = 0;
+
+               template = strchr (outarg, '%')
+                       ? g_strdup (outarg)
+                       : g_strconcat (outarg, ".%n", NULL);
+
+               sheets = workbook_sheets (wb);
+               for (ptr = sheets; ptr; ptr = ptr->next) {
+                       Sheet *sheet = ptr->data;
+                       char *tmpfile = resolve_template (template, sheet);
+                       int oldn = sheet->index_in_wb;
+
+                       g_ptr_array_set_size (sheet_sel, 0);
+                       g_ptr_array_add (sheet_sel, sheet);
+
+                       if (!fs_sheet_selection) {
                                /*
                                 * HACK: (bug 694408).
                                 *
                                 * We don't have a good way of specifying the
                                 * sheet.  Move it to the front and select
                                 * it.  That will at least make cvs and txt
-                                * exporters reliable find it.
+                                * exporters reliably find it.
                                 */
                                workbook_sheet_move (sheet, -oldn);
                                wb_view_sheet_focus (wbv, sheet);
+                       }
+
+                       res = !workbook_view_save_as (wbv, fs, tmpfile, cc);
 
-                               res = !workbook_view_save_as (wbv, fs, tmpfile, cc);
+                       if (!fs_sheet_selection)
                                workbook_sheet_move (sheet, +oldn);
-                               g_free (tmpfile);
-                               if (res)
-                                       break;
-                       }
 
-                       g_free (template);
-                       g_slist_free (sheets);
-                       goto out;
-               } else
-                       g_printerr (_("Selected exporter (%s) does not support saving multiple sheets in one 
file.\n"
-                                     "Only the current sheet will be saved.  To get around this limitation, 
use -S.\n"),
-                                   go_file_saver_get_id (fs));
+                       g_free (tmpfile);
+                       if (res)
+                               break;
+               }
+
+               g_free (template);
+               g_slist_free (sheets);
+       } else {
+               res = !workbook_view_save_as (wbv, fs, outfile, cc);
+       }
+
+       if (sheet_sel) {
+               g_object_set_data (G_OBJECT (wb),
+                                  SHEET_SELECTION_KEY, NULL);
+               g_ptr_array_free (sheet_sel, TRUE);
        }
-       res = !workbook_view_save_as (wbv, fs, outfile, cc);
 
  out:
        if (wb)
@@ -917,6 +974,11 @@ main (int argc, char const **argv)
                return 0;
        }
 
+       if (ssconvert_one_file_per_sheet && ssconvert_merge_target) {
+               g_printerr (_("--export-file-per-sheet and --merge-to are incompatible\n"));
+               return 1;
+       }
+
        gnm_init ();
 
        cc = gnm_cmd_context_stderr_new ();
diff --git a/src/stf-export.c b/src/stf-export.c
index 0c0d530..e93d25d 100644
--- a/src/stf-export.c
+++ b/src/stf-export.c
@@ -44,6 +44,7 @@
 #include <string.h>
 #include <locale.h>
 
+#define SHEET_SELECTION_KEY "sheet-selection"
 
 struct _GnmStfExport {
        GsfOutputCsv csv;
@@ -657,7 +658,8 @@ gnm_stf_get_stfe (GObject *obj)
 }
 
 static void
-gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *context,
+gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs,
+                        GOIOContext *context,
                         GoView const *view, GsfOutput *output)
 {
        WorkbookView *wbv = GNM_WORKBOOK_VIEW (view);
@@ -678,9 +680,17 @@ gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *conte
        }
 
        nosheets = (stfe->sheet_list == NULL);
-       if (nosheets)
-               gnm_stf_export_options_sheet_list_add
-                       (stfe, wb_view_cur_sheet (wbv));
+       if (nosheets) {
+               GPtrArray *sel = g_object_get_data (G_OBJECT (wb), SHEET_SELECTION_KEY);
+               if (sel) {
+                       unsigned ui;
+                       for (ui = 0; ui < sel->len; ui++)
+                               gnm_stf_export_options_sheet_list_add
+                                       (stfe, g_ptr_array_index (sel, ui));
+               } else
+                       gnm_stf_export_options_sheet_list_add
+                               (stfe, wb_view_cur_sheet (wbv));
+       }
 
        g_object_set (G_OBJECT (stfe), "sink", output, NULL);
        if (gnm_stf_export (stfe) == FALSE)
@@ -782,6 +792,7 @@ gnm_stf_file_saver_create (gchar const *id)
                                             GO_FILE_FL_WRITE_ONLY,
                                             gnm_stf_file_saver_save);
        go_file_saver_set_save_scope (fs, GO_FILE_SAVE_WORKBOOK);
+       g_object_set (G_OBJECT (fs), "sheet-selection", TRUE, NULL);
        g_signal_connect (G_OBJECT (fs), "set-export-options",
                          G_CALLBACK (gnm_stf_fs_set_export_options),
                          NULL);
diff --git a/src/stf.c b/src/stf.c
index 4000b98..c40714b 100644
--- a/src/stf.c
+++ b/src/stf.c
@@ -58,6 +58,7 @@
 #include <gsf/gsf-utils.h>
 #include <locale.h>
 
+#define SHEET_SELECTION_KEY "sheet-selection"
 
 static void
 stf_warning (GOIOContext *context, char const *msg)
@@ -490,8 +491,9 @@ stf_write_csv (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *context,
               GoView const *view, GsfOutput *output)
 {
        Sheet *sheet;
-       GnmRangeRef const *range;
        WorkbookView *wbv = GNM_WORKBOOK_VIEW (view);
+       Workbook *wb = wb_view_get_workbook (wbv);
+       GPtrArray *sel = g_object_get_data (G_OBJECT (wb), SHEET_SELECTION_KEY);
 
        GnmStfExport *config = g_object_new
                (GNM_STF_EXPORT_TYPE,
@@ -499,14 +501,13 @@ stf_write_csv (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *context,
                 "quoting-triggers", ", \t\n\"",
                 NULL);
 
-       /* FIXME: this is crap in both branches of the "if".  */
-       range = g_object_get_data (G_OBJECT (wb_view_get_workbook (wbv)), "ssconvert-range");
-       if (range && range->a.sheet)
-               sheet = range->a.sheet;
+       if (sel)
+               sheet = sel->len ? g_ptr_array_index (sel, 0) : NULL;
        else
                sheet = wb_view_cur_sheet (wbv);
 
-       gnm_stf_export_options_sheet_list_add (config, sheet);
+       if (sheet)
+               gnm_stf_export_options_sheet_list_add (config, sheet);
 
        if (gnm_stf_export (config) == FALSE)
                go_cmd_context_error_import (GO_CMD_CONTEXT (context),
@@ -636,6 +637,7 @@ stf_init (void)
                _("Comma separated values (CSV)"),
                GO_FILE_FL_MANUAL_REMEMBER, stf_write_csv);
        go_file_saver_set_save_scope (saver, GO_FILE_SAVE_SHEET);
+       g_object_set (G_OBJECT (saver), "sheet-selection", TRUE, NULL);
        go_file_saver_register (saver);
        g_object_unref (saver);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]