[gnumeric] cls: fix import/export of alignment block in conditional formatting.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] cls: fix import/export of alignment block in conditional formatting.
- Date: Fri, 14 Mar 2014 19:05:26 +0000 (UTC)
commit 365a1105576283f69dff2ace22146aae832ebb63
Author: Morten Welinder <terra gnome org>
Date: Fri Mar 14 15:04:53 2014 -0400
cls: fix import/export of alignment block in conditional formatting.
NEWS | 5 +-
plugins/excel/ms-excel-read.c | 147 +++++++++++++++---------
plugins/excel/ms-excel-write.c | 255 +++++++++++++++++++++++++---------------
3 files changed, 256 insertions(+), 151 deletions(-)
---
diff --git a/NEWS b/NEWS
index 680b9dc..16f8294 100644
--- a/NEWS
+++ b/NEWS
@@ -20,9 +20,10 @@ Morten:
* Import xlsx auto-filters. [#725460]
* Update Gnumeric schema.
* Fix rich text problem. [#726086]
- * Improve xls export of conditional formats.
- * Fix case sensitivity for conditional formats. [#726246]Jean:
+ * Improve xls import/export of conditional formats. [#726202]
+ * Fix case sensitivity for conditional formats. [#726246]
+--------------------------------------------------------------------------
Gnumeric 1.12.12
Andreas:
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 5f004cf..1a2bdb6 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -2396,6 +2396,63 @@ excel_map_pattern_index_from_excel (int const i)
return map_from_excel[i];
}
+static GnmHAlign
+halign_from_excel (guint e)
+{
+ switch (e) {
+ case 0: return GNM_HALIGN_GENERAL;
+ case 1: return GNM_HALIGN_LEFT;
+ case 2: return GNM_HALIGN_CENTER;
+ case 3: return GNM_HALIGN_RIGHT;
+ case 4: return GNM_HALIGN_FILL;
+ case 5: return GNM_HALIGN_JUSTIFY;
+ case 6: return GNM_HALIGN_CENTER_ACROSS_SELECTION;
+ case 7: return GNM_HALIGN_DISTRIBUTED;
+
+ default:
+ g_printerr ("Unknown halign %d\n", e);
+ return GNM_HALIGN_GENERAL;
+ }
+}
+
+static GnmVAlign
+valign_from_excel (guint e)
+{
+ switch (e) {
+ case 0: return GNM_VALIGN_TOP;
+ case 1: return GNM_VALIGN_CENTER;
+ case 2: return GNM_VALIGN_BOTTOM;
+ case 3: return GNM_VALIGN_JUSTIFY;
+ case 4: return GNM_VALIGN_DISTRIBUTED;
+ default:
+ g_printerr ("Unknown valign %d\n", e);
+ return GNM_VALIGN_TOP;
+ }
+}
+
+static int
+rotation_from_excel_v8 (guint e)
+{
+ if (e == 0xff)
+ return -1;
+ else if (e > 90)
+ return 360 + 90 - e;
+ else
+ return e;
+}
+
+static int
+rotation_from_excel_v7 (guint e)
+{
+ switch (e) {
+ default:
+ case 0: return 0;
+ case 1: return -1;
+ case 2: return 90;
+ case 3: return 270;
+ }
+}
+
static void
excel_read_XF_OLD (BiffQuery *q, GnmXLImporter *importer)
{
@@ -2562,61 +2619,12 @@ excel_read_XF (BiffQuery *q, GnmXLImporter *importer)
}
data = GSF_LE_GET_GUINT16 (q->data + 6);
- subdata = data & 0x0007;
- switch (subdata) {
- case 0: xf->halign = GNM_HALIGN_GENERAL; break;
- case 1: xf->halign = GNM_HALIGN_LEFT; break;
- case 2: xf->halign = GNM_HALIGN_CENTER; break;
- case 3: xf->halign = GNM_HALIGN_RIGHT; break;
- case 4: xf->halign = GNM_HALIGN_FILL; break;
- case 5: xf->halign = GNM_HALIGN_JUSTIFY; break;
- case 6:
- /*
- * All adjacent blank cells with this type of alignment
- * are merged into a single span. cursor still behaves
- * normally and the span is adjusted if contents are changed.
- * Use center for now.
- */
- xf->halign = GNM_HALIGN_CENTER_ACROSS_SELECTION;
- break;
-
- /* no idea what this does */
- case 7 : xf->halign = GNM_HALIGN_DISTRIBUTED; break;
-
- default:
- xf->halign = GNM_HALIGN_JUSTIFY;
- g_printerr ("Unknown halign %d\n", subdata);
- break;
- }
+ xf->halign = halign_from_excel (data & 0x0007);
xf->wrap_text = (data & 0x0008) != 0;
- subdata = (data & 0x0070) >> 4;
- switch (subdata) {
- case 0: xf->valign = GNM_VALIGN_TOP; break;
- case 1: xf->valign = GNM_VALIGN_CENTER; break;
- case 2: xf->valign = GNM_VALIGN_BOTTOM; break;
- case 3: xf->valign = GNM_VALIGN_JUSTIFY; break;
- /* What does this do ?? */
- case 4: xf->valign = GNM_VALIGN_DISTRIBUTED; break;
- default:
- g_printerr ("Unknown valign %d\n", subdata);
- break;
- }
-
- if (importer->ver >= MS_BIFF_V8) {
- xf->rotation = (data >> 8);
- if (xf->rotation == 0xff)
- xf->rotation = -1;
- else if (xf->rotation > 90)
- xf->rotation = 360 + 90 - xf->rotation;
- } else {
- subdata = (data & 0x0300) >> 8;
- switch (subdata) {
- case 0: xf->rotation = 0; break;
- case 1: xf->rotation = -1; break;
- case 2: xf->rotation = 90; break;
- case 3: xf->rotation = 270; break;
- }
- }
+ xf->valign = valign_from_excel ((data & 0x0070) >> 4);
+ xf->rotation = (importer->ver >= MS_BIFF_V8)
+ ? rotation_from_excel_v8 (data >> 8)
+ : rotation_from_excel_v7 (data >> 8);
if (importer->ver >= MS_BIFF_V8) {
guint16 const data = GSF_LE_GET_GUINT16 (q->data + 8);
@@ -5301,6 +5309,37 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc)
offset += 118;
}
+ if (flags & 0x08000000) { /* alignment block */
+ guint16 d1 = GSF_LE_GET_GUINT16 (q->data + offset);
+ guint16 d2 = GSF_LE_GET_GUINT16 (q->data + offset + 2);
+
+ if (0 == (flags & 0x1))
+ gnm_style_set_align_h (overlay,
+ halign_from_excel ((d1 >> 0) & 7));
+
+ if (0 == (flags & 0x2))
+ gnm_style_set_align_v (overlay,
+ valign_from_excel ((d1 >> 4) & 7));
+
+ if (0 == (flags & 0x4))
+ gnm_style_set_wrap_text (overlay, ((d1 >> 3) & 1));
+
+ if (0 == (flags & 0x8)) {
+ int r = (esheet_ver (esheet) >= MS_BIFF_V8
+ ? rotation_from_excel_v8 (d1 >> 8)
+ : rotation_from_excel_v7 (d1 >> 8));
+ gnm_style_set_rotation (overlay, r);
+ }
+
+ if (0 == (flags & 0x20))
+ gnm_style_set_indent (overlay, ((d2 >> 0) & 0xf));
+
+ if (0 == (flags & 0x40))
+ gnm_style_set_shrink_to_fit (overlay, ((d2 >> 4) & 1));
+
+ offset += 8;
+ }
+
if (flags & 0x10000000) { /* borders */
guint16 patterns = GSF_LE_GET_GUINT16 (q->data + offset);
guint32 colours = GSF_LE_GET_GUINT32 (q->data + offset + 2);
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index c149c73..161aabe 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -982,6 +982,99 @@ map_script_to_xl (GnmStyle const *style)
}
}
+static guint
+halign_to_excel (GnmHAlign halign)
+{
+ guint ialign;
+
+ switch (halign) {
+ case GNM_HALIGN_GENERAL:
+ ialign = MS_BIFF_H_A_GENERAL;
+ break;
+ case GNM_HALIGN_LEFT:
+ ialign = MS_BIFF_H_A_LEFT;
+ break;
+ case GNM_HALIGN_RIGHT:
+ ialign = MS_BIFF_H_A_RIGHT;
+ break;
+ case GNM_HALIGN_CENTER:
+ ialign = MS_BIFF_H_A_CENTER;
+ break;
+ case GNM_HALIGN_FILL:
+ ialign = MS_BIFF_H_A_FILL;
+ break;
+ case GNM_HALIGN_JUSTIFY:
+ ialign = MS_BIFF_H_A_JUSTIFTY;
+ break;
+ case GNM_HALIGN_CENTER_ACROSS_SELECTION:
+ ialign = MS_BIFF_H_A_CENTER_ACROSS_SELECTION;
+ break;
+ case GNM_HALIGN_DISTRIBUTED:
+ ialign = MS_BIFF_H_A_DISTRIBUTED;
+ break;
+ default:
+ ialign = MS_BIFF_H_A_GENERAL;
+ }
+
+ return ialign;
+}
+
+static guint
+valign_to_excel (GnmVAlign valign)
+{
+ guint ialign;
+
+ switch (valign) {
+ case GNM_VALIGN_TOP:
+ ialign = MS_BIFF_V_A_TOP;
+ break;
+ case GNM_VALIGN_BOTTOM:
+ ialign = MS_BIFF_V_A_BOTTOM;
+ break;
+ case GNM_VALIGN_CENTER:
+ ialign = MS_BIFF_V_A_CENTER;
+ break;
+ case GNM_VALIGN_JUSTIFY:
+ ialign = MS_BIFF_V_A_JUSTIFY;
+ break;
+ case GNM_VALIGN_DISTRIBUTED:
+ ialign = MS_BIFF_V_A_DISTRIBUTED;
+ break;
+ default:
+ ialign = MS_BIFF_V_A_TOP;
+ }
+
+ return ialign;
+}
+
+static guint
+rotation_to_excel_v7 (int rotation)
+{
+ if (rotation < 0)
+ return 1;
+ if (rotation == 0)
+ return 0;
+ if (rotation <= 45)
+ return 0;
+ if (rotation <= 135)
+ return 2;
+ if (rotation <= 225)
+ return 0;
+ if (rotation <= 315)
+ return 3;
+ return 0;
+}
+static guint
+rotation_to_excel_v8 (int rotation)
+{
+ if (rotation < 0)
+ return 0xff;
+ rotation = rotation % 360;
+ if (rotation > 90)
+ return 360 + 90 - rotation;
+ return rotation;
+}
+
static void
cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
ExcelWriteSheet *esheet)
@@ -990,7 +1083,7 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
BiffPut *bp = esheet->ewb->bp;
guint16 range_count;
guint8 buf[14], type, op;
- guint32 flags = 0x38C3FF; /* these are always true */
+ guint32 flags = 0x0038C380; /* these are always true */
unsigned i, expr0_len, expr1_len, header_pos;
GPtrArray const *details = gnm_style_conditions_details (sc);
unsigned det_len = details ? details->len : 0;
@@ -1088,12 +1181,77 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
flags |= 0x04000000;
}
+ if (gnm_style_is_element_set (s, MSTYLE_ALIGN_H) ||
+ gnm_style_is_element_set (s, MSTYLE_ALIGN_V) ||
+ gnm_style_is_element_set (s, MSTYLE_WRAP_TEXT) ||
+ gnm_style_is_element_set (s, MSTYLE_ROTATION) ||
+ /* what is just-last? */
+ gnm_style_is_element_set (s, MSTYLE_INDENT) ||
+ gnm_style_is_element_set (s, MSTYLE_SHRINK_TO_FIT) ||
+ gnm_style_is_element_set (s, MSTYLE_TEXT_DIR)) {
+ guint16 d1 = 0;
+ guint16 d2 = 0;
+ guint16 d3 = 0;
+
+ if (gnm_style_is_element_set (s, MSTYLE_ALIGN_H))
+ d1 |= (halign_to_excel (gnm_style_get_align_h (s)) << 0);
+ else
+ flags |= 1;
+
+ if (gnm_style_is_element_set (s, MSTYLE_ALIGN_V))
+ d1 |= (valign_to_excel (gnm_style_get_align_v (s)) << 4);
+ else
+ flags |= 2;
+
+ if (gnm_style_is_element_set (s, MSTYLE_WRAP_TEXT))
+ d1 |= ((gnm_style_get_wrap_text (s) ? 1 : 0) << 3);
+ else
+ flags |= 4;
+
+ if (gnm_style_is_element_set (s, MSTYLE_ROTATION))
+ d1 |= (bp->version >= MS_BIFF_V8
+ ? rotation_to_excel_v8 (gnm_style_get_rotation (s))
+ : rotation_to_excel_v7 (gnm_style_get_rotation (s))) << 8;
+ else
+ flags |= 8;
+
+ flags |= 0x10; /* just-last? */
+
+ if (gnm_style_is_element_set (s, MSTYLE_INDENT)) {
+ d2 |= ((gnm_style_get_indent (s) & 0xf) << 0);
+ } else
+ flags |= 0x20;
+
+ if (gnm_style_is_element_set (s, MSTYLE_SHRINK_TO_FIT))
+ d2 |= ((gnm_style_get_shrink_to_fit (s) ? 1 : 0) << 4);
+ else
+ flags |= 0x40;
+
+ if (gnm_style_is_element_set (s, MSTYLE_TEXT_DIR)) {
+ switch (gnm_style_get_text_dir (s)) {
+ case GNM_TEXT_DIR_RTL: d2 |= (2 << 6); break;
+ case GNM_TEXT_DIR_LTR: d2 |= (1 << 6); break;
+ case GNM_TEXT_DIR_CONTEXT: d2 |= (0 << 6); break;
+ default: break;
+ }
+ } else
+ flags |= 0x80000000;
+
+ flags |= 0x08000000;
+
+ GSF_LE_SET_GUINT16 (buf+0, d1);
+ GSF_LE_SET_GUINT16 (buf+2, d2);
+ GSF_LE_SET_GUINT16 (buf+6, d3);
+ GSF_LE_SET_GUINT16 (buf+6, 0);
+ ms_biff_put_var_write (bp, buf, 8);
+ }
+
if (gnm_style_is_element_set (s, MSTYLE_BORDER_LEFT) ||
gnm_style_is_element_set (s, MSTYLE_BORDER_RIGHT) ||
gnm_style_is_element_set (s, MSTYLE_BORDER_TOP) ||
gnm_style_is_element_set (s, MSTYLE_BORDER_BOTTOM)) {
guint16 p = 0;
- guint32 c = 0;
+ guint32 c = 0;
if (write_border (esheet, s, MSTYLE_BORDER_LEFT, &p, &c, 0, 0))
flags |= 0x0400;
if (write_border (esheet, s, MSTYLE_BORDER_RIGHT, &p, &c, 4, 7))
@@ -2710,99 +2868,6 @@ gather_styles (ExcelWriteState *ewb)
}
}
-static guint
-halign_to_excel (GnmHAlign halign)
-{
- guint ialign;
-
- switch (halign) {
- case GNM_HALIGN_GENERAL:
- ialign = MS_BIFF_H_A_GENERAL;
- break;
- case GNM_HALIGN_LEFT:
- ialign = MS_BIFF_H_A_LEFT;
- break;
- case GNM_HALIGN_RIGHT:
- ialign = MS_BIFF_H_A_RIGHT;
- break;
- case GNM_HALIGN_CENTER:
- ialign = MS_BIFF_H_A_CENTER;
- break;
- case GNM_HALIGN_FILL:
- ialign = MS_BIFF_H_A_FILL;
- break;
- case GNM_HALIGN_JUSTIFY:
- ialign = MS_BIFF_H_A_JUSTIFTY;
- break;
- case GNM_HALIGN_CENTER_ACROSS_SELECTION:
- ialign = MS_BIFF_H_A_CENTER_ACROSS_SELECTION;
- break;
- case GNM_HALIGN_DISTRIBUTED:
- ialign = MS_BIFF_H_A_DISTRIBUTED;
- break;
- default:
- ialign = MS_BIFF_H_A_GENERAL;
- }
-
- return ialign;
-}
-
-static guint
-valign_to_excel (GnmVAlign valign)
-{
- guint ialign;
-
- switch (valign) {
- case GNM_VALIGN_TOP:
- ialign = MS_BIFF_V_A_TOP;
- break;
- case GNM_VALIGN_BOTTOM:
- ialign = MS_BIFF_V_A_BOTTOM;
- break;
- case GNM_VALIGN_CENTER:
- ialign = MS_BIFF_V_A_CENTER;
- break;
- case GNM_VALIGN_JUSTIFY:
- ialign = MS_BIFF_V_A_JUSTIFY;
- break;
- case GNM_VALIGN_DISTRIBUTED:
- ialign = MS_BIFF_V_A_DISTRIBUTED;
- break;
- default:
- ialign = MS_BIFF_V_A_TOP;
- }
-
- return ialign;
-}
-
-static guint
-rotation_to_excel_v7 (int rotation)
-{
- if (rotation < 0)
- return 1;
- if (rotation == 0)
- return 0;
- if (rotation <= 45)
- return 0;
- if (rotation <= 135)
- return 2;
- if (rotation <= 225)
- return 0;
- if (rotation <= 315)
- return 3;
- return 0;
-}
-static guint
-rotation_to_excel_v8 (int rotation)
-{
- if (rotation < 0)
- return 0xff;
- rotation = rotation % 360;
- if (rotation > 90)
- return 360 + 90 - rotation;
- return rotation;
-}
-
/**
* get_xf_differences
* @ewb workbook
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]