[gnumeric] xls: export improvements and fixes.



commit 1daae87b4e7f571b5d0084e10937a89bed5f7e07
Author: Morten Welinder <terra gnome org>
Date:   Thu Mar 8 16:48:56 2012 -0500

    xls: export improvements and fixes.

 ChangeLog                        |    3 +
 NEWS                             |    3 +
 plugins/excel/ChangeLog          |   15 +++++
 plugins/excel/ms-chart.c         |    8 +--
 plugins/excel/ms-excel-read.c    |    4 +-
 plugins/excel/ms-excel-write.c   |  113 ++++++++++++++------------------------
 plugins/excel/ms-formula-write.c |    4 +-
 src/expr-name.c                  |    8 +-
 8 files changed, 73 insertions(+), 85 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e431211..95c501c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2012-03-08  Morten Welinder  <terra gnome org>
 
+	* src/expr-name.c (expr_name_set_pos): Make this work even without
+	an existing scope.
+
 	* src/sheet-object-image.c (gnm_soi_new_view): Fix crash.
 
 2012-03-08  Jean Brefort  <jean brefort normalesup org>
diff --git a/NEWS b/NEWS
index 0f5d5d3..3bb1498 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,9 @@ Morten:
 	* Improve xls import of rich text.  [Part of #671513]
 	* Fix rich text export problem with non-ASCII.  [Part of #671513]
 	* Fix crash with images on sheet.
+	* Improve xls image export.   [Part of #671513]
+	* Fix sheet object order on xls export.
+	* Fix xls export for formulas in conditions.  [Part of #671513]
 
 --------------------------------------------------------------------------
 Gnumeric 1.11.2
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 55b91ca..acdc7c9 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,18 @@
+2012-03-08  Morten Welinder  <terra gnome org>
+
+	* ms-formula-write.c (excel_write_formula): Base length
+	calculation on position, not length.  That matters if we have
+	seeked.
+
+	* ms-excel-write.c (excel_write_image_v8): Reimplement based on
+	excel_write_textbox_or_widget_v8.
+	(excel_write_textbox_or_widget_v8): Don't write text style
+	properties unless we have a text.
+	(excel_write_vector_blip, excel_write_raster_blip): Constify.
+
+	* ms-excel-read.c (excel_fill_bmp_header): Fix incorrect use of
+	sizeof.
+
 2012-03-07  Morten Welinder  <terra gnome org>
 
 	* ms-obj.c (ms_obj_read_pre_biff8_obj): Use symbolic object type
diff --git a/plugins/excel/ms-chart.c b/plugins/excel/ms-chart.c
index 9058502..32ca50c 100644
--- a/plugins/excel/ms-chart.c
+++ b/plugins/excel/ms-chart.c
@@ -3229,9 +3229,7 @@ BC(register_handlers)(void)
 static void
 BC(register_handler)(XLChartHandler const *const handle)
 {
-	unsigned const num_handler = sizeof(chart_biff_handler) /
-		sizeof(XLChartHandler *);
-
+	unsigned const num_handler = G_N_ELEMENTS (chart_biff_handler);
 	guint32 num = handle->opcode & 0xff;
 
 	if (num >= num_handler)
@@ -3546,9 +3544,7 @@ ms_excel_chart_read (BiffQuery *q, MSContainer *container,
 		chart_get_sheet,
 		NULL
 	};
-	int const num_handler = sizeof(chart_biff_handler) /
-		sizeof(XLChartHandler *);
-
+	int const num_handler = G_N_ELEMENTS (chart_biff_handler);
 	int i;
 	gboolean done = FALSE;
 	XLChartReadState state;
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 35cd513..885d9be 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -499,7 +499,7 @@ static void excel_fill_bmp_header(guint8 *bmphdr, guint8 *data, guint32 len)
 
 	bmphdr[0] = 'B';
 	bmphdr[1] = 'M';
-	GSF_LE_SET_GUINT32 (bmphdr + 2, len + sizeof bmphdr);
+	GSF_LE_SET_GUINT32 (bmphdr + 2, len + BMP_HDR_SIZE);
 	GSF_LE_SET_GUINT16 (bmphdr + 6, 0);
 	GSF_LE_SET_GUINT16 (bmphdr + 8, 0);
 	bpp = GSF_LE_GET_GUINT16 (data + 18);
@@ -509,7 +509,7 @@ static void excel_fill_bmp_header(guint8 *bmphdr, guint8 *data, guint32 len)
 	case 4:  offset = 16 * 3;  break;
 	default: offset = 2 * 3;   break;
 	}
-	offset += sizeof bmphdr + 12;
+	offset += BMP_HDR_SIZE + 2;
 	GSF_LE_SET_GUINT32 (bmphdr + 10, offset);
 }
 
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 55f243d..4a2ef70 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -111,7 +111,7 @@ struct _BlipType {
 	guint8 blip_tag[2];
 	void (*handler) (ExcelWriteState *ewb,
 			 BlipInf *blip,
-			 BlipType *bt);
+			 const BlipType *bt);
 };
 
 /*
@@ -918,8 +918,7 @@ map_script_to_xl (GnmStyle const *style)
 	}
 }
 
-static guint8 const zeros[64];
-static void
+void
 cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
 		    ExcelWriteSheet *esheet)
 {
@@ -3884,11 +3883,7 @@ static void
 excel_write_autofilter_names (ExcelWriteState *ewb)
 {
 	unsigned i;
-	GnmNamedExpr *nexpr;
 
-	nexpr = expr_name_new ("_FilterDatabase");
-	nexpr->is_hidden = TRUE;
-	expr_name_set_is_placeholder (nexpr, FALSE);
 	for (i = 0; i < ewb->esheets->len; i++) {
 		ExcelWriteSheet const *esheet =
 			g_ptr_array_index (ewb->esheets, i);
@@ -3896,6 +3891,9 @@ excel_write_autofilter_names (ExcelWriteState *ewb)
 		if (sheet->filters != NULL) {
 			GnmFilter const *filter = sheet->filters->data;
 			GnmParsePos pp;
+			GnmNamedExpr *nexpr = expr_name_new ("_FilterDatabase");
+			nexpr->is_hidden = TRUE;
+			expr_name_set_is_placeholder (nexpr, FALSE);
 			parse_pos_init_sheet (&pp, sheet);
 			expr_name_set_pos (nexpr, &pp);
 			expr_name_set_expr (nexpr,
@@ -3906,9 +3904,9 @@ excel_write_autofilter_names (ExcelWriteState *ewb)
 			if (NULL != sheet->filters->next) {
 				/* TODO Warn of lost autofilters */
 			}
+			expr_name_remove (nexpr);
 		}
 	}
-	expr_name_unref (nexpr);
 }
 
 static void
@@ -4180,50 +4178,6 @@ blipinf_free (BlipInf *blip)
 }
 
 static gsize
-excel_write_image_v8 (ExcelWriteSheet *esheet, BlipInf *bi)
-{
-	static guint8 const obj_v8[] = {
-/* SpContainer */   0xf,   0,   4, 0xf0,   0x4c, 0, 0, 0,
-/* Sp */	   0xb2,   4, 0xa, 0xf0,      8, 0, 0, 0,
-			0,   0, 0, 0,	/* fill in spid */
-			0, 0xa, 0, 0,
-
-/* OPT */	   0x33,   0, 0xb, 0xf0,   0x12, 0, 0, 0,
-			0x7f,    0, 0x80,  0, 0x80, 0, /* bool   LockAgainstGrouping 127 = 0x800080; */
-			   4, 0x41,    1, 0,     0, 0, /* blip x is blip (fill in); */
-			0x80,    1,    3, 0,     0, 0, /* FillType fillType 384 = 0x3; */
-
-/* ClientAnchor */    0, 0, 0x10, 0xf0,   0x12, 0, 0, 0, 0,0,
-			0,0,  0,0,	0,0,  0,0,	0,0,  0,0,	0,0,  0,0,
-/* ClientData */      0, 0, 0x11, 0xf0,  0, 0, 0, 0
-	};
-	guint8 buf [sizeof obj_v8];
-	ExcelWriteState *ewb = esheet->ewb;
-	BiffPut *bp = ewb->bp;
-	guint32 id = excel_write_start_drawing (esheet);
-	guint32 blip_id = ewb->cur_blip + 1;
-	gsize draw_len = 0;
-
-	memcpy (buf, obj_v8, sizeof obj_v8);
-	GSF_LE_SET_GUINT32 (buf + 16, id);
-	GSF_LE_SET_GUINT32 (buf + 40, blip_id);
-	excel_write_anchor (buf + 0x3c, sheet_object_get_anchor (bi->so));
-	ms_biff_put_var_write (bp, buf, sizeof obj_v8);
-	draw_len += sizeof (obj_v8);
-	ms_biff_put_commit (bp);
-
-	ms_biff_put_var_next (bp, BIFF_OBJ);
-	ms_objv8_write_common (bp, esheet->cur_obj, MSOT_PICTURE, 0x6011);
-	GSF_LE_SET_GUINT32 (buf, 0); /* end */
-	ms_biff_put_var_write (bp, buf, 4);
-
-	ms_biff_put_commit (bp);
-	ewb->cur_blip++;
-
-	return draw_len;
-}
-
-static gsize
 excel_write_ClientTextbox (ExcelWriteState *ewb, SheetObject *so,
 			   const char *label)
 {
@@ -4319,6 +4273,7 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 	GnmNamedExpr *macro_nexpr;
 	gboolean terminate_obj = TRUE;
 	gboolean transparent = FALSE;
+	gboolean is_image = FALSE;
 
 	if (has_text_prop) {
 		g_object_get (so,
@@ -4400,6 +4355,11 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 		shape = 0xc9;
 		type = MSOT_COMBO;
 		flags = 0x2011;
+	} else if (IS_SHEET_OBJECT_IMAGE (so)) {
+		shape = 0x4b;
+		type = MSOT_PICTURE;
+		flags = 0x6011;
+		is_image = TRUE;
 	} else {
 		g_assert_not_reached ();
 		return 0;
@@ -4414,13 +4374,18 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 	if (is_widget)
 		ms_escher_opt_add_bool (escher, optmark,
 					MSEP_LOCKROTATION, TRUE);
-	ms_escher_opt_add_simple (escher, optmark,
-				  MSEP_TXID, 0x00c600a0);
-	ms_escher_opt_add_simple (escher, optmark,
-				  MSEP_WRAPTEXT, 1);
-	ms_escher_opt_add_simple (escher, optmark,
-				  MSEP_TXDIR, 2);
-	ms_escher_opt_add_bool (escher, optmark, MSEP_SELECTTEXT, TRUE);
+	if (is_image)
+		ms_escher_opt_add_bool (escher, optmark,
+					MSEP_LOCKASPECTRATIO, TRUE);
+	if (has_text_prop) {
+		ms_escher_opt_add_simple (escher, optmark,
+					  MSEP_TXID, 0x00c600a0);
+		ms_escher_opt_add_simple (escher, optmark,
+					  MSEP_WRAPTEXT, 1);
+		ms_escher_opt_add_simple (escher, optmark,
+					  MSEP_TXDIR, 2);
+		ms_escher_opt_add_bool (escher, optmark, MSEP_SELECTTEXT, TRUE);
+	}
 	if (is_widget) {
 		ms_escher_opt_add_bool (escher, optmark, MSEP_AUTOTEXTMARGIN, FALSE);
 		ms_escher_opt_add_bool (escher, optmark, MSEP_SHADOWOK, TRUE);
@@ -4428,6 +4393,10 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 		ms_escher_opt_add_bool (escher, optmark, MSEP_FILLOK, TRUE);
 	} else if (transparent)
 		ms_escher_opt_add_bool (escher, optmark, MSEP_FILLOK, FALSE);
+	if (is_image) {
+		guint32 blip_id = ++(ewb->cur_blip);
+		ms_escher_opt_add_simple (escher, optmark, MSEP_BLIPINDEX, blip_id);
+	}
 	ms_escher_opt_add_color (escher, optmark, MSEP_FILLCOLOR,
 				 style == NULL || style->fill.auto_back
 				 ? GO_COLOR_WHITE
@@ -4587,6 +4556,12 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 }
 
 static gsize
+excel_write_image_v8 (ExcelWriteSheet *esheet, BlipInf *bi)
+{
+	return excel_write_textbox_or_widget_v8 (esheet, bi->so, FALSE, FALSE);
+}
+
+static gsize
 excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 {
 	return excel_write_textbox_or_widget_v8 (esheet, so, TRUE, FALSE);
@@ -5619,12 +5594,8 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 	}
 	g_slist_free (objs);
 
-	esheet->blips = g_slist_reverse (esheet->blips);
-	esheet->textboxes = g_slist_reverse (esheet->textboxes);
-	esheet->widgets = g_slist_reverse (esheet->widgets);
-	esheet->lines = g_slist_reverse (esheet->lines);
-	esheet->comments = g_slist_reverse (esheet->comments);
-	esheet->graphs = g_slist_reverse (esheet->graphs);
+	/* We used to reserve the lists here, but we actually need
+	   to write the objects in reverse order for xls.  */
 
 	/* ---------------------------------------- */
 
@@ -5920,7 +5891,7 @@ excel_write_image_bytes (BiffPut *bp, GByteArray *bytes)
  *        OpenOffice.org can read the images.
  */
 static void
-excel_write_vector_blip (ExcelWriteState *ewb, BlipInf *blip, BlipType *bt)
+excel_write_vector_blip (ExcelWriteState *ewb, BlipInf *blip, const BlipType *bt)
 {
 	BiffPut	 *bp = ewb->bp;
 
@@ -5982,7 +5953,7 @@ excel_write_vector_blip (ExcelWriteState *ewb, BlipInf *blip, BlipType *bt)
 }
 
 static void
-excel_write_raster_blip (ExcelWriteState *ewb, BlipInf *blip, BlipType *bt)
+excel_write_raster_blip (ExcelWriteState *ewb, BlipInf *blip, const BlipType *bt)
 {
 	BiffPut	 *bp = ewb->bp;
 
@@ -6003,7 +5974,7 @@ excel_write_raster_blip (ExcelWriteState *ewb, BlipInf *blip, BlipType *bt)
 	}
 }
 
-static BlipType bliptypes[] =
+static const BlipType bliptypes[] =
 {
 	{"emf",  2, {0x40, 0x3d}, excel_write_vector_blip},
 	{"wmf",  3, {0x60, 0x21}, excel_write_vector_blip},
@@ -6013,10 +5984,10 @@ static BlipType bliptypes[] =
 	{"dib",  7, {0x80, 0x7a}, excel_write_raster_blip}
 };
 
-static BlipType *
+static const BlipType *
 get_bliptype (char const *type)
 {
-	int n = sizeof bliptypes / sizeof bliptypes[0];
+	int n = G_N_ELEMENTS (bliptypes);
 	int i;
 
 	for (i = 0; i < n; i++)
@@ -6028,7 +5999,7 @@ static void
 excel_write_blip (ExcelWriteState *ewb, BlipInf *blip)
 {
 	BiffPut	 *bp = ewb->bp;
-	BlipType *bt;
+	const BlipType *bt;
 
 	if (bp->version >= MS_BIFF_V8) {
 		static guint8 const header_obj_v8[] = {
diff --git a/plugins/excel/ms-formula-write.c b/plugins/excel/ms-formula-write.c
index 32e3e71..2e252a4 100644
--- a/plugins/excel/ms-formula-write.c
+++ b/plugins/excel/ms-formula-write.c
@@ -1013,9 +1013,9 @@ excel_write_formula (ExcelWriteState *ewb, GnmExprTop const *texpr,
 		pd.use_name_variant = TRUE;
 	}
 
-	start = ewb->bp->length;
+	start = ewb->bp->curpos;
 	write_node (&pd, texpr->expr, 0, XL_ROOT);
-	len = ewb->bp->length - start;
+	len = ewb->bp->curpos - start;
 
 	write_arrays (&pd);
 
diff --git a/src/expr-name.c b/src/expr-name.c
index a99edc2..db287ba 100644
--- a/src/expr-name.c
+++ b/src/expr-name.c
@@ -837,7 +837,6 @@ expr_name_set_pos (GnmNamedExpr *nexpr, GnmParsePos const *pp)
 	const char *name;
 
 	g_return_val_if_fail (nexpr != NULL, NULL);
-	g_return_val_if_fail (nexpr->scope != NULL, NULL);
 	g_return_val_if_fail (pp != NULL, NULL);
 
 	old_scope = nexpr->scope;
@@ -853,9 +852,10 @@ expr_name_set_pos (GnmNamedExpr *nexpr, GnmParsePos const *pp)
 		return g_strdup_printf (fmt, name);
 	}
 
-	g_hash_table_steal (
-		nexpr->is_placeholder ? old_scope->placeholders : old_scope->names,
-		name);
+	if (old_scope)
+		g_hash_table_steal
+			(nexpr->is_placeholder ? old_scope->placeholders : old_scope->names,
+			 name);
 
 	nexpr->pos = *pp;
 	gnm_named_expr_collection_insert (new_scope, nexpr);



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