[gnumeric] xls: export list widgets.



commit abd2124d905b3967286c8de414a62d7a2ea50d29
Author: Morten Welinder <terra gnome org>
Date:   Tue Oct 13 16:17:05 2009 -0400

    xls: export list widgets.

 NEWS                             |    1 +
 plugins/excel/ms-excel-write.c   |   31 ++++++++-
 plugins/excel/ms-formula-write.c |    2 +-
 plugins/excel/ms-obj.c           |  133 +++++++++++++++++++++++++++----------
 plugins/excel/ms-obj.h           |    6 ++
 5 files changed, 133 insertions(+), 40 deletions(-)
---
diff --git a/NEWS b/NEWS
index 3d8fff3..8c7c20a 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ Morten:
 	* Fix xls export of check boxes and radio buttons.  [Part of #597035]
 	* Add xls export of spin buttons.  [Part of #597035]
 	* Add xls export of scroll bars.  [Part of #597035]
+	* Add xls export of list widgets.  [Part of #597035]
 
 --------------------------------------------------------------------------
 Gnumeric 1.9.14
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 841abb2..98ca0a4 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -4271,7 +4271,7 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 	GOStyle *style = NULL;
 	gboolean checkbox_active = FALSE;
 	GnmNamedExpr *macro_nexpr;
-	guint8 zero[4] = { 0, 0, 0, 0 };
+	gboolean terminate_obj = TRUE;
 
 	if (has_text_prop) {
 		g_object_get (so,
@@ -4340,6 +4340,10 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 		shape = 0xc9;
 		type = 0x11;
 		flags = 0x6011;
+	} else if (GNM_IS_SOW_LIST (so)) {
+		shape = 0xc9;
+		type = 0x12;
+		flags = 0x2011;
 	} else {
 		g_assert_not_reached ();
 		return 0;
@@ -4462,6 +4466,23 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 		if (link) gnm_expr_top_unref (link);
 		break;
 	}
+	case 0x12: {
+		GnmExprTop const *res_link =
+			sheet_widget_list_base_get_result_link (so);
+		GnmExprTop const *data_link =
+			sheet_widget_list_base_get_content_link (so);
+		GtkAdjustment *adj =
+			sheet_widget_list_base_get_adjustment (so);
+		ms_objv8_write_list (bp,
+				     esheet,
+				     adj, res_link, data_link,
+				     macro_nexpr);
+		if (res_link) gnm_expr_top_unref (res_link);
+		if (data_link) gnm_expr_top_unref (data_link);
+		g_object_unref (adj);
+		terminate_obj = FALSE;  /* GR_LISTBOX_DATA is strange */
+		break;
+	}
 	case 0x19:
 		/* Cell comment. */
 		ms_objv8_write_note (bp);
@@ -4471,7 +4492,10 @@ excel_write_textbox_or_widget_v8 (ExcelWriteSheet *esheet,
 		break;
 	}
 
-	ms_biff_put_var_write (bp, zero, 4);
+	if (terminate_obj) {
+		guint8 zero[4] = { 0, 0, 0, 0 };
+		ms_biff_put_var_write (bp, zero, 4);
+	}
 	ms_biff_put_commit (bp);
 
 	/* ---------------------------------------- */
@@ -5406,7 +5430,8 @@ excel_sheet_new (ExcelWriteState *ewb, Sheet *sheet,
 		} else if (GNM_IS_SOW_CHECKBOX (so) ||
 			   GNM_IS_SOW_RADIO_BUTTON (so) ||
 			   GNM_IS_SOW_SPINBUTTON (so) ||
-			   GNM_IS_SOW_SCROLLBAR (so)) {
+			   GNM_IS_SOW_SCROLLBAR (so) ||
+			   GNM_IS_SOW_LIST (so)) {
 			esheet->widgets =
 				g_slist_prepend (esheet->widgets, so);
 			g_hash_table_insert (esheet->widget_macroname,
diff --git a/plugins/excel/ms-formula-write.c b/plugins/excel/ms-formula-write.c
index 73322a3..1ddda0f 100644
--- a/plugins/excel/ms-formula-write.c
+++ b/plugins/excel/ms-formula-write.c
@@ -420,7 +420,7 @@ excel_formula_write_AREA (PolishData *pd, GnmCellRef const *a, GnmCellRef const
 
 	if (a->sheet == NULL && b->sheet == NULL) {
 
-		if (pd->context == CTXT_NAME_OBJ) {
+		if (!pd->allow_sheetless_ref) {
 			g_warning ("XL does not support unqualified references in global names");
 		}
 
diff --git a/plugins/excel/ms-obj.c b/plugins/excel/ms-obj.c
index 57a8bf9..cea7f99 100644
--- a/plugins/excel/ms-obj.c
+++ b/plugins/excel/ms-obj.c
@@ -1095,7 +1095,8 @@ ms_obj_read_biff8_obj (BiffQuery *q, MSContainer *c, MSObj *obj)
 
 			/* UNDOCUMENTED :
 			 * It seems as if list box data does not conform to
-			 * the docs.  It acts like an end and has no size.  */
+			 * the docs.  It acts like an end and has no size.
+			 */
 			hit_end = TRUE;
 			len = data_len_left - 4;
 
@@ -1475,6 +1476,20 @@ ms_objv8_write_macro_fmla (BiffPut *bp,
 	ms_biff_put_var_seekto (bp, end_pos);
 }
 
+static void
+ms_objv8_write_macro_ref (BiffPut *bp,
+			  ExcelWriteSheet *esheet,
+			  GnmNamedExpr *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);
+}
+
 void
 ms_objv8_write_checkbox (BiffPut *bp,
 			 gboolean active,
@@ -1486,15 +1501,8 @@ ms_objv8_write_checkbox (BiffPut *bp,
 	if (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
-			(gnm_expr_new_name (macro_nexpr,
-					    esheet->gnum_sheet,
-					    NULL));
-		ms_objv8_write_macro_fmla (bp, esheet, texpr);
-		gnm_expr_top_unref (texpr);
-	}
+	if (0 && macro_nexpr)
+		ms_objv8_write_macro_ref (bp, esheet, macro_nexpr);
 	ms_objv8_write_checkbox_data (bp, active);
 }
 
@@ -1534,15 +1542,8 @@ ms_objv8_write_radiobutton (BiffPut *bp,
 	if (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
-			(gnm_expr_new_name (macro_nexpr,
-					    esheet->gnum_sheet,
-					    NULL));
-		ms_objv8_write_macro_fmla (bp, esheet, texpr);
-		gnm_expr_top_unref (texpr);
-	}
+	if (0 && macro_nexpr)
+		ms_objv8_write_macro_ref (bp, esheet, macro_nexpr);
 	ms_objv8_write_checkbox_data (bp, active);
 	ms_objv8_write_radiobutton_data (bp, 0, TRUE);
 }
@@ -1581,15 +1582,8 @@ ms_objv8_write_spinbutton (BiffPut *bp,
 	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);
-	}
+	if (0 && macro_nexpr)
+		ms_objv8_write_macro_ref (bp, esheet, macro_nexpr);
 }
 
 void
@@ -1603,13 +1597,80 @@ ms_objv8_write_scrollbar (BiffPut *bp,
 	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);
+	if (0 && macro_nexpr)
+		ms_objv8_write_macro_ref (bp, esheet, macro_nexpr);
+}
+
+static void
+ms_objv8_write_list_data (BiffPut *bp,
+			  ExcelWriteSheet *esheet,
+			  GnmExprTop const *texpr,
+			  guint16 N, guint16 selected)
+{
+	char hfmla[12];
+	char data[8];
+	unsigned pos, end_pos;
+	guint16 fmla_len;
+	guint16 ui;
+	guint16 style = 0;
+	guint8 *selection;
+
+	pos = bp->curpos;
+	GSF_LE_SET_GUINT16 (hfmla, GR_LISTBOX_DATA);
+	GSF_LE_SET_GUINT16 (hfmla + 2, 0x1fcc);  /* ??? */
+	GSF_LE_SET_GUINT16 (hfmla + 4, 0);  /* record len */
+	GSF_LE_SET_GUINT16 (hfmla + 6, 0);  /* formula len */
+	GSF_LE_SET_GUINT32 (hfmla + 8, 0);  /* calcid? */
+	ms_biff_put_var_write (bp, hfmla, sizeof hfmla);
+	if (texpr) {
+		fmla_len = excel_write_formula (esheet->ewb,
+						texpr,
+						esheet->gnum_sheet, 0, 0,
+						EXCEL_CALLED_FROM_OBJ);
+		if (fmla_len & 1)
+			ms_biff_put_var_write (bp, "", 1);
+		GSF_LE_SET_GUINT16 (hfmla + 6, fmla_len);
+	} else {
+		/* Needs testing.  */
+		ms_biff_put_var_write (bp, "\0", 2);
+		fmla_len = 0;
 	}
+
+	end_pos = bp->curpos;
+	ms_biff_put_var_seekto (bp, pos);
+	GSF_LE_SET_GUINT16 (hfmla + 4, (fmla_len + 7) & ~1);
+	ms_biff_put_var_write (bp, hfmla, sizeof hfmla);
+	ms_biff_put_var_seekto (bp, end_pos);
+
+	selection = g_new0 (char, N);
+	for (ui = 0; ui < N; ui++)
+		selection[ui] = (ui + 1 == selected);
+
+	GSF_LE_SET_GUINT16 (data, N);
+	GSF_LE_SET_GUINT16 (data + 2, selected);  /* iSel */
+	GSF_LE_SET_GUINT16 (data + 4, style);
+	GSF_LE_SET_GUINT16 (data + 6, 0);  /* edit object id */
+	ms_biff_put_var_write (bp, data, sizeof data);
+	ms_biff_put_var_write (bp, selection, N);
+
+	g_free (selection);
+}
+
+void
+ms_objv8_write_list (BiffPut *bp,
+		     ExcelWriteSheet *esheet,
+		     GtkAdjustment *adj,
+		     GnmExprTop const *res_texpr,
+		     GnmExprTop const *data_texpr,
+		     GnmNamedExpr *macro_nexpr)
+{
+	ms_objv8_write_adjustment (bp, adj, FALSE);
+	if (res_texpr)
+		ms_objv8_write_link_fmla (bp, GR_SCROLLBAR_FORMULA,
+					  esheet, res_texpr);
+	if (0 && macro_nexpr)
+		ms_objv8_write_macro_ref (bp, esheet, macro_nexpr);
+	ms_objv8_write_list_data (bp, esheet, data_texpr,
+				  (guint16)adj->upper - 1,
+				  (guint16)adj->value);
 }
diff --git a/plugins/excel/ms-obj.h b/plugins/excel/ms-obj.h
index a55a15e..1d0efa7 100644
--- a/plugins/excel/ms-obj.h
+++ b/plugins/excel/ms-obj.h
@@ -174,6 +174,12 @@ void ms_objv8_write_scrollbar (BiffPut *bp,
 			       GtkAdjustment *adj, gboolean horiz,
 			       GnmExprTop const *link_texpr,
 			       GnmNamedExpr *macro_nexpr);
+void ms_objv8_write_list (BiffPut *bp,
+			  ExcelWriteSheet *esheet,
+			  GtkAdjustment *adj,
+			  GnmExprTop const *res_texpr,
+			  GnmExprTop const *data_texpr,
+			  GnmNamedExpr *macro_nexpr);
 
 
 #endif /* GNM_MS_OBJ_H */



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