[gnumeric] Improve chart roundtrip through ODF. [#728197]



commit 2dffc30115c44d38697147ff62e09314b1028b9f
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Fri Apr 18 12:50:55 2014 -0600

    Improve chart roundtrip through ODF. [#728197]
    
    2014-04-18  Andreas J. Guelzow <aguelzow pyrshep ca>
    
        * openoffice-read.c (oo_parse_spec_distance): new
        (oo_parse_distance): use oo_parse_spec_distance
        (od_style_prop_chart): read fo:border
        (oo_chart): use fo:border
        * openoffice-write.c (odf_write_gog_style_graphic): add argument
        and change all callers
        (odf_get_border_info): new (partial implementation)
        (odf_write_plot): write graphic properties for the chart style

 plugins/openoffice/ChangeLog          |   11 ++++
 plugins/openoffice/openoffice-read.c  |   96 ++++++++++++++++++++++++++-------
 plugins/openoffice/openoffice-write.c |   38 +++++++++++--
 3 files changed, 120 insertions(+), 25 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 0ec43c0..af9b563 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,16 @@
 2014-04-18  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+       * openoffice-read.c (oo_parse_spec_distance): new
+       (oo_parse_distance): use oo_parse_spec_distance
+       (od_style_prop_chart): read fo:border
+       (oo_chart): use fo:border
+       * openoffice-write.c (odf_write_gog_style_graphic): add argument
+       and change all callers
+       (odf_get_border_info): new (partial implementation)
+       (odf_write_plot): write graphic properties for the chart style
+
+2014-04-18  Andreas J. Guelzow <aguelzow pyrshep ca>
+
        * openoffice-read.c (od_style_prop_chart): read auto-type
        * openoffice-write.c (odf_write_gog_style_graphic): write auto-type
 
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index e1388a1..5609e6e 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -1080,23 +1080,14 @@ odf_apply_style_props (GsfXMLIn *xin, GSList *props, GOStyle *style)
        }
 }
 
-
 /* returns pts */
 static char const *
-oo_parse_distance (GsfXMLIn *xin, xmlChar const *str,
-                 char const *name, gnm_float *pts)
+oo_parse_spec_distance (char const *str, gnm_float *pts)
 {
        double num;
        char *end = NULL;
 
-       g_return_val_if_fail (str != NULL, NULL);
-
-       if (0 == strncmp (CXML2C (str), "none", 4)) {
-               *pts = 0;
-               return CXML2C (str) + 4;
-       }
-
-       num = go_strtod (CXML2C (str), &end);
+       num = go_strtod (str, &end);
        if (CXML2C (str) != end) {
                if (0 == strncmp (end, "mm", 2)) {
                        num = GO_CM_TO_PT (num/10.);
@@ -1127,18 +1118,41 @@ oo_parse_distance (GsfXMLIn *xin, xmlChar const *str,
                } else if (0 == strncmp (end, "in", 2)) {
                        num = GO_IN_TO_PT (num);
                        end += 2;
-               } else {
-                       oo_warning (xin, _("Invalid attribute '%s', unknown unit '%s'"),
-                                   name, str);
-                       return NULL;
-               }
-       } else {
+               } else 
+                       return GINT_TO_POINTER(1);
+       } else return NULL;
+
+       *pts = num;
+       return end;
+       
+}
+
+/* returns pts */
+static char const *
+oo_parse_distance (GsfXMLIn *xin, xmlChar const *str,
+                 char const *name, gnm_float *pts)
+{
+       char const *end = NULL;
+
+       g_return_val_if_fail (str != NULL, NULL);
+
+       if (0 == strncmp (CXML2C (str), "none", 4)) {
+               *pts = 0;
+               return CXML2C (str) + 4;
+       }
+
+       end = oo_parse_spec_distance (CXML2C (str), pts);
+
+       if (end == GINT_TO_POINTER(1)) {
+               oo_warning (xin, _("Invalid attribute '%s', unknown unit '%s'"),
+                           name, str);
+               return NULL;
+       }
+       if (end == NULL) {
                oo_warning (xin, _("Invalid attribute '%s', expected distance, received '%s'"),
                            name, str);
                return NULL;
        }
-
-       *pts = num;
        return end;
 }
 
@@ -7103,6 +7117,13 @@ od_style_prop_chart (GsfXMLIn *xin, xmlChar const **attrs)
                                (style->other_props,
                                 oo_prop_new_string
                                 ("marker-end", CXML2C(attrs[1])));
+               else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]),
+                                            OO_NS_FO,
+                                            "border"))
+                       style->other_props = g_slist_prepend
+                               (style->other_props,
+                                oo_prop_new_string
+                                ("border", CXML2C(attrs[1])));
        }
 
        if ((stacked_set && !overlap_set) ||
@@ -9161,8 +9182,43 @@ oo_chart (GsfXMLIn *xin, xmlChar const **attrs)
        state->chart.axis = NULL;
        state->chart.legend = NULL;
        state->chart.cat_expr = NULL;
-       if (NULL != style)
+       if (NULL != style) {
+               GSList *ptr;
                state->chart.src_in_rows = style->src_in_rows;
+               for (ptr = style->other_props; ptr; ptr = ptr->next) {
+                       OOProp *prop = ptr->data;
+                       if (0 == strcmp (prop->name, "border")) {
+                               gnm_float pts = 0.;
+                               const char *border = g_value_get_string (&prop->value);
+                               const char *end;
+
+                               while (*border == ' ')
+                                       border++;
+                               end = oo_parse_spec_distance (border, &pts);
+
+                               if (end == GINT_TO_POINTER(1) || end == NULL) {
+                                       if (0 == strncmp (border, "thin", 4)) {
+                                               pts = 0.;
+                                               end = border + 4;
+                                       } else if (0 == strncmp (border, "medium", 6)) {
+                                               pts = 1.5;
+                                               end = border + 6;
+                                       } else if (0 == strncmp (border, "thick", 5)) {
+                                               pts = 3.;
+                                               end = border + 5;
+                                       }
+                               }
+
+                               if (end != GINT_TO_POINTER(1) && end != NULL && end > border) {
+                                       /* pts should be valid */
+                                       GOStyle *go_style = go_styled_object_get_style (GO_STYLED_OBJECT 
(state->chart.chart));
+                                       go_style->line.width = pts;
+                                       go_style->line.dash_type = GO_LINE_SOLID;
+                                       go_styled_object_style_changed (GO_STYLED_OBJECT 
(state->chart.chart));
+                               }  
+                       }
+               }
+       }
 
        if (type == OO_PLOT_UNKNOWN)
                oo_warning (xin , _("Encountered an unknown chart type, "
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index a548aaf..fd350fe 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -208,7 +208,7 @@ static void odf_write_hatch_info (GOPattern *pattern, char const *name, GnmOOExp
 static void odf_write_dash_info (char const *name, gpointer data, GnmOOExport *state);
 static void odf_write_arrow_marker_info (GOArrow const *arrow, char const *name, GnmOOExport *state);
 
-static void odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style);
+static void odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style, gboolean write_border);
 static void odf_write_gog_style_text (GnmOOExport *state, GOStyle const *style);
 
 
@@ -838,7 +838,7 @@ odf_write_sheet_object_style (GnmOOExport *state, SheetObject *so)
 
        odf_start_style (state->xml, name, "graphic");
        gsf_xml_out_start_element (state->xml, STYLE "graphic-properties");
-       odf_write_gog_style_graphic (state, style);
+       odf_write_gog_style_graphic (state, style, FALSE);
        gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
        gsf_xml_out_start_element (state->xml, STYLE "text-properties");
        odf_write_gog_style_text (state, style);
@@ -879,7 +879,7 @@ odf_write_sheet_object_line_style (GnmOOExport *state, SheetObject *so)
                gsf_xml_out_add_cstr (state->xml, DRAW "marker-start", start_arrow_name);
        if (end_arrow_name != NULL)
                gsf_xml_out_add_cstr (state->xml, DRAW "marker-end", end_arrow_name);
-       odf_write_gog_style_graphic (state, style);
+       odf_write_gog_style_graphic (state, style, FALSE);
        gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
        gsf_xml_out_end_element (state->xml); /* </style:style> */
 
@@ -7028,11 +7028,24 @@ odf_get_pattern_name (GnmOOExport *state, GOStyle const* style)
        return new_name;
 }
 
+static char *
+odf_get_border_info (G_GNUC_UNUSED GnmOOExport *state, GOStyle const *style)
+{
+       if (style->line.width <= 0)
+               return g_strdup ("thin");
+       if (style->line.width == 1.5)
+               return g_strdup ("medium");
+       if (style->line.width == 3)
+               return g_strdup ("thick");
+       return g_strdup_printf ("%.6fpt", style->line.width);
+}
+
 static void
-odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style)
+odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style, gboolean with_border)
 {
        char const *image_types[] =
                {"stretch", "repeat", "no-repeat"};
+       
        if (style != NULL) {
                char *color = NULL;
 
@@ -7133,6 +7146,13 @@ odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style)
                } else {
                        gsf_xml_out_add_cstr (state->xml, DRAW "stroke", "none");
                }
+
+               if (with_border && go_style_is_outline_visible (style)) {
+                       char *border = odf_get_border_info (state, style);
+                       if (strlen (border) > 0)
+                               gsf_xml_out_add_cstr (state->xml, FOSTYLE "border", border);
+                       g_free (border);
+               }
        }
 }
 
@@ -7290,7 +7310,7 @@ odf_write_gog_style (GnmOOExport *state, GOStyle const *style,
                gsf_xml_out_end_element (state->xml); /* </style:chart-properties> */
 
                gsf_xml_out_start_element (state->xml, STYLE "graphic-properties");
-               odf_write_gog_style_graphic (state, style);
+               odf_write_gog_style_graphic (state, style, FALSE);
                gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
 
                gsf_xml_out_start_element (state->xml, STYLE "paragraph-properties");
@@ -7440,6 +7460,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *graph,
        gchar *x_style = NULL;
        gchar *y_style = NULL;
        gchar *z_style = NULL;
+       GOStyle *style = NULL;
 
        static struct {
                char const * type;
@@ -7609,6 +7630,13 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *graph,
        gsf_xml_out_start_element (state->xml, STYLE "chart-properties");
        odf_add_bool (state->xml, CHART "auto-size", TRUE);
        gsf_xml_out_end_element (state->xml); /* </style:chart-properties> */
+       g_object_get (G_OBJECT (chart), "style", &style, NULL);
+       if (style) {
+               gsf_xml_out_start_element (state->xml, STYLE "graphic-properties");
+               odf_write_gog_style_graphic (state, style, TRUE);
+               gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
+               g_object_unref (style);
+       }
        gsf_xml_out_end_element (state->xml); /* </style:style> */
 
        odf_write_gog_styles (chart, state);


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