[gnumeric] CondFormat: make sure we have simple relative references
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] CondFormat: make sure we have simple relative references
- Date: Tue, 1 Dec 2015 01:43:49 +0000 (UTC)
commit ddfabad0a4560c62343a838d97e215f6d94ad1b3
Author: Morten Welinder <terra gnome org>
Date: Mon Nov 30 20:43:40 2015 -0500
CondFormat: make sure we have simple relative references
This fixes #750271.
NEWS | 1 +
src/dependent.c | 6 +---
src/xml-sax-read.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 67 insertions(+), 6 deletions(-)
---
diff --git a/NEWS b/NEWS
index 4d30a9d..a603ec7 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Morten:
* Fix TABLE problems. [#752181] [#752178] [#752182]
* Fuzzed file fixes. [#752179] [#752180]
* Add R.DGUMBEL, R.PGUMBEL, R.QGUMBEL.
+ * Fix conditional format problem. [#750271]
--------------------------------------------------------------------------
Gnumeric 1.12.24
diff --git a/src/dependent.c b/src/dependent.c
index 7e00240..6d2e6fd 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -1393,16 +1393,14 @@ style_dep_unrender (GnmDependent *dep, const char *what)
sheet_redraw_region (sheet,
pos->col, pos->row,
pos->col, pos->row);
-
-
}
static void
style_dep_eval (GnmDependent *dep)
{
/*
- * It is possible that the cell has been rendered between we ::changed
- * was called.
+ * It is possible that the cell has been rendered between ::changed
+ * was called and now.
*/
style_dep_unrender (dep, "being evaluated");
}
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 3dc0f93..d23eff5 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -45,6 +45,7 @@
#include "cell.h"
#include "position.h"
#include "expr.h"
+#include "expr-impl.h"
#include "expr-name.h"
#include "print-info.h"
#include "value.h"
@@ -1752,6 +1753,60 @@ xml_sax_condition_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
state->cond = NULL;
}
+/*
+ * We have saving expressions relative to A1. This means that we read
+ * see a relative reference to a cell above as R[65535]C. This function
+ * patches that to R[-1]C.
+ *
+ * We ought to fix the format, but then old Gnumerics couldn't read new
+ * files. In fact, if we just added a "Position" attribute then we would
+ * get silent corruption.
+ */
+static GnmExpr const *
+cond_patchup (GnmExpr const *expr, GnmExprWalk *data)
+{
+ XMLSaxParseState *state = data->user;
+ GnmCellPos const *pos = &state->style_range.start;
+ if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CELLREF) {
+ GnmCellPos tpos;
+ GnmCellRef const *oref = &expr->cellref.ref;
+ GnmCellRef tref = *oref;
+ gnm_cellpos_init_cellref (&tpos, &expr->cellref.ref,
+ pos, state->sheet);
+ if (tref.col_relative)
+ tref.col = tpos.col - pos->col;
+ if (tref.row_relative)
+ tref.row = tpos.row - pos->row;
+ if (gnm_cellref_equal (&tref, oref))
+ return NULL;
+ return gnm_expr_new_cellref (&tref);
+ } else if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CONSTANT &&
+ VALUE_IS_CELLRANGE (expr->constant.value)) {
+ GnmRangeRef const *oref = value_get_rangeref (expr->constant.value);
+ GnmRangeRef tref = *oref;
+ GnmRange trange;
+ Sheet *start_sheet, *end_sheet;
+ GnmEvalPos ep;
+
+ eval_pos_init_pos (&ep, state->sheet, pos);
+ gnm_rangeref_normalize (oref, &ep, &start_sheet, &end_sheet,
+ &trange);
+ if (tref.a.col_relative)
+ tref.a.col = trange.start.col - pos->col;
+ if (tref.a.row_relative)
+ tref.a.row = trange.start.row - pos->row;
+ if (tref.b.col_relative)
+ tref.b.col = trange.end.col - pos->col;
+ if (tref.b.row_relative)
+ tref.b.row = trange.end.row - pos->row;
+ if (gnm_rangeref_equal (&tref, oref))
+ return NULL;
+ return gnm_expr_new_constant (value_new_cellrange_unsafe (&tref.a, &tref.b));
+ }
+
+ return NULL;
+}
+
static void
xml_sax_condition_expr_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
{
@@ -1760,17 +1815,24 @@ xml_sax_condition_expr_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
int const i = xin->node->user_data.v_int;
GnmExprTop const *texpr;
GnmParsePos pos;
+ GnmExpr const *patched_expr;
g_return_if_fail (gnm_style_cond_get_expr (state->cond, i) == NULL);
+ parse_pos_init_sheet (&pos, state->sheet);
texpr = gnm_expr_parse_str (xin->content->str,
- parse_pos_init_sheet (&pos, state->sheet),
+ &pos,
GNM_EXPR_PARSE_DEFAULT,
state->convs,
NULL);
-
g_return_if_fail (texpr != NULL);
+ patched_expr = gnm_expr_walk (texpr->expr, cond_patchup, state);
+ if (patched_expr) {
+ gnm_expr_top_unref (texpr);
+ texpr = gnm_expr_top_new (patched_expr);
+ }
+
gnm_style_cond_set_expr (state->cond, texpr, i);
gnm_expr_top_unref (texpr);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]