[gnumeric] xlsx: initial export of sheet widgets.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] xlsx: initial export of sheet widgets.
- Date: Sat, 7 Feb 2015 03:12:16 +0000 (UTC)
commit 9e48bfff141f3a6aef0175a5c93ffff6606ef55f
Author: Morten Welinder <terra gnome org>
Date: Fri Feb 6 22:11:59 2015 -0500
xlsx: initial export of sheet widgets.
NEWS | 1 +
plugins/excel/ChangeLog | 5 +
plugins/excel/xlsx-write-drawing.c | 166 +++++++++++++++++++++++++++++------
plugins/excel/xlsx-write.c | 43 +++++++---
4 files changed, 175 insertions(+), 40 deletions(-)
---
diff --git a/NEWS b/NEWS
index 211c0dd..da6256e 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Gnumeric 1.12.21
Morten:
* Initial xlsx import of sheet widgets.
+ * Initial xlsx export of sheet widgets.
--------------------------------------------------------------------------
Gnumeric 1.12.20
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 9a84d24..f3bf8fc 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,5 +1,10 @@
2015-02-06 Morten Welinder <terra gnome org>
+ * xlsx-write.c (xlsx_write_sheet): Handle sheet widgets.
+
+ * xlsx-write-drawing.c (xlsx_write_legacy_drawing_objects): First
+ cut at writing sheet widgets.
+
* xlsx-read-drawing.c (xlsx_vml_client_data_start)
(xlsx_vml_client_data_end): First attempt at reading scrollbars,
radio buttons, checkboxes, buttons, and spin buttons.
diff --git a/plugins/excel/xlsx-write-drawing.c b/plugins/excel/xlsx-write-drawing.c
index 52ae7a5..ecef44b 100644
--- a/plugins/excel/xlsx-write-drawing.c
+++ b/plugins/excel/xlsx-write-drawing.c
@@ -949,16 +949,14 @@ xlsx_write_object_anchor (GsfXMLOut *xml, GnmCellPos const *pos, char const *ele
}
static char const *
-xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objects)
+xlsx_write_drawing_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objects)
{
- GSList *obj, *chart_id, *chart_ids = NULL;
- char *name, *tmp;
- char const *rId, *rId1;
+ GSList *obj, *rId_ptr, *rIds = NULL;
+ char *name;
+ char const *rId;
int count = 1;
- GsfOutput *drawing_part, *chart_part;
+ GsfOutput *drawing_part;
GsfXMLOut *xml;
- SheetObjectAnchor const *anchor;
- double res_pts[4] = {0.,0.,0.,0.};
if (NULL == state->drawing.dir)
state->drawing.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "drawings", TRUE);
@@ -972,33 +970,53 @@ xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *object
g_free (name);
rId = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (drawing_part),
- GSF_OUTFILE_OPEN_PKG (sheet_part), ns_rel_draw);
+ GSF_OUTFILE_OPEN_PKG (sheet_part),
+ ns_rel_draw);
- objects = sheet_objects_get (state->sheet, NULL, SHEET_OBJECT_GRAPH_TYPE);
for (obj = objects ; obj != NULL ; obj = obj->next) {
- char *name = g_strdup_printf ("chart%u.xml", ++state->chart.count);
- chart_part = gsf_outfile_new_child_full (state->chart.dir, name, FALSE,
- "content-type", "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
- NULL);
- g_free (name);
- rId1 = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (chart_part),
- GSF_OUTFILE_OPEN_PKG (drawing_part), ns_rel_chart);
+ SheetObject *so = obj->data;
+ const char *rId1;
+
+ if (IS_SHEET_OBJECT_GRAPH (so)) {
+ char *name = g_strdup_printf ("chart%u.xml", ++state->chart.count);
+ GsfOutput *chart_part = gsf_outfile_new_child_full
+ (state->chart.dir, name, FALSE,
+ "content-type",
+ "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+ NULL);
+ g_free (name);
+ rId1 = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (chart_part),
+ GSF_OUTFILE_OPEN_PKG (drawing_part),
+ ns_rel_chart);
- chart_ids = g_slist_prepend (chart_ids, (gpointer)rId1);
+ xlsx_write_chart (state, chart_part, so);
+ gsf_output_close (chart_part);
+ g_object_unref (chart_part);
+ } else {
+ rId1 = NULL;
+ }
- xlsx_write_chart (state, chart_part, obj->data);
- gsf_output_close (chart_part);
- g_object_unref (chart_part);
+ rIds = g_slist_prepend (rIds, (gpointer)rId1);
}
+ rIds = g_slist_reverse (rIds);
xml = gsf_xml_out_new (drawing_part);
gsf_xml_out_start_element (xml, "xdr:wsDr");
gsf_xml_out_add_cstr_unchecked (xml, "xmlns:xdr", ns_ss_drawing);
gsf_xml_out_add_cstr_unchecked (xml, "xmlns:a", ns_drawing);
- chart_id = g_slist_reverse (chart_ids);
- for (obj = objects; obj != NULL ; obj = obj->next, chart_id = chart_id->next) {
- anchor = sheet_object_get_anchor (obj->data);
+ for (obj = objects, rId_ptr = rIds;
+ obj != NULL ;
+ obj = obj->next, rId_ptr = rId_ptr->next) {
+ SheetObject *so = obj->data;
+ const char *rId1 = rId_ptr->data;
+ SheetObjectAnchor const *anchor = sheet_object_get_anchor (so);
+ double res_pts[4] = {0.,0.,0.,0.};
+ char *tmp;
+
+ if (!rId1)
+ continue;
+
sheet_object_anchor_to_offset_pts (anchor, state->sheet, res_pts);
gsf_xml_out_start_element (xml, "xdr:twoCellAnchor");
@@ -1014,10 +1032,9 @@ xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *object
gsf_xml_out_start_element (xml, "xdr:cNvPr");
gsf_xml_out_add_int (xml, "id", count+1);
- gsf_xml_out_add_cstr_unchecked (xml, "name",
- (tmp = g_strdup_printf ("Chart %d", count)));
+ tmp = g_strdup_printf ("Chart %d", count++);
+ gsf_xml_out_add_cstr_unchecked (xml, "name", tmp);
g_free (tmp);
- count++;
gsf_xml_out_end_element (xml);
gsf_xml_out_simple_element (xml, "xdr:cNvGraphicFramePr", NULL);
@@ -1044,7 +1061,7 @@ xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *object
gsf_xml_out_add_cstr_unchecked (xml, "xmlns:c", ns_chart);
gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel);
- gsf_xml_out_add_cstr_unchecked (xml, "r:id", chart_id->data);
+ gsf_xml_out_add_cstr_unchecked (xml, "r:id", rId1);
gsf_xml_out_end_element (xml); /* </c:chart> */
gsf_xml_out_end_element (xml); /* </a:graphicData> */
gsf_xml_out_end_element (xml); /* </a:graphic> */
@@ -1052,8 +1069,7 @@ xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *object
gsf_xml_out_simple_element (xml, "xdr:clientData", NULL);
gsf_xml_out_end_element (xml); /* </xdr:twoCellAnchor> */
}
- g_slist_free (objects);
- g_slist_free (chart_ids);
+ g_slist_free (rIds);
gsf_xml_out_end_element (xml); /* </wsDr> */
g_object_unref (xml);
@@ -1062,3 +1078,95 @@ xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *object
return rId;
}
+
+static char const *
+xlsx_write_legacy_drawing_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objects)
+{
+ GSList *obj;
+ char *name;
+ char const *rId;
+ GsfOutput *drawing_part;
+ GsfXMLOut *xml;
+ GnmParsePos pp0;
+
+ parse_pos_init_sheet (&pp0, state->sheet);
+
+ /* Note: we use drawing.dir here. */
+ if (NULL == state->drawing.dir)
+ state->drawing.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "drawings", TRUE);
+
+ name = g_strdup_printf ("vmlDrawing%u.vml", ++state->legacy_drawing.count);
+ drawing_part = gsf_outfile_new_child_full (state->drawing.dir, name, FALSE, NULL);
+ g_free (name);
+
+ rId = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (drawing_part),
+ GSF_OUTFILE_OPEN_PKG (sheet_part),
+ ns_rel_leg_draw);
+
+ xml = gsf_xml_out_new (drawing_part);
+ gsf_xml_out_start_element (xml, "xml");
+ gsf_xml_out_add_cstr_unchecked (xml, "xmlns:v", ns_vml);
+ gsf_xml_out_add_cstr_unchecked (xml, "xmlns:o", ns_leg_office);
+ gsf_xml_out_add_cstr_unchecked (xml, "xmlns:x", ns_leg_excel);
+
+ for (obj = objects ; obj != NULL ; obj = obj->next) {
+ SheetObject *so = obj->data;
+ const char *otype = NULL;
+ GnmExprTop const *tlink = NULL;
+ double res_pts[4] = {0.,0.,0.,0.};
+ GtkAdjustment *adj = NULL;
+ sheet_object_position_pts_get (so, res_pts);
+
+ gsf_xml_out_start_element (xml, "v:shape");
+ {
+ GString *str = g_string_new (NULL);
+ g_string_append (str, "position:absolute;");
+ g_string_append_printf (str, "margin-left:%.2fpt;", res_pts[0]);
+ g_string_append_printf (str, "margin-top:%.2fpt;", res_pts[1]);
+ g_string_append_printf (str, "width:%.2fpt;", res_pts[2] - res_pts[0]);
+ g_string_append_printf (str, "height:%.2fpt;", res_pts[3] - res_pts[1]);
+ gsf_xml_out_add_cstr (xml, "style", str->str);
+ g_string_free (str, TRUE);
+ }
+
+ gsf_xml_out_start_element (xml, "x:ClientData");
+ if (GNM_IS_SOW_SCROLLBAR (so)) {
+ otype = "Scroll";
+ tlink = sheet_widget_adjustment_get_link (so);
+ adj = sheet_widget_adjustment_get_adjustment (so);
+ }
+ gsf_xml_out_add_cstr_unchecked (xml, "ObjectType", otype);
+ gsf_xml_out_start_element (xml, "x:Anchor");
+ gsf_xml_out_end_element (xml); /* </x:Anchor> */
+ if (tlink) {
+ char *s = gnm_expr_top_as_string (tlink, &pp0, state->convs);
+ gsf_xml_out_start_element (xml, "x:FmlaLink");
+ gsf_xml_out_add_cstr (xml, NULL, s);
+ gsf_xml_out_end_element (xml); /* </x:FmlaLink> */
+ g_free (s);
+ gnm_expr_top_unref (tlink);
+ }
+ if (adj) {
+ gsf_xml_out_simple_float_element (xml, "x:Val",
+ gtk_adjustment_get_value (adj), -1);
+ gsf_xml_out_simple_float_element (xml, "x:Min",
+ gtk_adjustment_get_lower (adj), -1);
+ gsf_xml_out_simple_float_element (xml, "x:Max",
+ gtk_adjustment_get_upper (adj), -1);
+ gsf_xml_out_simple_float_element (xml, "x:Inc",
+ gtk_adjustment_get_step_increment (adj), -1);
+ gsf_xml_out_simple_float_element (xml, "x:Page",
+ gtk_adjustment_get_page_increment (adj), -1);
+ }
+ gsf_xml_out_end_element (xml); /* </x:ClientData> */
+
+ gsf_xml_out_end_element (xml); /* </v:shape> */
+ }
+
+ gsf_xml_out_end_element (xml); /* </xml> */
+ g_object_unref (xml);
+ gsf_output_close (drawing_part);
+ g_object_unref (drawing_part);
+
+ return rId;
+}
diff --git a/plugins/excel/xlsx-write.c b/plugins/excel/xlsx-write.c
index be56468..4e87b8c 100644
--- a/plugins/excel/xlsx-write.c
+++ b/plugins/excel/xlsx-write.c
@@ -52,6 +52,7 @@
#include "sheet-object.h"
#include "sheet-object-cell-comment.h"
#include "sheet-object-graph.h"
+#include "sheet-object-widget.h"
#include "graph.h"
#include "style-border.h"
#include "style-conditions.h"
@@ -93,9 +94,14 @@ static char const *ns_docprops_extended_vt = "http://schemas.openxmlformats.or
static char const *ns_docprops_custom =
"http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
static char const *ns_drawing = "http://schemas.openxmlformats.org/drawingml/2006/main";
static char const *ns_chart = "http://schemas.openxmlformats.org/drawingml/2006/chart";
+static char const *ns_vml = "urn:schemas-microsoft-com:vml";
+static char const *ns_leg_office = "urn:schemas-microsoft-com:office:office";
+static char const *ns_leg_excel = "urn:schemas-microsoft-com:office:excel";
+
static char const *ns_rel = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
static char const *ns_rel_hlink =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
static char const *ns_rel_draw =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
+static char const *ns_rel_leg_draw =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
static char const *ns_rel_chart =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
static char const *ns_rel_com =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
@@ -119,7 +125,7 @@ typedef struct {
struct {
unsigned int count;
GsfOutfile *dir;
- } chart, drawing, pivotCache, pivotTable;
+ } chart, drawing, legacy_drawing, pivotCache, pivotTable;
unsigned comment;
GOFormat *date_fmt;
@@ -2683,8 +2689,9 @@ xlsx_write_sheet (XLSXWriteState *state, GsfOutfile *dir, GsfOutfile *wb_part, u
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet");
GsfXMLOut *xml;
GnmRange extent, cell_extent;
- GSList *charts, *comments, *others, *objects, *p;
+ GSList *drawing_objs, *legacy_drawing_objs, *comments, *others, *objects, *p;
char const *chart_drawing_rel_id = NULL;
+ char const *legacy_drawing_rel_id = NULL;
GnmStyle **col_styles;
PrintInformation *pi = NULL;
@@ -2696,13 +2703,15 @@ xlsx_write_sheet (XLSXWriteState *state, GsfOutfile *dir, GsfOutfile *wb_part, u
extent = range_union (&extent, &cell_extent);
objects = sheet_objects_get (state->sheet, NULL, G_TYPE_NONE);
- charts = comments = others = NULL;
+ drawing_objs = legacy_drawing_objs = comments = others = NULL;
for (p = objects; p; p = p->next) {
SheetObject *so = p->data;
if (IS_CELL_COMMENT (so))
comments = g_slist_prepend (comments, so);
else if (IS_SHEET_OBJECT_GRAPH (so))
- charts = g_slist_prepend (charts, so);
+ drawing_objs = g_slist_prepend (drawing_objs, so);
+ else if (GNM_IS_SOW_SCROLLBAR (so))
+ legacy_drawing_objs = g_slist_prepend (legacy_drawing_objs, so);
else if (IS_GNM_FILTER_COMBO (so))
; /* Nothing here */
else
@@ -2710,16 +2719,22 @@ xlsx_write_sheet (XLSXWriteState *state, GsfOutfile *dir, GsfOutfile *wb_part, u
}
g_slist_free (objects);
- comments = g_slist_reverse (comments);
if (comments) {
+ comments = g_slist_reverse (comments);
xlsx_write_comments (state, sheet_part, comments);
g_slist_free (comments);
}
- charts = g_slist_reverse (charts);
- if (charts) {
- chart_drawing_rel_id = xlsx_write_objects (state, sheet_part, charts);
- g_slist_free (charts);
+ if (drawing_objs) {
+ drawing_objs = g_slist_reverse (drawing_objs);
+ chart_drawing_rel_id = xlsx_write_drawing_objects (state, sheet_part, drawing_objs);
+ g_slist_free (drawing_objs);
+ }
+
+ if (legacy_drawing_objs) {
+ legacy_drawing_objs = g_slist_reverse (legacy_drawing_objs);
+ legacy_drawing_rel_id = xlsx_write_legacy_drawing_objects (state, sheet_part,
legacy_drawing_objs);
+ g_slist_free (legacy_drawing_objs);
}
for (p = others; p; p = p->next) {
@@ -2817,6 +2832,11 @@ xlsx_write_sheet (XLSXWriteState *state, GsfOutfile *dir, GsfOutfile *wb_part, u
gsf_xml_out_end_element (xml); /* </drawing> */
}
/* element legacyDrawing { CT_LegacyDrawing }?, Deleted in edition 2 */
+ if (NULL != legacy_drawing_rel_id) {
+ gsf_xml_out_start_element (xml, "legacyDrawing");
+ gsf_xml_out_add_cstr_unchecked (xml, "r:id", legacy_drawing_rel_id);
+ gsf_xml_out_end_element (xml); /* </legacyDrawing> */
+ }
/* element legacyDrawingHF { CT_LegacyDrawing }?, Deleted in edition 2 */
/* element picture { CT_SheetBackgroundPicture }?, */
/* element oleObjects { CT_OleObjects }?, */
@@ -2951,8 +2971,8 @@ xlsx_write_workbook (XLSXWriteState *state, GsfOutfile *root_part)
gnm_style_unref (style);
state->convs = xlsx_conventions_new (TRUE);
- state->chart.dir = state->drawing.dir = NULL;
- state->chart.count = state->drawing.count = 0;
+ state->chart.dir = state->drawing.dir = state->legacy_drawing.dir = NULL;
+ state->chart.count = state->drawing.count = state->legacy_drawing.count = 0;
g_ptr_array_set_size (sheetIds, workbook_sheet_count (state->base.wb));
for (i = 0 ; i < workbook_sheet_count (state->base.wb); i++)
@@ -3049,6 +3069,7 @@ xlsx_write_workbook (XLSXWriteState *state, GsfOutfile *root_part)
gsf_output_close (GSF_OUTPUT (state->chart.dir));
if (NULL != state->drawing.dir)
gsf_output_close (GSF_OUTPUT (state->drawing.dir));
+ /* legacy_drawing.dir is unused */
gsf_output_close (GSF_OUTPUT (wb_part));
g_ptr_array_free (sheetIds, TRUE);
gsf_output_close (GSF_OUTPUT (sheet_dir));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]