[gnumeric] Improve ODF export of style conditions. [#676441]



commit 9fe47b52d5c476a320721bcbbb1891c6db2a092c
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Sun May 20 16:38:45 2012 -0600

    Improve ODF export of style conditions. [#676441]
    
    2012-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-write.c (odf_save_style_map_single_f): add arguments
    	(odf_save_style_map_double_f): ditto
    	(odf_determine_base): new
    	(odf_save_style_map): include the correct base

 NEWS                                  |    2 +-
 plugins/openoffice/ChangeLog          |    7 ++
 plugins/openoffice/openoffice-write.c |  138 +++++++++++++++++++++++----------
 3 files changed, 105 insertions(+), 42 deletions(-)
---
diff --git a/NEWS b/NEWS
index d44a30e..8e41ce1 100644
--- a/NEWS
+++ b/NEWS
@@ -15,7 +15,7 @@ Andreas:
 	* Write the formatted text of sheet objects to ODF.
 	* Fix consolidate tool. [#670155]
 	* Fix crash on ODF import of messagefree validations.
-	* Improve ODF import/export of style conditions. [#676289]
+	* Improve ODF import/export of style conditions. [#676289, #676441]
 	* Fix object placement in ODF import. [#676339]
 
 Jean:
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 351c14b..b96a216 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,12 @@
 2012-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-write.c (odf_save_style_map_single_f): add arguments
+	(odf_save_style_map_double_f): ditto
+	(odf_determine_base): new
+	(odf_save_style_map): include the correct base
+
+2012-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-read.c (OOCellStyle): new type
 	(_OOParseState.default_style.cells): change type
 	(odf_init_pp): new
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 80a79bb..5cf6b07 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -1460,12 +1460,12 @@ odf_find_style (GnmOOExport *state, GnmStyle const *style)
 }
 
 static void
-odf_save_style_map_single_f (GnmOOExport *state, GString *str, GnmExprTop const *texpr)
+odf_save_style_map_single_f (GnmOOExport *state, GString *str, GnmExprTop const *texpr, int col, int row)
 {
 	char *formula;
 	GnmParsePos pp;
 
-	parse_pos_init (&pp, WORKBOOK (state->wb), state->sheet, 0, 0);
+	parse_pos_init (&pp, WORKBOOK (state->wb), state->sheet, col, row);
 
 	formula = gnm_expr_top_as_string (texpr, &pp, state->conv);
 	g_string_append (str, formula);
@@ -1474,58 +1474,105 @@ odf_save_style_map_single_f (GnmOOExport *state, GString *str, GnmExprTop const
 
 
 static void
-odf_save_style_map_double_f (GnmOOExport *state, GString *str, GnmStyleCond const *cond)
+odf_save_style_map_double_f (GnmOOExport *state, GString *str, GnmStyleCond const *cond, int col, int row)
 {
 	g_string_append_c (str, '(');
-	odf_save_style_map_single_f (state, str, cond->texpr[0]);
+	odf_save_style_map_single_f (state, str, cond->texpr[0], col, row);
 	g_string_append_c (str, ',');
-	odf_save_style_map_single_f (state, str, cond->texpr[1]);
+	odf_save_style_map_single_f (state, str, cond->texpr[1], col, row);
 	g_string_append_c (str, ')');
 }
 
+static char *
+odf_strip_brackets (char *string)
+{
+	char *closing;
+	closing = strrchr(string, ']');
+	if (closing != NULL)
+		*closing = '\0';
+	return ((*string == '[') ? (string + 1) : string);
+}
+
+static void
+odf_determine_base (GnmOOExport *state, GnmExprTop const *texpr1, GnmExprTop const *texpr2, GnmRange *r)
+{
+	GnmRange bound1, bound2;
+
+	if (texpr1 == NULL && texpr2 == NULL)
+		return;
+	if (texpr1) {
+		range_init_full_sheet (&bound1, state->sheet);
+		gnm_expr_top_get_boundingbox (texpr1, state->sheet, &bound1);
+	}
+	if (texpr2) {
+		range_init_full_sheet (&bound2, state->sheet);
+		gnm_expr_top_get_boundingbox (texpr2, state->sheet, &bound2);
+	}
+	if (texpr1 && texpr2) {
+		if (!range_intersection (r, &bound1, &bound2))
+			range_init_full_sheet (r, state->sheet);
+	} else if (texpr1)
+		*r = bound1;
+	else
+		*r = bound2;
+}
+
 static void
 odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 {
 	char const *name = odf_find_style (state, cond->overlay);
 	GString *str;
 	gchar *address;
+	GnmExprTop const *texpr = NULL;
+	GnmCellRef ref;
+	GnmRange r;
+	GnmParsePos pp;
 
 	g_return_if_fail (name != NULL);
 
+	range_init_full_sheet (&r, state->sheet);
 	str = g_string_new (NULL);
 
 	switch (cond->op) {
 	case GNM_STYLE_COND_BETWEEN:
+		odf_determine_base (state, cond->texpr[0], cond->texpr[1], &r);
 		g_string_append (str, "of:cell-content-is-between");
-		odf_save_style_map_double_f (state, str, cond);
+		odf_save_style_map_double_f (state, str, cond, r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_NOT_BETWEEN:
+		odf_determine_base (state, cond->texpr[0], cond->texpr[1], &r);
 		g_string_append (str, "of:cell-content-is-not-between");
-		odf_save_style_map_double_f (state, str, cond);
+		odf_save_style_map_double_f (state, str, cond, r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_EQUAL:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()=");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_NOT_EQUAL:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()!=");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_GT:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()>");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_LT:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()<");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_GTE:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()>=");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_LTE:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:cell-content()<=");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		break;
 	case GNM_STYLE_COND_CONTAINS_ERR:
 		g_string_append (str, "of:is-true-formula(ISERROR([.A1]))");
@@ -1534,37 +1581,50 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 		g_string_append (str, "of:is-true-formula(NOT(ISERROR([.A1])))");
 		break;
 	case GNM_STYLE_COND_CONTAINS_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(NOT(ISERROR(FIND(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";[.A1]))))");
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";[.%s%s]))))", 
+					col_name (r.end.col), row_name (r.end.row));
 		break;
 	case GNM_STYLE_COND_NOT_CONTAINS_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(ISERROR(FIND(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";[.A1])))");
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";[.%s%s])))", 
+					col_name (r.end.col), row_name (r.end.row));
 		break;
 	case GNM_STYLE_COND_BEGINS_WITH_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
+
 		g_string_append (str, "of:is-true-formula(IFERROR(FIND(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";[.A1]);2)=1)");
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";[.%s%s]);2)=1)", 
+					col_name (r.end.col), row_name (r.end.row));
 		break;
 	case GNM_STYLE_COND_NOT_BEGINS_WITH_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(NOT(IFERROR(FIND(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";[.A1]);2)=1))");
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";[.%s%s]);2)=1))", 
+					col_name (r.end.col), row_name (r.end.row));
 		break;
 	case GNM_STYLE_COND_ENDS_WITH_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(EXACT(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";RIGHT([.A1];LEN(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";RIGHT([.%s%s];LEN(", 
+					col_name (r.end.col), row_name (r.end.row));
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		g_string_append (str, ")))");
 		break;
 	case GNM_STYLE_COND_NOT_ENDS_WITH_STR:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(NOT(EXACT(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
-		g_string_append (str, ";RIGHT([.A1];LEN(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
+		g_string_append_printf (str, ";RIGHT([.%s%s];LEN(", 
+					col_name (r.end.col), row_name (r.end.row));
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		g_string_append (str, "))))");
 		break;
 	case GNM_STYLE_COND_CONTAINS_BLANKS:
@@ -1574,8 +1634,9 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 		g_string_append (str, "of:is-true-formula(ISERROR(FIND(\" \";[.A1])))");
 		break;
 	case GNM_STYLE_COND_CUSTOM:
+		odf_determine_base (state, cond->texpr[0], NULL, &r);
 		g_string_append (str, "of:is-true-formula(");
-		odf_save_style_map_single_f (state, str, cond->texpr[0]);
+		odf_save_style_map_single_f (state, str, cond->texpr[0], r.end.col + 1, r.end.row + 1);
 		g_string_append (str, ")");
 		break;
 	default:
@@ -1589,10 +1650,15 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 	gsf_xml_out_add_cstr (state->xml, STYLE "condition", str->str);
 
 	/* ODF 1.2 requires a sheet name for the base-cell-address */
-	/* This is reall only needed if we included a formula      */
-	address = g_strdup_printf ("%s.A1", state->sheet->name_quoted);
-	gsf_xml_out_add_cstr (state->xml, STYLE "base-cell-address", address);
+	/* This is really only needed if we included a formula      */
+	gnm_cellref_init (&ref, (Sheet *)state->sheet,
+			  r.end.col + 1, r.end.row + 1, FALSE);
+	texpr =  gnm_expr_top_new (gnm_expr_new_cellref (&ref));
+	parse_pos_init (&pp, (Workbook *)state->wb, state->sheet,0,0);
+	address = gnm_expr_top_as_string (texpr, &pp, state->conv);
+	gsf_xml_out_add_cstr (state->xml, STYLE "base-cell-address", odf_strip_brackets (address));
 	g_free (address);
+	gnm_expr_top_unref (texpr);
 
 	gsf_xml_out_end_element (state->xml); /* </style:map> */
 
@@ -2732,16 +2798,6 @@ odf_write_comment (GnmOOExport *state, GnmComment const *cc)
 }
 
 static char *
-odf_strip_brackets (char *string)
-{
-	char *closing;
-	closing = strrchr(string, ']');
-	if (closing != NULL)
-		*closing = '\0';
-	return ((*string == '[') ? (string + 1) : string);
-}
-
-static char *
 odf_graph_get_series (GnmOOExport *state, GogGraph *sog, GnmParsePos *pp)
 {
 	GSList *list = gog_graph_get_data (sog);



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