[gnumeric] xls: improve object export.



commit 4a49dc5a2619d220d1b2f35f3881f1fb0829e8a2
Author: Morten Welinder <terra gnome org>
Date:   Mon Oct 5 14:48:59 2009 -0400

    xls: improve object export.

 ChangeLog                      |    6 ++
 plugins/excel/ChangeLog        |    2 +
 plugins/excel/ms-biff.c        |   18 +++++
 plugins/excel/ms-biff.h        |    4 +-
 plugins/excel/ms-escher.c      |   24 ++++++-
 plugins/excel/ms-escher.h      |    2 +
 plugins/excel/ms-excel-read.c  |    3 +-
 plugins/excel/ms-excel-write.c |  143 +++++++++++++++++++++++++++------------
 plugins/excel/ms-excel-write.h |    2 +-
 plugins/excel/ms-obj.c         |    3 +-
 10 files changed, 157 insertions(+), 50 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b007552..ea55d77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-10-05  Morten Welinder  <terra gnome org>
+
+	* plugins/excel/ms-excel-write.c (excel_write_textbox_v8): Export
+	object name.
+	(excel_sheet_new): Prepare for handling lines.
+
 2009-10-04  Morten Welinder  <terra gnome org>
 
 	* src/gnm-so-filled.c (gnm_so_filled_init): Make is-oval readable.
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 598a64b..bd4cd7c 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,5 +1,7 @@
 2009-10-05  Morten Welinder  <terra gnome org>
 
+	* ms-biff.h (_BiffPut): Change type of streamPos to gsf_off_t.
+
 	* ms-chart.c (chart_write_axis): Don't dump uninitialized memory
 	into file.
 
diff --git a/plugins/excel/ms-biff.c b/plugins/excel/ms-biff.c
index 6bb17e1..b8e003f 100644
--- a/plugins/excel/ms-biff.c
+++ b/plugins/excel/ms-biff.c
@@ -760,6 +760,15 @@ ms_biff_put_commit (BiffPut *bp)
 		g_warning ("Spurious commit");
 	}
 	bp->len_fixed = -1;
+
+	if (0) {
+		/*
+		 * This is useful to figure out who writes uninitialized
+		 * memory to files.  It causes layers below to flush.
+		 */
+		gsf_output_seek (bp->output, -1, G_SEEK_CUR);
+		gsf_output_seek (bp->output, +1, G_SEEK_CUR);
+	}
 }
 
 void
@@ -776,3 +785,12 @@ ms_biff_put_2byte (BiffPut *bp, guint16 opcode, guint16 content)
 	GSF_LE_SET_GUINT16 (data, content);
 	ms_biff_put_commit (bp);
 }
+
+void
+ms_biff_put_abs_write (BiffPut *bp, gsf_off_t pos, gconstpointer buf, gsize size)
+{
+	gsf_off_t old = gsf_output_tell (bp->output);
+	gsf_output_seek (bp->output, pos, G_SEEK_SET);
+	gsf_output_write (bp->output, size, buf);
+	gsf_output_seek (bp->output, old, G_SEEK_SET);
+}
diff --git a/plugins/excel/ms-biff.h b/plugins/excel/ms-biff.h
index 250376d..99fd84b 100644
--- a/plugins/excel/ms-biff.h
+++ b/plugins/excel/ms-biff.h
@@ -78,7 +78,7 @@ typedef struct _BiffPut {
 	guint16		 opcode;
 	guint32		 length; /* NB. can be extended by a continue opcode */
 	guint8		*data;
-	int		 streamPos;
+	gsf_off_t	 streamPos;
 	unsigned	 curpos; /* Curpos is offset from beginning of header */
 	gboolean	 data_malloced;
 	int		 len_fixed;
@@ -117,4 +117,6 @@ void     ms_biff_put_2byte   (BiffPut *bp, guint16 opcode, guint16 data);
 
 unsigned ms_biff_max_record_len (BiffPut const *bp);
 
+void ms_biff_put_abs_write (BiffPut *bp, gsf_off_t pos, gconstpointer buf, gsize size);
+
 #endif /* GNM_BIFF_H */
diff --git a/plugins/excel/ms-escher.c b/plugins/excel/ms-escher.c
index 04ce555..3ff3758 100644
--- a/plugins/excel/ms-escher.c
+++ b/plugins/excel/ms-escher.c
@@ -165,7 +165,7 @@ ms_escher_get_data (MSEscherState *state,
 		    q->opcode != BIFF_MS_O_DRAWING_SELECTION &&
 		    q->opcode != BIFF_CHART_gelframe &&
 		    q->opcode != BIFF_CONTINUE) {
-			g_warning ("Unexpected record type 0x%x len=0x%x @ 0x%x;", q->opcode, q->length, q->streamPos);
+		  g_warning ("Unexpected record type 0x%x len=0x%x @ 0x%lx;", q->opcode, q->length, (long)q->streamPos);
 			return NULL;
 		}
 
@@ -214,7 +214,7 @@ ms_escher_get_data (MSEscherState *state,
 			    q->opcode != BIFF_MS_O_DRAWING_SELECTION &&
 			    q->opcode != BIFF_CHART_gelframe &&
 			    q->opcode != BIFF_CONTINUE) {
-				g_warning ("Unexpected record type 0x%x @ 0x%x;", q->opcode, q->streamPos);
+			  g_warning ("Unexpected record type 0x%x @ 0x%lx;", q->opcode, (long)q->streamPos);
 				return NULL;
 			}
 
@@ -2260,6 +2260,26 @@ ms_escher_opt_add_simple (GString *buf, gsize marker, guint16 pid, gint32 val)
 }
 
 void
+ms_escher_opt_add_str_wchar (GString *buf, gsize marker, GString *extra,
+			     guint16 pid, const char *str)
+{
+	gsize ic;
+	gunichar2 *str16 = g_utf8_to_utf16 (str, -1, NULL, &ic, NULL);
+	guint8 tmp[6];
+
+	GSF_LE_SET_GUINT16 (tmp, pid | 0x8000);
+	GSF_LE_SET_GUINT32 (tmp + 2, ic * 2 + 2);
+	g_string_append_len (buf, tmp, sizeof tmp);
+	g_string_append_len (extra, (gpointer)str16, ic * 2 + 2);
+
+	g_free (str16);
+
+	ms_escher_set_inst (buf, marker,
+			    ms_escher_get_inst (buf, marker) + 1);
+}
+
+
+void
 ms_escher_clientanchor (GString *buf, SheetObjectAnchor const *anchor)
 {
 	guint8 tmp[26] = {
diff --git a/plugins/excel/ms-escher.h b/plugins/excel/ms-escher.h
index 9c87655..8bb9c9b 100644
--- a/plugins/excel/ms-escher.h
+++ b/plugins/excel/ms-escher.h
@@ -42,6 +42,8 @@ void ms_escher_sp (GString *buf, guint32 spid, guint16 shape, guint32 flags);
 gsize ms_escher_opt_start (GString *buf);
 void ms_escher_opt_add_simple (GString *buf, gsize marker,
 			       guint16 pid, gint32 val);
+void ms_escher_opt_add_str_wchar (GString *buf, gsize marker, GString *extra,
+				  guint16 pid, const char *str);
 void ms_escher_opt_end (GString *buf, gsize marker);
 
 void ms_escher_clientanchor (GString *buf, SheetObjectAnchor const *anchor);
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index f3ece31..031d058 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -6593,7 +6593,8 @@ excel_read_BOF (BiffQuery	 *q,
 		ExcelReadSheet *esheet;
 		if (bs == NULL) {
 			if (ver->version > MS_BIFF_V4) /* be anal */
-				g_printerr ("Sheet offset in stream of 0x%x not found in list\n", q->streamPos);
+				g_printerr ("Sheet offset in stream of 0x%lx not found in list\n",
+					    (long)q->streamPos);
 			if (*current_sheet >= importer->excel_sheets->len) {
 				esheet = excel_sheet_new (importer, "Worksheet", GNM_SHEET_DATA);
 				/* Top level worksheets existed up to & including 4.x */
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 56de42f..88fcf9d 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -46,6 +46,7 @@
 #include <sheet-object-graph.h>
 #include <sheet-object-image.h>
 #include <gnm-so-filled.h>
+#include <gnm-so-line.h>
 #include <application.h>
 #include <style.h>
 #include <style-conditions.h>
@@ -3873,7 +3874,7 @@ excel_write_start_drawing (ExcelWriteSheet *esheet)
 	return 0x400*esheet->ewb->cur_obj_group + esheet->cur_obj;
 }
 
-static void
+static gsize
 excel_write_autofilter_objs (ExcelWriteSheet *esheet)
 {
 	static guint8 const std_obj_v7[] = {
@@ -3926,9 +3927,10 @@ excel_write_autofilter_objs (ExcelWriteSheet *esheet)
 	unsigned i;
 	SheetObjectAnchor anchor;
 	GnmRange r;
+	gsize draw_len = 0;
 
 	if (esheet->gnum_sheet->filters == NULL)
-		return;
+		return 0;
 	filter = esheet->gnum_sheet->filters->data;
 	r.end.row = 1 + (r.start.row = filter->r.start.row);
 
@@ -3945,6 +3947,7 @@ excel_write_autofilter_objs (ExcelWriteSheet *esheet)
 			GSF_LE_SET_GUINT32 (buf + 16, id);
 			excel_write_anchor (buf + 66, &anchor);
 			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);
@@ -3965,12 +3968,16 @@ excel_write_autofilter_objs (ExcelWriteSheet *esheet)
 			excel_write_anchor (data + 10, &anchor);
 			if (cond != NULL)
 				GSF_LE_SET_GUINT16 (data + 124, 0xa);
+
+			/* No drawing here, it seems.  */
 		}
 		ms_biff_put_commit (bp);
 	}
+
+	return draw_len;
 }
 
-static void
+static gsize
 excel_write_chart_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 {
 	static guint8 const obj_v8[] = {
@@ -3997,11 +4004,13 @@ excel_write_chart_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	guint8 buf [sizeof obj_v8];
 	BiffPut *bp = esheet->ewb->bp;
 	guint32 id = excel_write_start_drawing (esheet);
+	gsize draw_len = 0;
 
 	memcpy (buf, obj_v8, sizeof obj_v8);
 	GSF_LE_SET_GUINT32 (buf + 16, id);
 	excel_write_anchor (buf + 0x5a, sheet_object_get_anchor (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);
@@ -4011,6 +4020,8 @@ excel_write_chart_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 
 	ms_biff_put_commit (bp);
 	ms_excel_chart_write (esheet->ewb, so);
+
+	return draw_len;
 }
 
 /* Return NULL when we cannot export. The NULL will be added to the list to
@@ -4109,7 +4120,7 @@ blipinf_free (BlipInf *blip)
 	}
 }
 
-static void
+static gsize
 excel_write_image_v8 (ExcelWriteSheet *esheet, BlipInf *bi)
 {
 	static guint8 const obj_v8[] = {
@@ -4132,12 +4143,14 @@ excel_write_image_v8 (ExcelWriteSheet *esheet, BlipInf *bi)
 	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);
@@ -4147,14 +4160,16 @@ excel_write_image_v8 (ExcelWriteSheet *esheet, BlipInf *bi)
 
 	ms_biff_put_commit (bp);
 	ewb->cur_blip++;
+
+	return draw_len;
 }
 
-static void
+static gsize
 excel_write_ClientTextbox (ExcelWriteState *ewb, SheetObject *so)
 {
 	guint8 buf [18];
 	int txo_len = 18;
-	int draw_len = 8;
+	int draw_len = 0;
 	int char_len;
 	char *label;
 	int markuplen;
@@ -4162,9 +4177,10 @@ excel_write_ClientTextbox (ExcelWriteState *ewb, SheetObject *so)
 	GArray *markup = g_hash_table_lookup (ewb->cell_markup, so);
 
 	ms_biff_put_var_next (bp,  BIFF_MS_O_DRAWING);
-	memset (buf, 0, draw_len);
+	memset (buf, 0, 8);
 	GSF_LE_SET_GUINT16 (buf + 2, 0xf00d); /* ClientTextbox */
-	ms_biff_put_var_write (bp, buf, draw_len);
+	ms_biff_put_var_write (bp, buf, 8);
+	draw_len += 8;
 	ms_biff_put_commit (bp);
 
 	ms_biff_put_var_next (bp, BIFF_TXO);
@@ -4210,12 +4226,15 @@ excel_write_ClientTextbox (ExcelWriteState *ewb, SheetObject *so)
 	GSF_LE_SET_GUINT16 (buf, char_len);
 	ms_biff_put_var_write (bp, buf, 8);
 	ms_biff_put_commit (bp);
+
+	return draw_len;
 }
 
-static void
+static gsize
 excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 {
 	GString *escher = g_string_new (NULL);
+	GString *extra;
 	ExcelWriteState *ewb = esheet->ewb;
 	BiffPut *bp = ewb->bp;
 	guint32 id = excel_write_start_drawing (esheet);
@@ -4227,6 +4246,8 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	int type;
 	guint16 shape = 0xca;  /* Textbox */
 	gboolean do_textbox;
+	gsize draw_len = 0;
+	char *name;
 
 	if (IS_CELL_COMMENT (so)) {
 		static float const offset [4] = { .5, .5, .5, .5 };
@@ -4268,7 +4289,7 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 		g_free (label);
 	} else {
 		g_assert_not_reached ();
-		return;
+		return 0;
 	}
 
 	spmark = ms_escher_spcontainer_start (escher);
@@ -4276,6 +4297,7 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	ms_escher_sp (escher, id, shape, 0x00000a00);  /* fHaveAnchor+fHaveSpt */
 	
 	optmark = ms_escher_opt_start (escher);
+	extra = g_string_new (NULL);
 	ms_escher_opt_add_simple (escher, optmark,
 				  0x0080, 0x00c600a0); /* Txid */
 	ms_escher_opt_add_simple (escher, optmark,
@@ -4288,9 +4310,17 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 				  0x01bf, 0x00010000); /* fNoFillHitTest */
 	ms_escher_opt_add_simple (escher, optmark,
 				  0x01c0, 0x08000040); /* lineColor */
+	g_object_get (so, "name", &name, NULL);
+	if (name) {
+		ms_escher_opt_add_str_wchar (escher, optmark, extra,
+					     0x0380, name);
+		g_free (name);
+	}
 	ms_escher_opt_add_simple (escher, optmark,
 				  0x03bf, 0x00080000); /* fPrint */
+	go_string_append_gstring (escher, extra);
 	ms_escher_opt_end (escher, optmark);
+	g_string_free (extra, TRUE);
 
 	ms_escher_clientanchor (escher, &anchor);
 
@@ -4300,6 +4330,7 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 
 	ms_biff_put_var_write (bp, escher->str, escher->len);
 	ms_biff_put_commit (bp);
+	draw_len += escher->len;
 
 	g_string_free (escher, TRUE);
 
@@ -4311,8 +4342,16 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 
 	ms_biff_put_commit (bp);
 
-	if (do_textbox)
-		excel_write_ClientTextbox (ewb, so);
+	if (1 || do_textbox)
+		draw_len += excel_write_ClientTextbox (ewb, so);
+
+	return draw_len;
+}
+
+static gsize
+excel_write_line_v8 (ExcelWriteSheet *esheet, SheetObject *so)
+{
+	return 0;
 }
 
 static void
@@ -4623,34 +4662,27 @@ excel_write_ROWINFO (BiffPut *bp, ExcelWriteSheet *esheet, guint32 row, guint32
 }
 
 static void
-excel_sheet_write_INDEX (ExcelWriteSheet *esheet, unsigned pos,
+excel_sheet_write_INDEX (ExcelWriteSheet *esheet, gsf_off_t fpos,
 			 GArray *dbcells)
 {
-	GsfOutput *output = esheet->ewb->bp->output;
-	guint8  data[4];
-	gsf_off_t oldpos;
+	BiffPut *bp = esheet->ewb->bp;
+	guint32 *data;
 	unsigned i;
 
-	g_return_if_fail (output);
-	g_return_if_fail (esheet);
-
-	oldpos = gsf_output_tell (output);
-	if (esheet->ewb->bp->version >= MS_BIFF_V8)
-		gsf_output_seek (output, pos+4+16, G_SEEK_SET);
-	else
-		gsf_output_seek (output, pos+4+12, G_SEEK_SET);
+	data = g_new (guint32, dbcells->len);
 
 	for (i = 0; i < dbcells->len; i++) {
 		unsigned pos = g_array_index (dbcells, unsigned, i);
-		GSF_LE_SET_GUINT32 (data, pos - esheet->ewb->streamPos);
+		GSF_LE_SET_GUINT32 (data + i, pos - esheet->ewb->streamPos);
 		d (2, fprintf (stderr, "Writing index record"
 			      " 0x%4.4x - 0x%4.4x = 0x%4.4x\n",
 			      pos, esheet->ewb->streamPos,
 			      pos - esheet->ewb->streamPos););
-		gsf_output_write (output, 4, data);
 	}
 
-	gsf_output_seek (output, oldpos, G_SEEK_SET);
+	ms_biff_put_abs_write (bp, fpos, data, 4 * dbcells->len);
+
+	g_free (data);
 }
 
 /**
@@ -4850,7 +4882,8 @@ excel_write_objs_v8 (ExcelWriteSheet *esheet)
 {
 	BiffPut *bp = esheet->ewb->bp;
 	GSList  *ptr;
-	int	 len;
+	gsf_off_t fpos = 0;
+	guint32 len = 0;
 
 	if (esheet->num_objs == 0)
 		return;
@@ -4868,9 +4901,6 @@ excel_write_objs_v8 (ExcelWriteSheet *esheet)
 		};
 		guint8 buf [sizeof header_obj_v8];
 		unsigned last_id, num_filters = 0;
-		unsigned num_charts = g_slist_length (esheet->graphs);
-		unsigned num_blips = g_slist_length (esheet->blips);
-		unsigned num_texts = g_slist_length (esheet->textboxes);
 
 		if (esheet->gnum_sheet->filters != NULL) {
 			GnmFilter const *f = esheet->gnum_sheet->filters->data;
@@ -4885,32 +4915,45 @@ excel_write_objs_v8 (ExcelWriteSheet *esheet)
 		last_id = 0x400*esheet->ewb->cur_obj_group + esheet->num_objs;
 
 		ms_biff_put_var_next (bp, BIFF_MS_O_DRAWING);
+		fpos = bp->streamPos + 4;
 		memcpy (buf, header_obj_v8, sizeof header_obj_v8);
-		len  =  90*num_filters;
-		len += 114*num_charts;
-		len +=  84*num_blips;
-		len += 116*num_texts;
-		GSF_LE_SET_GUINT32 (buf +  4, 72 + len);
+		// GSF_LE_SET_GUINT32 (buf +  4, 72 + len);
 		GSF_LE_SET_GUINT32 (buf + 16, esheet->num_objs + 1);
 		GSF_LE_SET_GUINT32 (buf + 20, last_id);	/* last spid in this group */
-		GSF_LE_SET_GUINT32 (buf + 28, 48 + len);
+		// GSF_LE_SET_GUINT32 (buf + 28, 48 + len);
 		ms_biff_put_var_write (bp, buf, sizeof header_obj_v8);
+		/* First object commits.  */
 	}
 
 #warning "handle multiple charts in a graph by creating multiple objects"
 	for (ptr = esheet->graphs; ptr != NULL ; ptr = ptr->next)
-		excel_write_chart_v8 (esheet, ptr->data);
+		len += excel_write_chart_v8 (esheet, ptr->data);
 
 	for (ptr = esheet->blips; ptr != NULL ; ptr = ptr->next)
-		excel_write_image_v8 (esheet, ptr->data);
+		len += excel_write_image_v8 (esheet, ptr->data);
 
 	for (ptr = esheet->textboxes; ptr != NULL ; ptr = ptr->next)
-		excel_write_textbox_v8 (esheet, ptr->data);
+		len += excel_write_textbox_v8 (esheet, ptr->data);
 
-	excel_write_autofilter_objs (esheet);
+	for (ptr = esheet->lines; ptr != NULL ; ptr = ptr->next)
+		len += excel_write_line_v8 (esheet, ptr->data);
+
+	len += excel_write_autofilter_objs (esheet);
 
 	g_hash_table_foreach (esheet->commentshash,
 			      (GHFunc) cb_NOTE_v8, bp);
+
+	if (bp->version >= MS_BIFF_V8) {
+		char tmp[4];
+		guint32 spcontlen = len + 48;
+		guint32 dgcontlen = spcontlen + 24;
+
+		GSF_LE_SET_GUINT32 (tmp, dgcontlen);
+		ms_biff_put_abs_write (bp, fpos + 4, tmp, 4);
+
+		GSF_LE_SET_GUINT32 (tmp, spcontlen);
+		ms_biff_put_abs_write (bp, fpos + 28, tmp, 4);
+	}
 }
 
 static void
@@ -4920,7 +4963,7 @@ excel_write_sheet (ExcelWriteState *ewb, ExcelWriteSheet *esheet)
 	guint32  block_end;
 	gint32	 y;
 	int	 rows_in_block = ROW_BLOCK_MAX_LEN;
-	unsigned	index_off;
+	gsf_off_t index_off;
 	MsBiffFileType	type;
 
 	/* No. of blocks of rows. Only correct as long as all rows
@@ -4946,19 +4989,23 @@ excel_write_sheet (ExcelWriteState *ewb, ExcelWriteSheet *esheet)
 	if (ewb->bp->version >= MS_BIFF_V8) {
 		guint8 *data = ms_biff_put_len_next (ewb->bp, BIFF_INDEX_v2,
 						     nblocks * 4 + 16);
-		index_off = ewb->bp->streamPos;
 		GSF_LE_SET_GUINT32 (data, 0);
 		GSF_LE_SET_GUINT32 (data +  4, 0);
 		GSF_LE_SET_GUINT32 (data +  8, esheet->max_row);
 		GSF_LE_SET_GUINT32 (data + 12, 0);
+
+		index_off = ewb->bp->streamPos + 4 + 16;
+		memset (data + 16, 0, nblocks * 4);
 	} else {
 		guint8 *data = ms_biff_put_len_next (ewb->bp, BIFF_INDEX_v2,
 						     nblocks * 4 + 12);
-		index_off = ewb->bp->streamPos;
 		GSF_LE_SET_GUINT32 (data, 0);
 		GSF_LE_SET_GUINT16 (data + 4, 0);
 		GSF_LE_SET_GUINT16 (data + 6, esheet->max_row);
 		GSF_LE_SET_GUINT32 (data + 8, 0);
+
+		index_off = ewb->bp->streamPos + 4 + 12;
+		memset (data + 12, 0, nblocks * 4);
 	}
 	ms_biff_put_commit (ewb->bp);
 
@@ -5084,6 +5131,12 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 			esheet->textboxes =
 				g_slist_prepend (esheet->textboxes, so);
 			handled = TRUE;
+		} else if (IS_GNM_SO_LINE (so)) {
+			if (1)
+				goto unhandled;
+			esheet->lines =
+				g_slist_prepend (esheet->lines, so);
+			handled = TRUE;
 		} else if (IS_GNM_FILTER_COMBO (so)) {
 			/* Handled outside loop.  */
 			continue;
@@ -5105,6 +5158,7 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 
 	esheet->blips = g_slist_reverse (esheet->blips);
 	esheet->textboxes = g_slist_reverse (esheet->textboxes);
+	esheet->lines = g_slist_reverse (esheet->lines);
 	esheet->comments = g_slist_reverse (esheet->comments);
 	esheet->graphs = g_slist_reverse (esheet->graphs);
 
@@ -5128,6 +5182,7 @@ static void
 excel_sheet_free (ExcelWriteSheet *esheet)
 {
 	g_slist_free (esheet->textboxes);
+	g_slist_free (esheet->lines);
 	g_slist_free (esheet->comments);
 	g_slist_free (esheet->graphs);
 	g_hash_table_destroy (esheet->commentshash);
diff --git a/plugins/excel/ms-excel-write.h b/plugins/excel/ms-excel-write.h
index 38d7eac..1f31214 100644
--- a/plugins/excel/ms-excel-write.h
+++ b/plugins/excel/ms-excel-write.h
@@ -49,7 +49,7 @@ typedef struct {
 	guint16		*col_xf;
 	GnmStyle	**col_style;
 	GnmStyleList	*conditions, *hlinks, *validations;
-	GSList          *blips, *textboxes, *graphs, *comments;
+	GSList          *blips, *textboxes, *lines, *graphs, *comments;
 	GHashTable	*commentshash;
 	unsigned	 cur_obj, num_objs;
 } ExcelWriteSheet;
diff --git a/plugins/excel/ms-obj.c b/plugins/excel/ms-obj.c
index 7c8002b..32b084d 100644
--- a/plugins/excel/ms-obj.c
+++ b/plugins/excel/ms-obj.c
@@ -452,7 +452,8 @@ ms_read_TXO (BiffQuery *q, MSContainer *c, PangoAttrList **markup)
 			*markup = ms_container_read_markup (c, q->data, q->length,
 							    text);
 		} else {
-			g_warning ("Unusual, TXO text with no formatting has 0x%x @ 0x%x", op, q->streamPos);
+			g_warning ("Unusual, TXO text with no formatting has 0x%x @ 0x%lx",
+				   op, (long)q->streamPos);
 		}
 	} else {
 		g_warning ("TXO len of %d but no continue", text_len);



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