[gnumeric] Conditional formats: handle starts-with for xls
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Conditional formats: handle starts-with for xls
- Date: Thu, 13 Mar 2014 01:26:46 +0000 (UTC)
commit 161a1003574801acd1c40b27d0bdc4b4d4e1cb5c
Author: Morten Welinder <terra gnome org>
Date: Wed Mar 12 21:26:19 2014 -0400
Conditional formats: handle starts-with for xls
samples/cond-format-tests.gnumeric | Bin 2254 -> 2355 bytes
src/style-conditions.c | 55 ++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 5 deletions(-)
---
diff --git a/samples/cond-format-tests.gnumeric b/samples/cond-format-tests.gnumeric
index fa935e4..7308171 100644
Binary files a/samples/cond-format-tests.gnumeric and b/samples/cond-format-tests.gnumeric differ
diff --git a/src/style-conditions.c b/src/style-conditions.c
index 31c83ad..cfb5236 100644
--- a/src/style-conditions.c
+++ b/src/style-conditions.c
@@ -295,8 +295,33 @@ gnm_style_cond_get_alternate_expr (GnmStyleCond const *cond)
gnm_expr_new_cellref (&self)));
break;
- case GNM_STYLE_COND_BEGINS_WITH_STR:
case GNM_STYLE_COND_NOT_BEGINS_WITH_STR:
+ negate = TRUE; /* ...and fall through */
+ case GNM_STYLE_COND_BEGINS_WITH_STR: {
+ GnmExprTop const *sexpr = gnm_style_cond_get_expr (cond, 0);
+ if (!sexpr)
+ return NULL;
+
+ /*
+ * We can do much better if sexpr is a constant. We are
+ * constrained by using only Excel functions and not
+ * evaluating the needle more than once. The expression
+ * used here works, but FIND is more expensive that it
+ * ought to be.
+ */
+ expr = gnm_expr_new_binary
+ (gnm_expr_new_funcall2
+ (gnm_func_lookup_or_add_placeholder ("IFERROR"),
+ gnm_expr_new_funcall2
+ (gnm_func_lookup_or_add_placeholder ("FIND"),
+ gnm_expr_copy (sexpr->expr),
+ gnm_expr_new_cellref (&self)),
+ gnm_expr_new_constant (value_new_int (2))),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_int (1)));
+ break;
+ }
+
case GNM_STYLE_COND_ENDS_WITH_STR:
case GNM_STYLE_COND_NOT_ENDS_WITH_STR:
/* we ought to do the above */
@@ -342,6 +367,7 @@ gnm_style_cond_canonicalize (GnmStyleCond *cond)
GnmValue const *v;
gboolean negate = FALSE;
GnmFunc const *iserror;
+ GnmFunc const *iferror;
GnmFunc const *find;
GnmStyleCondOp newop = GNM_STYLE_COND_CUSTOM;
@@ -364,6 +390,7 @@ gnm_style_cond_canonicalize (GnmStyleCond *cond)
}
iserror = gnm_func_lookup_or_add_placeholder ("ISERROR");
+ iferror = gnm_func_lookup_or_add_placeholder ("IFERROR");
find = gnm_func_lookup_or_add_placeholder ("FIND");
if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL &&
@@ -377,19 +404,37 @@ gnm_style_cond_canonicalize (GnmStyleCond *cond)
(expr2 = expr->func.argv[0]) &&
GNM_EXPR_GET_OPER (expr2) == GNM_EXPR_OP_FUNCALL &&
expr2->func.argc == 2 && expr2->func.func == find &&
- (v = gnm_expr_get_constant (expr2->func.argv[0])) &&
- VALUE_IS_STRING (v) &&
isself (expr2->func.argv[1])) {
- if (strcmp (value_peek_string (v), " ") == 0)
+ GnmValue const *v =
+ gnm_expr_get_constant (expr2->func.argv[0]);
+
+ if (v && VALUE_IS_STRING (v) &&
+ strcmp (value_peek_string (v), " ") == 0)
newop = negate
? GNM_STYLE_COND_CONTAINS_BLANKS
: GNM_STYLE_COND_NOT_CONTAINS_BLANKS;
else {
- texpr = gnm_expr_top_new_constant (value_dup (v));
+ texpr = gnm_expr_top_new (gnm_expr_copy (expr2->func.argv[0]));
newop = negate
? GNM_STYLE_COND_CONTAINS_STR
: GNM_STYLE_COND_NOT_CONTAINS_STR;
}
+ } else if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_EQUAL &&
+ (v = gnm_expr_get_constant (expr->binary.value_b)) &&
+ VALUE_IS_FLOAT (v) && value_get_as_float (v) == 1 &&
+ (expr2 = expr->binary.value_a) &&
+ GNM_EXPR_GET_OPER (expr2) == GNM_EXPR_OP_FUNCALL &&
+ expr2->func.argc == 2 && expr2->func.func == iferror &&
+ (v = gnm_expr_get_constant (expr2->func.argv[1])) &&
+ VALUE_IS_FLOAT (v) && value_get_as_float (v) != 1 &&
+ (expr2 = expr2->func.argv[0]) &&
+ GNM_EXPR_GET_OPER (expr2) == GNM_EXPR_OP_FUNCALL &&
+ expr2->func.argc == 2 && expr2->func.func == find &&
+ isself (expr2->func.argv[1])) {
+ texpr = gnm_expr_top_new (gnm_expr_copy (expr2->func.argv[0]));
+ newop = negate
+ ? GNM_STYLE_COND_NOT_BEGINS_WITH_STR
+ : GNM_STYLE_COND_BEGINS_WITH_STR;
}
if (newop != GNM_STYLE_COND_CUSTOM) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]