[gnumeric] Export basic charts to ODF.



commit 3279b8f775a7f97ca8a2e2bcf427a8255e099183
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Sun Jul 12 23:00:27 2009 -0600

    Export basic charts to ODF.
    
    2009-07-12 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_chart_axis): use more of the
    	  applicable styles
    	(oo_plot_area): ditto
    	(oo_plot_area_end): free GSList
    	(oo_chart): save applicable style
    	(openoffice_file_open): initialize chart.these_plot_styles
    	(od_draw_frame): calculate correct offsets
    	* openoffice-write.c (odf_write_bar_col_plot_style): new
    	(odf_write_bar_col_plot_styles): deleted
    	(odf_write_plot): try to implement basic support for all
    	  plot types
    	(odf_write_bar_col_plot): deleted and incorporated in
    	  odf_write_plot

 NEWS                                  |    2 +-
 plugins/openoffice/ChangeLog          |   16 ++++++
 plugins/openoffice/openoffice-read.c  |   45 +++++++++++++---
 plugins/openoffice/openoffice-write.c |   96 +++++++++++++++++++++++++++------
 4 files changed, 135 insertions(+), 24 deletions(-)
---
diff --git a/NEWS b/NEWS
index 82a8ff6..b8aec09 100644
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Andreas:
 	* Fix std error for intercept in non-affine case of LINEST. [#550933]
 	* Fix loading of charts from MS generated ODF files. [#588107]
 	* Add some sheet object support to ODF export.
-	* Export column charts to ODF.
+	* Export basic charts to ODF.
 
 Morten:
 	* Make SUMIF/COUNTIF and the D* functions understand pattern. [#586215]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 0d0b507..41d6a38 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,19 @@
+2009-07-12 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c (oo_chart_axis): use more of the 
+	  applicable styles
+	(oo_plot_area): ditto
+	(oo_plot_area_end): free GSList
+	(oo_chart): save applicable style
+	(openoffice_file_open): initialize chart.these_plot_styles
+	(od_draw_frame): calculate correct offsets
+	* openoffice-write.c (odf_write_bar_col_plot_style): new
+	(odf_write_bar_col_plot_styles): deleted
+	(odf_write_plot): try to implement basic support for all
+	  plot types
+	(odf_write_bar_col_plot): deleted and incorporated in 
+	  odf_write_plot
+
 2009-07-10 Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-write.c (odf_write_frame): also link to a png
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 3cb3749..1009568 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -144,7 +144,7 @@ typedef struct {
 typedef struct {
 	gboolean grid;		/* graph has grid? */
 	gboolean src_in_rows;	/* orientation of graph data: rows or columns */
-	GSList	*axis_props;		/* axis properties */
+	GSList	*axis_props;	/* axis properties */
 	GSList	*plot_props;	/* plot properties */
 } OOChartStyle;
 
@@ -167,6 +167,7 @@ typedef struct {
 
 	OOChartStyle		*cur_graph_style;
 	GHashTable		*graph_styles;	/* contain links to OOChartStyle GSLists */
+	GSList                  *these_plot_styles;  /*  */
 	OOPlotType		 plot_type;
 	SheetObjectAnchor	 anchor;	/* anchor to draw the frame (images or graphs) */
 } OOChartInfo;
@@ -3123,8 +3124,8 @@ od_draw_frame (GsfXMLIn *xin, xmlChar const **attrs)
 
 	frame_offset[0] = (x/col->size_pts);
 	frame_offset[1] = (y/row->size_pts);
-	frame_offset[2] = (width/col->size_pts);
-	frame_offset[3] = (height/row->size_pts);
+	frame_offset[2] = ((x+width)/col->size_pts);
+	frame_offset[3] = ((y+height)/row->size_pts);
 	sheet_object_anchor_init (&state->chart.anchor, &cell_base, frame_offset,
 		GOD_ANCHOR_DIR_DOWN_RIGHT);
 }
@@ -3247,6 +3248,7 @@ oo_chart_axis (GsfXMLIn *xin, xmlChar const **attrs)
 	gchar const *style_name = NULL;
 	GogAxisType  axis_type;
 	int tmp;
+	GSList *l;
 
 	axis_type = GOG_AXIS_UNKNOWN;
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
@@ -3261,6 +3263,11 @@ oo_chart_axis (GsfXMLIn *xin, xmlChar const **attrs)
 		g_slist_free (axes);
 	}
 
+	for (l = state->chart.these_plot_styles; l != NULL; l = l->next) { 
+		style = l->data;
+		oo_prop_list_apply (style->axis_props, G_OBJECT (state->chart.axis));
+	}
+
 	if (NULL != (style = g_hash_table_lookup (state->chart.graph_styles, style_name))) {
 		if (NULL != state->chart.axis)
 			oo_prop_list_apply (style->axis_props, G_OBJECT (state->chart.axis));
@@ -3287,10 +3294,15 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 	OOChartStyle	*style = NULL;
 	xmlChar const   *source_range_str = NULL;
 	int label_flags = 0;
+	GSList *l;
 
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style-name"))
-			style = g_hash_table_lookup (state->chart.graph_styles, CXML2C (attrs[1]));
+		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
+					OO_NS_CHART, "style-name"))
+			state->chart.these_plot_styles = g_slist_append 
+				(state->chart.these_plot_styles,
+				 g_hash_table_lookup 
+				 (state->chart.graph_styles, CXML2C (attrs[1])));
 		else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_TABLE, "cell-range-address"))
 			source_range_str = attrs[1];
 		else if (oo_attr_enum (xin, attrs, OO_NS_CHART, "data-source-has-labels", labels, &label_flags))
@@ -3316,8 +3328,10 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 			if (label_flags & 2)
 				state->chart.src_range.start.col++;
 
-			if (NULL != style)
+			for (l = state->chart.these_plot_styles; l != NULL; l = l->next) { 
+				style = l->data;
 				state->chart.src_in_rows = style->src_in_rows;
+			}
 			if (state->chart.src_in_rows) {
 				state->chart.src_n_vectors = range_height (&state->chart.src_range);
 				state->chart.src_range.end.row  = state->chart.src_range.start.row;
@@ -3345,8 +3359,10 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 	state->chart.plot = gog_plot_new_by_name (type);
 	gog_object_add_by_name (GOG_OBJECT (state->chart.chart),
 		"Plot", GOG_OBJECT (state->chart.plot));
-	if (style)
+	for (l = state->chart.these_plot_styles; l != NULL; l = l->next) { 
+		style = l->data;
 		oo_prop_list_apply (style->plot_props, G_OBJECT (state->chart.plot));
+	}
 }
 
 static void
@@ -3354,6 +3370,8 @@ oo_plot_area_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
 	state->chart.plot = NULL;
+	g_slist_free (state->chart.these_plot_styles);
+	state->chart.these_plot_styles = NULL;
 }
 
 static int
@@ -3500,16 +3518,28 @@ oo_chart (GsfXMLIn *xin, xmlChar const **attrs)
 	OOParseState *state = (OOParseState *)xin->user_state;
 	int tmp;
 	OOPlotType type = OO_PLOT_SCATTER; /* arbitrary default */
+	OOChartStyle	*style = NULL;
 
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 		if (oo_attr_enum (xin, attrs, OO_NS_CHART, "class", types, &tmp))
 			type = tmp;
+		else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), 
+					     OO_NS_CHART, "style-name"))
+			state->chart.these_plot_styles = g_slist_append 
+				(state->chart.these_plot_styles,
+				 g_hash_table_lookup 
+				 (state->chart.graph_styles, CXML2C (attrs[1])));
 	state->chart.plot_type = type;
 	state->chart.chart = GOG_CHART (gog_object_add_by_name (
 		GOG_OBJECT (state->chart.graph), "Chart", NULL));
 	state->chart.plot = NULL;
 	state->chart.series = NULL;
 	state->chart.axis = NULL;
+	if (NULL != style)
+		state->chart.src_in_rows = style->src_in_rows;
+
+	/* if (NULL != style) we also need to save the style for later use in oo_plot_area */
+
 }
 
 static void
@@ -4835,6 +4865,7 @@ openoffice_file_open (GOFileOpener const *fo, IOContext *io_context,
 	state.pos.eval.col	= -1;
 	state.pos.eval.row	= -1;
 	state.cell_comment      = NULL;
+	state.chart.these_plot_styles = NULL;
 	state.styles.sheet = g_hash_table_new_full (g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
 		(GDestroyNotify) g_free);
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index fa8db0d..a39673b 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3168,6 +3168,18 @@ odf_write_series (GnmOOExport *state, GSList const *series)
 }
 
 static void
+odf_write_bar_col_plot_style (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
+{
+	gboolean horizontal = FALSE;
+	if (plot == NULL)
+		return;
+
+	g_object_get (G_OBJECT (plot), "horizontal", &horizontal, NULL);
+	/* Note: horizontal refers to the bars and vertical to the x-axis */
+	odf_add_bool (state->xml, CHART "vertical", horizontal);
+}
+
+static void
 odf_write_axis_style (GnmOOExport *state, GogObject const *chart, char const *axis_role, 
 		      char const *style_label)
 {
@@ -3207,25 +3219,87 @@ odf_write_axis (GnmOOExport *state, GogObject const *chart, char const *axis_rol
 }
 
 static void
-odf_write_bar_col_plot_styles (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
+odf_write_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
 {
+	
+	enum {
+		ODF_BARCOL,
+		ODF_LINE,
+		ODF_AREA,
+		ODF_DROPBAR,
+		ODF_MINMAX,
+		ODF_CIRCLE,
+		ODF_RADAR,
+		ODF_RADARAREA,
+		ODF_RING,
+		ODF_SCATTER,
+		ODF_SURF,
+		ODF_STOCK
+	} gtype;
+	char const *plot_type = G_OBJECT_TYPE_NAME (plot);
+	char const *odf_plot_type;
+
+	if (0 == strcmp (plot_type, "GogBarColPlot")) {
+		gtype = ODF_BARCOL;
+		odf_plot_type = "chart:bar";
+	} else if (0 == strcmp (plot_type, "GogLinePlot")) {
+		gtype = ODF_LINE;
+		odf_plot_type = "chart:line";
+	} else if (0 == strcmp (plot_type, "GogAreaPlot")) {
+		gtype = ODF_AREA;
+		odf_plot_type = "chart:area";
+	} else if (0 == strcmp (plot_type, "GogDropBarPlot")) {
+		gtype = ODF_DROPBAR;
+		odf_plot_type = "chart:bar";
+	} else if (0 == strcmp (plot_type, "GogMinMaxPlot")) {
+		gtype = ODF_STOCK;
+		odf_plot_type = "chart:stock";
+	} else if (0 == strcmp (plot_type, "GogPiePlot")) {
+		gtype = ODF_CIRCLE;
+		odf_plot_type = "chart:circle";
+	} else if (0 == strcmp (plot_type, "GogRadarPlot")) {
+		gtype = ODF_RADAR;
+		odf_plot_type = "chart:radar";
+	} else if (0 == strcmp (plot_type, "GogRadarAreaPlot")) {
+		gtype = ODF_RADARAREA;
+		odf_plot_type = "chart:radararea";
+	} else if (0 == strcmp (plot_type, "GogRingPlot")) {
+		gtype = ODF_RING;
+		odf_plot_type = "chart:ring";
+	} else if (0 == strcmp (plot_type, "GogXYPlot")) {
+		gtype = ODF_SCATTER;
+		odf_plot_type = "chart:scatter";
+	} else if (0 == strcmp (plot_type, "GogContourPlot")) {
+		gtype = ODF_SURF;
+		odf_plot_type = "chart:surface";
+	} else {
+		g_print ("encountered unknown chart type %s\n", plot_type);
+		gtype = ODF_BARCOL;
+		odf_plot_type = "GogBarColPlot";
+	}
+
 	gsf_xml_out_start_element (state->xml, OFFICE "automatic-styles");
 	odf_write_axis_style (state, chart, "Y-Axis", "yaxis");
 	odf_write_axis_style (state, chart, "X-Axis", "xaxis");
+	odf_start_style (state->xml, "plotstyle", "chart");
+	gsf_xml_out_start_element (state->xml, STYLE "chart-properties");
 
+	if (gtype == ODF_BARCOL)
+		odf_write_bar_col_plot_style (state, chart, plot);	
+
+	gsf_xml_out_end_element (state->xml); /* </style:chart-properties> */
+	gsf_xml_out_end_element (state->xml); /* </style:style> */
 	gsf_xml_out_end_element (state->xml); /* </office:automatic-styles> */
-}
 
-static void
-odf_write_bar_col_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
-{
 	gsf_xml_out_start_element (state->xml, OFFICE "body");
 	gsf_xml_out_start_element (state->xml, OFFICE "chart");
 	gsf_xml_out_start_element (state->xml, CHART "chart");
 	if (get_gsf_odf_version () > 101)
 		gsf_xml_out_add_cstr (state->xml, XLINK "href", "..");
-	gsf_xml_out_add_cstr (state->xml, CHART "class", "chart:bar");
+	gsf_xml_out_add_cstr (state->xml, CHART "class", odf_plot_type);
+	gsf_xml_out_add_cstr (state->xml, CHART "style-name", "plotstyle");
 	gsf_xml_out_start_element (state->xml, CHART "plot-area");
+	gsf_xml_out_add_cstr (state->xml, CHART "style-name", "plotstyle");
 	if (get_gsf_odf_version () <= 101) {
 		GSList const *series = gog_plot_get_series (GOG_PLOT (plot));
 		for ( ; NULL != series ; series = series->next) {
@@ -3254,16 +3328,6 @@ odf_write_bar_col_plot (GnmOOExport *state, GogObject const *chart, GogObject co
 	gsf_xml_out_end_element (state->xml); /* </office:body> */
 }
 
-static void
-odf_write_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
-{
-	char const *plot_type = G_OBJECT_TYPE_NAME (plot);
-	if (0 == strcmp (plot_type, "GogBarColPlot")) {
-		odf_write_bar_col_plot_styles (state, chart, plot);
-		odf_write_bar_col_plot (state, chart, plot);
-	}
-}
-
 
 static void
 odf_write_graph_content (GnmOOExport *state, GsfOutput *child, SheetObject *so)



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