[gnumeric] cls: fix import/export of alignment block in conditional formatting.



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]