--- /dev/null
+/* ====================================================================
+ 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;
+ }
+}
* 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;
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;
}
* 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");
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");
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();
}
}
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);
}
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;