[gnumeric] Import Guppi graphs from gnumeric-1.0.x files. [#567953]
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Import Guppi graphs from gnumeric-1.0.x files. [#567953]
- Date: Sat, 31 Jul 2010 14:25:54 +0000 (UTC)
commit 4469b2eaf0760eda44418e2a89d630ef9c124a9b
Author: Jean Brefort <jean brefort normalesup org>
Date: Sat Jul 31 16:26:33 2010 +0200
Import Guppi graphs from gnumeric-1.0.x files. [#567953]
ChangeLog | 10 ++
NEWS | 3 +
src/sheet-object-graph.c | 280 +++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 290 insertions(+), 3 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a2a9973..5a19e3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-07-31 Jean Brefort <jean brefort normalesup org>
+
+ * src/sheet-object-graph.c (gnm_sog_prep_sax_parser),
+ (sheet_object_graph_ensure_size), (vector_start), (vector_end),
+ (plot_type_start), (series_start), (dim_start), (marker_end),
+ (linear_start), (cubic_start), (horiz_end), (stacked_end),
+ (percent_end), (separation_end), (bubble_end),
+ (gnm_sogg_sax_parser_done), (gnm_sogg_prep_sax_parser): import Guppi
+ graphs from gnumeric-1.0.x files. [#567953]
+
2010-07-30 Morten Welinder <terra gnome org>
* configure.in: Post-release bump.
diff --git a/NEWS b/NEWS
index d45e6df..40ab556 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Gnumeric 1.10.9
Andreas:
* Clarify autofilter dialog. [#625688]
+Jean:
+ * Import Guppi graphs from gnumeric-1.0.x files. [#567953]
+
--------------------------------------------------------------------------
Gnumeric 1.10.8
diff --git a/src/sheet-object-graph.c b/src/sheet-object-graph.c
index 9a03d5c..cf47cd1 100644
--- a/src/sheet-object-graph.c
+++ b/src/sheet-object-graph.c
@@ -397,13 +397,19 @@ sog_xml_finish (GogObject *graph, SheetObject *so)
g_object_unref (graph);
}
+static void gnm_sogg_prep_sax_parser (SheetObject *so, GsfXMLIn *xin,
+ xmlChar const **attrs,
+ GnmConventions const *convs);
static void
gnm_sog_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs,
GnmConventions const *convs)
{
- gog_object_sax_push_parser (xin, attrs,
- (GogObjectSaxHandler) sog_xml_finish,
- (gpointer)convs, so);
+ if (strcmp (xin->node->name, "GnmGraph"))
+ gog_object_sax_push_parser (xin, attrs,
+ (GogObjectSaxHandler) sog_xml_finish,
+ (gpointer)convs, so);
+ else
+ gnm_sogg_prep_sax_parser (so, xin, attrs, convs);
}
static void
@@ -758,3 +764,271 @@ sheet_object_graph_ensure_size (SheetObject *so)
ptr = ptr->next;
}
}
+
+/*****************************************************************************/
+/* Support for Guppi graphs */
+
+typedef struct {
+ GnmConventions const *convs;
+ GogGraph *graph;
+ GogObject *chart;
+ GogPlot *plot;
+ GogObject *cur;
+ GogStyle *style;
+ GPtrArray *data;
+ unsigned cur_index, max_data;
+} GuppiReadState;
+
+static void
+vector_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *) xin->user_state;
+ int i;
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "ID"))
+ state->cur_index = atoi (attrs[i+1]);
+ if (state->cur_index >= state->max_data) {
+ state->max_data += 10;
+ g_ptr_array_set_size (state->data, state->max_data);
+ }
+}
+
+static void
+vector_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *) xin->user_state;
+ GOData *data;
+ data = g_object_new (GNM_GO_DATA_VECTOR_TYPE, NULL);
+ go_data_unserialize (data, xin->content->str, (void*) state->convs);
+ g_ptr_array_index (state->data, state->cur_index) = data;
+}
+
+static void
+plot_type_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *) xin->user_state;
+ int i;
+ char const *name = NULL;
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "name"))
+ name = attrs[i+1];
+ if (name) {
+ if (0 == strcmp (name, "Scatter")) {
+ state->plot = gog_plot_new_by_name ("GogXYPlot");
+ g_object_set (G_OBJECT (state->plot),
+ "default-style-has-markers", FALSE,
+ "default-style-has-lines", FALSE,
+ NULL);
+ gog_object_add_by_name (state->chart, "Backplane", NULL);
+ }
+ else if (0 == strcmp (name, "Pie"))
+ state->plot = gog_plot_new_by_name ("GogPiePlot");
+ else if (0 == strcmp (name, "Bar")) {
+ state->plot = gog_plot_new_by_name ("GogBarColPlot");
+ gog_object_add_by_name (state->chart, "Backplane", NULL);
+ } else if (0 == strcmp (name, "Line")) {
+ state->plot = gog_plot_new_by_name ("GogLinePlot");
+ g_object_set (G_OBJECT (state->plot),
+ "default-style-has-markers", FALSE,
+ NULL);
+ gog_object_add_by_name (state->chart, "Backplane", NULL);
+ }
+ if (state->plot)
+ gog_object_add_by_name (GOG_OBJECT (state->chart), "Plot", GOG_OBJECT (state->plot));
+ }
+}
+
+static void
+series_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *) xin->user_state;
+ int i;
+ char *name = NULL;
+ GError *err = NULL;
+ GOData *data;
+
+ state->cur = GOG_OBJECT (gog_plot_new_series (state->plot));
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "name"))
+ name = g_strdup_printf ("\"%s\"", attrs[i+1]);
+ if (name) {
+ data = g_object_new (GNM_GO_DATA_SCALAR_TYPE, NULL);
+ go_data_unserialize (data, name, (void*) state->convs);
+ gog_dataset_set_dim (GOG_DATASET (state->cur), -1,
+ data, &err);
+ g_free (name);
+ }
+ if (err)
+ g_error_free (err);
+}
+
+static void
+dim_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *) xin->user_state;
+ unsigned i, id = 0;
+ char const *name = NULL;
+ GogMSDimType type = GOG_MS_DIM_LABELS;
+ GogPlotDesc const *desc = gog_plot_description (state->plot);
+ GError *err = NULL;
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "dim_name"))
+ name = attrs[i+1];
+ else if (0 == strcmp (attrs[i], "ID"))
+ id = atoi (attrs[i+1]);
+ if (0 == strcmp (name, "values"))
+ type = GOG_MS_DIM_VALUES;
+ else if (0 == strcmp (name, "categories"))
+ type = GOG_MS_DIM_CATEGORIES;
+ else if (0 == strcmp (name, "bubbles"))
+ type = GOG_MS_DIM_BUBBLES;
+ for (i = 0; i < desc->series.num_dim; i++)
+ if (desc->series.dim[i].ms_type == type) {
+ GOData *data = g_object_ref (g_ptr_array_index (state->data, id));
+ gog_dataset_set_dim (GOG_DATASET (state->cur), i,data,
+ //g_object_ref (g_ptr_array_index (state->data, id)),
+ &err);
+ break;
+ }
+ if (err)
+ g_error_free (err);
+}
+
+static void
+marker_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str && 0 == strcmp (xin->content->str, "true"))
+ g_object_set (G_OBJECT (state->plot), "default-style-has-markers", TRUE, NULL);
+}
+
+static void
+linear_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ g_object_set (G_OBJECT (state->plot),
+ "default-style-has-lines", TRUE,
+ NULL);
+}
+
+static void
+cubic_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ g_object_set (G_OBJECT (state->plot),
+ "default-style-has-lines", TRUE,
+ "use-splines", TRUE,
+ NULL);
+}
+
+static void
+horiz_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str)
+ g_object_set (G_OBJECT (state->plot), "horizontal", 0 == strcmp (xin->content->str, "true"), NULL);
+}
+
+static void
+stacked_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str && 0 == strcmp (xin->content->str, "true"))
+ g_object_set (G_OBJECT (state->plot), "type", "stacked", NULL);
+}
+
+static void
+percent_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str && 0 == strcmp (xin->content->str, "true"))
+ g_object_set (G_OBJECT (state->plot), "type", "as_percentage", NULL);
+}
+
+static void
+separation_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str) {
+ double separation = g_ascii_strtod (xin->content->str, NULL);
+ g_object_set (G_OBJECT (state->plot),
+ "default-separation", separation / 100.,
+ NULL);
+ }
+}
+
+static void
+bubble_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *unknown)
+{
+ GuppiReadState *state = (GuppiReadState *)xin->user_state;
+ if (xin->content->str && 0 == strcmp (xin->content->str, "true")) {
+ g_object_unref (state->plot);
+ state->plot = gog_plot_new_by_name ("GogBubblePlot");
+ gog_object_add_by_name (state->chart, "Backplane", NULL);
+ }
+}
+
+static void
+gnm_sogg_sax_parser_done (GsfXMLIn *xin, GuppiReadState *state)
+{
+ unsigned i;
+ GObject *obj;
+ g_object_unref (state->graph);
+ for (i = 0; i < state->max_data; i++) {
+ obj = (GObject *) g_ptr_array_index (state->data, i);
+ if (obj)
+ g_object_unref (obj);
+ }
+ g_free (state);
+}
+
+static void
+gnm_sogg_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs,
+ GnmConventions const *convs)
+{
+ static GsfXMLInNode const dtd[] = {
+ GSF_XML_IN_NODE (GRAPH, GRAPH, -1, "GmrGraph", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GRAPH, GUPPI_VECTORS, -1, "gmr:Vectors", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_VECTORS, GUPPI_VECTOR, -1, "gmr:Vector", GSF_XML_CONTENT, vector_start, vector_end),
+ GSF_XML_IN_NODE (GRAPH, GUPPI_GRAPH, -1, "graph:Graph", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_GRAPH, GUPPI_LEGEND, -1, "graph:Legend", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_LEGEND, GUPPI_LEGEND_POS, -1, "graph:Position", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_GRAPH, GUPPI_PLOTS, -1, "graph:Plots", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_PLOTS, GUPPI_PLOT, -1, "graph:Plot", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_PLOT, GUPPI_PLOT_TYPE, -1, "Type", GSF_XML_NO_CONTENT, plot_type_start, NULL),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_MARKER, -1, "with_marker", GSF_XML_CONTENT, NULL, marker_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_MARKERS, -1, "with_markers", GSF_XML_CONTENT, NULL, marker_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_LINES, -1, "with_line", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_LINES, GUPPI_PLOT_LINEAR, -1, "Linear", GSF_XML_NO_CONTENT, linear_start, NULL),
+ GSF_XML_IN_NODE (GUPPI_LINES, GUPPI_PLOT_CUBIC, -1, "Cubic", GSF_XML_NO_CONTENT, cubic_start, NULL),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_HORIZONTAL, -1, "horizontal", GSF_XML_CONTENT, NULL, horiz_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_STACKED, -1, "stacked", GSF_XML_CONTENT, NULL, stacked_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_AS_PERCENT, -1, "as_percentage", GSF_XML_CONTENT, NULL, percent_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_SEPARATION, -1, "separation_percent_of_radius", GSF_XML_CONTENT, NULL, separation_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT_TYPE, GUPPI_BUBBLE, -1, "auto_allocate_bubble_size", GSF_XML_CONTENT, NULL, bubble_end),
+ GSF_XML_IN_NODE (GUPPI_PLOT, GUPPI_DATA, -1, "graph:Data", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_DATA, GUPPI_SERIES, -1, "graph:Series", GSF_XML_NO_CONTENT, series_start, NULL),
+ GSF_XML_IN_NODE (GUPPI_SERIES, GUPPI_SERIES_DIM, -1, "graph:Dimension", GSF_XML_NO_CONTENT, dim_start, NULL),
+ GSF_XML_IN_NODE (GUPPI_PLOT, GUPPI_DATA_LAYOUT, -1, "graph:DataLayout", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (GUPPI_DATA_LAYOUT, GUPPI_DIMENSION, -1, "graph:Dimension", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE_END
+ };
+ static GsfXMLInDoc *doc = NULL;
+ GuppiReadState *state;
+ GogTheme *theme = gog_theme_registry_lookup ("Guppi");
+
+ if (NULL == doc)
+ doc = gsf_xml_in_doc_new (dtd, NULL);
+ state = g_new0 (GuppiReadState, 1);
+ state->graph = g_object_new (GOG_TYPE_GRAPH, NULL);
+ gog_graph_set_theme (state->graph, theme);
+ state->chart = gog_object_add_by_name (GOG_OBJECT (state->graph), "Chart", NULL);
+ state->convs = convs;
+ state->data = g_ptr_array_new ();
+ state->max_data = 10;
+ g_ptr_array_set_size (state->data, state->max_data);
+
+ sheet_object_graph_set_gog (so, state->graph);
+ gsf_xml_in_push_state (xin, doc, state,
+ (GsfXMLInExtDtor) gnm_sogg_sax_parser_done, attrs);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]