[gnumeric] ssconvert: allow export of graphs as images.



commit 4813920f6040b7e33ebc67f85622bac0bf832490
Author: Morten Welinder <terra gnome org>
Date:   Sun Nov 3 13:32:39 2019 -0500

    ssconvert: allow export of graphs as images.
    
    The format defaults to svg and can be set with "-T xyz".  That's a really
    ugly override and subject to change, if I find a better way.

 ChangeLog          |  9 ++++++
 NEWS               |  3 ++
 src/sheet-object.c | 46 ++++++++++++++++++++++++++++
 src/sheet-object.h |  5 +++
 src/ssconvert.c    | 89 +++++++++++++++++++++++++++++++++++++++++++++---------
 5 files changed, 138 insertions(+), 14 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c72f50044..ab357eca8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2019-11-03  Morten Welinder  <terra gnome org>
+
+       * src/ssconvert.c (do_split_save): Extend to create images from
+       each graph.  Code adapted from Shlomi Fish code in #410.
+
+       * src/sheet-object.c (sheet_object_write_image): Document.  Add
+       preconditions.
+       (sheet_object_save_as_image): New function.
+
 2019-11-02  Morten Welinder  <terra gnome org>
 
        * src/gutils.c (gnm_file_saver_common_export_option): Reorganize a
diff --git a/NEWS b/NEWS
index abb9ce11d..d637d0b52 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ Morten:
 Thomas Kuehne:
        * Improve html import.  [#392]
 
+Shlomi Fish:
+       * Command line export of graphs.  [#410]
+
 --------------------------------------------------------------------------
 Gnumeric 1.12.45
 
diff --git a/src/sheet-object.c b/src/sheet-object.c
index e28ba7cb3..2f1aed8ce 100644
--- a/src/sheet-object.c
+++ b/src/sheet-object.c
@@ -1715,17 +1715,63 @@ sheet_object_get_target_list (SheetObject const *so)
        return GNM_SO_IMAGEABLE_CLASS (so)->get_target_list (so);
 }
 
+/**
+ * sheet_object_write_image:
+ * @so: #SheetObject
+ * @format: image format to use
+ * @resolution: export resolution
+ * @output: destination
+ * @err: (out) (optional) (nullable): error indication
+ *
+ * Saves a sheet object as an image to @output.  If an error occurs, @err will
+ * be set.
+ **/
 void
 sheet_object_write_image (SheetObject const *so, char const *format, double resolution,
                          GsfOutput *output, GError **err)
 {
        g_return_if_fail (GNM_IS_SO_IMAGEABLE (so));
+       g_return_if_fail (format != NULL);
+       g_return_if_fail (GSF_IS_OUTPUT (output));
 
        GNM_SO_IMAGEABLE_CLASS (so)->write_image (so, format, resolution,
                                                        output, err);
 
 }
 
+/**
+ * sheet_object_save_as_image:
+ * @so: #SheetObject
+ * @format: image format to use
+ * @resolution: export resolution
+ * @url: destination url
+ * @err: (out) (optional) (nullable): error indication
+ *
+ * Saves a sheet object as an image to @url.  If an error occurs, @err
+ * will be set.
+ **/
+void
+sheet_object_save_as_image (SheetObject const *so,
+                           char const *format,
+                           double resolution,
+                           const char *url,
+                           GError **err)
+{
+       GsfOutput *dst;
+
+       g_return_if_fail (GNM_IS_SO_IMAGEABLE (so));
+       g_return_if_fail (format != NULL);
+       g_return_if_fail (url != NULL);
+
+       dst = go_file_create (url, err);
+       if (!dst)
+               return;
+
+       sheet_object_write_image (so, format, resolution, dst, err);
+       gsf_output_close (dst);
+       g_object_unref (dst);
+}
+
 /*****************************************************************************/
 
 GType
diff --git a/src/sheet-object.h b/src/sheet-object.h
index 5d9d91a1d..b71277648 100644
--- a/src/sheet-object.h
+++ b/src/sheet-object.h
@@ -130,6 +130,11 @@ void sheet_object_write_image      (SheetObject const *so,
                                 double resolution,
                                 GsfOutput *output,
                                 GError **err);
+void sheet_object_save_as_image        (SheetObject const *so,
+                                char const *format,
+                                double resolution,
+                                const char *url,
+                                GError **err);
 
 /* Object export */
 GtkTargetList *sheet_object_exportable_get_target_list (SheetObject const *so);
diff --git a/src/ssconvert.c b/src/ssconvert.c
index 4f0af7e9f..612840f74 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -19,6 +19,7 @@
 #include <workbook-priv.h>
 #include <workbook-control.h>
 #include <sheet.h>
+#include <sheet-object-graph.h>
 #include <dependent.h>
 #include <expr-name.h>
 #include <libgnumeric.h>
@@ -53,6 +54,8 @@ static gboolean ssconvert_verbose = FALSE;
 static gboolean ssconvert_list_exporters = FALSE;
 static gboolean ssconvert_list_importers = FALSE;
 static gboolean ssconvert_one_file_per_sheet = FALSE;
+static gboolean ssconvert_object_export = FALSE;
+static GType ssconvert_object_export_type;
 static gboolean ssconvert_recalc = FALSE;
 static gboolean ssconvert_solve = FALSE;
 static char *ssconvert_resize = NULL;
@@ -65,6 +68,7 @@ static char *ssconvert_export_options = NULL;
 static char *ssconvert_merge_target = NULL;
 static char **ssconvert_goal_seek = NULL;
 static char **ssconvert_tool_test = NULL;
+static const char *ssconvert_image_format = "svg";
 
 static const GOptionEntry ssconvert_options [] = {
        {
@@ -141,6 +145,13 @@ static const GOptionEntry ssconvert_options [] = {
                NULL
        },
 
+       {
+               "export-graphs", 0,
+               0, G_OPTION_ARG_NONE, &ssconvert_object_export,
+               N_("Export graphs"),
+               NULL
+       },
+
        {
                "recalc", 0,
                0, G_OPTION_ARG_NONE, &ssconvert_recalc,
@@ -783,8 +794,12 @@ do_split_save (GOFileSaver *fs, WorkbookView *wbv,
        GPtrArray *sheet_sel =
                g_object_get_data (G_OBJECT (wb), SHEET_SELECTION_KEY);
        gboolean fs_sheet_selection;
+       guint file_idx = 0;
 
-       g_object_get (G_OBJECT (fs), "sheet-selection", &fs_sheet_selection, NULL);
+       if (fs)
+               g_object_get (G_OBJECT (fs), "sheet-selection", &fs_sheet_selection, NULL);
+       else
+               fs_sheet_selection = FALSE;
 
        template = strchr (outarg, '%')
                ? g_strdup (outarg)
@@ -805,7 +820,6 @@ do_split_save (GOFileSaver *fs, WorkbookView *wbv,
 
        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);
@@ -824,12 +838,41 @@ do_split_save (GOFileSaver *fs, WorkbookView *wbv,
                        wb_view_sheet_focus (wbv, sheet);
                }
 
-               res = !workbook_view_save_as (wbv, fs, tmpfile, cc);
+               if (ssconvert_object_export) {
+                       GSList *l, *objs = sheet_objects_get (sheet, NULL, GNM_SO_GRAPH_TYPE);
+                       double resolution = 100.0;
+                       for (l = objs; l; l = l->next) {
+                               SheetObject *so = l->data;
+                               char *tmpfile;
+                               GError *err = NULL;
+
+                               if (!g_type_is_a (G_TYPE_FROM_INSTANCE (so),
+                                                 ssconvert_object_export_type))
+                                       continue;
+
+                               tmpfile = resolve_template (template, sheet, file_idx++);
+                               sheet_object_save_as_image (so, ssconvert_image_format, resolution,
+                                                           tmpfile, &err);
+
+                               if (err) {
+                                       g_printerr ("Failed to write %s: %s\n", tmpfile, err->message);
+                                       g_error_free (err);
+                                       res = 1;
+                                       g_free (tmpfile);
+                               }
+
+                               g_free (tmpfile);
+                       }
+                       g_slist_free (objs);
+               } else {
+                       char *tmpfile = resolve_template (template, sheet, file_idx++);
+                       res = !workbook_view_save_as (wbv, fs, tmpfile, cc);
+                       g_free (tmpfile);
+               }
 
                if (!fs_sheet_selection)
                        workbook_sheet_move (sheet, +oldn);
 
-               g_free (tmpfile);
                if (res)
                        break;
        }
@@ -856,7 +899,10 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
        GPtrArray *sheet_sel = NULL;
        GnmRangeRef const *range = NULL;
 
-       if (ssconvert_export_id != NULL) {
+       if (ssconvert_object_export) {
+               if (ssconvert_export_id)
+                       ssconvert_image_format = ssconvert_export_id;
+       } else if (ssconvert_export_id != NULL) {
                fs = go_file_saver_for_id (ssconvert_export_id);
                if (fs == NULL) {
                        res = 1;
@@ -909,9 +955,13 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
                }
        }
 
-       if (!fs)
-               goto out;
-       fsscope = go_file_saver_get_save_scope (fs);
+       if (ssconvert_object_export) {
+               fsscope = GO_FILE_SAVE_SHEET;
+       } else {
+               if (!fs)
+                       goto out;
+               fsscope = go_file_saver_get_save_scope (fs);
+       }
 
        io_context = go_io_context_new (cc);
        if (mergeargs == NULL) {
@@ -934,13 +984,15 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
 
        wb = wb_view_get_workbook (wbv);
 
-       res = handle_export_options (fs, wb);
-       if (res)
-               goto out;
+       if (fs) {
+               res = handle_export_options (fs, wb);
+               if (res)
+                       goto out;
 
-       res = validate_sheet_selection (fs, wb);
-       if (res)
-               goto out;
+               res = validate_sheet_selection (fs, wb);
+               if (res)
+                       goto out;
+       }
 
        if (mergeargs != NULL) {
                if (merge (wb, mergeargs, fo, io_context, cc))
@@ -1167,6 +1219,15 @@ main (int argc, char const **argv)
                return 1;
        }
 
+       if (ssconvert_object_export) {
+               // One file per object
+               ssconvert_one_file_per_sheet = TRUE;
+
+               // For now graphs only, but we can handle anything with
+               // GNM_SO_IMAGEABLE_TYPE
+               ssconvert_object_export_type = GNM_SO_GRAPH_TYPE;
+       }
+
        gnm_init ();
 
        cc = gnm_cmd_context_stderr_new ();


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