/** * Title: FeatFormulaErr2 (Formula Evaluation Shared Feature) common record part * * <p>This record part specifies Formula Evaluation & Error Ignoring data for a sheet, stored as * part of a Shared Feature. It can be found in records such as {@link FeatRecord}. For the full * meanings of the flags, see pages 669 and 670 of the Excel binary file format documentation. */ public final class FeatFormulaErr2 implements SharedFeature { static BitField checkCalculationErrors = BitFieldFactory.getInstance(0x01); static BitField checkEmptyCellRef = BitFieldFactory.getInstance(0x02); static BitField checkNumbersAsText = BitFieldFactory.getInstance(0x04); static BitField checkInconsistentRanges = BitFieldFactory.getInstance(0x08); static BitField checkInconsistentFormulas = BitFieldFactory.getInstance(0x10); static BitField checkDateTimeFormats = BitFieldFactory.getInstance(0x20); static BitField checkUnprotectedFormulas = BitFieldFactory.getInstance(0x40); static BitField performDataValidation = BitFieldFactory.getInstance(0x80); /** What errors we should ignore */ private int errorCheck; public FeatFormulaErr2() {} public FeatFormulaErr2(RecordInputStream in) { errorCheck = in.readInt(); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(" [FEATURE FORMULA ERRORS]\n"); buffer.append(" checkCalculationErrors = "); buffer.append(" checkEmptyCellRef = "); buffer.append(" checkNumbersAsText = "); buffer.append(" checkInconsistentRanges = "); buffer.append(" checkInconsistentFormulas = "); buffer.append(" checkDateTimeFormats = "); buffer.append(" checkUnprotectedFormulas = "); buffer.append(" performDataValidation = "); buffer.append(" [/FEATURE FORMULA ERRORS]\n"); return buffer.toString(); } public void serialize(LittleEndianOutput out) { out.writeInt(errorCheck); } public int getDataSize() { return 4; } public int _getRawErrorCheckValue() { return errorCheck; } public boolean getCheckCalculationErrors() { return checkCalculationErrors.isSet(errorCheck); } public void setCheckCalculationErrors(boolean checkCalculationErrors) { FeatFormulaErr2.checkCalculationErrors.setBoolean(errorCheck, checkCalculationErrors); } public boolean getCheckEmptyCellRef() { return checkEmptyCellRef.isSet(errorCheck); } public void setCheckEmptyCellRef(boolean checkEmptyCellRef) { FeatFormulaErr2.checkEmptyCellRef.setBoolean(errorCheck, checkEmptyCellRef); } public boolean getCheckNumbersAsText() { return checkNumbersAsText.isSet(errorCheck); } public void setCheckNumbersAsText(boolean checkNumbersAsText) { FeatFormulaErr2.checkNumbersAsText.setBoolean(errorCheck, checkNumbersAsText); } public boolean getCheckInconsistentRanges() { return checkInconsistentRanges.isSet(errorCheck); } public void setCheckInconsistentRanges(boolean checkInconsistentRanges) { FeatFormulaErr2.checkInconsistentRanges.setBoolean(errorCheck, checkInconsistentRanges); } public boolean getCheckInconsistentFormulas() { return checkInconsistentFormulas.isSet(errorCheck); } public void setCheckInconsistentFormulas(boolean checkInconsistentFormulas) { FeatFormulaErr2.checkInconsistentFormulas.setBoolean(errorCheck, checkInconsistentFormulas); } public boolean getCheckDateTimeFormats() { return checkDateTimeFormats.isSet(errorCheck); } public void setCheckDateTimeFormats(boolean checkDateTimeFormats) { FeatFormulaErr2.checkDateTimeFormats.setBoolean(errorCheck, checkDateTimeFormats); } public boolean getCheckUnprotectedFormulas() { return checkUnprotectedFormulas.isSet(errorCheck); } public void setCheckUnprotectedFormulas(boolean checkUnprotectedFormulas) { FeatFormulaErr2.checkUnprotectedFormulas.setBoolean(errorCheck, checkUnprotectedFormulas); } public boolean getPerformDataValidation() { return performDataValidation.isSet(errorCheck); } public void setPerformDataValidation(boolean performDataValidation) { FeatFormulaErr2.performDataValidation.setBoolean(errorCheck, performDataValidation); } }
/** * Title: Unicode String * * <p>Description: Unicode String - just standard fields that are in several records. It is * considered more desirable then repeating it in all of them. * * <p>This is often called a XLUnicodeRichExtendedString in MS documentation. * * <p>REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) * * <p>REFERENCE: PG 951 Excel Binary File Format (.xls) Structure Specification v20091214 */ public class UnicodeString implements Comparable< UnicodeString> { // TODO - make this final when the compatibility version is removed private short field_1_charCount; private byte field_2_optionflags; private String field_3_string; private List<FormatRun> field_4_format_runs; private ExtRst field_5_ext_rst; private static final BitField highByte = BitFieldFactory.getInstance(0x1); // 0x2 is reserved private static final BitField extBit = BitFieldFactory.getInstance(0x4); private static final BitField richText = BitFieldFactory.getInstance(0x8); public static class FormatRun implements Comparable<FormatRun> { final short _character; short _fontIndex; public FormatRun(short character, short fontIndex) { this._character = character; this._fontIndex = fontIndex; } public FormatRun(LittleEndianInput in) { this(in.readShort(), in.readShort()); } public short getCharacterPos() { return _character; } public short getFontIndex() { return _fontIndex; } public boolean equals(Object o) { if (!(o instanceof FormatRun)) { return false; } FormatRun other = (FormatRun) o; return _character == other._character && _fontIndex == other._fontIndex; } public int compareTo(FormatRun r) { if (_character == r._character && _fontIndex == r._fontIndex) { return 0; } if (_character == r._character) { return _fontIndex - r._fontIndex; } return _character - r._character; } public String toString() { return "character=" + _character + ",fontIndex=" + _fontIndex; } public void serialize(LittleEndianOutput out) { out.writeShort(_character); out.writeShort(_fontIndex); } } // See page 681 public static class ExtRst implements Comparable<ExtRst> { private short reserved; // This is a Phs (see page 881) private short formattingFontIndex; private short formattingOptions; // This is a RPHSSub (see page 894) private int numberOfRuns; private String phoneticText; // This is an array of PhRuns (see page 881) private PhRun[] phRuns; // Sometimes there's some cruft at the end private byte[] extraData; private void populateEmpty() { reserved = 1; phoneticText = ""; phRuns = new PhRun[0]; extraData = new byte[0]; } protected ExtRst() { populateEmpty(); } protected ExtRst(LittleEndianInput in, int expectedLength) { reserved = in.readShort(); // Old style detection (Reserved = 0xFF) if (reserved == -1) { populateEmpty(); return; } // Spot corrupt records if (reserved != 1) { System.err.println( "Warning - ExtRst was has wrong magic marker, expecting 1 but found " + reserved + " - ignoring"); // Grab all the remaining data, and ignore it for (int i = 0; i < expectedLength - 2; i++) { in.readByte(); } // And make us be empty populateEmpty(); return; } // Carry on reading in as normal short stringDataSize = in.readShort(); formattingFontIndex = in.readShort(); formattingOptions = in.readShort(); // RPHSSub numberOfRuns = in.readUShort(); short length1 = in.readShort(); // No really. Someone clearly forgot to read // the docs on their datastructure... short length2 = in.readShort(); // And sometimes they write out garbage :( if (length1 == 0 && length2 > 0) { length2 = 0; } if (length1 != length2) { throw new IllegalStateException( "The two length fields of the Phonetic Text don't agree! " + length1 + " vs " + length2); } phoneticText = StringUtil.readUnicodeLE(in, length1); int runData = stringDataSize - 4 - 6 - (2 * phoneticText.length()); int numRuns = (runData / 6); phRuns = new PhRun[numRuns]; for (int i = 0; i < phRuns.length; i++) { phRuns[i] = new PhRun(in); } int extraDataLength = runData - (numRuns * 6); if (extraDataLength < 0) { System.err.println("Warning - ExtRst overran by " + (0 - extraDataLength) + " bytes"); extraDataLength = 0; } extraData = new byte[extraDataLength]; for (int i = 0; i < extraData.length; i++) { extraData[i] = in.readByte(); } } /** Returns our size, excluding our 4 byte header */ protected int getDataSize() { return 4 + 6 + (2 * phoneticText.length()) + (6 * phRuns.length) + extraData.length; } protected void serialize(ContinuableRecordOutput out) { int dataSize = getDataSize(); out.writeContinueIfRequired(8); out.writeShort(reserved); out.writeShort(dataSize); out.writeShort(formattingFontIndex); out.writeShort(formattingOptions); out.writeContinueIfRequired(6); out.writeShort(numberOfRuns); out.writeShort(phoneticText.length()); out.writeShort(phoneticText.length()); out.writeContinueIfRequired(phoneticText.length() * 2); StringUtil.putUnicodeLE(phoneticText, out); for (int i = 0; i < phRuns.length; i++) { phRuns[i].serialize(out); } out.write(extraData); } public boolean equals(Object obj) { if (!(obj instanceof ExtRst)) { return false; } ExtRst other = (ExtRst) obj; return (compareTo(other) == 0); } public int compareTo(ExtRst o) { int result; result = reserved - o.reserved; if (result != 0) return result; result = formattingFontIndex - o.formattingFontIndex; if (result != 0) return result; result = formattingOptions - o.formattingOptions; if (result != 0) return result; result = numberOfRuns - o.numberOfRuns; if (result != 0) return result; result = phoneticText.compareTo(o.phoneticText); if (result != 0) return result; result = phRuns.length - o.phRuns.length; if (result != 0) return result; for (int i = 0; i < phRuns.length; i++) { result = phRuns[i].phoneticTextFirstCharacterOffset - o.phRuns[i].phoneticTextFirstCharacterOffset; if (result != 0) return result; result = phRuns[i].realTextFirstCharacterOffset - o.phRuns[i].realTextFirstCharacterOffset; if (result != 0) return result; result = phRuns[i].realTextFirstCharacterOffset - o.phRuns[i].realTextLength; if (result != 0) return result; } result = extraData.length - o.extraData.length; if (result != 0) return result; // If we get here, it's the same return 0; } protected ExtRst clone() { ExtRst ext = new ExtRst(); ext.reserved = reserved; ext.formattingFontIndex = formattingFontIndex; ext.formattingOptions = formattingOptions; ext.numberOfRuns = numberOfRuns; ext.phoneticText = phoneticText; ext.phRuns = new PhRun[phRuns.length]; for (int i = 0; i < ext.phRuns.length; i++) { ext.phRuns[i] = new PhRun( phRuns[i].phoneticTextFirstCharacterOffset, phRuns[i].realTextFirstCharacterOffset, phRuns[i].realTextLength); } return ext; } public short getFormattingFontIndex() { return formattingFontIndex; } public short getFormattingOptions() { return formattingOptions; } public int getNumberOfRuns() { return numberOfRuns; } public String getPhoneticText() { return phoneticText; } public PhRun[] getPhRuns() { return phRuns; } } public static class PhRun { private int phoneticTextFirstCharacterOffset; private int realTextFirstCharacterOffset; private int realTextLength; public PhRun( int phoneticTextFirstCharacterOffset, int realTextFirstCharacterOffset, int realTextLength) { this.phoneticTextFirstCharacterOffset = phoneticTextFirstCharacterOffset; this.realTextFirstCharacterOffset = realTextFirstCharacterOffset; this.realTextLength = realTextLength; } private PhRun(LittleEndianInput in) { phoneticTextFirstCharacterOffset = in.readUShort(); realTextFirstCharacterOffset = in.readUShort(); realTextLength = in.readUShort(); } private void serialize(ContinuableRecordOutput out) { out.writeContinueIfRequired(6); out.writeShort(phoneticTextFirstCharacterOffset); out.writeShort(realTextFirstCharacterOffset); out.writeShort(realTextLength); } } private UnicodeString() { // Used for clone method. } public UnicodeString(String str) { setString(str); } public int hashCode() { int stringHash = 0; if (field_3_string != null) stringHash = field_3_string.hashCode(); return field_1_charCount + stringHash; } /** * Our handling of equals is inconsistent with compareTo. The trouble is because we don't truely * understand rich text fields yet it's difficult to make a sound comparison. * * @param o The object to compare. * @return true if the object is actually equal. */ public boolean equals(Object o) { if (!(o instanceof UnicodeString)) { return false; } UnicodeString other = (UnicodeString) o; // OK lets do this in stages to return a quickly, first check the actual string boolean eq = ((field_1_charCount == other.field_1_charCount) && (field_2_optionflags == other.field_2_optionflags) && field_3_string.equals(other.field_3_string)); if (!eq) return false; // OK string appears to be equal but now lets compare formatting runs if ((field_4_format_runs == null) && (other.field_4_format_runs == null)) // Strings are equal, and there are not formatting runs. return true; if (((field_4_format_runs == null) && (other.field_4_format_runs != null)) || (field_4_format_runs != null) && (other.field_4_format_runs == null)) // Strings are equal, but one or the other has formatting runs return false; // Strings are equal, so now compare formatting runs. int size = field_4_format_runs.size(); if (size != other.field_4_format_runs.size()) return false; for (int i = 0; i < size; i++) { FormatRun run1 = field_4_format_runs.get(i); FormatRun run2 = other.field_4_format_runs.get(i); if (!run1.equals(run2)) return false; } // Well the format runs are equal as well!, better check the ExtRst data if (field_5_ext_rst == null && other.field_5_ext_rst == null) { // Good } else if (field_5_ext_rst != null && other.field_5_ext_rst != null) { int extCmp = field_5_ext_rst.compareTo(other.field_5_ext_rst); if (extCmp == 0) { // Good } else { return false; } } else { return false; } // Phew!! After all of that we have finally worked out that the strings // are identical. return true; } /** * construct a unicode string record and fill its fields, ID is ignored * * @param in the RecordInputstream to read the record from */ public UnicodeString(RecordInputStream in) { field_1_charCount = in.readShort(); field_2_optionflags = in.readByte(); int runCount = 0; int extensionLength = 0; // Read the number of rich runs if rich text. if (isRichText()) { runCount = in.readShort(); } // Read the size of extended data if present. if (isExtendedText()) { extensionLength = in.readInt(); } boolean isCompressed = ((field_2_optionflags & 1) == 0); if (isCompressed) { field_3_string = in.readCompressedUnicode(getCharCount()); } else { field_3_string = in.readUnicodeLEString(getCharCount()); } if (isRichText() && (runCount > 0)) { field_4_format_runs = new ArrayList<FormatRun>(runCount); for (int i = 0; i < runCount; i++) { field_4_format_runs.add(new FormatRun(in)); } } if (isExtendedText() && (extensionLength > 0)) { field_5_ext_rst = new ExtRst(new ContinuableRecordInput(in), extensionLength); if (field_5_ext_rst.getDataSize() + 4 != extensionLength) { System.err.println( "ExtRst was supposed to be " + extensionLength + " bytes long, but seems to actually be " + (field_5_ext_rst.getDataSize() + 4)); } } } /** * get the number of characters in the string, as an un-wrapped int * * @return number of characters */ public int getCharCount() { if (field_1_charCount < 0) { return field_1_charCount + 65536; } return field_1_charCount; } /** * get the number of characters in the string, wrapped as needed to fit within a short * * @return number of characters */ public short getCharCountShort() { return field_1_charCount; } /** * set the number of characters in the string * * @param cc - number of characters */ public void setCharCount(short cc) { field_1_charCount = cc; } /** * get the option flags which among other things return if this is a 16-bit or 8 bit string * * @return optionflags bitmask */ public byte getOptionFlags() { return field_2_optionflags; } /** * set the option flags which among other things return if this is a 16-bit or 8 bit string * * @param of optionflags bitmask */ public void setOptionFlags(byte of) { field_2_optionflags = of; } /** @return the actual string this contains as a java String object */ public String getString() { return field_3_string; } /** * set the actual string this contains * * @param string the text */ public void setString(String string) { field_3_string = string; setCharCount((short) field_3_string.length()); // scan for characters greater than 255 ... if any are // present, we have to use 16-bit encoding. Otherwise, we // can use 8-bit encoding boolean useUTF16 = false; int strlen = string.length(); for (int j = 0; j < strlen; j++) { if (string.charAt(j) > 255) { useUTF16 = true; break; } } if (useUTF16) // Set the uncompressed bit field_2_optionflags = highByte.setByte(field_2_optionflags); else field_2_optionflags = highByte.clearByte(field_2_optionflags); } public int getFormatRunCount() { if (field_4_format_runs == null) return 0; return field_4_format_runs.size(); } public FormatRun getFormatRun(int index) { if (field_4_format_runs == null) { return null; } if (index < 0 || index >= field_4_format_runs.size()) { return null; } return field_4_format_runs.get(index); } private int findFormatRunAt(int characterPos) { int size = field_4_format_runs.size(); for (int i = 0; i < size; i++) { FormatRun r = field_4_format_runs.get(i); if (r._character == characterPos) return i; else if (r._character > characterPos) return -1; } return -1; } /** * Adds a font run to the formatted string. * * <p>If a font run exists at the current charcter location, then it is replaced with the font run * to be added. */ public void addFormatRun(FormatRun r) { if (field_4_format_runs == null) { field_4_format_runs = new ArrayList<FormatRun>(); } int index = findFormatRunAt(r._character); if (index != -1) field_4_format_runs.remove(index); field_4_format_runs.add(r); // Need to sort the font runs to ensure that the font runs appear in // character order Collections.sort(field_4_format_runs); // Make sure that we now say that we are a rich string field_2_optionflags = richText.setByte(field_2_optionflags); } public Iterator<FormatRun> formatIterator() { if (field_4_format_runs != null) { return field_4_format_runs.iterator(); } return null; } public void removeFormatRun(FormatRun r) { field_4_format_runs.remove(r); if (field_4_format_runs.size() == 0) { field_4_format_runs = null; field_2_optionflags = richText.clearByte(field_2_optionflags); } } public void clearFormatting() { field_4_format_runs = null; field_2_optionflags = richText.clearByte(field_2_optionflags); } public ExtRst getExtendedRst() { return this.field_5_ext_rst; } void setExtendedRst(ExtRst ext_rst) { if (ext_rst != null) { field_2_optionflags = extBit.setByte(field_2_optionflags); } else { field_2_optionflags = extBit.clearByte(field_2_optionflags); } this.field_5_ext_rst = ext_rst; } /** * Swaps all use in the string of one font index for use of a different font index. Normally only * called when fonts have been removed / re-ordered */ public void swapFontUse(short oldFontIndex, short newFontIndex) { for (FormatRun run : field_4_format_runs) { if (run._fontIndex == oldFontIndex) { run._fontIndex = newFontIndex; } } } /** * unlike the real records we return the same as "getString()" rather than debug info * * @see #getDebugInfo() * @return String value of the record */ public String toString() { return getString(); } /** * return a character representation of the fields of this record * * @return String of output for biffviewer etc. */ public String getDebugInfo() { StringBuffer buffer = new StringBuffer(); buffer.append("[UNICODESTRING]\n"); buffer .append(" .charcount = ") .append(Integer.toHexString(getCharCount())) .append("\n"); buffer .append(" .optionflags = ") .append(Integer.toHexString(getOptionFlags())) .append("\n"); buffer.append(" .string = ").append(getString()).append("\n"); if (field_4_format_runs != null) { for (int i = 0; i < field_4_format_runs.size(); i++) { FormatRun r = field_4_format_runs.get(i); buffer.append(" .format_run" + i + " = ").append(r.toString()).append("\n"); } } if (field_5_ext_rst != null) { buffer.append(" .field_5_ext_rst = ").append("\n"); buffer.append(field_5_ext_rst.toString()).append("\n"); } buffer.append("[/UNICODESTRING]\n"); return buffer.toString(); } /** * Serialises out the String. There are special rules about where we can and can't split onto * Continue records. */ public void serialize(ContinuableRecordOutput out) { int numberOfRichTextRuns = 0; int extendedDataSize = 0; if (isRichText() && field_4_format_runs != null) { numberOfRichTextRuns = field_4_format_runs.size(); } if (isExtendedText() && field_5_ext_rst != null) { extendedDataSize = 4 + field_5_ext_rst.getDataSize(); } // Serialise the bulk of the String // The writeString handles tricky continue stuff for us out.writeString(field_3_string, numberOfRichTextRuns, extendedDataSize); if (numberOfRichTextRuns > 0) { // This will ensure that a run does not split a continue for (int i = 0; i < numberOfRichTextRuns; i++) { if (out.getAvailableSpace() < 4) { out.writeContinue(); } FormatRun r = field_4_format_runs.get(i); r.serialize(out); } } if (extendedDataSize > 0) { field_5_ext_rst.serialize(out); } } public int compareTo(UnicodeString str) { int result = getString().compareTo(str.getString()); // As per the equals method lets do this in stages if (result != 0) return result; // OK string appears to be equal but now lets compare formatting runs if ((field_4_format_runs == null) && (str.field_4_format_runs == null)) // Strings are equal, and there are no formatting runs. return 0; if ((field_4_format_runs == null) && (str.field_4_format_runs != null)) // Strings are equal, but one or the other has formatting runs return 1; if ((field_4_format_runs != null) && (str.field_4_format_runs == null)) // Strings are equal, but one or the other has formatting runs return -1; // Strings are equal, so now compare formatting runs. int size = field_4_format_runs.size(); if (size != str.field_4_format_runs.size()) return size - str.field_4_format_runs.size(); for (int i = 0; i < size; i++) { FormatRun run1 = field_4_format_runs.get(i); FormatRun run2 = str.field_4_format_runs.get(i); result = run1.compareTo(run2); if (result != 0) return result; } // Well the format runs are equal as well!, better check the ExtRst data if ((field_5_ext_rst == null) && (str.field_5_ext_rst == null)) return 0; if ((field_5_ext_rst == null) && (str.field_5_ext_rst != null)) return 1; if ((field_5_ext_rst != null) && (str.field_5_ext_rst == null)) return -1; result = field_5_ext_rst.compareTo(str.field_5_ext_rst); if (result != 0) return result; // Phew!! After all of that we have finally worked out that the strings // are identical. return 0; } private boolean isRichText() { return richText.isSet(getOptionFlags()); } private boolean isExtendedText() { return extBit.isSet(getOptionFlags()); } public Object clone() { UnicodeString str = new UnicodeString(); str.field_1_charCount = field_1_charCount; str.field_2_optionflags = field_2_optionflags; str.field_3_string = field_3_string; if (field_4_format_runs != null) { str.field_4_format_runs = new ArrayList<FormatRun>(); for (FormatRun r : field_4_format_runs) { str.field_4_format_runs.add(new FormatRun(r._character, r._fontIndex)); } } if (field_5_ext_rst != null) { str.field_5_ext_rst = field_5_ext_rst.clone(); } return str; } }
/** * The axis options record provides unit information and other various tidbits about the axis. * * <p> * * @author Andrew C. Oliver(acoliver at apache.org) */ public final class AxisOptionsRecord extends StandardRecord { public static final short sid = 0x1062; private static final BitField defaultMinimum = BitFieldFactory.getInstance(0x01); private static final BitField defaultMaximum = BitFieldFactory.getInstance(0x02); private static final BitField defaultMajor = BitFieldFactory.getInstance(0x04); private static final BitField defaultMinorUnit = BitFieldFactory.getInstance(0x08); private static final BitField isDate = BitFieldFactory.getInstance(0x10); private static final BitField defaultBase = BitFieldFactory.getInstance(0x20); private static final BitField defaultCross = BitFieldFactory.getInstance(0x40); private static final BitField defaultDateSettings = BitFieldFactory.getInstance(0x80); private short field_1_minimumCategory; private short field_2_maximumCategory; private short field_3_majorUnitValue; private short field_4_majorUnit; private short field_5_minorUnitValue; private short field_6_minorUnit; private short field_7_baseUnit; private short field_8_crossingPoint; private short field_9_options; public AxisOptionsRecord() {} public AxisOptionsRecord(RecordInputStream in) { field_1_minimumCategory = in.readShort(); field_2_maximumCategory = in.readShort(); field_3_majorUnitValue = in.readShort(); field_4_majorUnit = in.readShort(); field_5_minorUnitValue = in.readShort(); field_6_minorUnit = in.readShort(); field_7_baseUnit = in.readShort(); field_8_crossingPoint = in.readShort(); field_9_options = in.readShort(); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[AXCEXT]\n"); buffer .append(" .minimumCategory = ") .append("0x") .append(HexDump.toHex(getMinimumCategory())) .append(" (") .append(getMinimumCategory()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .maximumCategory = ") .append("0x") .append(HexDump.toHex(getMaximumCategory())) .append(" (") .append(getMaximumCategory()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .majorUnitValue = ") .append("0x") .append(HexDump.toHex(getMajorUnitValue())) .append(" (") .append(getMajorUnitValue()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .majorUnit = ") .append("0x") .append(HexDump.toHex(getMajorUnit())) .append(" (") .append(getMajorUnit()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .minorUnitValue = ") .append("0x") .append(HexDump.toHex(getMinorUnitValue())) .append(" (") .append(getMinorUnitValue()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .minorUnit = ") .append("0x") .append(HexDump.toHex(getMinorUnit())) .append(" (") .append(getMinorUnit()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .baseUnit = ") .append("0x") .append(HexDump.toHex(getBaseUnit())) .append(" (") .append(getBaseUnit()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .crossingPoint = ") .append("0x") .append(HexDump.toHex(getCrossingPoint())) .append(" (") .append(getCrossingPoint()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer .append(" .options = ") .append("0x") .append(HexDump.toHex(getOptions())) .append(" (") .append(getOptions()) .append(" )"); buffer.append(System.getProperty("line.separator")); buffer.append(" .defaultMinimum = ").append(isDefaultMinimum()).append('\n'); buffer.append(" .defaultMaximum = ").append(isDefaultMaximum()).append('\n'); buffer.append(" .defaultMajor = ").append(isDefaultMajor()).append('\n'); buffer .append(" .defaultMinorUnit = ") .append(isDefaultMinorUnit()) .append('\n'); buffer.append(" .isDate = ").append(isIsDate()).append('\n'); buffer.append(" .defaultBase = ").append(isDefaultBase()).append('\n'); buffer.append(" .defaultCross = ").append(isDefaultCross()).append('\n'); buffer .append(" .defaultDateSettings = ") .append(isDefaultDateSettings()) .append('\n'); buffer.append("[/AXCEXT]\n"); return buffer.toString(); } public void serialize(LittleEndianOutput out) { out.writeShort(field_1_minimumCategory); out.writeShort(field_2_maximumCategory); out.writeShort(field_3_majorUnitValue); out.writeShort(field_4_majorUnit); out.writeShort(field_5_minorUnitValue); out.writeShort(field_6_minorUnit); out.writeShort(field_7_baseUnit); out.writeShort(field_8_crossingPoint); out.writeShort(field_9_options); } protected int getDataSize() { return 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2; } public short getSid() { return sid; } public Object clone() { AxisOptionsRecord rec = new AxisOptionsRecord(); rec.field_1_minimumCategory = field_1_minimumCategory; rec.field_2_maximumCategory = field_2_maximumCategory; rec.field_3_majorUnitValue = field_3_majorUnitValue; rec.field_4_majorUnit = field_4_majorUnit; rec.field_5_minorUnitValue = field_5_minorUnitValue; rec.field_6_minorUnit = field_6_minorUnit; rec.field_7_baseUnit = field_7_baseUnit; rec.field_8_crossingPoint = field_8_crossingPoint; rec.field_9_options = field_9_options; return rec; } /** Get the minimum category field for the AxisOptions record. */ public short getMinimumCategory() { return field_1_minimumCategory; } /** Set the minimum category field for the AxisOptions record. */ public void setMinimumCategory(short field_1_minimumCategory) { this.field_1_minimumCategory = field_1_minimumCategory; } /** Get the maximum category field for the AxisOptions record. */ public short getMaximumCategory() { return field_2_maximumCategory; } /** Set the maximum category field for the AxisOptions record. */ public void setMaximumCategory(short field_2_maximumCategory) { this.field_2_maximumCategory = field_2_maximumCategory; } /** Get the major unit value field for the AxisOptions record. */ public short getMajorUnitValue() { return field_3_majorUnitValue; } /** Set the major unit value field for the AxisOptions record. */ public void setMajorUnitValue(short field_3_majorUnitValue) { this.field_3_majorUnitValue = field_3_majorUnitValue; } /** Get the major unit field for the AxisOptions record. */ public short getMajorUnit() { return field_4_majorUnit; } /** Set the major unit field for the AxisOptions record. */ public void setMajorUnit(short field_4_majorUnit) { this.field_4_majorUnit = field_4_majorUnit; } /** Get the minor unit value field for the AxisOptions record. */ public short getMinorUnitValue() { return field_5_minorUnitValue; } /** Set the minor unit value field for the AxisOptions record. */ public void setMinorUnitValue(short field_5_minorUnitValue) { this.field_5_minorUnitValue = field_5_minorUnitValue; } /** Get the minor unit field for the AxisOptions record. */ public short getMinorUnit() { return field_6_minorUnit; } /** Set the minor unit field for the AxisOptions record. */ public void setMinorUnit(short field_6_minorUnit) { this.field_6_minorUnit = field_6_minorUnit; } /** Get the base unit field for the AxisOptions record. */ public short getBaseUnit() { return field_7_baseUnit; } /** Set the base unit field for the AxisOptions record. */ public void setBaseUnit(short field_7_baseUnit) { this.field_7_baseUnit = field_7_baseUnit; } /** Get the crossing point field for the AxisOptions record. */ public short getCrossingPoint() { return field_8_crossingPoint; } /** Set the crossing point field for the AxisOptions record. */ public void setCrossingPoint(short field_8_crossingPoint) { this.field_8_crossingPoint = field_8_crossingPoint; } /** Get the options field for the AxisOptions record. */ public short getOptions() { return field_9_options; } /** Set the options field for the AxisOptions record. */ public void setOptions(short field_9_options) { this.field_9_options = field_9_options; } /** Sets the default minimum field value. use the default minimum category */ public void setDefaultMinimum(boolean value) { field_9_options = defaultMinimum.setShortBoolean(field_9_options, value); } /** * use the default minimum category * * @return the default minimum field value. */ public boolean isDefaultMinimum() { return defaultMinimum.isSet(field_9_options); } /** Sets the default maximum field value. use the default maximum category */ public void setDefaultMaximum(boolean value) { field_9_options = defaultMaximum.setShortBoolean(field_9_options, value); } /** * use the default maximum category * * @return the default maximum field value. */ public boolean isDefaultMaximum() { return defaultMaximum.isSet(field_9_options); } /** Sets the default major field value. use the default major unit */ public void setDefaultMajor(boolean value) { field_9_options = defaultMajor.setShortBoolean(field_9_options, value); } /** * use the default major unit * * @return the default major field value. */ public boolean isDefaultMajor() { return defaultMajor.isSet(field_9_options); } /** Sets the default minor unit field value. use the default minor unit */ public void setDefaultMinorUnit(boolean value) { field_9_options = defaultMinorUnit.setShortBoolean(field_9_options, value); } /** * use the default minor unit * * @return the default minor unit field value. */ public boolean isDefaultMinorUnit() { return defaultMinorUnit.isSet(field_9_options); } /** Sets the isDate field value. this is a date axis */ public void setIsDate(boolean value) { field_9_options = isDate.setShortBoolean(field_9_options, value); } /** * this is a date axis * * @return the isDate field value. */ public boolean isIsDate() { return isDate.isSet(field_9_options); } /** Sets the default base field value. use the default base unit */ public void setDefaultBase(boolean value) { field_9_options = defaultBase.setShortBoolean(field_9_options, value); } /** * use the default base unit * * @return the default base field value. */ public boolean isDefaultBase() { return defaultBase.isSet(field_9_options); } /** Sets the default cross field value. use the default crossing point */ public void setDefaultCross(boolean value) { field_9_options = defaultCross.setShortBoolean(field_9_options, value); } /** * use the default crossing point * * @return the default cross field value. */ public boolean isDefaultCross() { return defaultCross.isSet(field_9_options); } /** Sets the default date settings field value. use default date setttings for this axis */ public void setDefaultDateSettings(boolean value) { field_9_options = defaultDateSettings.setShortBoolean(field_9_options, value); } /** * use default date setttings for this axis * * @return the default date settings field value. */ public boolean isDefaultDateSettings() { return defaultDateSettings.isSet(field_9_options); } }
/** * Describes a chart sheet properties record. SHTPROPS (0x1044) * * <p>(As with all chart related records, documentation is lacking. See {@link ChartRecord} for more * details) * * @author Glen Stampoultzis (glens at apache.org) */ public final class SheetPropertiesRecord extends StandardRecord { public static final short sid = 0x1044; private static final BitField chartTypeManuallyFormatted = BitFieldFactory.getInstance(0x01); private static final BitField plotVisibleOnly = BitFieldFactory.getInstance(0x02); private static final BitField doNotSizeWithWindow = BitFieldFactory.getInstance(0x04); private static final BitField defaultPlotDimensions = BitFieldFactory.getInstance(0x08); private static final BitField autoPlotArea = BitFieldFactory.getInstance(0x10); private int field_1_flags; private int field_2_empty; public static final byte EMPTY_NOT_PLOTTED = 0; public static final byte EMPTY_ZERO = 1; public static final byte EMPTY_INTERPOLATED = 2; public SheetPropertiesRecord() { // fields uninitialised } public SheetPropertiesRecord(RecordInputStream in) { field_1_flags = in.readUShort(); field_2_empty = in.readUShort(); } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[SHTPROPS]\n"); buffer .append(" .flags = ") .append(HexDump.shortToHex(field_1_flags)) .append('\n'); buffer .append(" .chartTypeManuallyFormatted= ") .append(isChartTypeManuallyFormatted()) .append('\n'); buffer .append(" .plotVisibleOnly = ") .append(isPlotVisibleOnly()) .append('\n'); buffer .append(" .doNotSizeWithWindow = ") .append(isDoNotSizeWithWindow()) .append('\n'); buffer .append(" .defaultPlotDimensions = ") .append(isDefaultPlotDimensions()) .append('\n'); buffer.append(" .autoPlotArea = ").append(isAutoPlotArea()).append('\n'); buffer .append(" .empty = ") .append(HexDump.shortToHex(field_2_empty)) .append('\n'); buffer.append("[/SHTPROPS]\n"); return buffer.toString(); } public void serialize(LittleEndianOutput out) { out.writeShort(field_1_flags); out.writeShort(field_2_empty); } protected int getDataSize() { return 2 + 2; } public short getSid() { return sid; } public Object clone() { SheetPropertiesRecord rec = new SheetPropertiesRecord(); rec.field_1_flags = field_1_flags; rec.field_2_empty = field_2_empty; return rec; } /** Get the flags field for the SheetProperties record. */ public int getFlags() { return field_1_flags; } /** * Get the empty field for the SheetProperties record. * * @return One of EMPTY_NOT_PLOTTED EMPTY_ZERO EMPTY_INTERPOLATED */ public int getEmpty() { return field_2_empty; } /** * Set the empty field for the SheetProperties record. * * @param empty One of EMPTY_NOT_PLOTTED EMPTY_ZERO EMPTY_INTERPOLATED */ public void setEmpty(byte empty) { this.field_2_empty = empty; } /** * Sets the chart type manually formatted field value. Has the chart type been manually formatted? */ public void setChartTypeManuallyFormatted(boolean value) { field_1_flags = chartTypeManuallyFormatted.setBoolean(field_1_flags, value); } /** * Has the chart type been manually formatted? * * @return the chart type manually formatted field value. */ public boolean isChartTypeManuallyFormatted() { return chartTypeManuallyFormatted.isSet(field_1_flags); } /** Sets the plot visible only field value. Only show visible cells on the chart. */ public void setPlotVisibleOnly(boolean value) { field_1_flags = plotVisibleOnly.setBoolean(field_1_flags, value); } /** * Only show visible cells on the chart. * * @return the plot visible only field value. */ public boolean isPlotVisibleOnly() { return plotVisibleOnly.isSet(field_1_flags); } /** * Sets the do not size with window field value. Do not size the chart when the window changes * size */ public void setDoNotSizeWithWindow(boolean value) { field_1_flags = doNotSizeWithWindow.setBoolean(field_1_flags, value); } /** * Do not size the chart when the window changes size * * @return the do not size with window field value. */ public boolean isDoNotSizeWithWindow() { return doNotSizeWithWindow.isSet(field_1_flags); } /** * Sets the default plot dimensions field value. Indicates that the default area dimensions should * be used. */ public void setDefaultPlotDimensions(boolean value) { field_1_flags = defaultPlotDimensions.setBoolean(field_1_flags, value); } /** * Indicates that the default area dimensions should be used. * * @return the default plot dimensions field value. */ public boolean isDefaultPlotDimensions() { return defaultPlotDimensions.isSet(field_1_flags); } /** Sets the auto plot area field value. ?? */ public void setAutoPlotArea(boolean value) { field_1_flags = autoPlotArea.setBoolean(field_1_flags, value); } /** * ?? * * @return the auto plot area field value. */ public boolean isAutoPlotArea() { return autoPlotArea.isSet(field_1_flags); } }