[gnumeric] Conditional formats: improve xls import.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Conditional formats: improve xls import.
- Date: Wed, 12 Mar 2014 23:27:24 +0000 (UTC)
commit bbe34632e5b499431c94420f123c227dba22c619
Author: Morten Welinder <terra gnome org>
Date: Wed Mar 12 19:25:34 2014 -0400
Conditional formats: improve xls import.
ChangeLog | 1 +
plugins/excel/ChangeLog | 3 +
plugins/excel/ms-excel-read.c | 3 +
src/style-conditions.c | 87 +++++++++++++++++++++++++++++++++++++++++
src/style-conditions.h | 2 +
5 files changed, 96 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4533822..4af6a4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@
* src/style-conditions.c (gnm_style_cond_get_alternate_expr): New
function.
+ (gnm_style_cond_canonicalize): New function.
* src/ssconvert.c (convert): only print "Using exporter ..." if
--verbose is given, and print it to stderr.
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index c0fba41..b61a1f0 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -4,6 +4,9 @@
gnm_style_cond_get_alternate_expr for conditions not available in
xls.
+ * ms-excel-read.c (excel_read_CF): Undo the alternate expression
+ stuff.
+
2014-03-10 Morten Welinder <terra gnome org>
* xlsx-read.c (xlsx_CT_vertAlign): Read super/subscript.
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 55e0f70..5f004cf 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5204,6 +5204,9 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc)
gnm_expr_top_unref (texpr);
}
+ /* Reverse the alternate-expression treatment on save. */
+ gnm_style_cond_canonicalize (cond);
+
/* UNDOCUMENTED : the format of the conditional format
* is unspecified.
*
diff --git a/src/style-conditions.c b/src/style-conditions.c
index c0aaeeb..285cf35 100644
--- a/src/style-conditions.c
+++ b/src/style-conditions.c
@@ -26,6 +26,7 @@
#include "mstyle.h"
#include "gnm-style-impl.h"
#include "expr.h"
+#include "expr-impl.h"
#include "cell.h"
#include "value.h"
#include "sheet.h"
@@ -290,6 +291,92 @@ gnm_style_cond_get_alternate_expr (GnmStyleCond const *cond)
return gnm_expr_top_new (expr);
}
+static gboolean
+isself (GnmExpr const *expr)
+{
+ GnmCellRef const *cr;
+
+ if (GNM_EXPR_GET_OPER (expr) != GNM_EXPR_OP_CELLREF)
+ return FALSE;
+ cr = &expr->cellref.ref;
+
+ return (cr->sheet == NULL &&
+ cr->col == 0 && cr->row == 0 &&
+ cr->col_relative && cr->row_relative);
+}
+
+static gboolean
+issinglespace (GnmExpr const *expr)
+{
+ GnmValue const *v = gnm_expr_get_constant (expr);
+ return (v &&
+ VALUE_IS_STRING (v) &&
+ strcmp (value_peek_string (v), " ") == 0);
+}
+
+/**
+ * gnm_style_cond_canonicalize:
+ * @cond: condition
+ *
+ * Turns a custom condition into a more specific one, i.e., reverses the
+ * effect of using gnm_style_cond_get_alternate_expr. Leaves the condition
+ * alone if it is not recognized.
+ **/
+void
+gnm_style_cond_canonicalize (GnmStyleCond *cond)
+{
+ GnmExpr const *expr, *expr2;
+ GnmExprTop const *texpr;
+ gboolean negate = FALSE;
+ GnmFunc const *iserror;
+ GnmFunc const *find;
+ GnmStyleCondOp newop = GNM_STYLE_COND_CUSTOM;
+
+ g_return_if_fail (cond != NULL);
+
+ if (cond->op != GNM_STYLE_COND_CUSTOM)
+ return;
+
+ texpr = gnm_style_cond_get_expr (cond, 0);
+ if (!texpr)
+ return;
+ expr = texpr->expr;
+
+ if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL &&
+ expr->func.argc == 1 &&
+ expr->func.func == gnm_func_lookup_or_add_placeholder ("NOT")) {
+ negate = TRUE;
+ expr = expr->func.argv[0];
+ }
+
+ iserror = gnm_func_lookup_or_add_placeholder ("ISERROR");
+ find = gnm_func_lookup_or_add_placeholder ("FIND");
+
+ if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL &&
+ expr->func.argc == 1 && expr->func.func == iserror &&
+ isself (expr->func.argv[0])) {
+ newop = negate
+ ? GNM_STYLE_COND_NOT_CONTAINS_ERR
+ : GNM_STYLE_COND_CONTAINS_ERR;
+ } else if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL &&
+ expr->func.argc == 1 && expr->func.func == iserror &&
+ (expr2 = expr->func.argv[0]) &&
+ GNM_EXPR_GET_OPER (expr2) == GNM_EXPR_OP_FUNCALL &&
+ expr2->func.argc == 2 && expr2->func.func == find &&
+ issinglespace (expr2->func.argv[0]) &&
+ isself (expr2->func.argv[1])) {
+ newop = negate
+ ? GNM_STYLE_COND_CONTAINS_BLANKS
+ : GNM_STYLE_COND_NOT_CONTAINS_BLANKS;
+ }
+
+ if (newop != GNM_STYLE_COND_CUSTOM) {
+ gnm_style_cond_set_expr (cond, NULL, 0);
+ cond->op = newop;
+ }
+}
+
+
static void
gnm_style_conditions_finalize (GObject *obj)
{
diff --git a/src/style-conditions.h b/src/style-conditions.h
index e4790ae..4229496 100644
--- a/src/style-conditions.h
+++ b/src/style-conditions.h
@@ -57,7 +57,9 @@ GnmExprTop const *gnm_style_cond_get_expr (GnmStyleCond const *cond,
void gnm_style_cond_set_expr (GnmStyleCond *cond,
GnmExprTop const *texpr,
unsigned idx);
+
GnmExprTop const *gnm_style_cond_get_alternate_expr (GnmStyleCond const *cond);
+void gnm_style_cond_canonicalize (GnmStyleCond *cond);
Sheet *gnm_style_cond_get_sheet (GnmStyleCond const *cond);
void gnm_style_cond_set_sheet (GnmStyleCond *cond, Sheet *sheet);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]