You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC
svn commit: r1890120 [9/43] - in /poi/trunk/poi/src:
main/java/org/apache/poi/ main/java/org/apache/poi/ddf/
main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/
main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/
main/java/...
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TextObjectRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TextObjectRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TextObjectRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TextObjectRecord.java Sat May 22 20:56:44 2021
@@ -38,306 +38,306 @@ import org.apache.poi.util.RecordFormatE
* contains the formatting runs.
*/
public final class TextObjectRecord extends ContinuableRecord {
- public static final short sid = 0x01B6;
+ public static final short sid = 0x01B6;
- private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved
+ private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved
- private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
- private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
- private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
-
- public static final short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
- public static final short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
- public static final short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
- public static final short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
- public static final short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
- public static final short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
- public static final short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
- public static final short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
-
- public static final short TEXT_ORIENTATION_NONE = 0;
- public static final short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
- public static final short TEXT_ORIENTATION_ROT_RIGHT = 2;
- public static final short TEXT_ORIENTATION_ROT_LEFT = 3;
-
- private int field_1_options;
- private int field_2_textOrientation;
- private int field_3_reserved4;
- private int field_4_reserved5;
- private int field_5_reserved6;
- private int field_8_reserved7;
-
- private HSSFRichTextString _text;
-
- /*
- * Note - the next three fields are very similar to those on
- * EmbededObjectRefSubRecord(ftPictFmla 0x0009)
- *
- * some observed values for the 4 bytes preceding the formula: C0 5E 86 03
- * C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03
- */
- private int _unknownPreFormulaInt;
- /** expect tRef, tRef3D, tArea, tArea3D or tName */
- private OperandPtg _linkRefPtg;
- /**
- * Not clear if needed . Excel seems to be OK if this byte is not present.
- * Value is often the same as the earlier firstColumn byte. */
- private Byte _unknownPostFormulaByte;
-
- public TextObjectRecord() {}
-
- public TextObjectRecord(TextObjectRecord other) {
- super(other);
- field_1_options = other.field_1_options;
- field_2_textOrientation = other.field_2_textOrientation;
- field_3_reserved4 = other.field_3_reserved4;
- field_4_reserved5 = other.field_4_reserved5;
- field_5_reserved6 = other.field_5_reserved6;
- field_8_reserved7 = other.field_8_reserved7;
-
- _text = other._text;
-
- if (other._linkRefPtg != null) {
- _unknownPreFormulaInt = other._unknownPreFormulaInt;
- _linkRefPtg = other._linkRefPtg.copy();
- _unknownPostFormulaByte = other._unknownPostFormulaByte;
- }
- }
-
- public TextObjectRecord(RecordInputStream in) {
- field_1_options = in.readUShort();
- field_2_textOrientation = in.readUShort();
- field_3_reserved4 = in.readUShort();
- field_4_reserved5 = in.readUShort();
- field_5_reserved6 = in.readUShort();
- int field_6_textLength = in.readUShort();
- int field_7_formattingDataLength = in.readUShort();
- field_8_reserved7 = in.readInt();
-
- if (in.remaining() > 0) {
- // Text Objects can have simple reference formulas
- // (This bit not mentioned in the MS document)
- if (in.remaining() < 11) {
- throw new RecordFormatException("Not enough remaining data for a link formula");
- }
- int formulaSize = in.readUShort();
- _unknownPreFormulaInt = in.readInt();
- Ptg[] ptgs = Ptg.readTokens(formulaSize, in);
- if (ptgs.length != 1) {
- throw new RecordFormatException("Read " + ptgs.length
- + " tokens but expected exactly 1");
- }
- _linkRefPtg = (OperandPtg) ptgs[0];
- _unknownPostFormulaByte = in.remaining() > 0 ? in.readByte() : null;
- } else {
- _linkRefPtg = null;
- }
- if (in.remaining() > 0) {
- throw new RecordFormatException("Unused " + in.remaining() + " bytes at end of record");
- }
-
- String text;
- if (field_6_textLength > 0) {
- text = readRawString(in, field_6_textLength);
- } else {
- text = "";
- }
- _text = new HSSFRichTextString(text);
-
- if (field_7_formattingDataLength > 0) {
- processFontRuns(in, _text, field_7_formattingDataLength);
- }
- }
-
- private static String readRawString(RecordInputStream in, int textLength) {
- byte compressByte = in.readByte();
- boolean isCompressed = (compressByte & 0x01) == 0;
- if (isCompressed) {
- return in.readCompressedUnicode(textLength);
- }
- return in.readUnicodeLEString(textLength);
- }
-
- private static void processFontRuns(RecordInputStream in, HSSFRichTextString str,
- int formattingRunDataLength) {
- if (formattingRunDataLength % FORMAT_RUN_ENCODED_SIZE != 0) {
- throw new RecordFormatException("Bad format run data length " + formattingRunDataLength
- + ")");
- }
- int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE;
- for (int i = 0; i < nRuns; i++) {
- short index = in.readShort();
- short iFont = in.readShort();
- in.readInt(); // skip reserved.
- str.applyFont(index, str.length(), iFont);
- }
- }
-
- public short getSid() {
- return sid;
- }
-
- private void serializeTXORecord(ContinuableRecordOutput out) {
-
- out.writeShort(field_1_options);
- out.writeShort(field_2_textOrientation);
- out.writeShort(field_3_reserved4);
- out.writeShort(field_4_reserved5);
- out.writeShort(field_5_reserved6);
- out.writeShort(_text.length());
- out.writeShort(getFormattingDataLength());
- out.writeInt(field_8_reserved7);
-
- if (_linkRefPtg != null) {
- int formulaSize = _linkRefPtg.getSize();
- out.writeShort(formulaSize);
- out.writeInt(_unknownPreFormulaInt);
- _linkRefPtg.write(out);
- if (_unknownPostFormulaByte != null) {
- out.writeByte(_unknownPostFormulaByte);
- }
- }
- }
-
- private void serializeTrailingRecords(ContinuableRecordOutput out) {
- out.writeContinue();
- out.writeStringData(_text.getString());
- out.writeContinue();
- writeFormatData(out, _text);
- }
-
- protected void serialize(ContinuableRecordOutput out) {
-
- serializeTXORecord(out);
- if (_text.getString().length() > 0) {
- serializeTrailingRecords(out);
- }
- }
-
- private int getFormattingDataLength() {
- if (_text.length() < 1) {
- // important - no formatting data if text is empty
- return 0;
- }
- return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE;
- }
-
- private static void writeFormatData(ContinuableRecordOutput out , HSSFRichTextString str) {
- int nRuns = str.numFormattingRuns();
- for (int i = 0; i < nRuns; i++) {
- out.writeShort(str.getIndexOfFormattingRun(i));
- int fontIndex = str.getFontOfFormattingRun(i);
- out.writeShort(fontIndex == HSSFRichTextString.NO_FONT ? 0 : fontIndex);
- out.writeInt(0); // skip reserved
- }
- out.writeShort(str.length());
- out.writeShort(0);
- out.writeInt(0); // skip reserved
- }
-
- /**
- * Sets the Horizontal text alignment field value.
- *
- * @param value The horizontal alignment, use one of the HORIZONTAL_TEXT_ALIGNMENT_... constants in this class
- */
- public void setHorizontalTextAlignment(int value) {
- field_1_options = HorizontalTextAlignment.setValue(field_1_options, value);
- }
-
- /**
- * @return the Horizontal text alignment field value.
- */
- public int getHorizontalTextAlignment() {
- return HorizontalTextAlignment.getValue(field_1_options);
- }
-
- /**
- * Sets the Vertical text alignment field value.
- *
- * @param value The vertical alignment, use one of the VERTIUCAL_TEST_ALIGNMENT_... constants in this class
- */
- public void setVerticalTextAlignment(int value) {
- field_1_options = VerticalTextAlignment.setValue(field_1_options, value);
- }
-
- /**
- * @return the Vertical text alignment field value.
- */
- public int getVerticalTextAlignment() {
- return VerticalTextAlignment.getValue(field_1_options);
- }
-
- /**
- * Sets the text locked field value.
- *
- * @param value If the text should be locked
- */
- public void setTextLocked(boolean value) {
- field_1_options = textLocked.setBoolean(field_1_options, value);
- }
-
- /**
- * @return the text locked field value.
- */
- public boolean isTextLocked() {
- return textLocked.isSet(field_1_options);
- }
-
- /**
- * Get the text orientation field for the TextObjectBase record.
- *
- * @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
- * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
- */
- public int getTextOrientation() {
- return field_2_textOrientation;
- }
-
- /**
- * Set the text orientation field for the TextObjectBase record.
- *
- * @param textOrientation
- * One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
- * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
- */
- public void setTextOrientation(int textOrientation) {
- this.field_2_textOrientation = textOrientation;
- }
-
- public HSSFRichTextString getStr() {
- return _text;
- }
-
- public void setStr(HSSFRichTextString str) {
- _text = str;
- }
-
- public Ptg getLinkRefPtg() {
- return _linkRefPtg;
- }
-
- @Override
- public TextObjectRecord copy() {
- return new TextObjectRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.TEXT_OBJECT;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- final Map<String,Supplier<?>> m = new LinkedHashMap<>();
- m.put("isHorizontal", this::getHorizontalTextAlignment);
- m.put("isVertical", this::getVerticalTextAlignment);
- m.put("textLocked", this::isTextLocked);
- m.put("textOrientation", this::getTextOrientation);
- m.put("string", this::getStr);
- m.put("reserved4", () -> field_3_reserved4);
- m.put("reserved5", () -> field_4_reserved5);
- m.put("reserved6", () -> field_5_reserved6);
- m.put("reserved7", () -> field_8_reserved7);
- return Collections.unmodifiableMap(m);
- }
+ private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
+ private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
+ private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
+
+ public static final short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
+ public static final short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
+ public static final short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
+ public static final short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
+ public static final short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
+ public static final short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
+ public static final short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
+ public static final short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
+
+ public static final short TEXT_ORIENTATION_NONE = 0;
+ public static final short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
+ public static final short TEXT_ORIENTATION_ROT_RIGHT = 2;
+ public static final short TEXT_ORIENTATION_ROT_LEFT = 3;
+
+ private int field_1_options;
+ private int field_2_textOrientation;
+ private int field_3_reserved4;
+ private int field_4_reserved5;
+ private int field_5_reserved6;
+ private int field_8_reserved7;
+
+ private HSSFRichTextString _text;
+
+ /*
+ * Note - the next three fields are very similar to those on
+ * EmbededObjectRefSubRecord(ftPictFmla 0x0009)
+ *
+ * some observed values for the 4 bytes preceding the formula: C0 5E 86 03
+ * C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03
+ */
+ private int _unknownPreFormulaInt;
+ /** expect tRef, tRef3D, tArea, tArea3D or tName */
+ private OperandPtg _linkRefPtg;
+ /**
+ * Not clear if needed . Excel seems to be OK if this byte is not present.
+ * Value is often the same as the earlier firstColumn byte. */
+ private Byte _unknownPostFormulaByte;
+
+ public TextObjectRecord() {}
+
+ public TextObjectRecord(TextObjectRecord other) {
+ super(other);
+ field_1_options = other.field_1_options;
+ field_2_textOrientation = other.field_2_textOrientation;
+ field_3_reserved4 = other.field_3_reserved4;
+ field_4_reserved5 = other.field_4_reserved5;
+ field_5_reserved6 = other.field_5_reserved6;
+ field_8_reserved7 = other.field_8_reserved7;
+
+ _text = other._text;
+
+ if (other._linkRefPtg != null) {
+ _unknownPreFormulaInt = other._unknownPreFormulaInt;
+ _linkRefPtg = other._linkRefPtg.copy();
+ _unknownPostFormulaByte = other._unknownPostFormulaByte;
+ }
+ }
+
+ public TextObjectRecord(RecordInputStream in) {
+ field_1_options = in.readUShort();
+ field_2_textOrientation = in.readUShort();
+ field_3_reserved4 = in.readUShort();
+ field_4_reserved5 = in.readUShort();
+ field_5_reserved6 = in.readUShort();
+ int field_6_textLength = in.readUShort();
+ int field_7_formattingDataLength = in.readUShort();
+ field_8_reserved7 = in.readInt();
+
+ if (in.remaining() > 0) {
+ // Text Objects can have simple reference formulas
+ // (This bit not mentioned in the MS document)
+ if (in.remaining() < 11) {
+ throw new RecordFormatException("Not enough remaining data for a link formula");
+ }
+ int formulaSize = in.readUShort();
+ _unknownPreFormulaInt = in.readInt();
+ Ptg[] ptgs = Ptg.readTokens(formulaSize, in);
+ if (ptgs.length != 1) {
+ throw new RecordFormatException("Read " + ptgs.length
+ + " tokens but expected exactly 1");
+ }
+ _linkRefPtg = (OperandPtg) ptgs[0];
+ _unknownPostFormulaByte = in.remaining() > 0 ? in.readByte() : null;
+ } else {
+ _linkRefPtg = null;
+ }
+ if (in.remaining() > 0) {
+ throw new RecordFormatException("Unused " + in.remaining() + " bytes at end of record");
+ }
+
+ String text;
+ if (field_6_textLength > 0) {
+ text = readRawString(in, field_6_textLength);
+ } else {
+ text = "";
+ }
+ _text = new HSSFRichTextString(text);
+
+ if (field_7_formattingDataLength > 0) {
+ processFontRuns(in, _text, field_7_formattingDataLength);
+ }
+ }
+
+ private static String readRawString(RecordInputStream in, int textLength) {
+ byte compressByte = in.readByte();
+ boolean isCompressed = (compressByte & 0x01) == 0;
+ if (isCompressed) {
+ return in.readCompressedUnicode(textLength);
+ }
+ return in.readUnicodeLEString(textLength);
+ }
+
+ private static void processFontRuns(RecordInputStream in, HSSFRichTextString str,
+ int formattingRunDataLength) {
+ if (formattingRunDataLength % FORMAT_RUN_ENCODED_SIZE != 0) {
+ throw new RecordFormatException("Bad format run data length " + formattingRunDataLength
+ + ")");
+ }
+ int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE;
+ for (int i = 0; i < nRuns; i++) {
+ short index = in.readShort();
+ short iFont = in.readShort();
+ in.readInt(); // skip reserved.
+ str.applyFont(index, str.length(), iFont);
+ }
+ }
+
+ public short getSid() {
+ return sid;
+ }
+
+ private void serializeTXORecord(ContinuableRecordOutput out) {
+
+ out.writeShort(field_1_options);
+ out.writeShort(field_2_textOrientation);
+ out.writeShort(field_3_reserved4);
+ out.writeShort(field_4_reserved5);
+ out.writeShort(field_5_reserved6);
+ out.writeShort(_text.length());
+ out.writeShort(getFormattingDataLength());
+ out.writeInt(field_8_reserved7);
+
+ if (_linkRefPtg != null) {
+ int formulaSize = _linkRefPtg.getSize();
+ out.writeShort(formulaSize);
+ out.writeInt(_unknownPreFormulaInt);
+ _linkRefPtg.write(out);
+ if (_unknownPostFormulaByte != null) {
+ out.writeByte(_unknownPostFormulaByte);
+ }
+ }
+ }
+
+ private void serializeTrailingRecords(ContinuableRecordOutput out) {
+ out.writeContinue();
+ out.writeStringData(_text.getString());
+ out.writeContinue();
+ writeFormatData(out, _text);
+ }
+
+ protected void serialize(ContinuableRecordOutput out) {
+
+ serializeTXORecord(out);
+ if (_text.getString().length() > 0) {
+ serializeTrailingRecords(out);
+ }
+ }
+
+ private int getFormattingDataLength() {
+ if (_text.length() < 1) {
+ // important - no formatting data if text is empty
+ return 0;
+ }
+ return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE;
+ }
+
+ private static void writeFormatData(ContinuableRecordOutput out , HSSFRichTextString str) {
+ int nRuns = str.numFormattingRuns();
+ for (int i = 0; i < nRuns; i++) {
+ out.writeShort(str.getIndexOfFormattingRun(i));
+ int fontIndex = str.getFontOfFormattingRun(i);
+ out.writeShort(fontIndex == HSSFRichTextString.NO_FONT ? 0 : fontIndex);
+ out.writeInt(0); // skip reserved
+ }
+ out.writeShort(str.length());
+ out.writeShort(0);
+ out.writeInt(0); // skip reserved
+ }
+
+ /**
+ * Sets the Horizontal text alignment field value.
+ *
+ * @param value The horizontal alignment, use one of the HORIZONTAL_TEXT_ALIGNMENT_... constants in this class
+ */
+ public void setHorizontalTextAlignment(int value) {
+ field_1_options = HorizontalTextAlignment.setValue(field_1_options, value);
+ }
+
+ /**
+ * @return the Horizontal text alignment field value.
+ */
+ public int getHorizontalTextAlignment() {
+ return HorizontalTextAlignment.getValue(field_1_options);
+ }
+
+ /**
+ * Sets the Vertical text alignment field value.
+ *
+ * @param value The vertical alignment, use one of the VERTIUCAL_TEST_ALIGNMENT_... constants in this class
+ */
+ public void setVerticalTextAlignment(int value) {
+ field_1_options = VerticalTextAlignment.setValue(field_1_options, value);
+ }
+
+ /**
+ * @return the Vertical text alignment field value.
+ */
+ public int getVerticalTextAlignment() {
+ return VerticalTextAlignment.getValue(field_1_options);
+ }
+
+ /**
+ * Sets the text locked field value.
+ *
+ * @param value If the text should be locked
+ */
+ public void setTextLocked(boolean value) {
+ field_1_options = textLocked.setBoolean(field_1_options, value);
+ }
+
+ /**
+ * @return the text locked field value.
+ */
+ public boolean isTextLocked() {
+ return textLocked.isSet(field_1_options);
+ }
+
+ /**
+ * Get the text orientation field for the TextObjectBase record.
+ *
+ * @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
+ * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
+ */
+ public int getTextOrientation() {
+ return field_2_textOrientation;
+ }
+
+ /**
+ * Set the text orientation field for the TextObjectBase record.
+ *
+ * @param textOrientation
+ * One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
+ * TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
+ */
+ public void setTextOrientation(int textOrientation) {
+ this.field_2_textOrientation = textOrientation;
+ }
+
+ public HSSFRichTextString getStr() {
+ return _text;
+ }
+
+ public void setStr(HSSFRichTextString str) {
+ _text = str;
+ }
+
+ public Ptg getLinkRefPtg() {
+ return _linkRefPtg;
+ }
+
+ @Override
+ public TextObjectRecord copy() {
+ return new TextObjectRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.TEXT_OBJECT;
+ }
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+ m.put("isHorizontal", this::getHorizontalTextAlignment);
+ m.put("isVertical", this::getVerticalTextAlignment);
+ m.put("textLocked", this::isTextLocked);
+ m.put("textOrientation", this::getTextOrientation);
+ m.put("string", this::getStr);
+ m.put("reserved4", () -> field_3_reserved4);
+ m.put("reserved5", () -> field_4_reserved5);
+ m.put("reserved6", () -> field_5_reserved6);
+ m.put("reserved7", () -> field_8_reserved7);
+ return Collections.unmodifiableMap(m);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UncalcedRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UncalcedRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UncalcedRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UncalcedRecord.java Sat May 22 20:56:44 2021
@@ -28,51 +28,51 @@ import org.apache.poi.util.LittleEndianO
* been recalculated before the document was saved.
*/
public final class UncalcedRecord extends StandardRecord {
- public static final short sid = 0x005E;
+ public static final short sid = 0x005E;
private short _reserved;
- public UncalcedRecord() {
+ public UncalcedRecord() {
_reserved = 0;
- }
+ }
- public UncalcedRecord(UncalcedRecord other) {
- super(other);
- _reserved = other._reserved;
- }
-
- public short getSid() {
- return sid;
- }
-
- public UncalcedRecord(RecordInputStream in) {
- _reserved = in.readShort(); // unused
- }
-
- public void serialize(LittleEndianOutput out) {
- out.writeShort(_reserved);
- }
-
- protected int getDataSize() {
- return 2;
- }
-
- public static int getStaticRecordSize() {
- return 6;
- }
-
- @Override
- public UncalcedRecord copy() {
- return new UncalcedRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.UNCALCED;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- return GenericRecordUtil.getGenericProperties("reserved", () -> _reserved);
- }
+ public UncalcedRecord(UncalcedRecord other) {
+ super(other);
+ _reserved = other._reserved;
+ }
+
+ public short getSid() {
+ return sid;
+ }
+
+ public UncalcedRecord(RecordInputStream in) {
+ _reserved = in.readShort(); // unused
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(_reserved);
+ }
+
+ protected int getDataSize() {
+ return 2;
+ }
+
+ public static int getStaticRecordSize() {
+ return 6;
+ }
+
+ @Override
+ public UncalcedRecord copy() {
+ return new UncalcedRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.UNCALCED;
+ }
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ return GenericRecordUtil.getGenericProperties("reserved", () -> _reserved);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewBegin.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewBegin.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewBegin.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewBegin.java Sat May 22 20:56:44 2021
@@ -45,25 +45,25 @@ public final class UserSViewBegin extend
_rawData = data;
}
- /**
- * construct an UserSViewBegin record. No fields are interpreted and the record will
- * be serialized in its original form more or less
- * @param in the RecordInputstream to read the record from
- */
- public UserSViewBegin(RecordInputStream in) {
- _rawData = in.readRemainder();
- }
+ /**
+ * construct an UserSViewBegin record. No fields are interpreted and the record will
+ * be serialized in its original form more or less
+ * @param in the RecordInputstream to read the record from
+ */
+ public UserSViewBegin(RecordInputStream in) {
+ _rawData = in.readRemainder();
+ }
- /**
- * spit the record out AS IS. no interpretation or identification
- */
- public void serialize(LittleEndianOutput out) {
- out.write(_rawData);
- }
+ /**
+ * spit the record out AS IS. no interpretation or identification
+ */
+ public void serialize(LittleEndianOutput out) {
+ out.write(_rawData);
+ }
- protected int getDataSize() {
- return _rawData.length;
- }
+ protected int getDataSize() {
+ return _rawData.length;
+ }
public short getSid()
{
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewEnd.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewEnd.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewEnd.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/UserSViewEnd.java Sat May 22 20:56:44 2021
@@ -29,7 +29,7 @@ import org.apache.poi.util.LittleEndianO
public final class UserSViewEnd extends StandardRecord {
public static final short sid = 0x01AB;
- private byte[] _rawData;
+ private byte[] _rawData;
public UserSViewEnd(UserSViewEnd other) {
super(other);
@@ -40,25 +40,25 @@ public final class UserSViewEnd extends
_rawData = data;
}
- /**
- * construct an UserSViewEnd record. No fields are interpreted and the record will
- * be serialized in its original form more or less
- * @param in the RecordInputstream to read the record from
- */
- public UserSViewEnd(RecordInputStream in) {
- _rawData = in.readRemainder();
- }
-
- /**
- * spit the record out AS IS. no interpretation or identification
- */
- public void serialize(LittleEndianOutput out) {
- out.write(_rawData);
- }
-
- protected int getDataSize() {
- return _rawData.length;
- }
+ /**
+ * construct an UserSViewEnd record. No fields are interpreted and the record will
+ * be serialized in its original form more or less
+ * @param in the RecordInputstream to read the record from
+ */
+ public UserSViewEnd(RecordInputStream in) {
+ _rawData = in.readRemainder();
+ }
+
+ /**
+ * spit the record out AS IS. no interpretation or identification
+ */
+ public void serialize(LittleEndianOutput out) {
+ out.write(_rawData);
+ }
+
+ protected int getDataSize() {
+ return _rawData.length;
+ }
public short getSid()
{
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VCenterRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VCenterRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VCenterRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VCenterRecord.java Sat May 22 20:56:44 2021
@@ -51,7 +51,7 @@ public final class VCenterRecord extends
public void setVCenter(boolean hc)
{
- field_1_vcenter = hc ? 1 : 0;
+ field_1_vcenter = hc ? 1 : 0;
}
/**
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/VerticalPageBreakRecord.java Sat May 22 20:56:44 2021
@@ -24,35 +24,35 @@ package org.apache.poi.hssf.record;
*/
public final class VerticalPageBreakRecord extends PageBreakRecord {
- public static final short sid = 0x001A;
+ public static final short sid = 0x001A;
- /**
- * Creates an empty vertical page break record
- */
- public VerticalPageBreakRecord() {}
-
- public VerticalPageBreakRecord(VerticalPageBreakRecord other) {
- super(other);
- }
-
- /**
- * @param in the RecordInputstream to read the record from
- */
- public VerticalPageBreakRecord(RecordInputStream in) {
- super(in);
- }
-
- public short getSid() {
- return sid;
- }
-
- @Override
- public VerticalPageBreakRecord copy() {
- return new VerticalPageBreakRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.VERTICAL_PAGE_BREAK;
- }
+ /**
+ * Creates an empty vertical page break record
+ */
+ public VerticalPageBreakRecord() {}
+
+ public VerticalPageBreakRecord(VerticalPageBreakRecord other) {
+ super(other);
+ }
+
+ /**
+ * @param in the RecordInputstream to read the record from
+ */
+ public VerticalPageBreakRecord(RecordInputStream in) {
+ super(in);
+ }
+
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public VerticalPageBreakRecord copy() {
+ return new VerticalPageBreakRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.VERTICAL_PAGE_BREAK;
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WindowOneRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WindowOneRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WindowOneRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WindowOneRecord.java Sat May 22 20:56:44 2021
@@ -196,8 +196,8 @@ public final class WindowOneRecord exten
// end bitfields
public void setActiveSheetIndex(int index) {
- field_6_active_sheet = index;
- }
+ field_6_active_sheet = index;
+ }
/**
* Sets the first visible sheet in the worksheet tab-bar. This method does <b>not</b>
@@ -338,7 +338,7 @@ public final class WindowOneRecord exten
* @return the index of the currently displayed sheet
*/
public int getActiveSheetIndex() {
- return field_6_active_sheet;
+ return field_6_active_sheet;
}
/**
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WriteAccessRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WriteAccessRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WriteAccessRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/WriteAccessRecord.java Sat May 22 20:56:44 2021
@@ -34,135 +34,135 @@ import org.apache.poi.util.StringUtil;
* login, on Windoze its the name you typed when you installed the thing)
*/
public final class WriteAccessRecord extends StandardRecord {
- public static final short sid = 0x005C;
+ public static final short sid = 0x005C;
- private static final byte PAD_CHAR = (byte) ' ';
- private static final int DATA_SIZE = 112;
- /** this record is always padded to a constant length */
- private static final byte[] PADDING = new byte[DATA_SIZE];
- static {
- Arrays.fill(PADDING, PAD_CHAR);
- }
-
- private String field_1_username;
-
-
- public WriteAccessRecord() {
- setUsername("");
- }
-
- public WriteAccessRecord(WriteAccessRecord other) {
- super(other);
- field_1_username = other.field_1_username;
- }
-
- public WriteAccessRecord(RecordInputStream in) {
- if (in.remaining() > DATA_SIZE) {
- throw new RecordFormatException("Expected data size (" + DATA_SIZE + ") but got ("
- + in.remaining() + ")");
- }
- // The string is always 112 characters (padded with spaces), therefore
- // this record can not be continued.
-
- int nChars = in.readUShort();
- int is16BitFlag = in.readUByte();
- if (nChars > DATA_SIZE || (is16BitFlag & 0xFE) != 0) {
- // String header looks wrong (probably missing)
- // OOO doc says this is optional anyway.
- // reconstruct data
- byte[] data = new byte[3 + in.remaining()];
- LittleEndian.putUShort(data, 0, nChars);
- LittleEndian.putByte(data, 2, is16BitFlag);
- in.readFully(data, 3, data.length-3);
- String rawValue = new String(data, StringUtil.UTF8);
- setUsername(rawValue.trim());
- return;
- }
-
- String rawText;
- if ((is16BitFlag & 0x01) == 0x00) {
- rawText = StringUtil.readCompressedUnicode(in, nChars);
- } else {
- rawText = StringUtil.readUnicodeLE(in, nChars);
- }
- field_1_username = rawText.trim();
-
- // consume padding
- int padSize = in.remaining();
- while (padSize > 0) {
- // in some cases this seems to be garbage (non spaces)
- in.readUByte();
- padSize--;
- }
- }
-
- /**
- * set the username for the user that created the report. HSSF uses the
- * logged in user.
- *
- * @param username of the user who is logged in (probably "tomcat" or "apache")
- */
- public void setUsername(String username) {
- boolean is16bit = StringUtil.hasMultibyte(username);
- int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1);
- int paddingSize = DATA_SIZE - encodedByteCount;
- if (paddingSize < 0) {
- throw new IllegalArgumentException("Name is too long: " + username);
- }
-
- field_1_username = username;
- }
-
- /**
- * get the username for the user that created the report. HSSF uses the
- * logged in user. On natively created M$ Excel sheet this would be the name
- * you typed in when you installed it in most cases.
- *
- * @return username of the user who is logged in (probably "tomcat" or "apache")
- */
- public String getUsername() {
- return field_1_username;
- }
-
- @Override
- public void serialize(LittleEndianOutput out) {
- String username = getUsername();
- boolean is16bit = StringUtil.hasMultibyte(username);
-
- out.writeShort(username.length());
- out.writeByte(is16bit ? 0x01 : 0x00);
- if (is16bit) {
- StringUtil.putUnicodeLE(username, out);
- } else {
- StringUtil.putCompressedUnicode(username, out);
- }
- int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1);
- int paddingSize = DATA_SIZE - encodedByteCount;
- out.write(PADDING, 0, paddingSize);
- }
-
- @Override
- protected int getDataSize() {
- return DATA_SIZE;
- }
-
- @Override
- public short getSid() {
- return sid;
- }
-
- @Override
- public WriteAccessRecord copy() {
- return new WriteAccessRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.WRITE_ACCESS;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- return GenericRecordUtil.getGenericProperties("username", this::getUsername);
- }
+ private static final byte PAD_CHAR = (byte) ' ';
+ private static final int DATA_SIZE = 112;
+ /** this record is always padded to a constant length */
+ private static final byte[] PADDING = new byte[DATA_SIZE];
+ static {
+ Arrays.fill(PADDING, PAD_CHAR);
+ }
+
+ private String field_1_username;
+
+
+ public WriteAccessRecord() {
+ setUsername("");
+ }
+
+ public WriteAccessRecord(WriteAccessRecord other) {
+ super(other);
+ field_1_username = other.field_1_username;
+ }
+
+ public WriteAccessRecord(RecordInputStream in) {
+ if (in.remaining() > DATA_SIZE) {
+ throw new RecordFormatException("Expected data size (" + DATA_SIZE + ") but got ("
+ + in.remaining() + ")");
+ }
+ // The string is always 112 characters (padded with spaces), therefore
+ // this record can not be continued.
+
+ int nChars = in.readUShort();
+ int is16BitFlag = in.readUByte();
+ if (nChars > DATA_SIZE || (is16BitFlag & 0xFE) != 0) {
+ // String header looks wrong (probably missing)
+ // OOO doc says this is optional anyway.
+ // reconstruct data
+ byte[] data = new byte[3 + in.remaining()];
+ LittleEndian.putUShort(data, 0, nChars);
+ LittleEndian.putByte(data, 2, is16BitFlag);
+ in.readFully(data, 3, data.length-3);
+ String rawValue = new String(data, StringUtil.UTF8);
+ setUsername(rawValue.trim());
+ return;
+ }
+
+ String rawText;
+ if ((is16BitFlag & 0x01) == 0x00) {
+ rawText = StringUtil.readCompressedUnicode(in, nChars);
+ } else {
+ rawText = StringUtil.readUnicodeLE(in, nChars);
+ }
+ field_1_username = rawText.trim();
+
+ // consume padding
+ int padSize = in.remaining();
+ while (padSize > 0) {
+ // in some cases this seems to be garbage (non spaces)
+ in.readUByte();
+ padSize--;
+ }
+ }
+
+ /**
+ * set the username for the user that created the report. HSSF uses the
+ * logged in user.
+ *
+ * @param username of the user who is logged in (probably "tomcat" or "apache")
+ */
+ public void setUsername(String username) {
+ boolean is16bit = StringUtil.hasMultibyte(username);
+ int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1);
+ int paddingSize = DATA_SIZE - encodedByteCount;
+ if (paddingSize < 0) {
+ throw new IllegalArgumentException("Name is too long: " + username);
+ }
+
+ field_1_username = username;
+ }
+
+ /**
+ * get the username for the user that created the report. HSSF uses the
+ * logged in user. On natively created M$ Excel sheet this would be the name
+ * you typed in when you installed it in most cases.
+ *
+ * @return username of the user who is logged in (probably "tomcat" or "apache")
+ */
+ public String getUsername() {
+ return field_1_username;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+ String username = getUsername();
+ boolean is16bit = StringUtil.hasMultibyte(username);
+
+ out.writeShort(username.length());
+ out.writeByte(is16bit ? 0x01 : 0x00);
+ if (is16bit) {
+ StringUtil.putUnicodeLE(username, out);
+ } else {
+ StringUtil.putCompressedUnicode(username, out);
+ }
+ int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1);
+ int paddingSize = DATA_SIZE - encodedByteCount;
+ out.write(PADDING, 0, paddingSize);
+ }
+
+ @Override
+ protected int getDataSize() {
+ return DATA_SIZE;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public WriteAccessRecord copy() {
+ return new WriteAccessRecord(this);
+ }
+
+ @Override
+ public HSSFRecordTypes getGenericRecordType() {
+ return HSSFRecordTypes.WRITE_ACCESS;
+ }
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ return GenericRecordUtil.getGenericProperties("username", this::getUsername);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java Sat May 22 20:56:44 2021
@@ -29,54 +29,54 @@ import org.apache.poi.hssf.record.*;
*/
public final class ChartSubstreamRecordAggregate extends RecordAggregate {
- private final BOFRecord _bofRec;
- /**
- * All the records between BOF and EOF
- */
- private final List<RecordBase> _recs;
- private PageSettingsBlock _psBlock;
+ private final BOFRecord _bofRec;
+ /**
+ * All the records between BOF and EOF
+ */
+ private final List<RecordBase> _recs;
+ private PageSettingsBlock _psBlock;
- public ChartSubstreamRecordAggregate(RecordStream rs) {
- _bofRec = (BOFRecord) rs.getNext();
- List<RecordBase> temp = new ArrayList<>();
- while (rs.peekNextClass() != EOFRecord.class) {
- if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
- if (_psBlock != null) {
- if (rs.peekNextSid() == HeaderFooterRecord.sid) {
- // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
- _psBlock.addLateHeaderFooter((HeaderFooterRecord)rs.getNext());
- continue;
- }
- throw new IllegalStateException(
- "Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid());
- }
- _psBlock = new PageSettingsBlock(rs);
- temp.add(_psBlock);
- continue;
- }
- temp.add(rs.getNext());
- }
- _recs = temp;
- org.apache.poi.hssf.record.Record eof = rs.getNext(); // no need to save EOF in field
- if (!(eof instanceof EOFRecord)) {
- throw new IllegalStateException("Bad chart EOF");
- }
- }
+ public ChartSubstreamRecordAggregate(RecordStream rs) {
+ _bofRec = (BOFRecord) rs.getNext();
+ List<RecordBase> temp = new ArrayList<>();
+ while (rs.peekNextClass() != EOFRecord.class) {
+ if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
+ if (_psBlock != null) {
+ if (rs.peekNextSid() == HeaderFooterRecord.sid) {
+ // test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
+ _psBlock.addLateHeaderFooter((HeaderFooterRecord)rs.getNext());
+ continue;
+ }
+ throw new IllegalStateException(
+ "Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid());
+ }
+ _psBlock = new PageSettingsBlock(rs);
+ temp.add(_psBlock);
+ continue;
+ }
+ temp.add(rs.getNext());
+ }
+ _recs = temp;
+ org.apache.poi.hssf.record.Record eof = rs.getNext(); // no need to save EOF in field
+ if (!(eof instanceof EOFRecord)) {
+ throw new IllegalStateException("Bad chart EOF");
+ }
+ }
- @Override
+ @Override
public void visitContainedRecords(RecordVisitor rv) {
- if (_recs.isEmpty()) {
- return;
- }
- rv.visitRecord(_bofRec);
- for (int i = 0; i < _recs.size(); i++) {
- RecordBase rb = _recs.get(i);
- if (rb instanceof RecordAggregate) {
- ((RecordAggregate) rb).visitContainedRecords(rv);
- } else {
- rv.visitRecord((org.apache.poi.hssf.record.Record) rb);
- }
- }
- rv.visitRecord(EOFRecord.instance);
- }
+ if (_recs.isEmpty()) {
+ return;
+ }
+ rv.visitRecord(_bofRec);
+ for (int i = 0; i < _recs.size(); i++) {
+ RecordBase rb = _recs.get(i);
+ if (rb instanceof RecordAggregate) {
+ ((RecordAggregate) rb).visitContainedRecords(rv);
+ } else {
+ rv.visitRecord((org.apache.poi.hssf.record.Record) rb);
+ }
+ }
+ rv.visitRecord(EOFRecord.instance);
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java Sat May 22 20:56:44 2021
@@ -25,519 +25,519 @@ import org.apache.poi.hssf.model.RecordS
import org.apache.poi.hssf.record.ColumnInfoRecord;
public final class ColumnInfoRecordsAggregate extends RecordAggregate implements Duplicatable {
- /**
- * List of {@link ColumnInfoRecord}s assumed to be in order
- */
- private final List<ColumnInfoRecord> records = new ArrayList<>();
-
- /**
- * Creates an empty aggregate
- */
- public ColumnInfoRecordsAggregate() {}
-
- public ColumnInfoRecordsAggregate(ColumnInfoRecordsAggregate other) {
- other.records.stream().map(ColumnInfoRecord::copy).forEach(records::add);
- }
-
- public ColumnInfoRecordsAggregate(RecordStream rs) {
- this();
-
- boolean isInOrder = true;
- ColumnInfoRecord cirPrev = null;
- while (rs.peekNextClass() == ColumnInfoRecord.class) {
- ColumnInfoRecord cir = (ColumnInfoRecord) rs.getNext();
- records.add(cir);
- if (cirPrev != null && compareColInfos(cirPrev, cir) > 0) {
- isInOrder = false;
- }
- cirPrev = cir;
- }
- if (records.size() < 1) {
- throw new RuntimeException("No column info records found");
- }
- if (!isInOrder) {
- records.sort(ColumnInfoRecordsAggregate::compareColInfos);
- }
- }
-
- @Override
- public ColumnInfoRecordsAggregate copy() {
- return new ColumnInfoRecordsAggregate(this);
- }
-
- /**
- * Inserts a column into the aggregate (at the end of the list).
- */
- public void insertColumn(ColumnInfoRecord col) {
- records.add(col);
- records.sort(ColumnInfoRecordsAggregate::compareColInfos);
- }
-
- /**
- * Inserts a column into the aggregate (at the position specified by
- * {@code idx}.
- */
- private void insertColumn(int idx, ColumnInfoRecord col) {
- records.add(idx, col);
- }
-
- /* package */ int getNumColumns() {
- return records.size();
- }
-
- @Override
- public void visitContainedRecords(RecordVisitor rv) {
- int nItems = records.size();
- if (nItems < 1) {
- return;
- }
- ColumnInfoRecord cirPrev = null;
- for (ColumnInfoRecord cir : records) {
- rv.visitRecord(cir);
- if (cirPrev != null && compareColInfos(cirPrev, cir) > 0) {
- // Excel probably wouldn't mind, but there is much logic in this class
- // that assumes the column info records are kept in order
- throw new RuntimeException("Column info records are out of order");
- }
- cirPrev = cir;
- }
- }
-
- private int findStartOfColumnOutlineGroup(int pIdx) {
- // Find the start of the group.
- ColumnInfoRecord columnInfo = records.get(pIdx);
- int level = columnInfo.getOutlineLevel();
- int idx = pIdx;
- while (idx != 0) {
- ColumnInfoRecord prevColumnInfo = records.get(idx - 1);
- if (!prevColumnInfo.isAdjacentBefore(columnInfo)) {
- break;
- }
- if (prevColumnInfo.getOutlineLevel() < level) {
- break;
- }
- idx--;
- columnInfo = prevColumnInfo;
- }
-
- return idx;
- }
-
- private int findEndOfColumnOutlineGroup(int colInfoIndex) {
- // Find the end of the group.
- ColumnInfoRecord columnInfo = records.get(colInfoIndex);
- int level = columnInfo.getOutlineLevel();
- int idx = colInfoIndex;
- while (idx < records.size() - 1) {
- ColumnInfoRecord nextColumnInfo = records.get(idx + 1);
- if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
- break;
- }
- if (nextColumnInfo.getOutlineLevel() < level) {
- break;
- }
- idx++;
- columnInfo = nextColumnInfo;
- }
- return idx;
- }
-
- private ColumnInfoRecord getColInfo(int idx) {
- return records.get( idx );
- }
-
- /**
- * 'Collapsed' state is stored in a single column col info record immediately after the outline group
- * @return true, if the column is collapsed, false otherwise.
- */
- private boolean isColumnGroupCollapsed(int idx) {
- int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
- int nextColInfoIx = endOfOutlineGroupIdx+1;
- if (nextColInfoIx >= records.size()) {
- return false;
- }
- ColumnInfoRecord nextColInfo = getColInfo(nextColInfoIx);
- if (!getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextColInfo)) {
- return false;
- }
- return nextColInfo.getCollapsed();
- }
-
-
- private boolean isColumnGroupHiddenByParent(int idx) {
- // Look out outline details of end
- int endLevel = 0;
- boolean endHidden = false;
- int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
- if (endOfOutlineGroupIdx < records.size()) {
- ColumnInfoRecord nextInfo = getColInfo(endOfOutlineGroupIdx + 1);
- if (getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextInfo)) {
- endLevel = nextInfo.getOutlineLevel();
- endHidden = nextInfo.getHidden();
- }
- }
- // Look out outline details of start
- int startLevel = 0;
- boolean startHidden = false;
- int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx );
- if (startOfOutlineGroupIdx > 0) {
- ColumnInfoRecord prevInfo = getColInfo(startOfOutlineGroupIdx - 1);
- if (prevInfo.isAdjacentBefore(getColInfo(startOfOutlineGroupIdx))) {
- startLevel = prevInfo.getOutlineLevel();
- startHidden = prevInfo.getHidden();
- }
- }
- if (endLevel > startLevel) {
- return endHidden;
- }
- return startHidden;
- }
-
- public void collapseColumn(int columnIndex) {
- int colInfoIx = findColInfoIdx(columnIndex, 0);
- if (colInfoIx == -1) {
- return;
- }
-
- // Find the start of the group.
- int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx);
- ColumnInfoRecord columnInfo = getColInfo(groupStartColInfoIx);
-
- // Hide all the columns until the end of the group
- int lastColIx = setGroupHidden(groupStartColInfoIx, columnInfo.getOutlineLevel(), true);
-
- // Write collapse field
- setColumn(lastColIx + 1, null, null, null, null, Boolean.TRUE);
- }
- /**
- * Sets all adjacent columns of the same outline level to the specified hidden status.
- * @param pIdx the col info index of the start of the outline group
- * @return the column index of the last column in the outline group
- */
- private int setGroupHidden(int pIdx, int level, boolean hidden) {
- int idx = pIdx;
- ColumnInfoRecord columnInfo = getColInfo(idx);
- while (idx < records.size()) {
- columnInfo.setHidden(hidden);
- if (idx + 1 < records.size()) {
- ColumnInfoRecord nextColumnInfo = getColInfo(idx + 1);
- if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
- break;
- }
- if (nextColumnInfo.getOutlineLevel() < level) {
- break;
- }
- columnInfo = nextColumnInfo;
- }
- idx++;
- }
- return columnInfo.getLastColumn();
- }
-
-
- public void expandColumn(int columnIndex) {
- int idx = findColInfoIdx(columnIndex, 0);
- if (idx == -1) {
- return;
- }
-
- // If it is already expanded do nothing.
- if (!isColumnGroupCollapsed(idx)) {
- return;
- }
-
- // Find the start/end of the group.
- int startIdx = findStartOfColumnOutlineGroup(idx);
- int endIdx = findEndOfColumnOutlineGroup(idx);
-
- // expand:
- // colapsed bit must be unset
- // hidden bit gets unset _if_ surrounding groups are expanded you can determine
- // this by looking at the hidden bit of the enclosing group. You will have
- // to look at the start and the end of the current group to determine which
- // is the enclosing group
- // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
- ColumnInfoRecord columnInfo = getColInfo(endIdx);
- if (!isColumnGroupHiddenByParent(idx)) {
- int outlineLevel = columnInfo.getOutlineLevel();
- for (int i = startIdx; i <= endIdx; i++) {
- ColumnInfoRecord ci = getColInfo(i);
- if (outlineLevel == ci.getOutlineLevel())
- ci.setHidden(false);
- }
- }
-
- // Write collapse flag (stored in a single col info record after this outline group)
- setColumn(columnInfo.getLastColumn() + 1, null, null, null, null, Boolean.FALSE);
- }
-
- private static ColumnInfoRecord copyColInfo(ColumnInfoRecord ci) {
- return ci.copy();
- }
-
-
- public void setColumn(int targetColumnIx, Short xfIndex, Integer width,
- Integer level, Boolean hidden, Boolean collapsed) {
- ColumnInfoRecord ci = null;
- int k;
- for (k = 0; k < records.size(); k++) {
- ColumnInfoRecord tci = records.get(k);
- if (tci.containsColumn(targetColumnIx)) {
- ci = tci;
- break;
- }
- if (tci.getFirstColumn() > targetColumnIx) {
- // call column infos after k are for later columns
- break; // exit now so k will be the correct insert pos
- }
- }
-
- if (ci == null) {
- // okay so there ISN'T a column info record that covers this column so lets create one!
- ColumnInfoRecord nci = new ColumnInfoRecord();
-
- nci.setFirstColumn(targetColumnIx);
- nci.setLastColumn(targetColumnIx);
- setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
- insertColumn(k, nci);
- attemptMergeColInfoRecords(k);
- return;
- }
-
- boolean styleChanged = xfIndex != null && ci.getXFIndex() != xfIndex.shortValue();
- boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue();
- boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue();
- boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue();
- boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue();
-
- boolean columnChanged = styleChanged || widthChanged || levelChanged || hiddenChanged || collapsedChanged;
- if (!columnChanged) {
- // do nothing...nothing changed.
- return;
- }
-
- if (ci.getFirstColumn() == targetColumnIx && ci.getLastColumn() == targetColumnIx) {
- // ColumnInfo ci for a single column, the target column
- setColumnInfoFields(ci, xfIndex, width, level, hidden, collapsed);
- attemptMergeColInfoRecords(k);
- return;
- }
-
- if (ci.getFirstColumn() == targetColumnIx || ci.getLastColumn() == targetColumnIx) {
- // The target column is at either end of the multi-column ColumnInfo ci
- // we'll just divide the info and create a new one
- if (ci.getFirstColumn() == targetColumnIx) {
- ci.setFirstColumn(targetColumnIx + 1);
- } else {
- ci.setLastColumn(targetColumnIx - 1);
- k++; // adjust insert pos to insert after
- }
- ColumnInfoRecord nci = copyColInfo(ci);
-
- nci.setFirstColumn(targetColumnIx);
- nci.setLastColumn(targetColumnIx);
- setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
-
- insertColumn(k, nci);
- attemptMergeColInfoRecords(k);
- } else {
- //split to 3 records
+ /**
+ * List of {@link ColumnInfoRecord}s assumed to be in order
+ */
+ private final List<ColumnInfoRecord> records = new ArrayList<>();
+
+ /**
+ * Creates an empty aggregate
+ */
+ public ColumnInfoRecordsAggregate() {}
+
+ public ColumnInfoRecordsAggregate(ColumnInfoRecordsAggregate other) {
+ other.records.stream().map(ColumnInfoRecord::copy).forEach(records::add);
+ }
+
+ public ColumnInfoRecordsAggregate(RecordStream rs) {
+ this();
+
+ boolean isInOrder = true;
+ ColumnInfoRecord cirPrev = null;
+ while (rs.peekNextClass() == ColumnInfoRecord.class) {
+ ColumnInfoRecord cir = (ColumnInfoRecord) rs.getNext();
+ records.add(cir);
+ if (cirPrev != null && compareColInfos(cirPrev, cir) > 0) {
+ isInOrder = false;
+ }
+ cirPrev = cir;
+ }
+ if (records.size() < 1) {
+ throw new RuntimeException("No column info records found");
+ }
+ if (!isInOrder) {
+ records.sort(ColumnInfoRecordsAggregate::compareColInfos);
+ }
+ }
+
+ @Override
+ public ColumnInfoRecordsAggregate copy() {
+ return new ColumnInfoRecordsAggregate(this);
+ }
+
+ /**
+ * Inserts a column into the aggregate (at the end of the list).
+ */
+ public void insertColumn(ColumnInfoRecord col) {
+ records.add(col);
+ records.sort(ColumnInfoRecordsAggregate::compareColInfos);
+ }
+
+ /**
+ * Inserts a column into the aggregate (at the position specified by
+ * {@code idx}.
+ */
+ private void insertColumn(int idx, ColumnInfoRecord col) {
+ records.add(idx, col);
+ }
+
+ /* package */ int getNumColumns() {
+ return records.size();
+ }
+
+ @Override
+ public void visitContainedRecords(RecordVisitor rv) {
+ int nItems = records.size();
+ if (nItems < 1) {
+ return;
+ }
+ ColumnInfoRecord cirPrev = null;
+ for (ColumnInfoRecord cir : records) {
+ rv.visitRecord(cir);
+ if (cirPrev != null && compareColInfos(cirPrev, cir) > 0) {
+ // Excel probably wouldn't mind, but there is much logic in this class
+ // that assumes the column info records are kept in order
+ throw new RuntimeException("Column info records are out of order");
+ }
+ cirPrev = cir;
+ }
+ }
+
+ private int findStartOfColumnOutlineGroup(int pIdx) {
+ // Find the start of the group.
+ ColumnInfoRecord columnInfo = records.get(pIdx);
+ int level = columnInfo.getOutlineLevel();
+ int idx = pIdx;
+ while (idx != 0) {
+ ColumnInfoRecord prevColumnInfo = records.get(idx - 1);
+ if (!prevColumnInfo.isAdjacentBefore(columnInfo)) {
+ break;
+ }
+ if (prevColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ idx--;
+ columnInfo = prevColumnInfo;
+ }
+
+ return idx;
+ }
+
+ private int findEndOfColumnOutlineGroup(int colInfoIndex) {
+ // Find the end of the group.
+ ColumnInfoRecord columnInfo = records.get(colInfoIndex);
+ int level = columnInfo.getOutlineLevel();
+ int idx = colInfoIndex;
+ while (idx < records.size() - 1) {
+ ColumnInfoRecord nextColumnInfo = records.get(idx + 1);
+ if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
+ break;
+ }
+ if (nextColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ idx++;
+ columnInfo = nextColumnInfo;
+ }
+ return idx;
+ }
+
+ private ColumnInfoRecord getColInfo(int idx) {
+ return records.get( idx );
+ }
+
+ /**
+ * 'Collapsed' state is stored in a single column col info record immediately after the outline group
+ * @return true, if the column is collapsed, false otherwise.
+ */
+ private boolean isColumnGroupCollapsed(int idx) {
+ int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx);
+ int nextColInfoIx = endOfOutlineGroupIdx+1;
+ if (nextColInfoIx >= records.size()) {
+ return false;
+ }
+ ColumnInfoRecord nextColInfo = getColInfo(nextColInfoIx);
+ if (!getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextColInfo)) {
+ return false;
+ }
+ return nextColInfo.getCollapsed();
+ }
+
+
+ private boolean isColumnGroupHiddenByParent(int idx) {
+ // Look out outline details of end
+ int endLevel = 0;
+ boolean endHidden = false;
+ int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx );
+ if (endOfOutlineGroupIdx < records.size()) {
+ ColumnInfoRecord nextInfo = getColInfo(endOfOutlineGroupIdx + 1);
+ if (getColInfo(endOfOutlineGroupIdx).isAdjacentBefore(nextInfo)) {
+ endLevel = nextInfo.getOutlineLevel();
+ endHidden = nextInfo.getHidden();
+ }
+ }
+ // Look out outline details of start
+ int startLevel = 0;
+ boolean startHidden = false;
+ int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx );
+ if (startOfOutlineGroupIdx > 0) {
+ ColumnInfoRecord prevInfo = getColInfo(startOfOutlineGroupIdx - 1);
+ if (prevInfo.isAdjacentBefore(getColInfo(startOfOutlineGroupIdx))) {
+ startLevel = prevInfo.getOutlineLevel();
+ startHidden = prevInfo.getHidden();
+ }
+ }
+ if (endLevel > startLevel) {
+ return endHidden;
+ }
+ return startHidden;
+ }
+
+ public void collapseColumn(int columnIndex) {
+ int colInfoIx = findColInfoIdx(columnIndex, 0);
+ if (colInfoIx == -1) {
+ return;
+ }
+
+ // Find the start of the group.
+ int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx);
+ ColumnInfoRecord columnInfo = getColInfo(groupStartColInfoIx);
+
+ // Hide all the columns until the end of the group
+ int lastColIx = setGroupHidden(groupStartColInfoIx, columnInfo.getOutlineLevel(), true);
+
+ // Write collapse field
+ setColumn(lastColIx + 1, null, null, null, null, Boolean.TRUE);
+ }
+ /**
+ * Sets all adjacent columns of the same outline level to the specified hidden status.
+ * @param pIdx the col info index of the start of the outline group
+ * @return the column index of the last column in the outline group
+ */
+ private int setGroupHidden(int pIdx, int level, boolean hidden) {
+ int idx = pIdx;
+ ColumnInfoRecord columnInfo = getColInfo(idx);
+ while (idx < records.size()) {
+ columnInfo.setHidden(hidden);
+ if (idx + 1 < records.size()) {
+ ColumnInfoRecord nextColumnInfo = getColInfo(idx + 1);
+ if (!columnInfo.isAdjacentBefore(nextColumnInfo)) {
+ break;
+ }
+ if (nextColumnInfo.getOutlineLevel() < level) {
+ break;
+ }
+ columnInfo = nextColumnInfo;
+ }
+ idx++;
+ }
+ return columnInfo.getLastColumn();
+ }
+
+
+ public void expandColumn(int columnIndex) {
+ int idx = findColInfoIdx(columnIndex, 0);
+ if (idx == -1) {
+ return;
+ }
+
+ // If it is already expanded do nothing.
+ if (!isColumnGroupCollapsed(idx)) {
+ return;
+ }
+
+ // Find the start/end of the group.
+ int startIdx = findStartOfColumnOutlineGroup(idx);
+ int endIdx = findEndOfColumnOutlineGroup(idx);
+
+ // expand:
+ // colapsed bit must be unset
+ // hidden bit gets unset _if_ surrounding groups are expanded you can determine
+ // this by looking at the hidden bit of the enclosing group. You will have
+ // to look at the start and the end of the current group to determine which
+ // is the enclosing group
+ // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups
+ ColumnInfoRecord columnInfo = getColInfo(endIdx);
+ if (!isColumnGroupHiddenByParent(idx)) {
+ int outlineLevel = columnInfo.getOutlineLevel();
+ for (int i = startIdx; i <= endIdx; i++) {
+ ColumnInfoRecord ci = getColInfo(i);
+ if (outlineLevel == ci.getOutlineLevel())
+ ci.setHidden(false);
+ }
+ }
+
+ // Write collapse flag (stored in a single col info record after this outline group)
+ setColumn(columnInfo.getLastColumn() + 1, null, null, null, null, Boolean.FALSE);
+ }
+
+ private static ColumnInfoRecord copyColInfo(ColumnInfoRecord ci) {
+ return ci.copy();
+ }
+
+
+ public void setColumn(int targetColumnIx, Short xfIndex, Integer width,
+ Integer level, Boolean hidden, Boolean collapsed) {
+ ColumnInfoRecord ci = null;
+ int k;
+ for (k = 0; k < records.size(); k++) {
+ ColumnInfoRecord tci = records.get(k);
+ if (tci.containsColumn(targetColumnIx)) {
+ ci = tci;
+ break;
+ }
+ if (tci.getFirstColumn() > targetColumnIx) {
+ // call column infos after k are for later columns
+ break; // exit now so k will be the correct insert pos
+ }
+ }
+
+ if (ci == null) {
+ // okay so there ISN'T a column info record that covers this column so lets create one!
+ ColumnInfoRecord nci = new ColumnInfoRecord();
+
+ nci.setFirstColumn(targetColumnIx);
+ nci.setLastColumn(targetColumnIx);
+ setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
+ insertColumn(k, nci);
+ attemptMergeColInfoRecords(k);
+ return;
+ }
+
+ boolean styleChanged = xfIndex != null && ci.getXFIndex() != xfIndex.shortValue();
+ boolean widthChanged = width != null && ci.getColumnWidth() != width.shortValue();
+ boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue();
+ boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue();
+ boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue();
+
+ boolean columnChanged = styleChanged || widthChanged || levelChanged || hiddenChanged || collapsedChanged;
+ if (!columnChanged) {
+ // do nothing...nothing changed.
+ return;
+ }
+
+ if (ci.getFirstColumn() == targetColumnIx && ci.getLastColumn() == targetColumnIx) {
+ // ColumnInfo ci for a single column, the target column
+ setColumnInfoFields(ci, xfIndex, width, level, hidden, collapsed);
+ attemptMergeColInfoRecords(k);
+ return;
+ }
+
+ if (ci.getFirstColumn() == targetColumnIx || ci.getLastColumn() == targetColumnIx) {
+ // The target column is at either end of the multi-column ColumnInfo ci
+ // we'll just divide the info and create a new one
+ if (ci.getFirstColumn() == targetColumnIx) {
+ ci.setFirstColumn(targetColumnIx + 1);
+ } else {
+ ci.setLastColumn(targetColumnIx - 1);
+ k++; // adjust insert pos to insert after
+ }
+ ColumnInfoRecord nci = copyColInfo(ci);
+
+ nci.setFirstColumn(targetColumnIx);
+ nci.setLastColumn(targetColumnIx);
+ setColumnInfoFields( nci, xfIndex, width, level, hidden, collapsed );
+
+ insertColumn(k, nci);
+ attemptMergeColInfoRecords(k);
+ } else {
+ //split to 3 records
ColumnInfoRecord ciMid = copyColInfo(ci);
- ColumnInfoRecord ciEnd = copyColInfo(ci);
- int lastcolumn = ci.getLastColumn();
+ ColumnInfoRecord ciEnd = copyColInfo(ci);
+ int lastcolumn = ci.getLastColumn();
- ci.setLastColumn(targetColumnIx - 1);
+ ci.setLastColumn(targetColumnIx - 1);
- ciMid.setFirstColumn(targetColumnIx);
- ciMid.setLastColumn(targetColumnIx);
- setColumnInfoFields(ciMid, xfIndex, width, level, hidden, collapsed);
- insertColumn(++k, ciMid);
-
- ciEnd.setFirstColumn(targetColumnIx+1);
- ciEnd.setLastColumn(lastcolumn);
- insertColumn(++k, ciEnd);
- // no need to attemptMergeColInfoRecords because we
- // know both on each side are different
- }
- }
-
- /**
- * Sets all non null fields into the {@code ci} parameter.
- */
- private static void setColumnInfoFields(ColumnInfoRecord ci, Short xfStyle, Integer width,
- Integer level, Boolean hidden, Boolean collapsed) {
- if (xfStyle != null) {
- ci.setXFIndex(xfStyle.shortValue());
- }
- if (width != null) {
- ci.setColumnWidth(width.intValue());
- }
- if (level != null) {
- ci.setOutlineLevel( level.shortValue() );
- }
- if (hidden != null) {
- ci.setHidden( hidden.booleanValue() );
- }
- if (collapsed != null) {
- ci.setCollapsed( collapsed.booleanValue() );
- }
- }
-
- private int findColInfoIdx(int columnIx, int fromColInfoIdx) {
- if (columnIx < 0) {
- throw new IllegalArgumentException( "column parameter out of range: " + columnIx );
- }
- if (fromColInfoIdx < 0) {
- throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromColInfoIdx );
- }
-
- for (int k = fromColInfoIdx; k < records.size(); k++) {
- ColumnInfoRecord ci = getColInfo(k);
- if (ci.containsColumn(columnIx)) {
- return k;
- }
- if (ci.getFirstColumn() > columnIx) {
- break;
- }
- }
- return -1;
- }
-
- /**
- * Attempts to merge the col info record at the specified index
- * with either or both of its neighbours
- */
- private void attemptMergeColInfoRecords(int colInfoIx) {
- int nRecords = records.size();
- if (colInfoIx < 0 || colInfoIx >= nRecords) {
- throw new IllegalArgumentException("colInfoIx " + colInfoIx
- + " is out of range (0.." + (nRecords-1) + ")");
- }
- ColumnInfoRecord currentCol = getColInfo(colInfoIx);
- int nextIx = colInfoIx+1;
- if (nextIx < nRecords) {
- if (mergeColInfoRecords(currentCol, getColInfo(nextIx))) {
- records.remove(nextIx);
- }
- }
- if (colInfoIx > 0) {
- if (mergeColInfoRecords(getColInfo(colInfoIx - 1), currentCol)) {
- records.remove(colInfoIx);
- }
- }
- }
- /**
- * merges two column info records (if they are adjacent and have the same formatting, etc)
- * @return {@code false} if the two column records could not be merged
- */
- private static boolean mergeColInfoRecords(ColumnInfoRecord ciA, ColumnInfoRecord ciB) {
- if (ciA.isAdjacentBefore(ciB) && ciA.formatMatches(ciB)) {
- ciA.setLastColumn(ciB.getLastColumn());
- return true;
- }
- return false;
- }
- /**
- * Creates an outline group for the specified columns, by setting the level
- * field for each col info record in the range. {@link ColumnInfoRecord}s
- * may be created, split or merged as a result of this operation.
- *
- * @param fromColumnIx
- * group from this column (inclusive)
- * @param toColumnIx
- * group to this column (inclusive)
- * @param indent
- * if {@code true} the group will be indented by one
- * level, if {@code false} indenting will be decreased by
- * one level.
- */
- public void groupColumnRange(int fromColumnIx, int toColumnIx, boolean indent) {
-
- int colInfoSearchStartIdx = 0; // optimization to speed up the search for col infos
- for (int i = fromColumnIx; i <= toColumnIx; i++) {
- int level = 1;
- int colInfoIdx = findColInfoIdx(i, colInfoSearchStartIdx);
- if (colInfoIdx != -1) {
- level = getColInfo(colInfoIdx).getOutlineLevel();
- if (indent) {
- level++;
- } else {
- level--;
- }
- level = Math.max(0, level);
- level = Math.min(7, level);
- colInfoSearchStartIdx = Math.max(0, colInfoIdx - 1); // -1 just in case this column is collapsed later.
- }
- setColumn(i, null, null, Integer.valueOf(level), null, null);
- }
- }
-
- /**
- * Finds the {@code ColumnInfoRecord} which contains the specified columnIndex
- * @param columnIndex index of the column (not the index of the ColumnInfoRecord)
- * @return {@code null} if no column info found for the specified column
- */
- public ColumnInfoRecord findColumnInfo(int columnIndex) {
- int nInfos = records.size();
- for(int i=0; i< nInfos; i++) {
- ColumnInfoRecord ci = getColInfo(i);
- if (ci.containsColumn(columnIndex)) {
- return ci;
- }
- }
- return null;
- }
-
- public int getMaxOutlineLevel() {
- int result = 0;
- int count=records.size();
- for (int i=0; i<count; i++) {
- ColumnInfoRecord columnInfoRecord = getColInfo(i);
- result = Math.max(columnInfoRecord.getOutlineLevel(), result);
- }
- return result;
- }
-
- public int getOutlineLevel(int columnIndex) {
- ColumnInfoRecord ci = findColumnInfo(columnIndex);
- if (ci != null) {
+ ciMid.setFirstColumn(targetColumnIx);
+ ciMid.setLastColumn(targetColumnIx);
+ setColumnInfoFields(ciMid, xfIndex, width, level, hidden, collapsed);
+ insertColumn(++k, ciMid);
+
+ ciEnd.setFirstColumn(targetColumnIx+1);
+ ciEnd.setLastColumn(lastcolumn);
+ insertColumn(++k, ciEnd);
+ // no need to attemptMergeColInfoRecords because we
+ // know both on each side are different
+ }
+ }
+
+ /**
+ * Sets all non null fields into the {@code ci} parameter.
+ */
+ private static void setColumnInfoFields(ColumnInfoRecord ci, Short xfStyle, Integer width,
+ Integer level, Boolean hidden, Boolean collapsed) {
+ if (xfStyle != null) {
+ ci.setXFIndex(xfStyle.shortValue());
+ }
+ if (width != null) {
+ ci.setColumnWidth(width.intValue());
+ }
+ if (level != null) {
+ ci.setOutlineLevel( level.shortValue() );
+ }
+ if (hidden != null) {
+ ci.setHidden( hidden.booleanValue() );
+ }
+ if (collapsed != null) {
+ ci.setCollapsed( collapsed.booleanValue() );
+ }
+ }
+
+ private int findColInfoIdx(int columnIx, int fromColInfoIdx) {
+ if (columnIx < 0) {
+ throw new IllegalArgumentException( "column parameter out of range: " + columnIx );
+ }
+ if (fromColInfoIdx < 0) {
+ throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromColInfoIdx );
+ }
+
+ for (int k = fromColInfoIdx; k < records.size(); k++) {
+ ColumnInfoRecord ci = getColInfo(k);
+ if (ci.containsColumn(columnIx)) {
+ return k;
+ }
+ if (ci.getFirstColumn() > columnIx) {
+ break;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Attempts to merge the col info record at the specified index
+ * with either or both of its neighbours
+ */
+ private void attemptMergeColInfoRecords(int colInfoIx) {
+ int nRecords = records.size();
+ if (colInfoIx < 0 || colInfoIx >= nRecords) {
+ throw new IllegalArgumentException("colInfoIx " + colInfoIx
+ + " is out of range (0.." + (nRecords-1) + ")");
+ }
+ ColumnInfoRecord currentCol = getColInfo(colInfoIx);
+ int nextIx = colInfoIx+1;
+ if (nextIx < nRecords) {
+ if (mergeColInfoRecords(currentCol, getColInfo(nextIx))) {
+ records.remove(nextIx);
+ }
+ }
+ if (colInfoIx > 0) {
+ if (mergeColInfoRecords(getColInfo(colInfoIx - 1), currentCol)) {
+ records.remove(colInfoIx);
+ }
+ }
+ }
+ /**
+ * merges two column info records (if they are adjacent and have the same formatting, etc)
+ * @return {@code false} if the two column records could not be merged
+ */
+ private static boolean mergeColInfoRecords(ColumnInfoRecord ciA, ColumnInfoRecord ciB) {
+ if (ciA.isAdjacentBefore(ciB) && ciA.formatMatches(ciB)) {
+ ciA.setLastColumn(ciB.getLastColumn());
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Creates an outline group for the specified columns, by setting the level
+ * field for each col info record in the range. {@link ColumnInfoRecord}s
+ * may be created, split or merged as a result of this operation.
+ *
+ * @param fromColumnIx
+ * group from this column (inclusive)
+ * @param toColumnIx
+ * group to this column (inclusive)
+ * @param indent
+ * if {@code true} the group will be indented by one
+ * level, if {@code false} indenting will be decreased by
+ * one level.
+ */
+ public void groupColumnRange(int fromColumnIx, int toColumnIx, boolean indent) {
+
+ int colInfoSearchStartIdx = 0; // optimization to speed up the search for col infos
+ for (int i = fromColumnIx; i <= toColumnIx; i++) {
+ int level = 1;
+ int colInfoIdx = findColInfoIdx(i, colInfoSearchStartIdx);
+ if (colInfoIdx != -1) {
+ level = getColInfo(colInfoIdx).getOutlineLevel();
+ if (indent) {
+ level++;
+ } else {
+ level--;
+ }
+ level = Math.max(0, level);
+ level = Math.min(7, level);
+ colInfoSearchStartIdx = Math.max(0, colInfoIdx - 1); // -1 just in case this column is collapsed later.
+ }
+ setColumn(i, null, null, Integer.valueOf(level), null, null);
+ }
+ }
+
+ /**
+ * Finds the {@code ColumnInfoRecord} which contains the specified columnIndex
+ * @param columnIndex index of the column (not the index of the ColumnInfoRecord)
+ * @return {@code null} if no column info found for the specified column
+ */
+ public ColumnInfoRecord findColumnInfo(int columnIndex) {
+ int nInfos = records.size();
+ for(int i=0; i< nInfos; i++) {
+ ColumnInfoRecord ci = getColInfo(i);
+ if (ci.containsColumn(columnIndex)) {
+ return ci;
+ }
+ }
+ return null;
+ }
+
+ public int getMaxOutlineLevel() {
+ int result = 0;
+ int count=records.size();
+ for (int i=0; i<count; i++) {
+ ColumnInfoRecord columnInfoRecord = getColInfo(i);
+ result = Math.max(columnInfoRecord.getOutlineLevel(), result);
+ }
+ return result;
+ }
+
+ public int getOutlineLevel(int columnIndex) {
+ ColumnInfoRecord ci = findColumnInfo(columnIndex);
+ if (ci != null) {
return ci.getOutlineLevel();
- } else {
- return 0;
- }
- }
-
- public int getMinColumnIndex() {
- if(records.isEmpty()) {
- return 0;
- }
-
- int minIndex = Integer.MAX_VALUE;
- int nInfos = records.size();
- for(int i=0; i< nInfos; i++) {
- ColumnInfoRecord ci = getColInfo(i);
- minIndex = Math.min(minIndex, ci.getFirstColumn());
- }
-
- return minIndex;
- }
-
- public int getMaxColumnIndex() {
- if(records.isEmpty()) {
- return 0;
- }
-
- int maxIndex = 0;
- int nInfos = records.size();
- for(int i=0; i< nInfos; i++) {
- ColumnInfoRecord ci = getColInfo(i);
- maxIndex = Math.max(maxIndex, ci.getLastColumn());
- }
-
- return maxIndex;
- }
-
- private static int compareColInfos(ColumnInfoRecord a, ColumnInfoRecord b) {
- return a.getFirstColumn()-b.getFirstColumn();
- }
+ } else {
+ return 0;
+ }
+ }
+
+ public int getMinColumnIndex() {
+ if(records.isEmpty()) {
+ return 0;
+ }
+
+ int minIndex = Integer.MAX_VALUE;
+ int nInfos = records.size();
+ for(int i=0; i< nInfos; i++) {
+ ColumnInfoRecord ci = getColInfo(i);
+ minIndex = Math.min(minIndex, ci.getFirstColumn());
+ }
+
+ return minIndex;
+ }
+
+ public int getMaxColumnIndex() {
+ if(records.isEmpty()) {
+ return 0;
+ }
+
+ int maxIndex = 0;
+ int nInfos = records.size();
+ for(int i=0; i< nInfos; i++) {
+ ColumnInfoRecord ci = getColInfo(i);
+ maxIndex = Math.max(maxIndex, ci.getLastColumn());
+ }
+
+ return maxIndex;
+ }
+
+ private static int compareColInfos(ColumnInfoRecord a, ColumnInfoRecord b) {
+ return a.getFirstColumn()-b.getFirstColumn();
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/ConditionalFormattingTable.java Sat May 22 20:56:44 2021
@@ -30,64 +30,64 @@ import org.apache.poi.ss.formula.Formula
* See OOO exelfileformat.pdf sec 4.12 'Conditional Formatting Table'
*/
public final class ConditionalFormattingTable extends RecordAggregate {
- private final List<CFRecordsAggregate> _cfHeaders = new ArrayList<>();
+ private final List<CFRecordsAggregate> _cfHeaders = new ArrayList<>();
- /**
- * Creates an empty ConditionalFormattingTable
- */
- public ConditionalFormattingTable() {}
-
- public ConditionalFormattingTable(RecordStream rs) {
- while (rs.peekNextRecord() instanceof CFHeaderBase) {
- _cfHeaders.add(CFRecordsAggregate.createCFAggregate(rs));
- }
- }
+ /**
+ * Creates an empty ConditionalFormattingTable
+ */
+ public ConditionalFormattingTable() {}
+
+ public ConditionalFormattingTable(RecordStream rs) {
+ while (rs.peekNextRecord() instanceof CFHeaderBase) {
+ _cfHeaders.add(CFRecordsAggregate.createCFAggregate(rs));
+ }
+ }
- @Override
+ @Override
public void visitContainedRecords(RecordVisitor rv) {
- for (CFRecordsAggregate subAgg : _cfHeaders) {
- subAgg.visitContainedRecords(rv);
- }
- }
-
- /**
- * @return index of the newly added CF header aggregate
- */
- public int add(CFRecordsAggregate cfAggregate) {
- cfAggregate.getHeader().setID(_cfHeaders.size());
- _cfHeaders.add(cfAggregate);
- return _cfHeaders.size() - 1;
- }
-
- public int size() {
- return _cfHeaders.size();
- }
-
- public CFRecordsAggregate get(int index) {
- checkIndex(index);
- return _cfHeaders.get(index);
- }
-
- public void remove(int index) {
- checkIndex(index);
- _cfHeaders.remove(index);
- }
-
- private void checkIndex(int index) {
- if (index < 0 || index >= _cfHeaders.size()) {
- throw new IllegalArgumentException("Specified CF index " + index
- + " is outside the allowable range (0.." + (_cfHeaders.size() - 1) + ")");
- }
- }
-
- public void updateFormulasAfterCellShift(FormulaShifter shifter, int externSheetIndex) {
- for (int i = 0; i < _cfHeaders.size(); i++) {
- CFRecordsAggregate subAgg = _cfHeaders.get(i);
- boolean shouldKeep = subAgg.updateFormulasAfterCellShift(shifter, externSheetIndex);
- if (!shouldKeep) {
- _cfHeaders.remove(i);
- i--;
- }
- }
- }
+ for (CFRecordsAggregate subAgg : _cfHeaders) {
+ subAgg.visitContainedRecords(rv);
+ }
+ }
+
+ /**
+ * @return index of the newly added CF header aggregate
+ */
+ public int add(CFRecordsAggregate cfAggregate) {
+ cfAggregate.getHeader().setID(_cfHeaders.size());
+ _cfHeaders.add(cfAggregate);
+ return _cfHeaders.size() - 1;
+ }
+
+ public int size() {
+ return _cfHeaders.size();
+ }
+
+ public CFRecordsAggregate get(int index) {
+ checkIndex(index);
+ return _cfHeaders.get(index);
+ }
+
+ public void remove(int index) {
+ checkIndex(index);
+ _cfHeaders.remove(index);
+ }
+
+ private void checkIndex(int index) {
+ if (index < 0 || index >= _cfHeaders.size()) {
+ throw new IllegalArgumentException("Specified CF index " + index
+ + " is outside the allowable range (0.." + (_cfHeaders.size() - 1) + ")");
+ }
+ }
+
+ public void updateFormulasAfterCellShift(FormulaShifter shifter, int externSheetIndex) {
+ for (int i = 0; i < _cfHeaders.size(); i++) {
+ CFRecordsAggregate subAgg = _cfHeaders.get(i);
+ boolean shouldKeep = subAgg.updateFormulasAfterCellShift(shifter, externSheetIndex);
+ if (!shouldKeep) {
+ _cfHeaders.remove(i);
+ i--;
+ }
+ }
+ }
}
Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/aggregates/CustomViewSettingsRecordAggregate.java Sat May 22 20:56:44 2021
@@ -29,22 +29,22 @@ import org.apache.poi.hssf.record.*;
*/
public final class CustomViewSettingsRecordAggregate extends RecordAggregate {
- private final org.apache.poi.hssf.record.Record _begin;
- private final org.apache.poi.hssf.record.Record _end;
- /**
- * All the records between BOF and EOF
- */
- private final List<RecordBase> _recs;
- private PageSettingsBlock _psBlock;
+ private final org.apache.poi.hssf.record.Record _begin;
+ private final org.apache.poi.hssf.record.Record _end;
+ /**
+ * All the records between BOF and EOF
+ */
+ private final List<RecordBase> _recs;
+ private PageSettingsBlock _psBlock;
- public CustomViewSettingsRecordAggregate(RecordStream rs) {
- _begin = rs.getNext();
- if (_begin.getSid() != UserSViewBegin.sid) {
- throw new IllegalStateException("Bad begin record");
- }
- List<RecordBase> temp = new ArrayList<>();
- while (rs.peekNextSid() != UserSViewEnd.sid) {
- if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
+ public CustomViewSettingsRecordAggregate(RecordStream rs) {
+ _begin = rs.getNext();
+ if (_begin.getSid() != UserSViewBegin.sid) {
+ throw new IllegalStateException("Bad begin record");
+ }
+ List<RecordBase> temp = new ArrayList<>();
+ while (rs.peekNextSid() != UserSViewEnd.sid) {
+ if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
if (_psBlock != null) {
if (rs.peekNextSid() == HeaderFooterRecord.sid) {
// test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
@@ -54,39 +54,39 @@ public final class CustomViewSettingsRec
throw new IllegalStateException(
"Found more than one PageSettingsBlock in chart sub-stream, had sid: " + rs.peekNextSid());
}
- _psBlock = new PageSettingsBlock(rs);
- temp.add(_psBlock);
- continue;
- }
- temp.add(rs.getNext());
- }
- _recs = temp;
- _end = rs.getNext(); // no need to save EOF in field
- if (_end.getSid() != UserSViewEnd.sid) {
- throw new IllegalStateException("Bad custom view settings end record");
- }
- }
+ _psBlock = new PageSettingsBlock(rs);
+ temp.add(_psBlock);
+ continue;
+ }
+ temp.add(rs.getNext());
+ }
+ _recs = temp;
+ _end = rs.getNext(); // no need to save EOF in field
+ if (_end.getSid() != UserSViewEnd.sid) {
+ throw new IllegalStateException("Bad custom view settings end record");
+ }
+ }
- @Override
+ @Override
public void visitContainedRecords(RecordVisitor rv) {
- if (_recs.isEmpty()) {
- return;
- }
- rv.visitRecord(_begin);
- for (int i = 0; i < _recs.size(); i++) {
- RecordBase rb = _recs.get(i);
- if (rb instanceof RecordAggregate) {
- ((RecordAggregate) rb).visitContainedRecords(rv);
- } else {
- rv.visitRecord((org.apache.poi.hssf.record.Record) rb);
- }
- }
- rv.visitRecord(_end);
- }
+ if (_recs.isEmpty()) {
+ return;
+ }
+ rv.visitRecord(_begin);
+ for (int i = 0; i < _recs.size(); i++) {
+ RecordBase rb = _recs.get(i);
+ if (rb instanceof RecordAggregate) {
+ ((RecordAggregate) rb).visitContainedRecords(rv);
+ } else {
+ rv.visitRecord((org.apache.poi.hssf.record.Record) rb);
+ }
+ }
+ rv.visitRecord(_end);
+ }
- public static boolean isBeginRecord(int sid) {
- return sid == UserSViewBegin.sid;
- }
+ public static boolean isBeginRecord(int sid) {
+ return sid == UserSViewBegin.sid;
+ }
public void append(RecordBase r){
_recs.add(r);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org