[gnumeric] Validations: fix handling of expressions.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Validations: fix handling of expressions.
- Date: Thu, 10 May 2012 19:59:45 +0000 (UTC)
commit a5e192efbc781e2aee4a8fc6c2bc54e45991aa8c
Author: Morten Welinder <terra gnome org>
Date: Thu May 10 15:58:40 2012 -0400
Validations: fix handling of expressions.
With this change we use managed dependents which in turn means that the
expressions will auto-update as needed when rows or columns are inserted
or deleted.
ChangeLog | 20 ++++++++
NEWS | 1 +
plugins/excel/ms-excel-read.c | 4 +-
plugins/excel/ms-excel-write.c | 16 +++---
plugins/excel/xlsx-read.c | 7 ++-
plugins/excel/xlsx-write.c | 4 +-
plugins/openoffice/openoffice-read.c | 13 +++--
plugins/openoffice/openoffice-write.c | 34 +++++++-------
src/dialogs/dialog-cell-format.c | 8 ++-
src/mstyle.c | 15 +++++--
src/sheet-style.c | 14 +++++-
src/validation.c | 75 +++++++++++++++++-------------
src/validation.h | 4 +-
src/widgets/gnm-validation-combo-view.c | 4 +-
src/workbook.c | 21 +++-----
src/xml-sax-read.c | 1 +
src/xml-sax-write.c | 8 ++--
test/GnumericTest.pm | 4 ++
18 files changed, 158 insertions(+), 95 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b8602b7..bca40ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2012-05-10 Morten Welinder <terra gnome org>
+
+ * src/workbook.c (workbook_dispose): Dispose of views early.
+ (This is desirable since the views hold the auto-expression value
+ which in turn may references sheets via validations in the
+ format.)
+
+ * src/validation.h (GnmValidation): Use GnmDependent, not raw
+ GnmExprTop, for storing expressions. All users changed.
+
+ * src/validation.c (validation_new): Add new "sheet" argument.
+ All callers changed. Hook up expressions as managed dependents.
+ Fixes #674914.
+
+ * src/sheet-style.c (GnmSheetStyleData): Document the rules for
+ the style_hash member.
+
+ * src/mstyle.c (gnm_style_update): Don't use the validation's
+ address for the hash value -- use just whether it is NULL.
+
2012-05-02 Morten Welinder <terra gnome org>
* src/wbc-gtk.c (wbc_gtk_create_status_area): Get the
diff --git a/NEWS b/NEWS
index 31e9aac..f6a0207 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Andreas:
Morten:
* Minor doc improvement for non-C locales. [Part of #675000]
* Fix fullscreen criticals.
+ * Improve handling of expressions in validations. [#674914]
--------------------------------------------------------------------------
Gnumeric 1.11.3
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 52e1a72..312f885 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5523,7 +5523,9 @@ excel_read_DV (BiffQuery *q, ExcelReadSheet *esheet)
mstyle = gnm_style_new ();
gnm_style_set_validation
(mstyle,
- validation_new (style, type, op, error_title, error_msg,
+ validation_new (style, type, op,
+ esheet->sheet,
+ error_title, error_msg,
texpr1,
texpr2,
options & 0x0100, 0 == (options & 0x0200)));
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 47acb52..8671b2b 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -1256,10 +1256,10 @@ excel_write_DV (XLValInputPair const *vip, gpointer dummy, ExcelWriteSheet *eshe
GSF_LE_SET_GUINT16 (data+2, 0); /* Undocumented, use 0 for now */
ms_biff_put_var_write (bp, data, 4);
- if (vip->v != NULL && vip->v->texpr[0] != NULL) {
+ if (vip->v != NULL && vip->v->deps[0].texpr != NULL) {
unsigned pos = bp->curpos;
guint16 len = excel_write_formula (esheet->ewb,
- vip->v->texpr[0],
+ vip->v->deps[0].texpr,
esheet->gnum_sheet, col, row,
EXCEL_CALLED_FROM_VALIDATION);
unsigned end_pos = bp->curpos;
@@ -1272,10 +1272,10 @@ excel_write_DV (XLValInputPair const *vip, gpointer dummy, ExcelWriteSheet *eshe
GSF_LE_SET_GUINT16 (data , 0); /* bogus len fill in later */
GSF_LE_SET_GUINT16 (data+2, 0); /* Undocumented, use 0 for now */
ms_biff_put_var_write (bp, data, 4);
- if (vip->v != NULL && vip->v->texpr[1] != NULL) {
+ if (vip->v != NULL && vip->v->deps[1].texpr != NULL) {
unsigned pos = bp->curpos;
guint16 len = excel_write_formula (esheet->ewb,
- vip->v->texpr[1],
+ vip->v->deps[1].texpr,
esheet->gnum_sheet, col, row,
EXCEL_CALLED_FROM_VALIDATION);
unsigned end_pos = bp->curpos;
@@ -1529,10 +1529,10 @@ excel_write_prep_validations (ExcelWriteSheet *esheet)
for (; ptr != NULL ; ptr = ptr->next) {
sr = ptr->data;
v = gnm_style_get_validation (sr->style);
- if (v->texpr[0] != NULL)
- excel_write_prep_expr (esheet->ewb, v->texpr[0]);
- if (v->texpr[1] != NULL)
- excel_write_prep_expr (esheet->ewb, v->texpr[1]);
+ if (v->deps[0].texpr != NULL)
+ excel_write_prep_expr (esheet->ewb, v->deps[0].texpr);
+ if (v->deps[1].texpr != NULL)
+ excel_write_prep_expr (esheet->ewb, v->deps[1].texpr);
}
}
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index f5bff91..79e371a 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -1744,8 +1744,11 @@ xlsx_CT_DataValidation_begin (GsfXMLIn *xin, xmlChar const **attrs)
if (showErrorMessage) {
GnmRange const *r = state->validation_regions->data;
state->pos = r->start;
- state->validation = validation_new (val_style, val_type, val_op,
- errorTitle, error, NULL, NULL, allowBlank, showDropDown);
+ state->validation = validation_new
+ (val_style, val_type, val_op,
+ state->sheet,
+ errorTitle, error,
+ NULL, NULL, allowBlank, showDropDown);
}
if (showInputMessage && (NULL != promptTitle || NULL != prompt))
diff --git a/plugins/excel/xlsx-write.c b/plugins/excel/xlsx-write.c
index ace5c07..413c2ce 100644
--- a/plugins/excel/xlsx-write.c
+++ b/plugins/excel/xlsx-write.c
@@ -1416,9 +1416,9 @@ xlsx_write_validation (XLValInputPair const *vip, gpointer dummy, XLSXClosure *i
if (NULL != vip->v) {
GnmRange const *first = vip->ranges->data;
xlsx_write_validation_expr (info, &first->start,
- "formula1", vip->v->texpr[0]);
+ "formula1", vip->v->deps[0].texpr);
xlsx_write_validation_expr (info, &first->start,
- "formula2", vip->v->texpr[1]);
+ "formula2", vip->v->deps[1].texpr);
}
gsf_xml_out_end_element (info->xml); /* </dataValidation> */
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 2c9e051..2df37f2 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -2242,7 +2242,7 @@ odf_validation_new_list (GsfXMLIn *xin, odf_validation_t *val, guint offset)
char *start = NULL, *end = NULL;
GString *str;
GnmExprTop const *texpr = NULL;
- GnmParsePos pp;
+ GnmParsePos pp;
start = strchr (val->condition + offset, '(');
@@ -2287,6 +2287,7 @@ odf_validation_new_list (GsfXMLIn *xin, odf_validation_t *val, guint offset)
validation = validation_new (val->style,
GNM_VALIDATION_TYPE_IN_LIST,
GNM_VALIDATION_OP_NONE,
+ state->pos.sheet,
val->title,
val->message->str,
texpr,
@@ -2301,12 +2302,12 @@ odf_validation_new_list (GsfXMLIn *xin, odf_validation_t *val, guint offset)
static GnmValidation *
odf_validation_new_single_expr (GsfXMLIn *xin, odf_validation_t *val,
- char const *start, ValidationType val_type,
- ValidationOp val_op)
+ char const *start, ValidationType val_type,
+ ValidationOp val_op)
{
OOParseState *state = (OOParseState *)xin->user_state;
GnmExprTop const *texpr = NULL;
- GnmParsePos pp;
+ GnmParsePos pp;
pp = state->pos;
if (val->base_cell_address != NULL) {
@@ -2335,6 +2336,7 @@ odf_validation_new_single_expr (GsfXMLIn *xin, odf_validation_t *val,
return validation_new (val->style,
val_type,
val_op,
+ state->pos.sheet,
val->title,
val->message->str,
texpr,
@@ -2351,7 +2353,7 @@ odf_validation_new_pair_expr (GsfXMLIn *xin, odf_validation_t *val,
{
OOParseState *state = (OOParseState *)xin->user_state;
GnmExprTop const *texpr = NULL;
- GnmParsePos pp;
+ GnmParsePos pp;
GnmExprTop const *texpr_a = NULL, *texpr_b = NULL;
char *pair = NULL;
guint len = strlen (start);
@@ -2408,6 +2410,7 @@ odf_validation_new_pair_expr (GsfXMLIn *xin, odf_validation_t *val,
return validation_new (val->style,
val_type,
val_op,
+ state->pos.sheet,
val->title,
val->message->str,
texpr_a,
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index bfdb6d1..3648751 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -4080,9 +4080,11 @@ odf_validation_append_expression_pair (GnmOOExport *state, GString *str,
GnmParsePos *pp)
{
str = g_string_append_c (str, '(');
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str,
+ val->deps[0].texpr, pp);
str = g_string_append_c (str, ',');
- odf_validation_append_expression (state, str, val->texpr[1], pp);
+ odf_validation_append_expression (state, str,
+ val->deps[1].texpr, pp);
str = g_string_append_c (str, ')');
}
@@ -4111,27 +4113,27 @@ odf_validation_general (GnmOOExport *state, GnmValidation const *val,
break;
case GNM_VALIDATION_OP_EQUAL:
str = g_string_append (str, "cell-content() = ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_NOT_EQUAL:
str = g_string_append (str, "cell-content() != ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_GT:
str = g_string_append (str, "cell-content() > ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_LT:
str = g_string_append (str, "cell-content() < ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_GTE:
str = g_string_append (str, "cell-content() >= ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_LTE:
str = g_string_append (str, "cell-content() <= ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
}
@@ -4160,27 +4162,27 @@ odf_validation_length (GnmOOExport *state, GnmValidation const *val,
break;
case GNM_VALIDATION_OP_EQUAL:
str = g_string_append (str, "cell-content-text-length() = ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_NOT_EQUAL:
str = g_string_append (str, "cell-content-text-length() != ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_GT:
str = g_string_append (str, "cell-content-text-length() > ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_LT:
str = g_string_append (str, "cell-content-text-length() < ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_GTE:
str = g_string_append (str, "of:cell-content-text-length() >= ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
case GNM_VALIDATION_OP_LTE:
str = g_string_append (str, "cell-content-text-length() <= ");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
break;
}
@@ -4196,7 +4198,7 @@ odf_validation_custom (GnmOOExport *state, GnmValidation const *val,
GString *str = g_string_new (NULL);
str = g_string_append (str, "of:is-true-formula(");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
str = g_string_append_c (str, ')');
gsf_xml_out_add_cstr (state->xml, TABLE "condition", str->str);
@@ -4211,7 +4213,7 @@ odf_validation_in_list (GnmOOExport *state, GnmValidation const *val,
GString *str;
str = g_string_new ("of:cell-content-is-in-list(");
- odf_validation_append_expression (state, str, val->texpr[0], pp);
+ odf_validation_append_expression (state, str, val->deps[0].texpr, pp);
str = g_string_append_c (str, ')');
gsf_xml_out_add_cstr (state->xml, TABLE "condition", str->str);
diff --git a/src/dialogs/dialog-cell-format.c b/src/dialogs/dialog-cell-format.c
index 328d673..b40d8bf 100644
--- a/src/dialogs/dialog-cell-format.c
+++ b/src/dialogs/dialog-cell-format.c
@@ -1607,7 +1607,9 @@ validation_rebuild_validation (FormatState *state)
gnm_style_set_validation
(state->result,
validation_new
- (style, type, op, title, msg,
+ (style, type, op,
+ state->sheet,
+ title, msg,
texpr0,
texpr1,
allow_blank,
@@ -1905,9 +1907,9 @@ fmt_dialog_init_validation_page (FormatState *state)
parse_pos_init (&pp, state->sheet->workbook, state->sheet,
state->sv->edit_pos.col, state->sv->edit_pos.row);
gnm_expr_entry_load_from_expr (state->validation.expr0.entry,
- v->texpr[0], &pp);
+ v->deps[0].texpr, &pp);
gnm_expr_entry_load_from_expr (state->validation.expr1.entry,
- v->texpr[1], &pp);
+ v->deps[1].texpr, &pp);
}
cb_validation_sensitivity (NULL, state);
diff --git a/src/mstyle.c b/src/mstyle.c
index ca8e27f..ebf02d3 100644
--- a/src/mstyle.c
+++ b/src/mstyle.c
@@ -243,7 +243,8 @@ gnm_style_update (GnmStyle *style)
/* From here on, fields are not in MS XL */
- hash ^= GPOINTER_TO_UINT (style->validation);
+ if (style->validation)
+ hash ^= 0x1379;
hash = (hash << 7) ^ (hash >> (sizeof (hash) * 8 - 7));
hash ^= GPOINTER_TO_UINT (style->hlink);
@@ -339,6 +340,12 @@ gnm_style_hash (gconstpointer style)
? a->conditions == b->conditions \
: FALSE)))))))))))))))))))))))))
+/*
+ * Note: the above is suboptimal from validation and down.
+ *
+ * We are comparing pointers (which at least safely matches what we do
+ * with the hash), but I think we want proper equality.
+ */
static gboolean
elem_is_eq (GnmStyle const *a, GnmStyle const *b, GnmStyleElement elem)
@@ -424,16 +431,16 @@ elem_clear_contents (GnmStyle *style, GnmStyleElement elem)
return;
case MSTYLE_HLINK:
if (style->hlink)
- g_object_unref (G_OBJECT (style->hlink));
+ g_object_unref (style->hlink);
return;
case MSTYLE_INPUT_MSG:
if (style->input_msg)
- g_object_unref (G_OBJECT (style->input_msg));
+ g_object_unref (style->input_msg);
return;
case MSTYLE_CONDITIONS:
if (style->conditions) {
clear_conditional_merges (style);
- g_object_unref (G_OBJECT (style->conditions));
+ g_object_unref (style->conditions);
}
return;
default:
diff --git a/src/sheet-style.c b/src/sheet-style.c
index af2399f..f076e4e 100644
--- a/src/sheet-style.c
+++ b/src/sheet-style.c
@@ -41,7 +41,18 @@
typedef union _CellTile CellTile;
struct _GnmSheetStyleData {
+ /*
+ * style_hash is a set of all styles used by this sheet. These
+ * styles are all linked.
+ *
+ * We always re-use styles from here when we can, but there can
+ * still be duplicates. This happens when styles are changed
+ * while they are in the hash; such changes maintain the hash
+ * value. For example, this happens when an expression used by
+ * a validation style changes due to row/col insert/delete.
+ */
GHashTable *style_hash;
+
CellTile *styles;
GnmStyle *default_style;
GnmColor *auto_pattern_color;
@@ -535,7 +546,8 @@ sheet_style_init_size (Sheet *sheet, int cols, int rows)
sheet->style_data = g_new (GnmSheetStyleData, 1);
sheet->style_data->style_hash =
- g_hash_table_new (gnm_style_hash, (GCompareFunc) gnm_style_equal);
+ g_hash_table_new (gnm_style_hash,
+ (GCompareFunc) gnm_style_equal);
#warning "FIXME: Allocating a GnmColor here is dubious."
sheet->style_data->auto_pattern_color = g_new (GnmColor, 1);
*sheet->style_data->auto_pattern_color = *style_color_auto_pattern ();
diff --git a/src/validation.c b/src/validation.c
index fa60cbb..8da03ee 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -245,19 +245,21 @@ gnm_validation_op_get_type (void)
**/
GnmValidation *
validation_new (ValidationStyle style,
- ValidationType type,
- ValidationOp op,
+ ValidationType type,
+ ValidationOp op,
+ Sheet *sheet,
char const *title, char const *msg,
GnmExprTop const *texpr0, GnmExprTop const *texpr1,
gboolean allow_blank, gboolean use_dropdown)
{
GnmValidation *v;
- int nops, i;
+ int nops;
g_return_val_if_fail (type >= 0, NULL);
g_return_val_if_fail (type < G_N_ELEMENTS (typeinfo), NULL);
g_return_val_if_fail (op >= GNM_VALIDATION_OP_NONE, NULL);
g_return_val_if_fail (op < (int)G_N_ELEMENTS (opinfo), NULL);
+ g_return_val_if_fail (IS_SHEET (sheet), NULL);
switch (type) {
case GNM_VALIDATION_TYPE_CUSTOM:
@@ -282,21 +284,27 @@ validation_new (ValidationStyle style,
v->ref_count = 1;
v->title = title && title[0] ? go_string_new (title) : NULL;
v->msg = msg && msg[0] ? go_string_new (msg) : NULL;
- v->texpr[0] = texpr0;
- v->texpr[1] = texpr1;
+
+ dependent_managed_init (&v->deps[0], sheet);
+ if (texpr0) {
+ if (nops > 0)
+ dependent_managed_set_expr (&v->deps[0], texpr0);
+ gnm_expr_top_unref (texpr0);
+ }
+
+ dependent_managed_init (&v->deps[1], sheet);
+ if (texpr1) {
+ if (nops > 1)
+ dependent_managed_set_expr (&v->deps[1], texpr1);
+ gnm_expr_top_unref (texpr1);
+ }
+
v->style = style;
v->type = type;
v->op = op;
v->allow_blank = (allow_blank != FALSE);
v->use_dropdown = (use_dropdown != FALSE);
- /* Clear excess expressions. */
- for (i = nops; i < 2; i++)
- if (v->texpr[i]) {
- gnm_expr_top_unref (v->texpr[i]);
- v->texpr[i] = NULL;
- }
-
return v;
}
@@ -328,10 +336,7 @@ validation_unref (GnmValidation const *val)
v->msg = NULL;
}
for (i = 0 ; i < 2 ; i++)
- if (v->texpr[i] != NULL) {
- gnm_expr_top_unref (v->texpr[i]);
- v->texpr[i] = NULL;
- }
+ dependent_managed_set_expr (&v->deps[i], NULL);
g_free (v);
}
}
@@ -343,7 +348,7 @@ validation_unref (GnmValidation const *val)
* @indx : 0 or 1
*
* Assign an expression to a validation. validation_is_ok can be used to
- * verify that @v has all of the requisit information.
+ * verify that @v has all of the required information.
**/
void
validation_set_expr (GnmValidation *v,
@@ -351,11 +356,7 @@ validation_set_expr (GnmValidation *v,
{
g_return_if_fail (indx <= 1);
- if (NULL != texpr)
- gnm_expr_top_ref (texpr);
- if (NULL != v->texpr[indx])
- gnm_expr_top_unref (v->texpr[indx]);
- v->texpr[indx] = texpr;
+ dependent_managed_set_expr (&v->deps[indx], texpr);
}
GError *
@@ -365,13 +366,17 @@ validation_is_ok (GnmValidation const *v)
switch (v->type) {
case GNM_VALIDATION_TYPE_CUSTOM:
- case GNM_VALIDATION_TYPE_IN_LIST: nops = 1; break;
- case GNM_VALIDATION_TYPE_ANY: nops = 0; break;
+ case GNM_VALIDATION_TYPE_IN_LIST:
+ nops = 1;
+ break;
+ case GNM_VALIDATION_TYPE_ANY:
+ nops = 0;
+ break;
default: nops = (v->op == GNM_VALIDATION_OP_NONE) ? 0 : opinfo[v->op].nops;
}
for (i = 0 ; i < 2 ; i++)
- if (v->texpr[i] == NULL) {
+ if (v->deps[i].texpr == NULL) {
if (i < nops)
return g_error_new (1, 0, N_("Missing formula for validation"));
} else {
@@ -504,9 +509,11 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
x = value_get_as_float (val);
break;
- case GNM_VALIDATION_TYPE_IN_LIST:
- if (NULL != v->texpr[0]) {
- GnmValue *list = gnm_expr_top_eval (v->texpr[0], &ep,
+ case GNM_VALIDATION_TYPE_IN_LIST: {
+ GnmExprTop const *texpr = v->deps[0].texpr;
+ if (texpr) {
+ GnmValue *list = gnm_expr_top_eval
+ (texpr, &ep,
GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY);
GnmValue *res = value_area_foreach (list, &ep, CELL_ITER_IGNORE_BLANK,
(GnmValueIterFunc) cb_validate_custom, val);
@@ -514,7 +521,7 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
if (res == NULL) {
GnmParsePos pp;
char *expr_str = gnm_expr_top_as_string
- (v->texpr[0],
+ (texpr,
parse_pos_init_evalpos (&pp, &ep),
ep.sheet->convs);
char *msg = g_strdup_printf (_("%s does not contain the new value."), expr_str);
@@ -523,6 +530,7 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
}
}
return GNM_VALIDATION_STATUS_VALID;
+ }
case GNM_VALIDATION_TYPE_TEXT_LENGTH:
/* XL appears to use a very basic value->string mapping that
@@ -535,11 +543,12 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
case GNM_VALIDATION_TYPE_CUSTOM: {
gboolean valid;
+ GnmExprTop const *texpr = v->deps[0].texpr;
- if (v->texpr[0] == NULL)
+ if (!texpr)
return GNM_VALIDATION_STATUS_VALID;
- val = gnm_expr_top_eval (v->texpr[0], &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+ val = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
valid = value_get_as_bool (val, NULL);
value_release (val);
@@ -548,7 +557,7 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
else {
GnmParsePos pp;
char *expr_str = gnm_expr_top_as_string
- (v->texpr[0],
+ (texpr,
parse_pos_init_evalpos (&pp, &ep),
ep.sheet->convs);
char *msg = g_strdup_printf (_("%s is not true."), expr_str);
@@ -567,7 +576,7 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
nok = 0;
for (i = 0; i < opinfo[v->op].nops; i++) {
- GnmExprTop const *texpr_i = v->texpr[i];
+ GnmExprTop const *texpr_i = v->deps[i].texpr;
GnmExprTop const *texpr;
GnmValue *cres;
diff --git a/src/validation.h b/src/validation.h
index b8adb64..e88604d 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -3,6 +3,7 @@
# define _GNM_VALIDATION_H_
#include "gnumeric.h"
+#include "dependent.h"
G_BEGIN_DECLS
@@ -45,7 +46,7 @@ struct _GnmValidation {
GOString *title;
GOString *msg;
- GnmExprTop const *texpr[2];
+ GnmDependent deps[2];
ValidationStyle style;
ValidationType type;
ValidationOp op;
@@ -66,6 +67,7 @@ GType gnm_validation_op_get_type (void);
GnmValidation *validation_new (ValidationStyle style,
ValidationType type,
ValidationOp op,
+ Sheet *sheet,
char const *title, char const *msg,
GnmExprTop const *texpr0,
GnmExprTop const *texpr1,
diff --git a/src/widgets/gnm-validation-combo-view.c b/src/widgets/gnm-validation-combo-view.c
index 307b786..df048da 100644
--- a/src/widgets/gnm-validation-combo-view.c
+++ b/src/widgets/gnm-validation-combo-view.c
@@ -107,11 +107,11 @@ vcombo_create_list (SheetObject *so,
g_return_val_if_fail (val != NULL, NULL);
g_return_val_if_fail (val->type == GNM_VALIDATION_TYPE_IN_LIST, NULL);
- g_return_val_if_fail (val->texpr[0] != NULL, NULL);
+ g_return_val_if_fail (val->deps[0].texpr != NULL, NULL);
g_return_val_if_fail (sv != NULL, NULL);
eval_pos_init_editpos (&ep, sv);
- v = gnm_expr_top_eval (val->texpr[0], &ep,
+ v = gnm_expr_top_eval (val->deps[0].texpr, &ep,
GNM_EXPR_EVAL_PERMIT_NON_SCALAR |
GNM_EXPR_EVAL_PERMIT_EMPTY |
GNM_EXPR_EVAL_ARRAY_CONTEXT);
diff --git a/src/workbook.c b/src/workbook.c
index edf1281..60ad994 100644
--- a/src/workbook.c
+++ b/src/workbook.c
@@ -108,6 +108,14 @@ workbook_dispose (GObject *wb_object)
WORKBOOK_FOREACH_CONTROL (wb, view, control,
wb_control_sheet_remove_all (control););
+ /* Get rid of all the views */
+ WORKBOOK_FOREACH_VIEW (wb, wbv, {
+ wb_view_detach_from_workbook (wbv);
+ g_object_unref (wbv);
+ });
+ if (wb->wb_views != NULL)
+ g_warning ("Unexpected left over views");
+
command_list_release (wb->undo_commands);
wb->undo_commands = NULL;
command_list_release (wb->redo_commands);
@@ -132,19 +140,6 @@ workbook_dispose (GObject *wb_object)
}
g_slist_free (sheets);
- /* TODO : This should be earlier when we figure out how to deal with
- * the issue raised by 'pristine'.
- */
- /* Get rid of all the views */
- if (wb->wb_views != NULL) {
- WORKBOOK_FOREACH_VIEW (wb, wbv, {
- wb_view_detach_from_workbook (wbv);
- g_object_unref (wbv);
- });
- if (wb->wb_views != NULL)
- g_warning ("Unexpected left over views");
- }
-
workbook_parent_class->dispose (wb_object);
}
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 98c0d0e..b438bff 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -1629,6 +1629,7 @@ xml_sax_validation_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
validation_new (state->validation.style,
state->validation.type,
state->validation.op,
+ state->sheet,
state->validation.title,
state->validation.msg,
state->validation.texpr[0],
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index a41be86..a0c6f44 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -579,13 +579,13 @@ xml_write_style (GnmOutputXML *state, GnmStyle const *style)
parse_pos_init_sheet (&pp, (Sheet *)state->sheet);
- if (v->texpr[0] != NULL &&
- (tmp = gnm_expr_top_as_string (v->texpr[0], &pp, state->convs)) != NULL) {
+ if (v->deps[0].texpr != NULL &&
+ (tmp = gnm_expr_top_as_string (v->deps[0].texpr, &pp, state->convs)) != NULL) {
gsf_xml_out_simple_element (state->output, GNM "Expression0", tmp);
g_free (tmp);
}
- if (v->texpr[1] != NULL &&
- (tmp = gnm_expr_top_as_string (v->texpr[1], &pp, state->convs)) != NULL) {
+ if (v->deps[1].texpr != NULL &&
+ (tmp = gnm_expr_top_as_string (v->deps[1].texpr, &pp, state->convs)) != NULL) {
gsf_xml_out_simple_element (state->output, GNM "Expression1", tmp);
g_free (tmp);
}
diff --git a/test/GnumericTest.pm b/test/GnumericTest.pm
index a7a630f..4f7d482 100644
--- a/test/GnumericTest.pm
+++ b/test/GnumericTest.pm
@@ -326,6 +326,10 @@ sub test_exporter {
$code = system ("$ssconvert '$file' '$tmp1' 2>&1 | sed -e 's/^/| /'");
&system_failure ($ssconvert, $code) if $code;
+ print STDERR "file=$file\n";
+ print STDERR "tmp1=$tmp1\n";
+ system ("ls -lart | tail");
+
my $tmp2 = "$tmp-new.$ext";
&junkfile ($tmp2) unless $keep;
$code = system ("$ssconvert '$file' '$tmp2' 2>&1 | sed -e 's/^/| /'");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]