[gnumeric] Handle MinMax (Stock) plots in ODF export & import



commit e382f393bf49afd6d20828740ef29f7ba642dbeb
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date:   Thu Jul 16 20:28:04 2009 -0600

    Handle MinMax (Stock) plots in ODF export & import
    
    2009-07-16 Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_plot_area): set up series handling for
    	  Stock plot
    	(oo_plot_area_end): handle stock plot series
    	(odf_create_stock_plot): new
    	(oo_plot_series): for Stock plot just save the info
    	(oo_plot_series_end): for Stock plots we don't want to do
    	  anything here
    	(oo_chart): set up reading of more chart types
    	* openoffice-write.c (odf_write_bubble_series): fix style name
    	(odf_write_min_max_series): new
    	(odf_write_plot): set up writing of more plot types
    	(odf_write_plot): handle writing of minmax plots

 plugins/openoffice/ChangeLog          |   15 +++++
 plugins/openoffice/openoffice-read.c  |  101 ++++++++++++++++++++++++---------
 plugins/openoffice/openoffice-write.c |   54 ++++++++++++++++--
 3 files changed, 137 insertions(+), 33 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 8ada888..587468f 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,18 @@
+2009-07-16 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c (oo_plot_area): set up series handling for 
+	  Stock plot
+	(oo_plot_area_end): handle stock plot series
+	(odf_create_stock_plot): new
+	(oo_plot_series): for Stock plot just save the info
+	(oo_plot_series_end): for Stock plots we don't want to do 
+	  anything here
+	(oo_chart): set up reading of more chart types
+	* openoffice-write.c (odf_write_bubble_series): fix style name
+	(odf_write_min_max_series): new
+	(odf_write_plot): set up writing of more plot types
+	(odf_write_plot): handle writing of minmax plots
+
 2009-07-15 Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (od_style_prop_chart): handle 
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 0a4b437..b41b0ec 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -123,6 +123,8 @@ typedef enum {
 	OO_PLOT_SURF,
 	OO_PLOT_BUBBLE,
 	OO_PLOT_GANTT,
+	OO_PLOT_POLAR,
+	OO_PLOT_XYZ_CONTOUR,
 	OO_PLOT_UNKNOWN
 } OOPlotType;
 
@@ -153,6 +155,7 @@ typedef struct {
 typedef struct {
 	GogGraph	*graph;
 	GogChart	*chart;
+	GSList          *stock_series; /* used by Stcock plot */
 
 	/* set in plot-area */
 	GogPlot		*plot;
@@ -170,7 +173,7 @@ typedef struct {
 
 	OOChartStyle		*cur_graph_style;
 	GHashTable		*graph_styles;	/* contain links to OOChartStyle GSLists */
-	GSList                  *these_plot_styles;  /*  */
+	GSList                  *these_plot_styles;  /* currently active styles */
 	OOPlotType		 plot_type;
 	SheetObjectAnchor	 anchor;	/* anchor to draw the frame (images or graphs) */
 } OOChartInfo;
@@ -3446,6 +3449,7 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 	state->chart.src_in_rows = TRUE;
 	state->chart.series = NULL;
 	state->chart.series_count = 0;
+	state->chart.stock_series = NULL;
 	if (NULL != source_range_str) {
 		GnmParsePos pp;
 		GnmEvalPos  ep;
@@ -3487,10 +3491,12 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 	case OO_PLOT_RADARAREA: type = "GogRadarAreaPlot";break;
 	case OO_PLOT_RING:	type = "GogRingPlot";	break;
 	case OO_PLOT_SCATTER:	type = "GogXYPlot";	break;
-	case OO_PLOT_STOCK:	type = "GogMinMaxPlot";	break;
-	case OO_PLOT_SURF:	type = "GogContourPlot"; break;
+	case OO_PLOT_STOCK:	type = "GogMinMaxPlot";	break;  /* This is not quite right! */
+	case OO_PLOT_SURF:	type = "GogContourPlot"; break; /* This might not be right!? */
 	case OO_PLOT_BUBBLE:	type = "GogBubblePlot"; break;
 	case OO_PLOT_GANTT:	type = "GogDropBarPlot"; break;
+	case OO_PLOT_POLAR:	type = "GogPolarPlot"; break;
+	case OO_PLOT_XYZ_CONTOUR: type = "GogXYZContourPlot"; break;
 	default: return;
 	}
 
@@ -3515,10 +3521,36 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 }
 
 static void
+odf_create_stock_plot (GsfXMLIn *xin)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+	GSList *series_addresses = state->chart.stock_series;
+	int len = g_slist_length (series_addresses);
+
+	if (len > 3) {
+		series_addresses = series_addresses->next;
+		len--;
+	}
+
+	if (len-- > 0) {
+		state->chart.series = gog_plot_new_series (state->chart.plot);
+		oo_plot_assign_dim (xin, series_addresses->data, GOG_MS_DIM_LOW);
+	}
+	if (len-- > 0) {
+		series_addresses = series_addresses->next;
+		oo_plot_assign_dim (xin, series_addresses->data, GOG_MS_DIM_HIGH);
+	}
+}
+
+static void
 oo_plot_area_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
-	if (state->chart.series != NULL) {
+	if (state->chart.plot_type == OO_PLOT_STOCK) {
+		odf_create_stock_plot (xin);
+		go_slist_free_custom (state->chart.stock_series, g_free);
+		state->chart.stock_series = NULL;
+	} else if (state->chart.series != NULL) {
 		oo_plot_assign_dim (xin, NULL, GOG_MS_DIM_VALUES);
 		state->chart.series = NULL;		
 	}
@@ -3536,29 +3568,37 @@ oo_plot_series (GsfXMLIn *xin, xmlChar const **attrs)
 #ifdef OO_DEBUG_OBJS
 	g_print ("<<<<< Start\n");
 #endif
-	state->chart.series_count++;
-	if (state->chart.series == NULL)
-		state->chart.series = gog_plot_new_series (state->chart.plot);
-	state->chart.domain_count = 0;
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style"))
-			;
-		else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "values-cell-range-address")) {
-			int dim;
-			switch (state->chart.plot_type) {
-			case OO_PLOT_GANTT:
-				dim = (state->chart.series_count % 2 == 1) ? GOG_MS_DIM_START : GOG_MS_DIM_END;
-				break;
-			case OO_PLOT_BUBBLE:
-				dim = GOG_MS_DIM_BUBBLES;
-				break;
-			default:
-				dim = GOG_MS_DIM_VALUES;
-				break;
-			}
-			oo_plot_assign_dim (xin, attrs[1], dim);
-		} else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "label-cell-address"))
-			oo_plot_assign_dim (xin, attrs[1], GOG_MS_DIM_LABELS);
+	state->chart.series_count++; 
+
+	if (state->chart.plot_type == OO_PLOT_STOCK) {
+		for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+			if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "values-cell-range-address"))
+				state->chart.stock_series = g_slist_append (state->chart.stock_series, 
+									    g_strdup (attrs[1]));
+	} else {
+		if (state->chart.series == NULL)
+			state->chart.series = gog_plot_new_series (state->chart.plot);
+		state->chart.domain_count = 0;
+		for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+			if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style"))
+				;
+			else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "values-cell-range-address")) {
+				int dim;
+				switch (state->chart.plot_type) {
+				case OO_PLOT_GANTT:
+					dim = (state->chart.series_count % 2 == 1) ? GOG_MS_DIM_START : GOG_MS_DIM_END;
+					break;
+				case OO_PLOT_BUBBLE:
+					dim = GOG_MS_DIM_BUBBLES;
+					break;
+				default:
+					dim = GOG_MS_DIM_VALUES;
+					break;
+				}
+				oo_plot_assign_dim (xin, attrs[1], dim);
+			} else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "label-cell-address"))
+				oo_plot_assign_dim (xin, attrs[1], GOG_MS_DIM_LABELS);
+	}
 }
 
 static void
@@ -3567,9 +3607,12 @@ oo_plot_series_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 	OOParseState *state = (OOParseState *)xin->user_state;
 	
 	switch (state->chart.plot_type) {
+	case OO_PLOT_STOCK:
+		break;
 	case OO_PLOT_GANTT:
 		if ((state->chart.series_count % 2) != 0)
 			break;
+		/* else no break */
 	default:
 		oo_plot_assign_dim (xin, NULL, GOG_MS_DIM_VALUES);
 		state->chart.series = NULL;
@@ -3616,11 +3659,15 @@ oo_chart (GsfXMLIn *xin, xmlChar const **attrs)
 		{ "chart:circle",	OO_PLOT_CIRCLE },
 		{ "chart:line",		OO_PLOT_LINE },
 		{ "chart:radar",	OO_PLOT_RADAR },
+		{ "chart:filled-radar",	OO_PLOT_RADARAREA },
 		{ "chart:ring",		OO_PLOT_RING },
 		{ "chart:scatter",	OO_PLOT_SCATTER },
 		{ "chart:stock",	OO_PLOT_STOCK },
 		{ "chart:bubble",	OO_PLOT_BUBBLE },
 		{ "chart:gantt",	OO_PLOT_GANTT },
+		{ "chart:surface",	OO_PLOT_SURF },
+		{ "gnm:polar",  	OO_PLOT_POLAR },
+		{ "gnm:xyz-contour", 	OO_PLOT_XYZ_CONTOUR },
 		{ NULL,	0 },
 	};
 	OOParseState *state = (OOParseState *)xin->user_state;
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index cf8564a..05accf0 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3169,8 +3169,9 @@ typedef enum {
 	ODF_RING,
 	ODF_SCATTER,
 	ODF_SURF,
+	ODF_XYZ_SURF,
 	ODF_BUBBLE,
-	ODF_STOCK
+	ODF_POLAR
 } odf_chart_type_t; 
 
 static void
@@ -3273,7 +3274,7 @@ odf_write_bubble_series (GnmOOExport *state, GSList const *orig_series)
 	parse_pos_init (&pp, WORKBOOK (state->wb), NULL, 0,0 );
 
 	gsf_xml_out_start_element (state->xml, CHART "series");
-	for (series = orig_series, i = 0; NULL != series; series = series->next, i++) {
+	for (series = orig_series, i = 1; NULL != series; series = series->next, i++) {
 		GOData const *dat = gog_dataset_get_dim (GOG_DATASET (series->data), 2);
 
 		if (NULL != dat) {
@@ -3310,6 +3311,37 @@ odf_write_bubble_series (GnmOOExport *state, GSList const *orig_series)
 }
 
 static void
+odf_write_min_max_series (GnmOOExport *state, GSList const *orig_series)
+{
+	GnmParsePos pp;
+	int i, j;
+	GSList const *series;
+	parse_pos_init (&pp, WORKBOOK (state->wb), NULL, 0,0 );
+
+	for (j = 1; j < 3; j++) { 
+		gsf_xml_out_start_element (state->xml, CHART "series");
+		for (series = orig_series, i = 1; NULL != series; series = series->next, i++) {
+			GOData const *dat = gog_dataset_get_dim (GOG_DATASET (series->data), j);
+
+			if (NULL != dat) {
+				GnmExprTop const *texpr = gnm_go_data_get_expr (dat);
+				if (NULL != texpr) {
+					char *str = gnm_expr_top_as_string (texpr, &pp, state->conv);
+					gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
+							      odf_strip_brackets (str));
+					g_free (str);
+					str = g_strdup_printf ("series%i", i);
+					gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
+					g_free (str);
+					break;
+				}
+			}
+		}
+		gsf_xml_out_end_element (state->xml); /* </chart:series> */
+	}
+}
+
+static void
 odf_write_bar_col_plot_style (GnmOOExport *state, G_GNUC_UNUSED GogObject const *chart, GogObject const *plot)
 {
 	gboolean horizontal = FALSE;
@@ -3441,6 +3473,10 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		gtype = ODF_LINE;
 		odf_plot_type = "chart:line";
 		pad = 20.;
+	} else if (0 == strcmp (plot_type, "GogPolarPlot")) {
+		gtype = ODF_POLAR;
+		odf_plot_type = "gnm:polar";
+		pad = 20.;
 	} else if (0 == strcmp (plot_type, "GogAreaPlot")) {
 		gtype = ODF_AREA;
 		odf_plot_type = "chart:area";
@@ -3450,7 +3486,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		odf_plot_type = "chart:gantt";
 		pad = 20.;
 	} else if (0 == strcmp (plot_type, "GogMinMaxPlot")) {
-		gtype = ODF_STOCK;
+		gtype = ODF_MINMAX;
 		odf_plot_type = "chart:stock";
 		pad = 10.;
 	} else if (0 == strcmp (plot_type, "GogPiePlot")) {
@@ -3463,7 +3499,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		pad = 10.;
 	} else if (0 == strcmp (plot_type, "GogRadarAreaPlot")) {
 		gtype = ODF_RADARAREA;
-		odf_plot_type = "chart:radararea";
+		odf_plot_type = "chart:filled-radar";
 		pad = 10.;
 	} else if (0 == strcmp (plot_type, "GogRingPlot")) {
 		gtype = ODF_RING;
@@ -3478,8 +3514,8 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		odf_plot_type = "chart:surface";
 		pad = 20.;
 	} else if (0 == strcmp (plot_type, "GogXYZContourPlot")) {
-		gtype = ODF_SURF;
-		odf_plot_type = "chart:surface";
+		gtype = ODF_XYZ_SURF;
+		odf_plot_type = "gnm:xyz-contour";
 		pad = 20.;
 	} else if (0 == strcmp (plot_type, "GogBubblePlot")) {
 		gtype = ODF_BUBBLE;
@@ -3502,6 +3538,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		break;
 	case ODF_BARCOL:
 	case ODF_DROPBAR:
+	case ODF_MINMAX:
 		g_object_get (G_OBJECT (plot), "horizontal", &horizontal, NULL);
 		odf_write_axis_style (state, chart, "Y-Axis", horizontal ? "xaxis" : "yaxis", gtype);
 		odf_write_axis_style (state, chart, "X-Axis", horizontal ? "yaxis" : "xaxis", gtype);
@@ -3628,6 +3665,11 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *chart, Gog
 		odf_write_axis (state, chart, "X-Axis", "xaxis", "x", gtype);
 		odf_write_gantt_series (state, series);
 		break;
+	case ODF_MINMAX:
+		odf_write_axis (state, chart, "Y-Axis", "yaxis", "y", gtype);
+		odf_write_axis (state, chart, "X-Axis", "xaxis", "x", gtype);
+		odf_write_min_max_series (state, series);
+		break;		
 	default:
 		odf_write_axis (state, chart, "Y-Axis", "yaxis", "y", gtype);
 		odf_write_axis (state, chart, "X-Axis", "xaxis", "x", gtype);



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