[gnumeric] ssconvert: handle sheet selection in one place.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ssconvert: handle sheet selection in one place.
- Date: Fri, 11 May 2018 19:14:48 +0000 (UTC)
commit 22ac6f52955f5e3e42c4dd7e433c48f74fb92070
Author: Morten Welinder <terra gnome org>
Date: Fri May 11 15:13:34 2018 -0400
ssconvert: handle sheet selection in one place.
This makes sheet selection (-O 'sheet=Sheet1 sheet=Sheet2') work in more
contexts.
NEWS | 3 +-
src/gutils.c | 54 +++++++++++-
src/gutils.h | 6 ++
src/print-info.c | 54 ++++--------
src/ssconvert.c | 261 +++++++++++++++++++++++++++++++++++------------------
src/stf-export.c | 34 ++++----
6 files changed, 266 insertions(+), 146 deletions(-)
---
diff --git a/NEWS b/NEWS
index b63b7b7..2b21967 100644
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,9 @@ Morten:
* Introspection fixes.
* Work around gtk+ breakage re. link colors.
* Fix problems with ssconvert --export-file-per-sheet. [#694408]
- * Enable --export-file-per-sheet for html, latex, and pdf.
+ * Enable ssconvert --export-file-per-sheet for html, latex, and pdf.
* Test suite improvements.
+ * ssconvert improvements.
--------------------------------------------------------------------------
Gnumeric 1.12.41
diff --git a/src/gutils.c b/src/gutils.c
index c17278f..2657a3e 100644
--- a/src/gutils.c
+++ b/src/gutils.c
@@ -34,6 +34,7 @@
#include <gsf/gsf-timestamp.h>
#define SHEET_SELECTION_KEY "sheet-selection"
+#define SSCONVERT_SHEET_SET_KEY "ssconvert-sheets"
static char *gnumeric_lib_dir;
static char *gnumeric_data_dir;
@@ -904,7 +905,7 @@ gnm_file_saver_get_sheets (GOFileSaver const *fs,
gboolean default_all)
{
Workbook *wb;
- GPtrArray *sel;
+ GPtrArray *sel, *sheets;
g_return_val_if_fail (GO_IS_FILE_SAVER (fs), NULL);
g_return_val_if_fail (go_file_saver_get_save_scope (fs) ==
@@ -913,8 +914,11 @@ gnm_file_saver_get_sheets (GOFileSaver const *fs,
wb = wb_view_get_workbook (wbv);
sel = g_object_get_data (G_OBJECT (wb), SHEET_SELECTION_KEY);
+ sheets = g_object_get_data (G_OBJECT (wb), SSCONVERT_SHEET_SET_KEY);
if (sel)
g_ptr_array_ref (sel);
+ else if (sheets)
+ sel = g_ptr_array_ref (sheets);
else if (default_all) {
int i;
sel = g_ptr_array_new ();
@@ -926,3 +930,51 @@ gnm_file_saver_get_sheets (GOFileSaver const *fs,
return sel;
}
+
+gboolean
+gnm_file_saver_common_export_option (GOFileSaver const *fs,
+ Workbook const *wb,
+ const char *key, const char *value,
+ GError **err)
+{
+ if (err)
+ *err = NULL;
+
+ g_return_val_if_fail (GO_IS_FILE_SAVER (fs), FALSE);
+ g_return_val_if_fail (GNM_IS_WORKBOOK (wb), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ if (strcmp (key, "sheet") == 0) {
+ GPtrArray *sheets;
+ Sheet *sheet = workbook_sheet_by_name (wb, value);
+
+ if (!sheet) {
+ if (err)
+ *err = g_error_new (go_error_invalid (), 0,
+ _("Unknown sheet \"%s\""),
+ value);
+ return TRUE;
+ }
+
+ sheets = g_object_get_data (G_OBJECT (wb), SSCONVERT_SHEET_SET_KEY);
+ if (!sheets) {
+ sheets = g_ptr_array_new ();
+ g_object_set_data_full (G_OBJECT (wb),
+ SSCONVERT_SHEET_SET_KEY,
+ sheets,
+ (GDestroyNotify)g_ptr_array_unref);
+ }
+ g_ptr_array_add (sheets, sheet);
+
+ return FALSE;
+ }
+
+ if (err)
+ *err = g_error_new (go_error_invalid (), 0,
+ _("Invalid export option \"%s\" for format %s"),
+ key,
+ go_file_saver_get_id (fs));
+
+ return TRUE;
+}
diff --git a/src/gutils.h b/src/gutils.h
index 8940413..904911f 100644
--- a/src/gutils.h
+++ b/src/gutils.h
@@ -68,6 +68,12 @@ GPtrArray *gnm_file_saver_get_sheets (GOFileSaver const *fs,
WorkbookView const *wbv,
gboolean default_all);
+gboolean gnm_file_saver_common_export_option (GOFileSaver const *fs,
+ Workbook const *wb,
+ const char *key,
+ const char *value,
+ GError **err);
+
G_END_DECLS
#endif /* _GNM_GUTILS_H_ */
diff --git a/src/print-info.c b/src/print-info.c
index d143b25..54b3ac9 100644
--- a/src/print-info.c
+++ b/src/print-info.c
@@ -833,13 +833,7 @@ pdf_write_workbook (G_GNUC_UNUSED GOFileSaver const *fs,
WorkbookView const *wbv, GsfOutput *output)
{
Workbook const *wb = wb_view_get_workbook (wbv);
- GPtrArray *sheets;
-
- sheets = g_object_get_data (G_OBJECT (wb), "pdf-sheets");
- if (sheets)
- g_ptr_array_ref (sheets);
- else
- sheets = gnm_file_saver_get_sheets (fs, wbv, FALSE);
+ GPtrArray *sheets = gnm_file_saver_get_sheets (fs, wbv, FALSE);
if (sheets) {
int i;
@@ -885,33 +879,17 @@ pdf_export (GOFileSaver const *fs, GOIOContext *context,
pdf_write_workbook (fs, context, wbv, output);
}
+struct cb_set_pdf_option {
+ GOFileSaver *fs;
+ Workbook const *wb;
+};
+
static gboolean
cb_set_pdf_option (const char *key, const char *value,
- GError **err, gpointer user)
+ GError **err, gpointer user_)
{
- Workbook *wb = user;
-
- if (strcmp (key, "sheet") == 0) {
- Sheet *sheet = workbook_sheet_by_name (wb, value);
- GPtrArray *sheets;
-
- if (!sheet) {
- *err = g_error_new (go_error_invalid (), 0,
- _("There is no such sheet"));
- return TRUE;
- }
-
- sheets = g_object_get_data (G_OBJECT (wb), "pdf-sheets");
- if (!sheets) {
- sheets = g_ptr_array_new ();
- g_object_set_data_full (G_OBJECT (wb),
- "pdf-sheets", sheets,
- (GDestroyNotify)g_ptr_array_unref);
- }
- g_ptr_array_add (sheets, sheet);
-
- return FALSE;
- }
+ struct cb_set_pdf_option *user = user_;
+ Workbook const *wb = user->wb;
if (strcmp (key, "object") == 0) {
GPtrArray *objects = g_object_get_data (G_OBJECT (wb), "pdf-objects");
@@ -965,21 +943,21 @@ cb_set_pdf_option (const char *key, const char *value,
return FALSE;
}
- if (err)
- *err = g_error_new (go_error_invalid (), 0,
- _("Invalid option for pdf exporter"));
-
- return TRUE;
+ return gnm_file_saver_common_export_option (user->fs, wb,
+ key, value, err);
}
static gboolean
-pdf_set_export_options (G_GNUC_UNUSED GOFileSaver *fs,
+pdf_set_export_options (GOFileSaver *fs,
GODoc *doc,
const char *options,
GError **err,
G_GNUC_UNUSED gpointer user)
{
- return go_parse_key_value (options, err, cb_set_pdf_option, doc);
+ struct cb_set_pdf_option data;
+ data.fs = fs;
+ data.wb = WORKBOOK (doc);
+ return go_parse_key_value (options, err, cb_set_pdf_option, &data);
}
/**
diff --git a/src/ssconvert.c b/src/ssconvert.c
index 3d09cd8..41ec540 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -1,4 +1,3 @@
-/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* ssconvert.c: A wrapper application to convert spreadsheet formats
*
@@ -40,8 +39,11 @@
#include <sys/resource.h>
#endif
+// Sheets that an exporter should export.
#define SHEET_SELECTION_KEY "sheet-selection"
+// Sheets user has specified as export options
+#define SSCONVERT_SHEET_SET_KEY "ssconvert-sheets"
static gboolean ssconvert_show_version = FALSE;
static gboolean ssconvert_verbose = FALSE;
@@ -210,36 +212,109 @@ setup_range (GObject *obj, const char *key, Workbook *wb, const char *rtxt)
return rrc;
}
+struct cb_handle_export_options {
+ GOFileSaver *fs;
+ Workbook const *wb;
+};
+
+static gboolean
+cb_handle_export_options (const char *key, const char *value,
+ GError **err, gpointer user_)
+{
+ struct cb_handle_export_options *user = user_;
+ return gnm_file_saver_common_export_option (user->fs, user->wb,
+ key, value, err);
+}
+
static int
-handle_export_options (GOFileSaver *fs, GODoc *doc)
+handle_export_options (GOFileSaver *fs, Workbook *wb)
{
- guint sig = g_signal_lookup ("set-export-options",
- G_TYPE_FROM_INSTANCE (fs));
+ GError *err = NULL;
+ gboolean fail;
+ guint sig;
if (!ssconvert_export_options)
return 0;
+ sig = g_signal_lookup ("set-export-options", G_TYPE_FROM_INSTANCE (fs));
if (g_signal_handler_find (fs, G_SIGNAL_MATCH_ID,
- sig, 0, NULL, NULL, NULL)) {
- GError *err = NULL;
- gboolean fail =
- go_file_saver_set_export_options
- (fs, doc,
+ sig, 0, NULL, NULL, NULL))
+ fail = go_file_saver_set_export_options
+ (fs, GO_DOC (wb),
ssconvert_export_options,
&err);
+ else {
+ struct cb_handle_export_options data;
+ data.fs = fs;
+ data.wb = wb;
+ fail = go_parse_key_value (ssconvert_export_options, &err,
+ cb_handle_export_options, &data);
+ }
+
+ if (fail) {
+ g_printerr ("ssconvert: %s\n", err
+ ? err->message
+ : _("Cannot parse export options."));
+ return 1;
+ }
+
+ return 0;
+}
+
+// Check that the sheet selection, if any, matches the file saver's
+// capabilities.
+static int
+validate_sheet_selection (GOFileSaver *fs, Workbook *wb)
+{
+ GOFileSaveScope fsscope = go_file_saver_get_save_scope (fs);
+ gboolean fs_sheet_selection;
+
+ g_object_get (G_OBJECT (fs),
+ "sheet-selection", &fs_sheet_selection, NULL);
- if (fail) {
- g_printerr ("ssconvert: %s\n", err
- ? err->message
- : _("Cannot parse export options."));
+ 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));
return 1;
}
-
- return 0;
} else {
- g_printerr (_("The file saver does not take options\n"));
- return 1;
+ GPtrArray *sheets = g_object_get_data (G_OBJECT (wb),
+ SSCONVERT_SHEET_SET_KEY);
+ switch (fsscope) {
+ case GO_FILE_SAVE_WORKBOOK:
+ case GO_FILE_SAVE_RANGE:
+ default:
+ if (sheets && !fs_sheet_selection) {
+ g_printerr (_("Selected exporter (%s) does not have the ability to export a
subset of sheets.\n"),
+ go_file_saver_get_id (fs));
+ return 1;
+ }
+ break;
+ case GO_FILE_SAVE_SHEET:
+ if (sheets && sheets->len != 1) {
+ g_printerr (_("Selected exporter (%s) can only export one sheet at a
time.\n"),
+ go_file_saver_get_id (fs));
+ return 1;
+ }
+ break;
+ }
}
+
+ return 0;
}
@@ -490,7 +565,7 @@ merge (Workbook *wb, char const *inputs[],
}
static char *
-resolve_template (const char *template, Sheet *sheet)
+resolve_template (const char *template, Sheet *sheet, unsigned n)
{
GString *s = g_string_new (NULL);
while (1) {
@@ -507,7 +582,7 @@ resolve_template (const char *template, Sheet *sheet)
case 0:
goto done;
case 'n':
- g_string_append_printf (s, "%d", sheet->index_in_wb);
+ g_string_append_printf (s, "%u", n);
break;
case 's':
g_string_append (s, sheet->name_unquoted);
@@ -683,6 +758,76 @@ run_tool_test (const char *tool, char **argv, WorkbookView *wbv)
#undef RANGE_LISTARG
#undef SHEET_ARG
+
+static int
+do_split_save (GOFileSaver *fs, WorkbookView *wbv,
+ const char *outarg, GOCmdContext *cc)
+{
+ Workbook *wb = wb_view_get_workbook (wbv);
+ char *template;
+ GPtrArray *sheets;
+ unsigned ui;
+ int res = 0;
+ GPtrArray *sheet_sel =
+ g_object_get_data (G_OBJECT (wb), SHEET_SELECTION_KEY);
+ gboolean fs_sheet_selection;
+
+ g_object_get (G_OBJECT (fs), "sheet-selection", &fs_sheet_selection, NULL);
+
+ template = strchr (outarg, '%')
+ ? g_strdup (outarg)
+ : g_strconcat (outarg, ".%n", NULL);
+
+ sheets = g_object_get_data (G_OBJECT (wb),
+ SSCONVERT_SHEET_SET_KEY);
+ if (sheets)
+ g_ptr_array_ref (sheets);
+ else {
+ int i;
+ sheets = g_ptr_array_new ();
+ for (i = 0; i < workbook_sheet_count (wb); i++) {
+ Sheet *sheet = workbook_sheet_by_index (wb, i);
+ g_ptr_array_add (sheets, sheet);
+ }
+ }
+
+ for (ui = 0; ui < sheets->len; ui++) {
+ Sheet *sheet = g_ptr_array_index (sheets, ui);
+ char *tmpfile = resolve_template (template, sheet, ui);
+ 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 reliably find it.
+ */
+ workbook_sheet_move (sheet, -oldn);
+ wb_view_sheet_focus (wbv, sheet);
+ }
+
+ 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_ptr_array_unref (sheets);
+
+ return res;
+}
+
static int
convert (char const *inarg, char const *outarg, char const *mergeargs[],
GOCmdContext *cc)
@@ -696,7 +841,6 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
GOIOContext *io_context = NULL;
Workbook *wb = NULL;
GOFileSaveScope fsscope;
- gboolean fs_sheet_selection;
GPtrArray *sheet_sel = NULL;
GnmRangeRef const *range = NULL;
@@ -756,35 +900,12 @@ 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) {
wbv = workbook_view_new_from_uri (infile, fo,
- io_context,
- ssconvert_import_encoding);
+ io_context,
+ ssconvert_import_encoding);
} else {
wbv = workbook_view_new (NULL);
}
@@ -801,7 +922,11 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
wb = wb_view_get_workbook (wbv);
- res = handle_export_options (fs, GO_DOC (wb));
+ res = handle_export_options (fs, wb);
+ if (res)
+ goto out;
+
+ res = validate_sheet_selection (fs, wb);
if (res)
goto out;
@@ -886,49 +1011,7 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
}
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 reliably find it.
- */
- workbook_sheet_move (sheet, -oldn);
- wb_view_sheet_focus (wbv, sheet);
- }
-
- 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);
+ res = do_split_save (fs, wbv, outarg, cc);
} else {
res = !workbook_view_save_as (wbv, fs, outfile, cc);
}
diff --git a/src/stf-export.c b/src/stf-export.c
index a1166f4..0dceb93 100644
--- a/src/stf-export.c
+++ b/src/stf-export.c
@@ -685,6 +685,7 @@ gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs,
for (ui = 0; ui < sel->len; ui++)
gnm_stf_export_options_sheet_list_add
(stfe, g_ptr_array_index (sel, ui));
+ g_ptr_array_unref (sel);
}
g_object_set (G_OBJECT (stfe), "sink", output, NULL);
@@ -701,26 +702,20 @@ gnm_stf_file_saver_save (G_GNUC_UNUSED GOFileSaver const *fs,
gnm_stf_export_options_sheet_list_clear (stfe);
}
+struct cb_set_export_option {
+ GOFileSaver *fs;
+ Workbook const *wb;
+};
+
static gboolean
cb_set_export_option (const char *key, const char *value,
- GError **err, gpointer user)
+ GError **err, gpointer user_)
{
- Workbook *wb = user;
+ struct cb_set_export_option *user = user_;
+ Workbook const *wb = user->wb;
GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (wb));
const char *errtxt;
- if (strcmp (key, "sheet") == 0) {
- Sheet *sheet = workbook_sheet_by_name (wb, value);
- if (!sheet) {
- errtxt = _("There is no such sheet");
- goto error;
- }
-
- gnm_stf_export_options_sheet_list_add (stfe, sheet);
-
- return FALSE;
- }
-
if (strcmp (key, "eol") == 0) {
const char *eol;
if (g_ascii_strcasecmp ("unix", value) == 0)
@@ -752,7 +747,9 @@ cb_set_export_option (const char *key, const char *value,
err,
(_("Invalid value for option %s: \"%s\"")));
- errtxt = _("Invalid option for stf exporter");
+ return gnm_file_saver_common_export_option (user->fs, wb,
+ key, value, err);
+
error:
if (err)
*err = g_error_new (go_error_invalid (), 0, "%s", errtxt);
@@ -761,15 +758,18 @@ error:
}
static gboolean
-gnm_stf_fs_set_export_options (G_GNUC_UNUSED GOFileSaver *fs,
+gnm_stf_fs_set_export_options (GOFileSaver *fs,
GODoc *doc,
const char *options,
GError **err,
G_GNUC_UNUSED gpointer user)
{
GnmStfExport *stfe = gnm_stf_get_stfe (G_OBJECT (doc));
+ struct cb_set_export_option data;
+ data.fs = fs;
+ data.wb = WORKBOOK (doc);
gnm_stf_export_options_sheet_list_clear (stfe);
- return go_parse_key_value (options, err, cb_set_export_option, doc);
+ return go_parse_key_value (options, err, cb_set_export_option, &data);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]