[gnumeric] handle chart axis label rotation in ODF import/export



commit 86f17f38a857696a06c40adf486daa81eca5c7a8
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Fri Aug 20 11:21:56 2010 -0600

    handle chart axis label rotation in ODF import/export
    
    2010-08-20  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c: mark all oo_warning texts for translation
    	(oo_attr_non_neg_int): don't ignore excess values but clamp to max.
    	(odf_apply_style_props): moved and handle text-rotation-angle
    	(od_style_prop_chart): handle text-rotation-angle
    	(oo_chart_title): handle style and ODF 1.0 bug
    	(oo_chart_title_end): handle style
    	(opendoc_content_dtd): add text:tab
    	* openoffice-write.c (odf_get_gog_style_name): new
    	(odf_get_gog_style_name_from_obj): new
    	(odf_write_title): write style-name
    	(odf_write_gog_style_graphic): new
    	(odf_write_gog_style_text): new
    	(odf_write_gog_style): new
    	(odf_write_gog_styles): new
    	(odf_write_plot): write gog_styles and use gog_styles for wall
    
    2010-08-18  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* samples/chart-tests.gnumeric: add tab colours to indicate ODF support
    	  for those pages (in round trip)

 ChangeLog                             |    5 +
 plugins/openoffice/ChangeLog          |   18 ++++
 plugins/openoffice/openoffice-read.c  |  124 +++++++++++++++++++----------
 plugins/openoffice/openoffice-write.c |  140 +++++++++++++++++++++++++++------
 samples/chart-tests.gnumeric          |  Bin 807197 -> 807386 bytes
 5 files changed, 219 insertions(+), 68 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index be688c4..ded9076 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2010-08-18  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* samples/chart-tests.gnumeric: add tab colours to indicate ODF support
+	  for those pages (in round trip)
+
+2010-08-18  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* samples/chart-tests.gnumeric: test plot types separately from our
 	  ability to combine them.
 
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index d48c7b9..b286ffc 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,21 @@
+2010-08-20  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c: mark all oo_warning texts for translation
+	(oo_attr_non_neg_int): don't ignore excess values but clamp to max.
+	(odf_apply_style_props): moved and handle text-rotation-angle
+	(od_style_prop_chart): handle text-rotation-angle
+	(oo_chart_title): handle style and ODF 1.0 bug 
+	(oo_chart_title_end): handle style
+	(opendoc_content_dtd): add text:tab
+	* openoffice-write.c (odf_get_gog_style_name): new
+	(odf_get_gog_style_name_from_obj): new
+	(odf_write_title): write style-name
+	(odf_write_gog_style_graphic): new
+	(odf_write_gog_style_text): new
+	(odf_write_gog_style): new
+	(odf_write_gog_styles): new
+	(odf_write_plot): write gog_styles and use gog_styles for wall
+
 2010-08-19  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (odf_go_string_append_c_n): new
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index e1b5fc4..107563a 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -193,6 +193,7 @@ typedef struct {
 	xmlChar         *cat_expr;
 
 	GnmExprTop const        *title_expr;
+	gchar                   *title_style;
 
 	OOChartStyle		*cur_graph_style;
 	GHashTable		*graph_styles;	/* contain links to OOChartStyle GSLists */
@@ -293,7 +294,7 @@ static void
 odf_go_string_append_c_n (GString *target, char c, int n)
 {
 	if (n > 0)
-		odf_go_string_append_c_n (target, c, (gsize) n);
+		go_string_append_c_n (target, c, (gsize) n);
 }
 
 static void
@@ -378,7 +379,7 @@ oo_attr_int (GsfXMLIn *xin, xmlChar const * const *attrs,
 	errno = 0; /* strtol sets errno, but does not clear it.  */
 	tmp = strtol (CXML2C (attrs[1]), &end, 10);
 	if (*end || errno != 0 || tmp < INT_MIN || tmp > INT_MAX)
-		return oo_warning (xin, "Invalid integer '%s', for '%s'",
+		return oo_warning (xin, _("Invalid integer '%s', for '%s'"),
 				   attrs[1], name);
 
 	*res = tmp;
@@ -393,7 +394,7 @@ oo_attr_pos_int (GsfXMLIn *xin, xmlChar const * const *attrs,
 	if (!oo_attr_int (xin, attrs, ns_id, name, &tmp))
 		return FALSE;
 	if (tmp < 1)
-		return oo_warning (xin, "Invalid integer '%s', for '%s'",
+		return oo_warning (xin, _("Invalid integer '%s', for '%s'"),
 				   attrs[1], name);
 	*res = tmp;
 	return TRUE;
@@ -409,9 +410,12 @@ oo_attr_non_neg_int (GsfXMLIn *xin, xmlChar const * const *attrs,
 		return FALSE;
 	if (max == -1) 
 		max = INT_MAX;
-	if (tmp < 0 || tmp > max)
-		return oo_warning (xin, "Invalid integer '%s', for '%s'",
+	if (tmp < 0 || tmp > max) {
+		oo_warning (xin, _("Possible corrupted integer '%s', for '%s'"),
 				   attrs[1], name);
+		*res = max;
+		return TRUE;
+	}
 	*res = tmp;
 	return TRUE;
 }
@@ -433,7 +437,7 @@ oo_attr_float (GsfXMLIn *xin, xmlChar const * const *attrs,
 
 	tmp = gnm_strto (CXML2C (attrs[1]), &end);
 	if (*end)
-		return oo_warning (xin, "Invalid attribute '%s', expected number, received '%s'",
+		return oo_warning (xin, _("Invalid attribute '%s', expected number, received '%s'"),
 				   name, attrs[1]);
 	*res = tmp;
 	return TRUE;
@@ -456,8 +460,8 @@ oo_attr_percent (GsfXMLIn *xin, xmlChar const * const *attrs,
 	tmp = gnm_strto (CXML2C (attrs[1]), &end);
 	if (*end != '%' || *(end + 1))
 		return oo_warning (xin, 
-				   "Invalid attribute '%s', expected percentage,"
-				   " received '%s'",
+				   _("Invalid attribute '%s', expected percentage,"
+				     " received '%s'"),
 				   name, attrs[1]);
 	*res = tmp/100.;
 	return TRUE;
@@ -477,7 +481,7 @@ oo_parse_color (GsfXMLIn *xin, xmlChar const *str, char const *name)
 	if (0 == strcmp (CXML2C (str), "transparent"))
 		return style_color_ref (magic_transparent);
 
-	oo_warning (xin, "Invalid attribute '%s', expected color, received '%s'",
+	oo_warning (xin, _("Invalid attribute '%s', expected color, received '%s'"),
 		    name, str);
 	return NULL;
 }
@@ -492,6 +496,36 @@ oo_attr_color (GsfXMLIn *xin, xmlChar const * const *attrs,
 		return NULL;
 	return oo_parse_color (xin, attrs[1], name);
 }
+
+static void
+odf_apply_style_props (GSList *props, GOStyle *style)
+{
+	GSList *l;
+	for (l = props; l != NULL; l = l->next) {
+		OOProp *prop = l->data;
+		if (0 == strcmp (prop->name, "fill")) {
+			if (0 == strcmp (g_value_get_string (&prop->value), "solid")) {
+				style->fill.type = GO_STYLE_FILL_PATTERN;
+				style->fill.pattern.pattern = GO_PATTERN_SOLID;
+			} else {
+				style->fill.type = GO_STYLE_FILL_NONE;
+			}
+		} else if (0 == strcmp (prop->name, "fill-color")) {
+			GdkColor gdk_color;
+			gchar const *color = g_value_get_string (&prop->value);
+			if (gdk_color_parse (color, &gdk_color))
+				style->fill.pattern.back = GO_COLOR_FROM_GDK (gdk_color);
+		} else if (0 == strcmp (prop->name, "text-rotation-angle")) {
+			int angle = g_value_get_int (&prop->value);
+			go_style_set_text_angle (style, angle);
+		}
+	}
+}
+
+
+
+
+
 /* returns pts */
 static char const *
 oo_parse_distance (GsfXMLIn *xin, xmlChar const *str,
@@ -539,12 +573,12 @@ oo_parse_distance (GsfXMLIn *xin, xmlChar const *str,
 			num = GO_IN_TO_PT (num);
 			end += 2;
 		} else {
-			oo_warning (xin, "Invalid attribute '%s', unknown unit '%s'",
+			oo_warning (xin, _("Invalid attribute '%s', unknown unit '%s'"),
 				    name, str);
 			return NULL;
 		}
 	} else {
-		oo_warning (xin, "Invalid attribute '%s', expected distance, received '%s'",
+		oo_warning (xin, _("Invalid attribute '%s', expected distance, received '%s'"),
 			    name, str);
 		return NULL;
 	}
@@ -588,7 +622,7 @@ oo_attr_enum (GsfXMLIn *xin, xmlChar const * const *attrs,
 			*res = enums->val;
 			return TRUE;
 		}
-	return oo_warning (xin, "Invalid attribute '%s', unknown enum value '%s'",
+	return oo_warning (xin, _("Invalid attribute '%s', unknown enum value '%s'"),
 			   name, attrs[1]);
 }
 
@@ -3427,6 +3461,10 @@ od_style_prop_chart (GsfXMLIn *xin, xmlChar const **attrs)
 				(style->style_props,
 				 oo_prop_new_string ("fill-color",
 						     CXML2C(attrs[1])));
+		else if (oo_attr_int (xin, attrs, OO_NS_STYLE, "text-rotation-angle", &tmp))
+			style->style_props = g_slist_prepend
+				(style->style_props,
+				 oo_prop_new_int ("text-rotation-angle", tmp));
 	}
 
 	if (draw_stroke_set && !default_style_has_lines_set)
@@ -3875,10 +3913,13 @@ oo_chart_title (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
 	state->chart.title_expr = NULL;
+	state->chart.title_style = NULL;
 
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2){
-		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
-					OO_NS_TABLE, "cell-address")
+		if ((gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
+					 OO_NS_TABLE, "cell-address" ) || 
+		     gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
+					 OO_NS_TABLE, "cell-range" ))
 		    && state->chart.title_expr == NULL) {
 			GnmParsePos   pp;
 			char *end_str = g_strconcat ("[", CXML2C (attrs[1]), "]", NULL);
@@ -3902,6 +3943,9 @@ oo_chart_title (GsfXMLIn *xin, xmlChar const **attrs)
 				(xin, CXML2C (attrs[1]), &pp,
 				 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES,
 				 FORMULA_OPENFORMULA);
+		} else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
+					       OO_NS_CHART, "style-name")) {
+			state->chart.title_style = g_strdup (CXML2C (attrs[1]));
 		}
 	}
 }
@@ -3928,6 +3972,21 @@ oo_chart_title_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 		label = gog_object_add_by_name (obj, tag, NULL);
 		gog_dataset_set_dim (GOG_DATASET (label), 0, data, NULL);
 		state->chart.title_expr = NULL;
+		if (state->chart.title_style != NULL) {
+			OOChartStyle *oostyle = g_hash_table_lookup 
+				(state->chart.graph_styles, state->chart.title_style);
+			if (oostyle != NULL) {
+				GOStyle *style;
+				g_object_get (G_OBJECT (label), "style", &style, NULL);
+		
+				if (style != NULL) {
+					odf_apply_style_props (oostyle->style_props, style);
+					g_object_unref (style);
+				}
+			}
+			g_free (state->chart.title_style);
+			state->chart.title_style = NULL;
+		}
 	}
 		
 }
@@ -4077,7 +4136,7 @@ oo_plot_assign_dim (GsfXMLIn *xin, xmlChar const *range, int dim_type, char cons
 		return;	/* implicit does not overwrite existing */
 	else if (state->chart.src_n_vectors <= 0) {
 		oo_warning (xin,
-			"Not enough data in the supplied range for all the requests");
+			    _("Not enough data in the supplied range (%s) for all the requests"), CXML2C (range));
 		return;
 	} else {
 		v = value_new_cellrange_r (
@@ -4584,29 +4643,6 @@ oo_chart_grid (GsfXMLIn *xin, xmlChar const **attrs)
 }
 
 static void
-odf_apply_style_props (GSList *props, GOStyle *style)
-{
-	GSList *l;
-	for (l = props; l != NULL; l = l->next) {
-		OOProp *prop = l->data;
-		if (0 == strcmp (prop->name, "fill")) {
-			if (0 == strcmp (g_value_get_string (&prop->value), "solid")) {
-				style->fill.type = GO_STYLE_FILL_PATTERN;
-				style->fill.pattern.pattern = GO_PATTERN_SOLID;
-			} else {
-				style->fill.type = GO_STYLE_FILL_NONE;
-			}
-		} else if (0 == strcmp (prop->name, "fill-color")) {
-			GdkColor gdk_color;
-			gchar const *color = g_value_get_string (&prop->value);
-			if (gdk_color_parse (color, &gdk_color))
-				style->fill.pattern.back = GO_COLOR_FROM_GDK (gdk_color);
-		}
-	}
-}
-
-
-static void
 oo_chart_wall (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
@@ -5051,12 +5087,14 @@ static GsfXMLInNode const opendoc_content_dtd [] =
 		  GSF_XML_IN_NODE (TABLE_CELL, CELL_TEXT, OO_NS_TEXT, "p", GSF_XML_CONTENT, NULL, &oo_cell_content_end),
 		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),
 		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_ADDR, OO_NS_TEXT, "a", GSF_XML_SHARED_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_SHARED_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
-		    GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_LINE_BREAK,    OO_NS_TEXT, "line-break", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_LINE_BREAK,    OO_NS_TEXT, "line-break", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
+	            GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_TAB, OO_NS_TEXT, "tab", GSF_XML_SHARED_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_SHARED_CONTENT, NULL, NULL),
+		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
+		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
+		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_LINE_BREAK,    OO_NS_TEXT, "line-break", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_SPAN_ADDR, OO_NS_TEXT, "a", GSF_XML_SHARED_CONTENT, NULL, NULL),
+		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_TAB, OO_NS_TEXT, "tab", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 		  GSF_XML_IN_NODE (TABLE_CELL, CELL_OBJECT, OO_NS_DRAW, "object", GSF_XML_NO_CONTENT, NULL, NULL),		/* ignore for now */
 		  GSF_XML_IN_NODE (TABLE_CELL, CELL_GRAPHIC, OO_NS_DRAW, "g", GSF_XML_NO_CONTENT, NULL, NULL),			/* ignore for now */
 		    GSF_XML_IN_NODE (CELL_GRAPHIC, CELL_GRAPHIC, OO_NS_DRAW, "g", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd def */
@@ -5073,9 +5111,11 @@ static GsfXMLInNode const opendoc_content_dtd [] =
 	          GSF_XML_IN_NODE (TABLE_CELL, CELL_ANNOTATION, OO_NS_OFFICE, "annotation", GSF_XML_NO_CONTENT, &odf_annotation_start, &odf_annotation_end),
 	            GSF_XML_IN_NODE (CELL_ANNOTATION, CELL_ANNOTATION_TEXT, OO_NS_TEXT, "p", GSF_XML_CONTENT, NULL, &odf_annotation_content_end),
   		      GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT, CELL_ANNOTATION_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),
+  		      GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT, CELL_ANNOTATION_TEXT_TAB,  OO_NS_TEXT, "tab", GSF_XML_NO_CONTENT, NULL, NULL),
 		      GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT, CELL_ANNOTATION_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_SHARED_CONTENT, NULL, NULL),
 		        GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT_SPAN, CELL_ANNOTATION_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 		        GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT_SPAN, CELL_ANNOTATION_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
+		        GSF_XML_IN_NODE (CELL_ANNOTATION_TEXT_SPAN, CELL_ANNOTATION_TEXT_TAB,  OO_NS_TEXT, "tab", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 	            GSF_XML_IN_NODE (CELL_ANNOTATION, CELL_ANNOTATION_AUTHOR, OO_NS_DC, "creator", GSF_XML_CONTENT, NULL, &odf_annotation_author_end),
 	            GSF_XML_IN_NODE (CELL_ANNOTATION, CELL_ANNOTATION_DATE, OO_NS_DC, "date", GSF_XML_NO_CONTENT, NULL, NULL),
 
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 1e1d277..f325d37 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -4020,6 +4020,31 @@ odf_write_axis_grid (GnmOOExport *state, GogObject const *axis)
 	odf_write_one_axis_grid (state, axis, "MinorGrid", "minor");
 }
 
+static gchar*
+odf_get_gog_style_name (GOStyle const *style)
+{
+	if (style == NULL)
+		return NULL;
+	else
+		return g_strdup_printf ("GogStyle-%p", style);
+}
+
+static gchar*
+odf_get_gog_style_name_from_obj (GogObject const *obj)
+{
+	GObjectClass *klass = G_OBJECT_GET_CLASS (G_OBJECT (obj));
+
+	if (NULL != g_object_class_find_property (klass, "style")) {
+		GOStyle const *style = NULL;
+		gchar *name;
+		g_object_get (G_OBJECT (obj), "style", &style, NULL);
+		name = odf_get_gog_style_name (style);
+		g_object_unref (G_OBJECT (style));
+		return name;
+	}
+	return NULL;
+}
+
 static void
 odf_write_title (GnmOOExport *state, GogObject const *title, char const *id)
 {
@@ -4030,14 +4055,25 @@ odf_write_title (GnmOOExport *state, GogObject const *title, char const *id)
 			if (texpr != NULL) {
 				GnmParsePos pp;
 				char *formula;
-				parse_pos_init (&pp, WORKBOOK (state->wb), NULL, 0,0 );
-				formula = gnm_expr_top_as_string (texpr, &pp, state->conv);
+				char *name;
 
 				gsf_xml_out_start_element (state->xml, id);
 
+				name = odf_get_gog_style_name_from_obj (title);
+		      
+				if (name != NULL) {
+					gsf_xml_out_add_cstr (state->xml, CHART "style-name",
+								      name);
+					g_free (name);
+				}
+
+				parse_pos_init (&pp, WORKBOOK (state->wb), NULL, 0,0 );
+				formula = gnm_expr_top_as_string (texpr, &pp, state->conv);
+
 				if (gnm_expr_top_is_rangeref (texpr)) {
-					gsf_xml_out_add_cstr (state->xml, TABLE "cell-address",
-								      odf_strip_brackets (formula));
+					char *f = odf_strip_brackets (formula);
+					gsf_xml_out_add_cstr (state->xml, TABLE "cell-address", f);
+					gsf_xml_out_add_cstr (state->xml, TABLE "cell-range", f);
 				} else if (GNM_EXPR_GET_OPER (texpr->expr) == GNM_EXPR_OP_CONSTANT 
 					   && texpr->expr->constant.value->type == VALUE_STRING) {
 					gboolean white_written = TRUE;
@@ -4081,6 +4117,73 @@ odf_write_label (GnmOOExport *state, GogObject const *axis)
 }
 
 static void
+odf_write_gog_style_graphic (GnmOOExport *state, GOStyle const *style)
+{
+		if (style->fill.type == GO_STYLE_FILL_PATTERN) {
+			char *color;
+			color = odf_go_color_to_string (style->fill.pattern.back);
+			gsf_xml_out_add_cstr (state->xml, DRAW "fill", "solid");
+			gsf_xml_out_add_cstr (state->xml, DRAW "fill-color", color);
+			g_free (color);
+		} else
+			gsf_xml_out_add_cstr (state->xml, DRAW "fill", "none");	
+}
+
+static void
+odf_write_gog_style_text (GnmOOExport *state, GOStyle const *style)
+{
+	int val = style->text_layout.angle;
+	odf_add_angle (state->xml,  STYLE "text-rotation-angle", val);
+}
+
+static void
+odf_write_gog_style (GnmOOExport *state, GOStyle const *style)
+{
+	char *name = odf_get_gog_style_name (style);
+	if (name != NULL) {
+		odf_start_style (state->xml, name, "chart");
+
+		gsf_xml_out_start_element (state->xml, STYLE "chart-properties");
+		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);
+		gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
+       
+		gsf_xml_out_start_element (state->xml, STYLE "paragraph-properties");
+		gsf_xml_out_end_element (state->xml); /* </style:paragraph-properties> */
+       
+		gsf_xml_out_start_element (state->xml, STYLE "text-properties");
+		odf_write_gog_style_text (state, style);
+		gsf_xml_out_end_element (state->xml); /* </style:text-properties> */
+
+		gsf_xml_out_end_element (state->xml); /* </style:style> */
+		
+		g_free (name);
+	}
+}
+
+static void
+odf_write_gog_styles (GogObject const *obj, GnmOOExport *state)
+{
+	GObjectClass *klass = G_OBJECT_GET_CLASS (G_OBJECT (obj));
+	GSList *children;
+				
+	if (NULL != g_object_class_find_property (klass, "style")) {
+		GOStyle const *style = NULL;
+		g_object_get (G_OBJECT (obj), "style", &style, NULL);
+		if (style != NULL) {
+			odf_write_gog_style (state, style);
+			g_object_unref (G_OBJECT (style));
+		}
+	}
+
+	children = gog_object_get_children (obj, NULL);
+	g_slist_foreach (children, (GFunc) odf_write_gog_styles, state);
+	g_slist_free (children);
+}
+
+static void
 odf_write_axis (GnmOOExport *state, GogObject const *chart, char const *axis_role, 
 		char const *style_label,
 		char const *dimension, odf_chart_type_t gtype, GSList const *series)
@@ -4384,27 +4487,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		g_free (name);
 	}
 
-	if (wall != NULL) {
-		GOStyle *style = NULL;
-		g_object_get (G_OBJECT (wall), "style", &style, NULL);
-
-		odf_start_style (state->xml, "wallstyle", "chart");
-		gsf_xml_out_start_element (state->xml, STYLE "graphic-properties");
-
-		if (style->fill.type == GO_STYLE_FILL_PATTERN) {
-			char *color;
-			color = odf_go_color_to_string (style->fill.pattern.back);
-			gsf_xml_out_add_cstr (state->xml, DRAW "fill", "solid");
-			gsf_xml_out_add_cstr (state->xml, DRAW "fill-color", color);
-			g_free (color);
-		} else
-			gsf_xml_out_add_cstr (state->xml, DRAW "fill", "none");
-
-		gsf_xml_out_end_element (state->xml); /* </style:graphic-properties> */
-		gsf_xml_out_end_element (state->xml); /* </style:style> */
-
-		g_object_unref (G_OBJECT (style));
-	}
+	odf_write_gog_styles (chart, state);
 
 	gsf_xml_out_end_element (state->xml); /* </office:automatic-styles> */
 
@@ -4511,10 +4594,15 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		this_plot->odf_write_series (state, series);
 
 	if (wall != NULL) {
+		char *name = odf_get_gog_style_name_from_obj (wall);
+		
 		gsf_xml_out_start_element (state->xml, CHART "wall");
 		odf_add_pt (state->xml, SVG "width", res_pts[2] - res_pts[0] - 2 * this_plot->pad);
-		gsf_xml_out_add_cstr (state->xml, CHART "style-name", "wallstyle");
+		if (name != NULL)
+			gsf_xml_out_add_cstr (state->xml, CHART "style-name", name);
 		gsf_xml_out_end_element (state->xml); /* </chart:wall> */
+
+		g_free (name);
 	}
 	gsf_xml_out_end_element (state->xml); /* </chart:plot_area> */
 
diff --git a/samples/chart-tests.gnumeric b/samples/chart-tests.gnumeric
index 52d6dc0..060398e 100644
Binary files a/samples/chart-tests.gnumeric and b/samples/chart-tests.gnumeric differ



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