[gnumeric] ODF: drop lines support



commit e0c025b84ba9013b0fc4071da86934152c8b88d7
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon Aug 23 13:23:01 2010 -0600

    ODF: drop lines support
    
    2010-08-23  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_warning): fix return value
    	(oo_series_droplines): new
    	(opendoc_content_dtd): connect oo_series_droplines
    	* openoffice-write.c (odf_get_gog_style_name): move and extend
    	(odf_get_gog_style_name_from_obj): ditto
    	(odf_write_drop_line): new
    	(odf_write_standard_series): write drop lines
    	(odf_write_gog_style): extend
    	(odf_write_drop): new
    	(odf_fill_chart_props_hash): new
    	(odf_write_graphs): fine-tune progress reporting
    	(openoffice_file_save_real): complete progress

 plugins/openoffice/ChangeLog          |   32 ++++++--
 plugins/openoffice/openoffice-read.c  |   48 ++++++++++-
 plugins/openoffice/openoffice-write.c |  154 +++++++++++++++++++++++++--------
 3 files changed, 190 insertions(+), 44 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index da52e17..408be2f 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,28 +1,46 @@
+2010-08-23  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c (oo_warning): fix return value
+	(oo_series_droplines): new
+	(opendoc_content_dtd): connect oo_series_droplines
+	* openoffice-write.c (odf_get_gog_style_name): move and extend
+	(odf_get_gog_style_name_from_obj): ditto
+	(odf_write_drop_line): new
+	(odf_write_standard_series): write drop lines
+	(odf_write_gog_style): extend
+	(odf_write_drop): new
+	(odf_fill_chart_props_hash): new
+	(odf_write_graphs): fine-tune progress reporting
+	(openoffice_file_save_real): complete progress
+
 2010-08-22  Andreas J. Guelzow <aguelzow pyrshep ca>
 
-	* openoffice-write.c (odf_write_graph_content): fix role request (capitalization of 
-	  role name)
+	* openoffice-write.c (odf_write_graph_content): fix role request 
+	  (capitalization of role name)
 
 2010-08-22  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (oo_plot_area): handle OO_PLOT_UNKNOWN:
-	(oo_chart): set type to OO_PLOT_UNKNOWN on unknown charts and raise a warning
+	(oo_chart): set type to OO_PLOT_UNKNOWN on unknown charts and raise 
+	  a warning
 	(oo_warning): make sure we are showing the first error
 
 2010-08-22  Andreas J. Guelzow <aguelzow pyrshep ca>
 
-	* openoffice-read.c (oo_plot_series): Also read gnm:label-cell-expression
+	* openoffice-read.c (oo_plot_series): Also read 
+	  gnm:label-cell-expression
 	* openoffice-write.c (odf_update_progress): new
 	(odf_write_content): call odf_update_progress
 	(odf_write_label_cell_address): new
 	(odf_write_standard_series): use odf_write_label_cell_address
 	(odf_write_box_series): ditto
-	(odf_write_plot_style): make sure we are using the correct type, add attributes
+	(odf_write_plot_style): make sure we are using the correct type, 
+	  add attributes
 	(odf_write_surface_plot_style): replace with odf_write_plot_style
 	(odf_write_xl_surface_plot_style): ditto
 	(odf_write_plot): simplify
-	(odf_write_graph_content): make sure we are finding a chart and plot, and write a fake
-	  if there is none.
+	(odf_write_graph_content): make sure we are finding a chart and plot, 
+	  and write a fake if there is none.
 	(odf_write_images): update progress
 	(odf_write_graphs): update progress
 	(openoffice_file_save_real): setup progress
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 11c08cb..58bd126 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -328,7 +328,7 @@ oo_warning (GsfXMLIn *xin, char const *fmt, ...)
 
 	if (go_io_error_occurred (state->context) || 
 	    go_io_warning_occurred (state->context))
-		return;
+		return FALSE;
 
 	va_start (args, fmt);
 	msg = g_strdup_vprintf (fmt, args);
@@ -4676,6 +4676,51 @@ oo_series_pt (GsfXMLIn *xin, xmlChar const **attrs)
 }
 
 static void
+oo_series_droplines (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+	char const *style_name = NULL;
+	gboolean vertical = TRUE;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style-name"))
+			style_name = CXML2C (attrs[1]);
+	if (style_name != NULL) {
+		OOChartStyle *chart_style = g_hash_table_lookup
+			(state->chart.graph_styles, style_name);
+		GOStyle *style = NULL;
+		GSList *l;
+		char const *role_name = NULL;
+		GogObject const *lines;
+
+		for (l = chart_style->plot_props; l != NULL; l = l->next) {
+			OOProp *prop = l->data;
+			if (0 == strcmp ("vertical", prop->name))
+				vertical = g_value_get_boolean (&prop->value);
+		}
+
+		switch (state->chart.plot_type) {
+		case OO_PLOT_LINE: 
+			role_name = "Drop lines";
+			break;
+		case OO_PLOT_SCATTER:
+			role_name = vertical ? "Vertical drop lines" : "Horizontal drop lines";
+			break;
+		default:
+			oo_warning (xin , _("Encountered drop lines in a plot not supporting them."));
+			return;
+		}
+		
+		lines = gog_object_add_by_name (GOG_OBJECT (state->chart.series), role_name, NULL);
+
+		g_object_get (G_OBJECT (lines), "style", &style, NULL);
+		if (style != NULL) {
+			odf_apply_style_props (chart_style->style_props, style);
+			g_object_unref (style);			
+		}
+	}
+}
+
+static void
 oo_chart_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
@@ -5210,6 +5255,7 @@ static GsfXMLInNode const opendoc_content_dtd [] =
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DOMAIN, OO_NS_CHART, "domain", GSF_XML_NO_CONTENT, &oo_series_domain, NULL),
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DATA_PT, OO_NS_CHART, "data-point", GSF_XML_NO_CONTENT, &oo_series_pt, NULL),
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DATA_ERR, OO_NS_CHART, "error-indicator", GSF_XML_NO_CONTENT, NULL, NULL),
+		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DROPLINES, OO_GNUM_NS_EXT, "droplines", GSF_XML_NO_CONTENT, &oo_series_droplines, NULL),
 		GSF_XML_IN_NODE (CHART_PLOT_AREA, CHART_WALL, OO_NS_CHART, "wall", GSF_XML_NO_CONTENT, &oo_chart_wall, NULL),
 		GSF_XML_IN_NODE (CHART_PLOT_AREA, CHART_FLOOR, OO_NS_CHART, "floor", GSF_XML_NO_CONTENT, NULL, NULL),
 		GSF_XML_IN_NODE (CHART_PLOT_AREA, CHART_AXIS, OO_NS_CHART, "axis", GSF_XML_NO_CONTENT, &oo_chart_axis, &oo_chart_axis_end),
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index d1a4084..e0ec604 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -116,6 +116,7 @@ typedef struct {
 	ColRowInfo const *column_default;
 	GHashTable *graphs;
 	GHashTable *graph_dashes;
+	GHashTable *chart_props_hash;
 	GHashTable *images;
 	gboolean with_extension;
 	GOFormat const *time_fmt;
@@ -488,6 +489,32 @@ table_style_name (Sheet const *sheet)
 		sheet->text_is_rtl ? "rl" : "lr");
 }
 
+static gchar*
+odf_get_gog_style_name (GOStyle const *style, GogObject const *obj)
+{
+	if (style == NULL)
+		return g_strdup_printf ("GogStyle--%p", obj);
+	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, obj);
+		g_object_unref (G_OBJECT (style));
+		return name;
+	} else
+		return odf_get_gog_style_name (NULL, obj);
+	return NULL;
+}
+
 static const char*
 xl_find_format (GnmOOExport *state, GOFormat const *format, int i)
 {
@@ -3500,6 +3527,28 @@ odf_write_label_cell_address (GnmOOExport *state, GOData const *dat)
 	}
 }
 
+static void
+odf_write_drop_line (GnmOOExport *state, GogObject const *series, char const *drop, 
+		     gboolean vertical)
+{
+	GogObjectRole const *role = gog_object_find_role_by_name (series, drop);	
+
+	if (role != NULL) {
+		GSList *drops = gog_object_get_children 
+			(series, role);
+		if (drops != NULL && drops->data != NULL) {
+			char *style = odf_get_gog_style_name_from_obj (GOG_OBJECT (drops->data));
+
+			gsf_xml_out_start_element (state->xml, GNMSTYLE "droplines");
+			gsf_xml_out_add_cstr (state->xml, CHART "style-name", style);
+			gsf_xml_out_end_element (state->xml); /* </gnm:droplines> */
+
+			g_free (style);
+		}
+		g_slist_free (drops);
+	}
+}
+
 
 static void
 odf_write_standard_series (GnmOOExport *state, GSList const *series)
@@ -3514,7 +3563,8 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
 			GnmExprTop const *texpr = gnm_go_data_get_expr (dat);
 			if (NULL != texpr) {
 				char *str = gnm_expr_top_as_string (texpr, &pp, state->conv);
-				GOData const *cat = gog_dataset_get_dim (GOG_DATASET (series->data), GOG_MS_DIM_LABELS);
+				GOData const *cat = gog_dataset_get_dim (GOG_DATASET (series->data), 
+									 GOG_MS_DIM_LABELS);
 				gsf_xml_out_start_element (state->xml, CHART "series");
 				gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
 						      odf_strip_brackets (str));
@@ -3537,6 +3587,15 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
 						g_free (str);
 					}
 				}
+
+				if (state->with_extension) {
+					odf_write_drop_line (state, GOG_OBJECT (series->data), 
+							     "Horizontal drop lines", FALSE);
+					odf_write_drop_line (state, GOG_OBJECT (series->data), 
+							     "Vertical drop lines", TRUE);
+					odf_write_drop_line (state, GOG_OBJECT (series->data), 
+							     "Drop lines", TRUE);
+				}
 				gsf_xml_out_end_element (state->xml); /* </chart:series> */
 			}
 		}
@@ -4103,31 +4162,6 @@ 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)
 {
@@ -4285,13 +4319,27 @@ odf_write_gog_style_text (GnmOOExport *state, GOStyle const *style)
 }
 
 static void
-odf_write_gog_style (GnmOOExport *state, GOStyle const *style)
+odf_write_gog_style_chart (GnmOOExport *state, GOStyle const *style, GogObject const *obj)
+{
+	gchar const *type = G_OBJECT_TYPE_NAME (G_OBJECT (obj));
+
+	void (*func) (GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+		= g_hash_table_lookup (state->chart_props_hash, type);
+
+	if (func != NULL)
+		func (state, style, obj);
+}
+
+static void
+odf_write_gog_style (GnmOOExport *state, GOStyle const *style, 
+		     GogObject const *obj)
 {
-	char *name = odf_get_gog_style_name (style);
+	char *name = odf_get_gog_style_name (style, obj);
 	if (name != NULL) {
 		odf_start_style (state->xml, name, "chart");
 
 		gsf_xml_out_start_element (state->xml, STYLE "chart-properties");
+		odf_write_gog_style_chart (state, style, obj);
 		gsf_xml_out_end_element (state->xml); /* </style:chart-properties> */
 
 		gsf_xml_out_start_element (state->xml, STYLE "graphic-properties");
@@ -4321,7 +4369,7 @@ odf_write_gog_styles (GogObject const *obj, GnmOOExport *state)
 		GOStyle const *style = NULL;
 		g_object_get (G_OBJECT (obj), "style", &style, NULL);
 		if (style != NULL) {
-			odf_write_gog_style (state, style);
+			odf_write_gog_style (state, style, obj);
 			g_object_unref (G_OBJECT (style));
 		}
 	}
@@ -4822,6 +4870,35 @@ odf_write_images (SheetObjectImage *image, char const *name, GnmOOExport *state)
 }
 
 static void
+odf_write_drop(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	GogObjectRole const *h_role = gog_object_find_role_by_name 
+		(obj->parent, "Horizontal drop lines");
+	gboolean vertical = !(h_role == obj->role);
+
+	odf_add_bool (state->xml, CHART "vertical", vertical);
+}
+
+
+static void
+odf_fill_chart_props_hash (GnmOOExport *state)
+{
+	int i;
+	static struct {
+		gchar const *type;
+		void (*odf_write_property) (GnmOOExport *state, 
+					    GOStyle const *style, 
+					    GogObject const *obj);
+	} props[] = {
+		{"GogSeriesLines", odf_write_drop}
+	};
+		
+	for (i = 0 ; i < (int)G_N_ELEMENTS (props) ; i++)
+		g_hash_table_insert (state->chart_props_hash, (gpointer) props[i].type, 
+				     props[i].odf_write_property);
+}
+
+static void
 odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 {
 	GsfOutput  *child;
@@ -4836,6 +4913,9 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 		state->graph_dashes = g_hash_table_new_full (g_str_hash, g_str_equal,
 							     (GDestroyNotify) g_free, 
 							     NULL);
+		state->chart_props_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+							     NULL, NULL);
+		odf_fill_chart_props_hash (state);
 
 		sec_child = gsf_outfile_new_child_full (state->outfile, fullname, FALSE,
 							"compression-level", GSF_ZIP_DEFLATED,
@@ -4847,7 +4927,7 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 		}
 		g_free (fullname);
 
-		odf_update_progress (state, state->graph_progress);
+		odf_update_progress (state, 4 * state->graph_progress);
 
 		fullname = g_strdup_printf ("%s/meta.xml", name);
 		sec_child = gsf_outfile_new_child_full (state->outfile, fullname, FALSE,
@@ -4859,7 +4939,7 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 			g_object_unref (G_OBJECT (sec_child));
 		}
 		g_free (fullname);
-		odf_update_progress (state, state->graph_progress / 8);
+		odf_update_progress (state, state->graph_progress / 2);
 
 		fullname = g_strdup_printf ("%s/styles.xml", name);
 		sec_child = gsf_outfile_new_child_full (state->outfile, fullname, FALSE,
@@ -4873,7 +4953,9 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 		g_free (fullname);
 		g_hash_table_unref (state->graph_dashes);
 		state->graph_dashes = NULL;
-		odf_update_progress (state, state->graph_progress * (3./8.));
+		g_hash_table_unref (state->chart_props_hash);
+		state->chart_props_hash = NULL;
+		odf_update_progress (state, state->graph_progress * (3./2.));
 
 		gsf_output_close (child);
 		g_object_unref (G_OBJECT (child));
@@ -4890,7 +4972,7 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 			g_object_unref (G_OBJECT (sec_child));
 		}
 		g_free (fullname);
-		odf_update_progress (state, state->graph_progress / 4);
+		odf_update_progress (state, state->graph_progress);
 
 		fullname = g_strdup_printf ("Pictures/%s.png", name);
 		sec_child = gsf_outfile_new_child_full (state->outfile, fullname, FALSE,
@@ -4904,7 +4986,7 @@ odf_write_graphs (SheetObject *graph, char const *name, GnmOOExport *state)
 			g_object_unref (G_OBJECT (sec_child));
 		}
 		g_free (fullname);
-		odf_update_progress (state, state->graph_progress / 4);
+		odf_update_progress (state, state->graph_progress);
 	}
 }
 
@@ -5001,7 +5083,7 @@ openoffice_file_save_real (GOFileSaver const *fs, GOIOContext *ioc,
 	}
 
 	state.graph_progress = ((float) PROGRESS_STEPS) / 2 /
-		(2 * g_hash_table_size (state.graphs) + g_hash_table_size (state.images) + 1);
+		(8 * g_hash_table_size (state.graphs) + g_hash_table_size (state.images) + 1);
 	go_io_progress_message (state.ioc, _("Writing Sheet Objects..."));
 
         pictures = gsf_outfile_new_child_full (state.outfile, "Pictures", TRUE,
@@ -5014,9 +5096,9 @@ openoffice_file_save_real (GOFileSaver const *fs, GOIOContext *ioc,
 		g_object_unref (G_OBJECT (pictures));
 	}
 
-
 	g_free (state.conv);
 
+	go_io_value_progress_update (state.ioc, PROGRESS_STEPS);
 	go_io_progress_unset (state.ioc);
 	gsf_output_close (GSF_OUTPUT (state.outfile));
 	g_object_unref (G_OBJECT (state.outfile));



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