[gnumeric] xls: export spin buttons.



commit 2416e5f94eca7dd89a2171bb4d82f32b7b12e74d
Author: Morten Welinder <terra gnome org>
Date:   Tue Oct 13 10:16:18 2009 -0400

    xls: export spin buttons.

 NEWS                           |    3 +-
 plugins/excel/ChangeLog        |    5 ++
 plugins/excel/ms-excel-write.c |  100 ++++++++++++++++++++++++++++++---------
 plugins/excel/ms-excel-write.h |    2 +-
 plugins/excel/ms-obj.c         |   61 +++++++++++++++++++++---
 plugins/excel/ms-obj.h         |    6 ++
 6 files changed, 144 insertions(+), 33 deletions(-)
---
diff --git a/NEWS b/NEWS
index 57f6ad9..6c7b8f1 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ Jody:
 
 Morten:
 	* Fix sheet-resize vs. merges issue.  [#582030]
-	* Fix xls export if check boxes and radio buttons.  [#597035]
+	* Fix xls export of check boxes and radio buttons.  [#597035]
+	* Add xls export of spin buttons.  [#597035]
 
 --------------------------------------------------------------------------
 Gnumeric 1.9.14
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 5699583..16e1c8c 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-13  Morten Welinder  <terra gnome org>
+
+	* ms-obj.c (ms_objv8_write_spinbutton, ms_objv8_write_adjustment):
+	New functions.
+
 2009-10-12  Morten Welinder  <terra gnome org>
 
 	* ms-formula-write.c (excel_write_formula): Handle new
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 987274e..594b1ec 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -4247,7 +4247,10 @@ excel_write_ClientTextbox (ExcelWriteState *ewb, SheetObject *so,
 }
 
 static gsize
-excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
+excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
+				  SheetObject *so,
+				  gboolean has_text_prop,
+				  gboolean is_widget)
 {
 	GString *escher = g_string_new (NULL);
 	GString *extra;
@@ -4266,16 +4269,19 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	gsize draw_len = 0;
 	char *name, *label;
 	GOStyle *style = NULL;
-	GnmExprTop const *checkbox_texpr = NULL;
 	gboolean checkbox_active = FALSE;
-	gboolean is_widget = FALSE;
 	GnmNamedExpr *macro_nexpr = NULL;
 	guint8 zero[4] = { 0, 0, 0, 0 };
 
-	g_object_get (so,
-		      "name", &name,
-		      "text", &label,
-		      NULL);
+	if (has_text_prop) {
+		g_object_get (so,
+			      "name", &name,
+			      "text", &label,
+			      NULL);
+	} else {
+		label = NULL;
+		g_object_get (so, "name", &name, NULL);
+	}
 	do_textbox = (label != NULL && label[0] != 0);
 
 	if (IS_CELL_COMMENT (so)) {
@@ -4316,19 +4322,18 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 		shape = 0xc9;
 		type = 0x0b;
 		flags = 0x0011;
-		checkbox_texpr = sheet_widget_checkbox_get_link (so);
 		g_object_get (so, "active", &checkbox_active, NULL);
-		is_widget = TRUE;
-
 		macro_nexpr = g_hash_table_lookup (esheet->widget_macroname, so);
 	} else if (GNM_IS_SOW_RADIO_BUTTON (so)) {
 		shape = 0xc9;
 		type = 0x0c;
 		flags = 0x0011;
-		checkbox_texpr = sheet_widget_radio_button_get_link (so);
 		g_object_get (so, "active", &checkbox_active, NULL);
-		is_widget = TRUE;
-
+		macro_nexpr = g_hash_table_lookup (esheet->widget_macroname, so);
+	} else if (GNM_IS_SOW_SPINBUTTON (so)) {
+		shape = 0xc9;
+		type = 0x10;
+		flags = 0x0011;
 		macro_nexpr = g_hash_table_lookup (esheet->widget_macroname, so);
 	} else {
 		g_assert_not_reached ();
@@ -4406,20 +4411,39 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	ms_objv8_write_common (bp, esheet->cur_obj, type, flags);
 
 	switch (type) {
-	case 0x0b:
+	case 0x0b: {
+		GnmExprTop const *link = sheet_widget_checkbox_get_link (so);
 		ms_objv8_write_checkbox (bp,
 					 checkbox_active,
 					 esheet,
-					 checkbox_texpr,
+					 link,
 					 macro_nexpr);
+		if (link) gnm_expr_top_unref (link);
 		break;
-	case 0x0c:
+	}
+	case 0x0c: {
+		GnmExprTop const *link = sheet_widget_radio_button_get_link (so);
 		ms_objv8_write_radiobutton (bp,
 					    checkbox_active,
 					    esheet,
-					    checkbox_texpr,
+					    link,
 					    macro_nexpr);
+		if (link) gnm_expr_top_unref (link);
+		break;
+	}
+	case 0x10: {
+		GnmExprTop const *link = sheet_widget_adjustment_get_link (so);
+		GtkAdjustment *adj =
+			sheet_widget_adjustment_get_adjustment (so);
+		gboolean horiz = sheet_widget_adjustment_get_horizontal (so);
+		ms_objv8_write_spinbutton (bp,
+					   esheet,
+					   adj, horiz,
+					   link,
+					   macro_nexpr);
+		if (link) gnm_expr_top_unref (link);
 		break;
+	}
 	case 0x19:
 		/* Cell comment. */
 		ms_objv8_write_note (bp);
@@ -4444,12 +4468,26 @@ excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 	g_free (name);
 	g_free (label);
 	if (style) g_object_unref (style);
-	if (checkbox_texpr) gnm_expr_top_unref (checkbox_texpr);
 
 	return draw_len;
 }
 
 static gsize
+excel_write_textbox_v8 (ExcelWriteSheet *esheet, SheetObject *so)
+{
+	return excel_write_textbox_or_widget_v8 (esheet, so, TRUE, FALSE);
+}
+
+static gsize
+excel_write_widget_v8 (ExcelWriteSheet *esheet, SheetObject *so)
+{
+	GParamSpec *pspec = g_object_class_find_property
+		(G_OBJECT_GET_CLASS (so), "text");
+	return excel_write_textbox_or_widget_v8 (esheet, so,
+						 pspec != NULL, TRUE);
+}
+
+static gsize
 excel_write_line_v8 (ExcelWriteSheet *esheet, SheetObject *so)
 {
 	gboolean is_arrow;
@@ -5109,6 +5147,9 @@ excel_write_objs_v8 (ExcelWriteSheet *esheet)
 	for (ptr = esheet->textboxes; ptr != NULL ; ptr = ptr->next)
 		len += excel_write_textbox_v8 (esheet, ptr->data);
 
+	for (ptr = esheet->widgets; ptr != NULL ; ptr = ptr->next)
+		len += excel_write_widget_v8 (esheet, ptr->data);
+
 	for (ptr = esheet->lines; ptr != NULL ; ptr = ptr->next)
 		len += excel_write_line_v8 (esheet, ptr->data);
 
@@ -5345,9 +5386,10 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 				g_slist_prepend (esheet->textboxes, so);
 			handled = TRUE;
 		} else if (GNM_IS_SOW_CHECKBOX (so) ||
-			   GNM_IS_SOW_RADIO_BUTTON (so)) {
-			esheet->textboxes =
-				g_slist_prepend (esheet->textboxes, so);
+			   GNM_IS_SOW_RADIO_BUTTON (so) ||
+			   GNM_IS_SOW_SPINBUTTON (so)) {
+			esheet->widgets =
+				g_slist_prepend (esheet->widgets, so);
 			g_hash_table_insert (esheet->widget_macroname,
 					     so,
 					     create_macroname (so));
@@ -5377,6 +5419,7 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 
 	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);
@@ -5401,6 +5444,7 @@ static void
 excel_sheet_free (ExcelWriteSheet *esheet)
 {
 	g_slist_free (esheet->textboxes);
+	g_slist_free (esheet->widgets);
 	g_slist_free (esheet->lines);
 	g_slist_free (esheet->comments);
 	g_slist_free (esheet->graphs);
@@ -6258,8 +6302,18 @@ excel_write_state_new (GOIOContext *context, WorkbookView const *wb_view,
 		for (ptr = esheet->graphs ; ptr != NULL ; ptr = ptr->next)
 			extract_gog_object_style (&ewb->base,
 				(GogObject *)sheet_object_graph_get_gog (ptr->data));
-		for (ptr = esheet->textboxes ; ptr != NULL ; ptr = ptr->next)
-			extract_txomarkup (ewb, ptr->data);
+		for (ptr = esheet->textboxes ; ptr != NULL ; ptr = ptr->next) {
+			SheetObject *so = ptr->data;
+			extract_txomarkup (ewb, so);
+		}
+
+		for (ptr = esheet->widgets ; ptr != NULL ; ptr = ptr->next) {
+			SheetObject *so = ptr->data;
+			GParamSpec *pspec = g_object_class_find_property
+				(G_OBJECT_GET_CLASS (so), "text");
+			if (pspec)
+				extract_txomarkup (ewb, so);
+		}
 	}
 
 	if (biff8) {
diff --git a/plugins/excel/ms-excel-write.h b/plugins/excel/ms-excel-write.h
index 00f8a82..ae5dd08 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, *lines, *graphs, *comments;
+	GSList          *blips, *textboxes, *widgets, *lines, *graphs, *comments;
 	GHashTable	*commentshash;
 	GHashTable      *widget_macroname;
 	unsigned	 cur_obj, num_objs;
diff --git a/plugins/excel/ms-obj.c b/plugins/excel/ms-obj.c
index ad33a2e..9f2efac 100644
--- a/plugins/excel/ms-obj.c
+++ b/plugins/excel/ms-obj.c
@@ -1418,16 +1418,16 @@ ms_objv8_write_checkbox_link (BiffPut *bp, gboolean active)
 }
 
 static void
-ms_objv8_write_checkbox_fmla (BiffPut *bp,
-			      ExcelWriteSheet *esheet,
-			      GnmExprTop const *texpr)
+ms_objv8_write_link_fmla (BiffPut *bp, guint16 typ,
+			  ExcelWriteSheet *esheet,
+			  GnmExprTop const *texpr)
 {
 	char hfmla[10];
 	unsigned pos, end_pos;
 	guint16 fmla_len;
 
 	pos = bp->curpos;
-	GSF_LE_SET_GUINT16 (hfmla, GR_CHECKBOX_FORMULA);
+	GSF_LE_SET_GUINT16 (hfmla, typ);
 	GSF_LE_SET_GUINT16 (hfmla + 2, 0);  /* record len */
 	GSF_LE_SET_GUINT16 (hfmla + 4, 0);  /* formula len */
 	GSF_LE_SET_GUINT32 (hfmla + 6, 0);  /* calcid? */
@@ -1484,8 +1484,8 @@ ms_objv8_write_checkbox (BiffPut *bp,
 {
 	ms_objv8_write_checkbox_link (bp, active);
 	if (link_texpr)
-		ms_objv8_write_checkbox_fmla (bp, esheet,
-					      link_texpr);
+		ms_objv8_write_link_fmla (bp, GR_CHECKBOX_FORMULA,
+					  esheet, link_texpr);
 	if (0 && macro_nexpr) {
 		GnmExprTop const *texpr =
 			gnm_expr_top_new
@@ -1532,8 +1532,8 @@ ms_objv8_write_radiobutton (BiffPut *bp,
 	ms_objv8_write_checkbox_link (bp, active);
 	ms_objv8_write_radiobutton_rec (bp);
 	if (link_texpr)
-		ms_objv8_write_checkbox_fmla (bp, esheet,
-					      link_texpr);
+		ms_objv8_write_link_fmla (bp, GR_CHECKBOX_FORMULA,
+					  esheet, link_texpr);
 	if (0 && macro_nexpr) {
 		GnmExprTop const *texpr =
 			gnm_expr_top_new
@@ -1546,3 +1546,48 @@ ms_objv8_write_radiobutton (BiffPut *bp,
 	ms_objv8_write_checkbox_data (bp, active);
 	ms_objv8_write_radiobutton_data (bp, 0, TRUE);
 }
+
+static void
+ms_objv8_write_adjustment (BiffPut *bp,
+			   GtkAdjustment *adj, gboolean horiz)
+{
+	char data[24];
+
+	GSF_LE_SET_GUINT16 (data, GR_SCROLLBAR);
+	GSF_LE_SET_GUINT16 (data + 2, sizeof (data) - 4);
+	GSF_LE_SET_GUINT32 (data + 4, 0); /* Unused */
+#define SQUEEZE(f) ((guint16)CLAMP(f, -32768, 32767))
+	GSF_LE_SET_GUINT16 (data +  8, SQUEEZE (adj->value));
+	GSF_LE_SET_GINT16  (data + 10, SQUEEZE (adj->lower));
+	GSF_LE_SET_GINT16  (data + 12, SQUEEZE (adj->upper + adj->step_increment));
+	GSF_LE_SET_GINT16  (data + 14, SQUEEZE (adj->step_increment));
+	GSF_LE_SET_GINT16  (data + 16, SQUEEZE (adj->page_increment));
+#undef SQUEEZE
+	GSF_LE_SET_GINT16  (data + 18, !!horiz);
+	GSF_LE_SET_GINT16  (data + 20, 42);  /* widget in pixels */
+	GSF_LE_SET_GINT16  (data + 22, 0x0001);  /* draw */
+
+	ms_biff_put_var_write (bp, data, sizeof data);
+}
+
+void
+ms_objv8_write_spinbutton (BiffPut *bp,
+			   ExcelWriteSheet *esheet,
+			   GtkAdjustment *adj, gboolean horiz,
+			   GnmExprTop const *link_texpr,
+			   GnmNamedExpr *macro_nexpr)
+{
+	ms_objv8_write_adjustment (bp, adj, horiz);
+	if (link_texpr)
+		ms_objv8_write_link_fmla (bp, GR_SCROLLBAR_FORMULA,
+					  esheet, link_texpr);
+	if (0 && macro_nexpr) {
+		GnmExprTop const *texpr =
+			gnm_expr_top_new
+			(gnm_expr_new_name (macro_nexpr,
+					    esheet->gnum_sheet,
+					    NULL));
+		ms_objv8_write_macro_fmla (bp, esheet, texpr);
+		gnm_expr_top_unref (texpr);
+	}
+}
diff --git a/plugins/excel/ms-obj.h b/plugins/excel/ms-obj.h
index db189aa..42d22c4 100644
--- a/plugins/excel/ms-obj.h
+++ b/plugins/excel/ms-obj.h
@@ -164,5 +164,11 @@ void ms_objv8_write_radiobutton (BiffPut *bp,
 				 ExcelWriteSheet *esheet,
 				 GnmExprTop const *link_texpr,
 				 GnmNamedExpr *macro_nexpr);
+void ms_objv8_write_spinbutton (BiffPut *bp,
+				ExcelWriteSheet *esheet,
+				GtkAdjustment *adj, gboolean horiz,
+				GnmExprTop const *link_texpr,
+				GnmNamedExpr *macro_nexpr);
+
 
 #endif /* GNM_MS_OBJ_H */



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