]> source.dussan.org Git - poi.git/commitdiff
Start to support CF12 headers for #58130
authorNick Burch <nick@apache.org>
Sun, 12 Jul 2015 17:58:27 +0000 (17:58 +0000)
committerNick Burch <nick@apache.org>
Sun, 12 Jul 2015 17:58:27 +0000 (17:58 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1690494 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/dev/BiffViewer.java
src/java/org/apache/poi/hssf/record/CFHeader12Record.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
src/java/org/apache/poi/hssf/record/RecordFactory.java
src/java/org/apache/poi/hssf/record/common/FtrHeader.java

index 42d851de7686343b4c1bcdd649090988c6eed4ce..a14339a66db34515f44e5ad9cce3e44bcb38bbd4 100644 (file)
@@ -180,6 +180,7 @@ public final class BiffViewer {
                        case BottomMarginRecord.sid:   return new BottomMarginRecord(in);
                        case BoundSheetRecord.sid:     return new BoundSheetRecord(in);
                        case CFHeaderRecord.sid:       return new CFHeaderRecord(in);
+            case CFHeader12Record.sid:     return new CFHeader12Record(in);
                        case CFRuleRecord.sid:         return new CFRuleRecord(in);
                        case CalcCountRecord.sid:      return new CalcCountRecord(in);
                        case CalcModeRecord.sid:       return new CalcModeRecord(in);
diff --git a/src/java/org/apache/poi/hssf/record/CFHeader12Record.java b/src/java/org/apache/poi/hssf/record/CFHeader12Record.java
new file mode 100644 (file)
index 0000000..4b0345e
--- /dev/null
@@ -0,0 +1,75 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Conditional Formatting Header v12 record CFHEADER12 (0x0879),
+ *  for conditional formattings introduced in Excel 2007 and newer.
+ */
+public final class CFHeader12Record extends CFHeaderRecord {
+    public static final short sid = 0x0879;
+
+    private FtrHeader futureHeader;
+
+    /** Creates new CFHeaderRecord */
+    public CFHeader12Record() {
+        super();
+        futureHeader = new FtrHeader();
+        futureHeader.setRecordType(sid);
+    }
+    public CFHeader12Record(CellRangeAddress[] regions, int nRules) {
+        super(regions, nRules);
+        futureHeader = new FtrHeader();
+        futureHeader.setRecordType(sid);
+    }
+
+       public CFHeader12Record(RecordInputStream in)
+       {
+           futureHeader = new FtrHeader(in);
+           read(in);
+       }
+
+       @Override
+       protected String getRecordName() {
+        return "CFHEADER12";
+    }
+       
+    protected int getDataSize() {
+               return FtrHeader.getDataSize() + super.getDataSize();
+       }
+       
+       public void serialize(LittleEndianOutput out) {
+           futureHeader.serialize(out);
+           super.serialize(out);
+       }
+
+       public short getSid() {
+               return sid;
+       }
+
+       public Object clone() {
+               CFHeader12Record result = new CFHeader12Record();
+               result.futureHeader = (FtrHeader)futureHeader.clone();
+               // TODO Clone the rest via the base
+               return result;
+       }
+}
index bfdd4b05793c240fd8b189960b7db81c3585cb5f..55dd98d50a38d1885c96e5ae05a722b0f3a9a43a 100644 (file)
@@ -26,12 +26,13 @@ import org.apache.poi.util.LittleEndianOutput;
  * Conditional Formatting Header record CFHEADER (0x01B0).
  * Used to describe a {@link CFRuleRecord}.
  * @see CFHeader12Record
+ * TODO Move most of the logic into a base class
  */
-public final class CFHeaderRecord extends StandardRecord {
+public class CFHeaderRecord extends StandardRecord {
        public static final short sid = 0x01B0;
 
        private int field_1_numcf;
-       private int field_2_need_recalculation;
+       private int field_2_need_recalculation_and_id;
        private CellRangeAddress field_3_enclosing_cell_range;
        private CellRangeAddressList field_4_cell_ranges;
 
@@ -47,40 +48,51 @@ public final class CFHeaderRecord extends StandardRecord {
                field_1_numcf = nRules;
        }
 
-       public CFHeaderRecord(RecordInputStream in)
-       {
+       public CFHeaderRecord(RecordInputStream in) {
+           read(in);
+       }
+       protected void read(RecordInputStream in) {
                field_1_numcf = in.readShort();
-               field_2_need_recalculation = in.readShort();
+               field_2_need_recalculation_and_id = in.readShort();
                field_3_enclosing_cell_range = new CellRangeAddress(in);
                field_4_cell_ranges = new CellRangeAddressList(in);
        }
        
-       public int getNumberOfConditionalFormats()
-       {
+       public int getNumberOfConditionalFormats() {
                return field_1_numcf;
        }
-       public void setNumberOfConditionalFormats(int n)
-       {
+       public void setNumberOfConditionalFormats(int n) {
                field_1_numcf=n;
        }
        
-       public boolean getNeedRecalculation()
+       public boolean getNeedRecalculation() {
+           // Held on the 1st bit
+           return field_2_need_recalculation_and_id % 2 == 1;
+       }
+       public void setNeedRecalculation(boolean b) {
+           // held on the first bit
+           if (b == getNeedRecalculation()) return;
+           if (b) field_2_need_recalculation_and_id++;
+           else   field_2_need_recalculation_and_id--;
+       }
+       
+       public int getID()
        {
-               return field_2_need_recalculation==1?true:false;
+           // Remaining 15 bits of field 2
+           return field_2_need_recalculation_and_id>>1;
        }
-
-       public void setNeedRecalculation(boolean b)
+       public void setID(int id)
        {
-               field_2_need_recalculation=b?1:0;
+        // Remaining 15 bits of field 2
+           boolean needsRecalc = getNeedRecalculation();
+           field_2_need_recalculation_and_id = (id<<1);
+           if (needsRecalc) field_2_need_recalculation_and_id++;
        }
        
-       public CellRangeAddress getEnclosingCellRange()
-       {
+       public CellRangeAddress getEnclosingCellRange() {
                return field_3_enclosing_cell_range;
        }
-
-       public void setEnclosingCellRange(CellRangeAddress cr)
-       {
+       public void setEnclosingCellRange(CellRangeAddress cr) {
                field_3_enclosing_cell_range = cr;
        }
 
@@ -89,8 +101,7 @@ public final class CFHeaderRecord extends StandardRecord {
         * modify the enclosing cell range accordingly.
         * @param cellRanges - list of CellRange objects
         */
-       public void setCellRanges(CellRangeAddress[] cellRanges)
-       {
+       public void setCellRanges(CellRangeAddress[] cellRanges) {
                if(cellRanges == null)
                {
                        throw new IllegalArgumentException("cellRanges must not be null");
@@ -111,11 +122,13 @@ public final class CFHeaderRecord extends StandardRecord {
                return field_4_cell_ranges.getCellRangeAddresses();
        }
 
-       public String toString()
-       {
+       protected String getRecordName() {
+           return "CFHEADER";
+       }
+       public String toString() {
                StringBuffer buffer = new StringBuffer();
 
-               buffer.append("[CFHEADER]\n");
+               buffer.append("[").append(getRecordName()).append("]\n");
                buffer.append(" .id             = ").append(Integer.toHexString(sid)).append("\n");
                buffer.append(" .numCF                  = ").append(getNumberOfConditionalFormats()).append("\n");
                buffer.append(" .needRecalc        = ").append(getNeedRecalculation()).append("\n");
@@ -126,7 +139,7 @@ public final class CFHeaderRecord extends StandardRecord {
                        buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
                }
                buffer.append("]\n");
-               buffer.append("[/CFHEADER]\n");
+               buffer.append("[/").append(getRecordName()).append("]\n");
                return buffer.toString();
        }
 
@@ -137,9 +150,8 @@ public final class CFHeaderRecord extends StandardRecord {
        }
        
        public void serialize(LittleEndianOutput out) {
-
                out.writeShort(field_1_numcf);
-               out.writeShort(field_2_need_recalculation);
+               out.writeShort(field_2_need_recalculation_and_id);
                field_3_enclosing_cell_range.serialize(out);
                field_4_cell_ranges.serialize(out);
        }
@@ -148,11 +160,10 @@ public final class CFHeaderRecord extends StandardRecord {
                return sid;
        }
 
-       public Object clone() 
-       {
+       public Object clone() {
                CFHeaderRecord result = new CFHeaderRecord();
                result.field_1_numcf = field_1_numcf;
-               result.field_2_need_recalculation = field_2_need_recalculation;
+               result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
                result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
                result.field_4_cell_ranges = field_4_cell_ranges.copy();
                return result;
index 3a1f7acca307a831465559ad69130cc38aaf0cc7..83622e1fb586f92b22d23c87ccd1dde85e3c485a 100644 (file)
@@ -155,6 +155,7 @@ public final class RecordFactory {
                CalcCountRecord.class,
                CalcModeRecord.class,
                CFHeaderRecord.class,
+        CFHeader12Record.class,
                CFRuleRecord.class,
                ChartRecord.class,
                ChartTitleFormatRecord.class,
@@ -166,7 +167,7 @@ public final class RecordFactory {
                CRNRecord.class,
                DateWindow1904Record.class,
                DBCellRecord.class,
-                DConRefRecord.class,
+        DConRefRecord.class,
                DefaultColWidthRecord.class,
                DefaultRowHeightRecord.class,
                DeltaRecord.class,
index dc2d4e26e95ea022a91065d90548eda504fab832..b240e8112fa3a81a0e9fbac21c0b001ffc73dc06 100644 (file)
@@ -32,7 +32,7 @@ public final class FtrHeader {
        private short recordType;
        /** This is a FrtFlags */
        private short grbitFrt;
-       /** MUST be 8 bytes and all zero */
+       /** MUST be 8 bytes and all zero TODO Correct this! */
        private byte[] reserved;
 
        public FtrHeader() {
@@ -86,4 +86,12 @@ public final class FtrHeader {
        public void setReserved(byte[] reserved) {
                this.reserved = reserved;
        }
+       
+       public Object clone() {
+           FtrHeader result = new FtrHeader();
+           result.recordType = recordType;
+           result.grbitFrt = grbitFrt;
+           result.reserved = reserved;
+           return result;
+       }
 }
\ No newline at end of file