From e33dbf93a0ba2c109184832e19028c25444de6f1 Mon Sep 17 00:00:00 2001
From: Nick Burch
+ *
+ * OVERLAP - both ranges partially overlap;
+ * INSIDE - the specified range is inside of this one
+ * ENCLOSES - the specified range encloses this range
+ */
+ public int intersect(CellRange another )
+ {
+ int firstRow = another.getFirstRow();
+ int lastRow = another.getLastRow();
+ short firstCol = another.getFirstColumn();
+ short lastCol = another.getLastColumn();
+
+ if
+ (
+ gt(this.getFirstRow(),lastRow) ||
+ lt(this.getLastRow(),firstRow) ||
+ gt(this.getFirstColumn(),lastCol) ||
+ lt(this.getLastColumn(),firstCol)
+ )
+ {
+ return NO_INTERSECTION;
+ }
+ else if( this.contains(another) )
+ {
+ return INSIDE;
+ }
+ else if( another.contains(this) )
+ {
+ return ENCLOSES;
+ }
+ else
+ {
+ return OVERLAP;
+ }
+
+ }
+
+ /**
+ * Check if the specified range is located inside of this cell range.
+ *
+ * @param range
+ * @return true if this cell range contains the argument range inside if it's area
+ */
+ public boolean contains(CellRange range)
+ {
+ int firstRow = range.getFirstRow();
+ int lastRow = range.getLastRow();
+ short firstCol = range.getFirstColumn();
+ short lastCol = range.getLastColumn();
+ return le(this.getFirstRow(), firstRow) && ge(this.getLastRow(), lastRow)
+ && le(this.getFirstColumn(), firstCol) && ge(this.getLastColumn(), lastCol);
+ }
+
+ public boolean contains(int row, short column)
+ {
+ return le(this.getFirstRow(), row) && ge(this.getLastRow(), row)
+ && le(this.getFirstColumn(), column) && ge(this.getLastColumn(), column);
+ }
+
+ /**
+ * Check if the specified cell range has a shared border with the current range.
+ *
+ * @return true if the ranges have a shared border.
+ */
+ public boolean hasSharedBorder(CellRange range)
+ {
+ int firstRow = range.getFirstRow();
+ int lastRow = range.getLastRow();
+ short firstCol = range.getFirstColumn();
+ short lastCol = range.getLastColumn();
+ return
+ (this.getFirstRow()>0 && this.getFirstRow() - 1 == lastRow || firstRow>0 &&this.getLastRow() == firstRow -1)&&
+ (this.getFirstColumn() == firstCol) &&
+ (this.getLastColumn() == lastCol) ||
+ (this.getFirstColumn()>0 && this.getFirstColumn() - 1 == lastCol || firstCol>0 && this.getLastColumn() == firstCol -1) &&
+ (this.getFirstRow() == firstRow) &&
+ (this.getLastRow() == lastRow)
+ ;
+ }
+
+ /**
+ * Create an enclosing CellRange for the two cell ranges.
+ *
+ * @return enclosing CellRange
+ */
+ public CellRange createEnclosingCellRange(CellRange range)
+ {
+ if( range == null)
+ {
+ return cloneCellRange();
+ }
+ else
+ {
+ CellRange cellRange =
+ new CellRange(
+ lt(range.getFirstRow(),getFirstRow())?range.getFirstRow():getFirstRow(),
+ gt(range.getLastRow(),getLastRow())?range.getLastRow():getLastRow(),
+ lt(range.getFirstColumn(),getFirstColumn())?range.getFirstColumn():getFirstColumn(),
+ gt(range.getLastColumn(),getLastColumn())?range.getLastColumn():getLastColumn()
+ );
+ return cellRange;
+ }
+ }
+
+ public CellRange cloneCellRange()
+ {
+ return new CellRange(getFirstRow(),getLastRow(),getFirstColumn(),getLastColumn());
+ }
+
+ /**
+ * Copy data from antother cell range to this cell range
+ * @param cr - another cell range
+ */
+ public void setCellRange(CellRange cr)
+ {
+ setFirstRow(cr.getFirstRow());
+ setLastRow(cr.getLastRow());
+ setFirstColumn(cr.getFirstColumn());
+ setLastColumn(cr.getLastColumn());
+ }
+
+ /**
+ * @return true if a < b
+ */
+ private static boolean lt(int a, int b)
+ {
+ return a == -1 ? false : (b == -1 ? true : a < b);
+ }
+
+ /**
+ * @return true if a <= b
+ */
+ private static boolean le(int a, int b)
+ {
+ return a == b || lt(a,b);
+ }
+
+ /**
+ * @return true if a > b
+ */
+ private static boolean gt(int a, int b)
+ {
+ return lt(b,a);
+ }
+
+ /**
+ * @return true if a >= b
+ */
+ private static boolean ge(int a, int b)
+ {
+ return !lt(a,b);
+ }
+
+ public String toString()
+ {
+ return "("+this.getFirstRow()+","+this.getLastRow()+","+this.getFirstColumn()+","+this.getLastColumn()+")";
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
new file mode 100644
index 0000000000..1e6abee7c9
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
@@ -0,0 +1,591 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Font Formatting Block of the Conditional Formatting Rule Record.
+ *
+ * Created on January 22, 2008, 10:05 PM
+ *
+ * @author Dmitriy Kumshayev
+ */
+
+public class FontFormatting
+{
+ private byte [] record;
+
+ private static final int OFFSET_FONT_NAME = 0;
+ private static final int OFFSET_FONT_HEIGHT = 64;
+ private static final int OFFSET_FONT_OPTIONS = 68;
+ private static final int OFFSET_FONT_WEIGHT = 72;
+ private static final int OFFSET_ESCAPEMENT_TYPE = 74;
+ private static final int OFFSET_UNDERLINE_TYPE = 76;
+ private static final int OFFSET_FONT_COLOR_INDEX = 80;
+ private static final int OFFSET_OPTION_FLAGS = 88;
+ private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
+ private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
+ private static final int OFFSET_NOT_USED1 = 100;
+ private static final int OFFSET_NOT_USED2 = 104;
+ private static final int OFFSET_FONT_FORMATING_END = 116;
+
+
+ public final static int FONT_CELL_HEIGHT_PRESERVED = 0xFFFFFFFF;
+
+ // FONT OPTIONS MASKS
+ private static final BitField posture = BitFieldFactory.getInstance(0x00000002);
+ private static final BitField outline = BitFieldFactory.getInstance(0x00000008);
+ private static final BitField shadow = BitFieldFactory.getInstance(0x00000010);
+ private static final BitField condense = BitFieldFactory.getInstance(0x00000020);
+ private static final BitField cancellation = BitFieldFactory.getInstance(0x00000080);
+
+ // OPTION FLAGS MASKS
+
+ private static final BitField styleModified = BitFieldFactory.getInstance(0x00000002);
+ private static final BitField outlineModified = BitFieldFactory.getInstance(0x00000008);
+ private static final BitField shadowModified = BitFieldFactory.getInstance(0x00000010);
+ private static final BitField condenseModified = BitFieldFactory.getInstance(0x00000020);
+ private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
+
+ /**
+ * Escapement type - None
+ */
+ public final static short SS_NONE = 0;
+
+ /**
+ * Escapement type - Superscript
+ */
+ public final static short SS_SUPER = 1;
+
+ /**
+ * Escapement type - Subscript
+ */
+ public final static short SS_SUB = 2;
+
+ /**
+ * Underline type - None
+ */
+ public final static byte U_NONE = 0;
+
+ /**
+ * Underline type - Single
+ */
+ public final static byte U_SINGLE = 1;
+
+ /**
+ * Underline type - Double
+ */
+ public final static byte U_DOUBLE = 2;
+
+ /**
+ * Underline type - Single Accounting
+ */
+ public final static byte U_SINGLE_ACCOUNTING = 0x21;
+
+ /**
+ * Underline type - Double Accounting
+ */
+ public final static byte U_DOUBLE_ACCOUNTING = 0x22;
+
+ /**
+ * Normal boldness (not bold)
+ */
+
+ protected final static short FONT_WEIGHT_NORMAL = 0x190;
+
+ /**
+ * Bold boldness (bold)
+ */
+
+ protected final static short FONT_WEIGHT_BOLD = 0x2bc;
+
+ public FontFormatting()
+ {
+ this(new byte[118]);
+
+ this.setFontHeight((short)-1);
+ this.setItalic(false);
+ this.setBold(false);
+ this.setOutline(false);
+ this.setShadow(false);
+ this.setCondense(false);
+ this.setStrikeout(false);
+ this.setEscapementType((short)0);
+ this.setUnderlineType((byte)0);
+ this.setFontColorIndex((short)-1);
+
+ this.setFontStyleModified(false);
+ this.setFontOutlineModified(false);
+ this.setFontShadowModified(false);
+ this.setFontCondenseModified(false);
+ this.setFontCancellationModified(false);
+
+ this.setEscapementTypeModified(false);
+ this.setUnderlineTypeModified(false);
+
+ LittleEndian.putShort(record, OFFSET_FONT_NAME, (short)0);
+ LittleEndian.putInt(record, OFFSET_NOT_USED1, 0x00000001);
+ LittleEndian.putInt(record, OFFSET_NOT_USED2, 0x00000001);
+ LittleEndian.putShort(record, OFFSET_FONT_FORMATING_END, (short)0x0001);
+ }
+
+ /** Creates new FontFormatting */
+ private FontFormatting(byte[] record)
+ {
+ this.record = record;
+ }
+
+ /** Creates new FontFormatting */
+ public FontFormatting(RecordInputStream in)
+ {
+ record = new byte[118];
+ for (int i = 0; i != record.length; i++)
+ {
+ record[i] = in.readByte();
+ }
+ }
+
+ public byte[] getRawRecord()
+ {
+ return record;
+ }
+
+ /**
+ * sets the height of the font in 1/20th point units
+ *
+ *
+ * @param height fontheight (in points/20); or -1 to preserve the cell font height
+ */
+
+ public void setFontHeight(short height)
+ {
+ LittleEndian.putInt(record, OFFSET_FONT_HEIGHT, height);
+ }
+
+ /**
+ * gets the height of the font in 1/20th point units
+ *
+ * @return fontheight (in points/20); or -1 if not modified
+ */
+ public short getFontHeight()
+ {
+ return (short) LittleEndian.getInt(record, OFFSET_FONT_HEIGHT);
+ }
+
+ private void setFontOption(boolean option, BitField field)
+ {
+ int options = LittleEndian.getInt(record,OFFSET_FONT_OPTIONS);
+ options = field.setBoolean(options, option);
+ LittleEndian.putInt(record,OFFSET_FONT_OPTIONS, options);
+ }
+
+ private boolean getFontOption(BitField field)
+ {
+ int options = LittleEndian.getInt(record,OFFSET_FONT_OPTIONS);
+ return field.isSet(options);
+ }
+
+ /**
+ * set the font to be italics or not
+ *
+ * @param italics - whether the font is italics or not
+ * @see #setAttributes(short)
+ */
+
+ public void setItalic(boolean italic)
+ {
+ setFontOption(italic, posture);
+ }
+
+ /**
+ * get whether the font is to be italics or not
+ *
+ * @return italics - whether the font is italics or not
+ * @see #getAttributes()
+ */
+
+ public boolean isItalic()
+ {
+ return getFontOption(posture);
+ }
+
+ public void setOutline(boolean on)
+ {
+ setFontOption(on, outline);
+ }
+
+ public boolean isOutlineOn()
+ {
+ return getFontOption(outline);
+ }
+
+ public void setShadow(boolean on)
+ {
+ setFontOption(on, shadow);
+ }
+
+ public boolean isShadowOn()
+ {
+ return getFontOption(shadow);
+ }
+
+ public void setCondense(boolean on)
+ {
+ setFontOption(on, condense);
+ }
+
+ public boolean isCondenseOn()
+ {
+ return getFontOption(condense);
+ }
+
+ /**
+ * set the font to be stricken out or not
+ *
+ * @param strike - whether the font is stricken out or not
+ */
+
+ public void setStrikeout(boolean strike)
+ {
+ setFontOption(strike, cancellation);
+ }
+
+ /**
+ * get whether the font is to be stricken out or not
+ *
+ * @return strike - whether the font is stricken out or not
+ * @see #getAttributes()
+ */
+
+ public boolean isStruckout()
+ {
+ return getFontOption(cancellation);
+ }
+
+ /**
+ * set the font weight (100-1000dec or 0x64-0x3e8). Default is
+ * 0x190 for normal and 0x2bc for bold
+ *
+ * @param bw - a number between 100-1000 for the fonts "boldness"
+ */
+
+ private void setFontWeight(short bw)
+ {
+ if( bw<100) { bw=100; }
+ if( bw>1000){ bw=1000; }
+ LittleEndian.putShort(record,OFFSET_FONT_WEIGHT, bw);
+ }
+
+ /**
+ * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
+ *
+ * @param bold - set font weight to bold if true; to normal otherwise
+ */
+ public void setBold(boolean bold)
+ {
+ setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
+ }
+
+ /**
+ * get the font weight for this font (100-1000dec or 0x64-0x3e8). Default is
+ * 0x190 for normal and 0x2bc for bold
+ *
+ * @return bw - a number between 100-1000 for the fonts "boldness"
+ */
+
+ public short getFontWeight()
+ {
+ return LittleEndian.getShort(record,OFFSET_FONT_WEIGHT);
+ }
+
+ /**
+ * get whether the font weight is set to bold or not
+ *
+ * @return bold - whether the font is bold or not
+ */
+
+ public boolean isBold()
+ {
+ return getFontWeight()==FONT_WEIGHT_BOLD;
+ }
+
+ /**
+ * get the type of super or subscript for the font
+ *
+ * @return super or subscript option
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+ */
+ public short getEscapementType()
+ {
+ return LittleEndian.getShort(record,OFFSET_ESCAPEMENT_TYPE);
+ }
+
+ /**
+ * set the escapement type for the font
+ *
+ * @param escapementType super or subscript option
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+ */
+ public void setEscapementType( short escapementType)
+ {
+ LittleEndian.putShort(record,OFFSET_ESCAPEMENT_TYPE, escapementType);
+ }
+
+ /**
+ * get the type of underlining for the font
+ *
+ * @return font underlining type
+ *
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+ */
+
+ public short getUnderlineType()
+ {
+ return LittleEndian.getShort(record,OFFSET_UNDERLINE_TYPE);
+ }
+
+ /**
+ * set the type of underlining type for the font
+ *
+ * @param u super or subscript option
+ *
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+ * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+ */
+ public void setUnderlineType( short underlineType)
+ {
+ LittleEndian.putShort(record,OFFSET_UNDERLINE_TYPE, underlineType);
+ }
+
+
+ public short getFontColorIndex()
+ {
+ return (short)LittleEndian.getInt(record,OFFSET_FONT_COLOR_INDEX);
+ }
+
+ public void setFontColorIndex(short fci )
+ {
+ LittleEndian.putInt(record,OFFSET_FONT_COLOR_INDEX,fci);
+ }
+
+ private boolean getOptionFlag(BitField field)
+ {
+ int optionFlags = LittleEndian.getInt(record,OFFSET_OPTION_FLAGS);
+ int value = field.getValue(optionFlags);
+ return value==0? true : false ;
+ }
+
+ private void setOptionFlag(boolean modified, BitField field)
+ {
+ int value = modified? 0 : 1;
+ int optionFlags = LittleEndian.getInt(record,OFFSET_OPTION_FLAGS);
+ optionFlags = field.setValue(optionFlags, value);
+ LittleEndian.putInt(record,OFFSET_OPTION_FLAGS, optionFlags);
+ }
+
+
+ public boolean isFontStyleModified()
+ {
+ return getOptionFlag(styleModified);
+ }
+
+ public void setFontStyleModified(boolean modified)
+ {
+ setOptionFlag(modified, styleModified);
+ }
+
+ public boolean isFontOutlineModified()
+ {
+ return getOptionFlag(outlineModified);
+ }
+
+ public void setFontOutlineModified(boolean modified)
+ {
+ setOptionFlag(modified, outlineModified);
+ }
+
+ public boolean isFontShadowModified()
+ {
+ return getOptionFlag(shadowModified);
+ }
+
+ public void setFontShadowModified(boolean modified)
+ {
+ setOptionFlag(modified, shadowModified);
+ }
+ public boolean isFontCondenseModified()
+ {
+ return getOptionFlag(condenseModified);
+ }
+
+ public void setFontCondenseModified(boolean modified)
+ {
+ setOptionFlag(modified, condenseModified);
+ }
+
+ public void setFontCancellationModified(boolean modified)
+ {
+ setOptionFlag(modified, cancellationModified);
+ }
+
+ public boolean isFontCancellationModified()
+ {
+ return getOptionFlag(cancellationModified);
+ }
+
+ public void setEscapementTypeModified(boolean modified)
+ {
+ int value = modified? 0 : 1;
+ LittleEndian.putInt(record,OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
+ }
+
+ public boolean isEscapementTypeModified()
+ {
+ int escapementModified = LittleEndian.getInt(record,OFFSET_ESCAPEMENT_TYPE_MODIFIED);
+ return escapementModified == 0;
+ }
+
+ public void setUnderlineTypeModified(boolean modified)
+ {
+ int value = modified? 0 : 1;
+ LittleEndian.putInt(record,OFFSET_UNDERLINE_TYPE_MODIFIED, value);
+ }
+
+ public boolean isUnderlineTypeModified()
+ {
+ int underlineModified = LittleEndian.getInt(record,OFFSET_UNDERLINE_TYPE_MODIFIED);
+ return underlineModified == 0;
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(" [Font Formatting]\n");
+
+ buffer.append(" .font height = ").append(getFontHeight()).append(" twips\n");
+
+ if( isFontStyleModified() )
+ {
+ buffer.append(" .font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
+ }
+ else
+ {
+ buffer.append(" .font posture = ]not modified]").append("\n");
+ }
+
+ if( isFontOutlineModified() )
+ {
+ buffer.append(" .font outline = ").append(isOutlineOn()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .font outline is not modified\n");
+ }
+
+ if( isFontShadowModified() )
+ {
+ buffer.append(" .font shadow = ").append(isShadowOn()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .font shadow is not modified\n");
+ }
+ if( isFontCondenseModified() )
+ {
+ buffer.append(" .font condense = ").append(isCondenseOn()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .font condense is not modified\n");
+ }
+
+ if( isFontCancellationModified() )
+ {
+ buffer.append(" .font strikeout = ").append(isStruckout()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .font strikeout is not modified\n");
+ }
+
+ if( isFontStyleModified() )
+ {
+ buffer.append(" .font weight = ").
+ append(getFontWeight()).
+ append(
+ getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
+ : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" : "0x"+Integer.toHexString(getFontWeight())).
+ append("\n");
+ }
+ else
+ {
+ buffer.append(" .font weight = ]not modified]").append("\n");
+ }
+
+ if( isEscapementTypeModified() )
+ {
+ buffer.append(" .escapement type = ").append(getEscapementType()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .escapement type is not modified\n");
+ }
+
+ if( isUnderlineTypeModified() )
+ {
+ buffer.append(" .underline type = ").append(getUnderlineType()).append("\n");
+ }
+ else
+ {
+ buffer.append(" .underline type is not modified\n");
+ }
+ buffer.append(" .color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
+
+
+ buffer.append(" [/Font Formatting]\n");
+ return buffer.toString();
+ }
+
+ public Object clone()
+ {
+ FontFormatting rec = new FontFormatting();
+ if( record != null)
+ {
+ byte[] clone = new byte[record.length];
+ System.arraycopy(record, 0, clone, 0, record.length);
+ rec.record = clone;
+ }
+ return rec;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java b/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
new file mode 100644
index 0000000000..3157bf46c8
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
@@ -0,0 +1,206 @@
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+
+/*
+ * FontFormatting.java
+ *
+ * Created on January 22, 2008, 10:05 PM
+ */
+package org.apache.poi.hssf.record.cf;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Pattern Formatting Block of the Conditional Formatting Rule Record.
+ *
+ * @author Dmitriy Kumshayev
+ */
+
+public class PatternFormatting implements Cloneable
+{
+ /** No background */
+ public final static short NO_FILL = 0 ;
+ /** Solidly filled */
+ public final static short SOLID_FOREGROUND = 1 ;
+ /** Small fine dots */
+ public final static short FINE_DOTS = 2 ;
+ /** Wide dots */
+ public final static short ALT_BARS = 3 ;
+ /** Sparse dots */
+ public final static short SPARSE_DOTS = 4 ;
+ /** Thick horizontal bands */
+ public final static short THICK_HORZ_BANDS = 5 ;
+ /** Thick vertical bands */
+ public final static short THICK_VERT_BANDS = 6 ;
+ /** Thick backward facing diagonals */
+ public final static short THICK_BACKWARD_DIAG = 7 ;
+ /** Thick forward facing diagonals */
+ public final static short THICK_FORWARD_DIAG = 8 ;
+ /** Large spots */
+ public final static short BIG_SPOTS = 9 ;
+ /** Brick-like layout */
+ public final static short BRICKS = 10 ;
+ /** Thin horizontal bands */
+ public final static short THIN_HORZ_BANDS = 11 ;
+ /** Thin vertical bands */
+ public final static short THIN_VERT_BANDS = 12 ;
+ /** Thin backward diagonal */
+ public final static short THIN_BACKWARD_DIAG = 13 ;
+ /** Thin forward diagonal */
+ public final static short THIN_FORWARD_DIAG = 14 ;
+ /** Squares */
+ public final static short SQUARES = 15 ;
+ /** Diamonds */
+ public final static short DIAMONDS = 16 ;
+ /** Less Dots */
+ public final static short LESS_DOTS = 17 ;
+ /** Least Dots */
+ public final static short LEAST_DOTS = 18 ;
+
+ public PatternFormatting()
+ {
+ field_15_pattern_style = (short)0;
+ field_16_pattern_color_indexes = (short)0;
+ }
+
+ /** Creates new FontFormatting */
+ public PatternFormatting(RecordInputStream in)
+ {
+ field_15_pattern_style = in.readShort();
+ field_16_pattern_color_indexes = in.readShort();
+ }
+
+ // PATTERN FORMATING BLOCK
+ // For Pattern Styles see constants at HSSFCellStyle (from NO_FILL to LEAST_DOTS)
+ private short field_15_pattern_style;
+ private static final BitField fillPatternStyle = BitFieldFactory.getInstance(0xFC00);
+
+ private short field_16_pattern_color_indexes;
+ private static final BitField patternColorIndex = BitFieldFactory.getInstance(0x007F);
+ private static final BitField patternBackgroundColorIndex = BitFieldFactory.getInstance(0x3F80);
+
+ /**
+ * setting fill pattern
+ *
+ * @see #NO_FILL
+ * @see #SOLID_FOREGROUND
+ * @see #FINE_DOTS
+ * @see #ALT_BARS
+ * @see #SPARSE_DOTS
+ * @see #THICK_HORZ_BANDS
+ * @see #THICK_VERT_BANDS
+ * @see #THICK_BACKWARD_DIAG
+ * @see #THICK_FORWARD_DIAG
+ * @see #BIG_SPOTS
+ * @see #BRICKS
+ * @see #THIN_HORZ_BANDS
+ * @see #THIN_VERT_BANDS
+ * @see #THIN_BACKWARD_DIAG
+ * @see #THIN_FORWARD_DIAG
+ * @see #SQUARES
+ * @see #DIAMONDS
+ *
+ * @param fp fill pattern
+ */
+ public void setFillPattern(short fp)
+ {
+ field_15_pattern_style = fillPatternStyle.setShortValue(field_15_pattern_style, fp);
+ }
+
+ /**
+ * get the fill pattern
+ * @return fill pattern
+ */
+
+ public short getFillPattern()
+ {
+ return fillPatternStyle.getShortValue(field_15_pattern_style);
+ }
+
+ /**
+ * set the background fill color.
+ *
+ * @param bg color
+ */
+
+ public void setFillBackgroundColor(short bg)
+ {
+ field_16_pattern_color_indexes = patternBackgroundColorIndex.setShortValue(field_16_pattern_color_indexes,bg);
+ }
+
+ /**
+ * get the background fill color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @return fill color
+ */
+ public short getFillBackgroundColor()
+ {
+ return patternBackgroundColorIndex.getShortValue(field_16_pattern_color_indexes);
+ }
+
+ /**
+ * set the foreground fill color
+ * @param bg color
+ */
+ public void setFillForegroundColor(short fg)
+ {
+ field_16_pattern_color_indexes = patternColorIndex.setShortValue(field_16_pattern_color_indexes,fg);
+ }
+
+ /**
+ * get the foreground fill color
+ * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
+ * @return fill color
+ */
+ public short getFillForegroundColor()
+ {
+ return patternColorIndex.getShortValue(field_16_pattern_color_indexes);
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(" [Pattern Formatting]\n");
+ buffer.append(" .fillpattern= ").append(Integer.toHexString(getFillPattern())).append("\n");
+ buffer.append(" .fgcoloridx= ").append(Integer.toHexString(getFillForegroundColor())).append("\n");
+ buffer.append(" .bgcoloridx= ").append(Integer.toHexString(getFillBackgroundColor())).append("\n");
+ buffer.append(" [/Pattern Formatting]\n");
+ return buffer.toString();
+ }
+
+ public Object clone()
+ {
+ PatternFormatting rec = new PatternFormatting();
+ rec.field_15_pattern_style = field_15_pattern_style;
+ rec.field_16_pattern_color_indexes = field_16_pattern_color_indexes;
+ return rec;
+ }
+
+ public int serialize(int offset, byte [] data)
+ {
+ LittleEndian.putShort(data, offset, field_15_pattern_style);
+ offset += 2;
+ LittleEndian.putShort(data, offset, field_16_pattern_color_indexes);
+ offset += 2;
+ return 4;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
new file mode 100644
index 0000000000..622f3a6742
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
@@ -0,0 +1,128 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.record.cf.BorderFormatting;
+
+/**
+ * High level representation for Border Formatting component
+ * of Conditional Formatting settings
+ *
+ * @author Dmitriy Kumshayev
+ *
+ */
+public class HSSFBorderFormatting
+{
+ /**
+ * No border
+ */
+
+ public final static short BORDER_NONE = BorderFormatting.BORDER_NONE;
+
+ /**
+ * Thin border
+ */
+
+ public final static short BORDER_THIN = BorderFormatting.BORDER_THIN;
+
+ /**
+ * Medium border
+ */
+
+ public final static short BORDER_MEDIUM = BorderFormatting.BORDER_MEDIUM;
+
+ /**
+ * dash border
+ */
+
+ public final static short BORDER_DASHED = BorderFormatting.BORDER_DASHED;
+
+ /**
+ * dot border
+ */
+
+ public final static short BORDER_HAIR = BorderFormatting.BORDER_HAIR;
+
+ /**
+ * Thick border
+ */
+
+ public final static short BORDER_THICK = BorderFormatting.BORDER_THICK;
+
+ /**
+ * double-line border
+ */
+
+ public final static short BORDER_DOUBLE = BorderFormatting.BORDER_DOUBLE;
+
+ /**
+ * hair-line border
+ */
+
+ public final static short BORDER_DOTTED = BorderFormatting.BORDER_DOTTED;
+
+ /**
+ * Medium dashed border
+ */
+
+ public final static short BORDER_MEDIUM_DASHED = BorderFormatting.BORDER_MEDIUM_DASHED;
+
+ /**
+ * dash-dot border
+ */
+
+ public final static short BORDER_DASH_DOT = BorderFormatting.BORDER_DASH_DOT;
+
+ /**
+ * medium dash-dot border
+ */
+
+ public final static short BORDER_MEDIUM_DASH_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT;
+
+ /**
+ * dash-dot-dot border
+ */
+
+ public final static short BORDER_DASH_DOT_DOT = BorderFormatting.BORDER_DASH_DOT_DOT;
+
+ /**
+ * medium dash-dot-dot border
+ */
+
+ public final static short BORDER_MEDIUM_DASH_DOT_DOT = BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT;
+
+ /**
+ * slanted dash-dot border
+ */
+
+ public final static short BORDER_SLANTED_DASH_DOT = BorderFormatting.BORDER_SLANTED_DASH_DOT;
+
+
+ private BorderFormatting borderFormatting;
+
+ public HSSFBorderFormatting()
+ {
+ borderFormatting = new BorderFormatting();
+ }
+
+ protected BorderFormatting getBorderFormattingBlock()
+ {
+ return borderFormatting;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
new file mode 100644
index 0000000000..e5fbb1d300
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
@@ -0,0 +1,201 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.hssf.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.record.CFHeaderRecord;
+import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
+import org.apache.poi.hssf.record.cf.CellRange;
+import org.apache.poi.hssf.util.Region;
+
+public class HSSFConditionalFormatting
+{
+ HSSFSheet sheet;
+ CFRecordsAggregate cfAggregate;
+
+ protected HSSFConditionalFormatting(HSSFSheet sheet)
+ {
+ this.sheet = sheet;
+ this.cfAggregate = new CFRecordsAggregate();
+ }
+
+ protected HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate)
+ {
+ this.sheet = sheet;
+ this.cfAggregate = cfAggregate;
+ }
+
+
+ public void setFormattingRegions(Region[] regions)
+ {
+ if( regions != null)
+ {
+ CFHeaderRecord header = cfAggregate.getHeader();
+ header.setCellRanges(mergeCellRanges(toCellRangeList(regions)));
+ }
+ }
+
+ public Region[] getFormattingRegions()
+ {
+ CFHeaderRecord cfh = cfAggregate.getHeader();
+
+ List cellRanges = cfh.getCellRanges();
+
+ if (cellRanges != null)
+ {
+ return toRegionArray(cellRanges);
+ }
+ return null;
+ }
+
+ public void setConditionalFormat(int idx, HSSFConditionalFormattingRule cfRule)
+ {
+ cfAggregate.getRules().set(idx, cfRule);
+ }
+
+ public void addConditionalFormat(HSSFConditionalFormattingRule cfRule)
+ {
+ cfAggregate.getRules().add(cfRule);
+ }
+
+ public HSSFConditionalFormattingRule getConditionalFormat(int idx)
+ {
+ CFRuleRecord ruleRecord = (CFRuleRecord)cfAggregate.getRules().get(idx);
+ return new HSSFConditionalFormattingRule(sheet.workbook, ruleRecord);
+ }
+
+ /**
+ * Do all possible cell merges between cells of the list so that:
+ *
+ *
This method could be used to copy HSSFConditionalFormatting object + * from one sheet to another. For example: + *
+ * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index); + * newSheet.addConditionalFormatting(cf); + *+ * + * @param cf HSSFConditionalFormatting object + * @return index of the new Conditional Formatting object + */ + public int addConditionalFormatting( HSSFConditionalFormatting cf ) + { + HSSFConditionalFormatting cfClone = new HSSFConditionalFormatting(this,cf.cfAggregate.cloneCFAggregate()); + cfClone.sheet=this; + return sheet.addConditionalFormatting(cfClone.cfAggregate); + } + + /** + * Allows to add a new Conditional Formatting set to the sheet. + * + * @param regions - list of rectangular regions to apply conditional formatting rules + * @param cfRules - set of up to three conditional formatting rules + * + * @return index of the newly created Conditional Formatting object + */ + + public int addConditionalFormatting( Region [] regions, HSSFConditionalFormattingRule [] cfRules ) + { + HSSFConditionalFormatting cf = new HSSFConditionalFormatting(this); + cf.setFormattingRegions(regions); + if( cfRules != null ) + { + for( int i=0; i!= cfRules.length; i++ ) + { + cf.addConditionalFormat(cfRules[i]); + } + } + return sheet.addConditionalFormatting(cf.cfAggregate); + } + + /** + * gets Conditional Formatting object at a particular index + * @param index of the Conditional Formatting object to fetch + * @return Conditional Formatting object + */ + + public HSSFConditionalFormatting getConditionalFormattingAt(int index) + { + CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index); + if( cf != null ) + { + return new HSSFConditionalFormatting(this,cf); + } + return null; + } + + /** + * @return number of Conditional Formatting objects of the sheet + */ + public int getNumConditionalFormattings() + { + return sheet.getNumConditionalFormattings(); + } + + /** + * removes a Conditional Formatting object by index + * @param index of a Conditional Formatting object to remove + */ + public void removeConditionalFormatting(int index) + { + sheet.removeConditionalFormatting(index); + } + } diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java new file mode 100644 index 0000000000..c3e5684798 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java @@ -0,0 +1,145 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.cf.CellRange; + +/** + * Tests the serialization and deserialization of the TestCFHeaderRecord + * class works correctly. + * + * @author Dmitriy Kumshayev + */ +public class TestCFHeaderRecord + extends TestCase +{ + + public TestCFHeaderRecord(String name) + { + super(name); + } + + public void testCreateCFHeaderRecord () + { + CFHeaderRecord record = new CFHeaderRecord(); + List ranges = new ArrayList(); + ranges.add(new CellRange(0,-1,(short)5,(short)5)); + ranges.add(new CellRange(0,-1,(short)6,(short)6)); + ranges.add(new CellRange(0,1,(short)0,(short)1)); + ranges.add(new CellRange(0,1,(short)2,(short)3)); + ranges.add(new CellRange(2,3,(short)0,(short)1)); + ranges.add(new CellRange(2,3,(short)2,(short)3)); + record.setCellRanges(ranges); + ranges = record.getCellRanges(); + assertEquals(6,ranges.size()); + CellRange enclosingCellRange = record.getEnclosingCellRange(); + assertEquals(0, enclosingCellRange.getFirstRow()); + assertEquals(-1, enclosingCellRange.getLastRow()); + assertEquals(0, enclosingCellRange.getFirstColumn()); + assertEquals(6, enclosingCellRange.getLastColumn()); + record.setNeedRecalculation(true); + assertTrue(record.getNeedRecalculation()); + record.setNeedRecalculation(false); + assertFalse(record.getNeedRecalculation()); + } + + public void testSerialization() { + byte[] recordData = new byte[] + { + (byte)0x03, (byte)0x00, + (byte)0x01, (byte)0x00, + + (byte)0x00, (byte)0x00, + (byte)0x03, (byte)0x00, + (byte)0x00, (byte)0x00, + (byte)0x03, (byte)0x00, + + (byte)0x04, (byte)0x00, + + (byte)0x00, (byte)0x00, + (byte)0x01, (byte)0x00, + (byte)0x00, (byte)0x00, + (byte)0x01, (byte)0x00, + + (byte)0x00, (byte)0x00, + (byte)0x01, (byte)0x00, + (byte)0x02, (byte)0x00, + (byte)0x03, (byte)0x00, + + (byte)0x02, (byte)0x00, + (byte)0x03, (byte)0x00, + (byte)0x00, (byte)0x00, + (byte)0x01, (byte)0x00, + + (byte)0x02, (byte)0x00, + (byte)0x03, (byte)0x00, + (byte)0x02, (byte)0x00, + (byte)0x03, (byte)0x00, + }; + + CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData)); + + assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats()); + assertTrue(record.getNeedRecalculation()); + CellRange enclosingCellRange = record.getEnclosingCellRange(); + assertEquals(0, enclosingCellRange.getFirstRow()); + assertEquals(3, enclosingCellRange.getLastRow()); + assertEquals(0, enclosingCellRange.getFirstColumn()); + assertEquals(3, enclosingCellRange.getLastColumn()); + List ranges = record.getCellRanges(); + assertEquals(0, ((CellRange)ranges.get(0)).getFirstRow()); + assertEquals(1, ((CellRange)ranges.get(0)).getLastRow()); + assertEquals(0, ((CellRange)ranges.get(0)).getFirstColumn()); + assertEquals(1, ((CellRange)ranges.get(0)).getLastColumn()); + assertEquals(0, ((CellRange)ranges.get(1)).getFirstRow()); + assertEquals(1, ((CellRange)ranges.get(1)).getLastRow()); + assertEquals(2, ((CellRange)ranges.get(1)).getFirstColumn()); + assertEquals(3, ((CellRange)ranges.get(1)).getLastColumn()); + assertEquals(2, ((CellRange)ranges.get(2)).getFirstRow()); + assertEquals(3, ((CellRange)ranges.get(2)).getLastRow()); + assertEquals(0, ((CellRange)ranges.get(2)).getFirstColumn()); + assertEquals(1, ((CellRange)ranges.get(2)).getLastColumn()); + assertEquals(2, ((CellRange)ranges.get(3)).getFirstRow()); + assertEquals(3, ((CellRange)ranges.get(3)).getLastRow()); + assertEquals(2, ((CellRange)ranges.get(3)).getFirstColumn()); + assertEquals(3, ((CellRange)ranges.get(3)).getLastColumn()); + assertEquals(recordData.length+4, record.getRecordSize()); + + byte[] output = record.serialize(); + + assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength + + for (int i = 0; i < recordData.length;i++) + { + assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]); + } + } + + + public static void main(String[] ignored_args) + { + System.out.println("Testing org.apache.poi.hssf.record.CFHeaderRecord"); + junit.textui.TestRunner.run(TestCFHeaderRecord.class); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java new file mode 100644 index 0000000000..77731d7812 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java @@ -0,0 +1,296 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.cf.BorderFormatting; +import org.apache.poi.hssf.record.cf.FontFormatting; +import org.apache.poi.hssf.record.cf.PatternFormatting; +import org.apache.poi.hssf.util.HSSFColor; + +/** + * Tests the serialization and deserialization of the TestCFRuleRecord + * class works correctly. + * + * @author Dmitriy Kumshayev + */ +public class TestCFRuleRecord + extends TestCase +{ + + public TestCFRuleRecord(String name) + { + super(name); + } + + public void testCreateCFRuleRecord () + { + CFRuleRecord record = new CFRuleRecord(); + testCFRuleRecord(record); + + // Serialize + byte [] serializedRecord = record.serialize(); + + // Strip header + byte [] recordData = new byte[serializedRecord.length-4]; + System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length); + + // Deserialize + record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData)); + + // Serialize again + byte[] output = record.serialize(); + + // Compare + assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength + + for (int i = 0; i < recordData.length;i++) + { + assertEquals("CFRuleRecord doesn't match", recordData[i], output[i+4]); + } + } + + private void testCFRuleRecord(CFRuleRecord record) + { + FontFormatting fontFormatting = new FontFormatting(); + testFontFormattingAccessors(fontFormatting); + assertFalse(record.containsFontFormattingBlock()); + record.setFontFormatting(fontFormatting); + assertTrue(record.containsFontFormattingBlock()); + + BorderFormatting borderFormatting = new BorderFormatting(); + testBorderFormattingAccessors(borderFormatting); + assertFalse(record.containsBorderFormattingBlock()); + record.setBorderFormatting(borderFormatting); + assertTrue(record.containsBorderFormattingBlock()); + + assertFalse(record.isLeftBorderModified()); + record.setLeftBorderModified(true); + assertTrue(record.isLeftBorderModified()); + + assertFalse(record.isRightBorderModified()); + record.setRightBorderModified(true); + assertTrue(record.isRightBorderModified()); + + assertFalse(record.isTopBorderModified()); + record.setTopBorderModified(true); + assertTrue(record.isTopBorderModified()); + + assertFalse(record.isBottomBorderModified()); + record.setBottomBorderModified(true); + assertTrue(record.isBottomBorderModified()); + + assertFalse(record.isTopLeftBottomRightBorderModified()); + record.setTopLeftBottomRightBorderModified(true); + assertTrue(record.isTopLeftBottomRightBorderModified()); + + assertFalse(record.isBottomLeftTopRightBorderModified()); + record.setBottomLeftTopRightBorderModified(true); + assertTrue(record.isBottomLeftTopRightBorderModified()); + + + PatternFormatting patternFormatting = new PatternFormatting(); + testPatternFormattingAccessors(patternFormatting); + assertFalse(record.containsPatternFormattingBlock()); + record.setPatternFormatting(patternFormatting); + assertTrue(record.containsPatternFormattingBlock()); + + assertFalse(record.isPatternBackgroundColorModified()); + record.setPatternBackgroundColorModified(true); + assertTrue(record.isPatternBackgroundColorModified()); + + assertFalse(record.isPatternColorModified()); + record.setPatternColorModified(true); + assertTrue(record.isPatternColorModified()); + + assertFalse(record.isPatternStyleModified()); + record.setPatternStyleModified(true); + assertTrue(record.isPatternStyleModified()); + } + + private void testPatternFormattingAccessors(PatternFormatting patternFormatting) + { + patternFormatting.setFillBackgroundColor(HSSFColor.GREEN.index); + assertEquals(HSSFColor.GREEN.index,patternFormatting.getFillBackgroundColor()); + + patternFormatting.setFillForegroundColor(HSSFColor.INDIGO.index); + assertEquals(HSSFColor.INDIGO.index,patternFormatting.getFillForegroundColor()); + + patternFormatting.setFillPattern(PatternFormatting.DIAMONDS); + assertEquals(PatternFormatting.DIAMONDS,patternFormatting.getFillPattern()); + + } + + private void testBorderFormattingAccessors(BorderFormatting borderFormatting) + { + borderFormatting.setBackwardDiagonalOn(false); + assertFalse(borderFormatting.isBackwardDiagonalOn()); + borderFormatting.setBackwardDiagonalOn(true); + assertTrue(borderFormatting.isBackwardDiagonalOn()); + + borderFormatting.setBorderBottom(BorderFormatting.BORDER_DOTTED); + assertEquals(BorderFormatting.BORDER_DOTTED, borderFormatting.getBorderBottom()); + + borderFormatting.setBorderDiagonal(BorderFormatting.BORDER_MEDIUM); + assertEquals(BorderFormatting.BORDER_MEDIUM, borderFormatting.getBorderDiagonal()); + + borderFormatting.setBorderLeft(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT); + assertEquals(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT, borderFormatting.getBorderLeft()); + + borderFormatting.setBorderRight(BorderFormatting.BORDER_MEDIUM_DASHED); + assertEquals(BorderFormatting.BORDER_MEDIUM_DASHED, borderFormatting.getBorderRight()); + + borderFormatting.setBorderTop(BorderFormatting.BORDER_HAIR); + assertEquals(BorderFormatting.BORDER_HAIR, borderFormatting.getBorderTop()); + + borderFormatting.setBottomBorderColor(HSSFColor.AQUA.index); + assertEquals(HSSFColor.AQUA.index, borderFormatting.getBottomBorderColor()); + + borderFormatting.setDiagonalBorderColor(HSSFColor.RED.index); + assertEquals(HSSFColor.RED.index, borderFormatting.getDiagonalBorderColor()); + + assertFalse(borderFormatting.isForwardDiagonalOn()); + borderFormatting.setForwardDiagonalOn(true); + assertTrue(borderFormatting.isForwardDiagonalOn()); + + borderFormatting.setLeftBorderColor(HSSFColor.BLACK.index); + assertEquals(HSSFColor.BLACK.index, borderFormatting.getLeftBorderColor()); + + borderFormatting.setRightBorderColor(HSSFColor.BLUE.index); + assertEquals(HSSFColor.BLUE.index, borderFormatting.getRightBorderColor()); + + borderFormatting.setTopBorderColor(HSSFColor.GOLD.index); + assertEquals(HSSFColor.GOLD.index, borderFormatting.getTopBorderColor()); + } + + + private void testFontFormattingAccessors(FontFormatting fontFormatting) + { + // Check for defaults + assertFalse(fontFormatting.isEscapementTypeModified()); + assertFalse(fontFormatting.isFontCancellationModified()); + assertFalse(fontFormatting.isFontCondenseModified()); + assertFalse(fontFormatting.isFontOutlineModified()); + assertFalse(fontFormatting.isFontShadowModified()); + assertFalse(fontFormatting.isFontStyleModified()); + assertFalse(fontFormatting.isUnderlineTypeModified()); + + assertFalse(fontFormatting.isBold()); + assertFalse(fontFormatting.isCondenseOn()); + assertFalse(fontFormatting.isItalic()); + assertFalse(fontFormatting.isOutlineOn()); + assertFalse(fontFormatting.isShadowOn()); + assertFalse(fontFormatting.isStruckout()); + + assertEquals(0, fontFormatting.getEscapementType()); + assertEquals(-1, fontFormatting.getFontColorIndex()); + assertEquals(-1, fontFormatting.getFontHeight()); + assertEquals(400, fontFormatting.getFontWeight()); + assertEquals(0, fontFormatting.getUnderlineType()); + + fontFormatting.setBold(true); + assertTrue(fontFormatting.isBold()); + fontFormatting.setBold(false); + assertFalse(fontFormatting.isBold()); + + fontFormatting.setCondense(true); + assertTrue(fontFormatting.isCondenseOn()); + fontFormatting.setCondense(false); + assertFalse(fontFormatting.isCondenseOn()); + + fontFormatting.setEscapementType(FontFormatting.SS_SUB); + assertEquals(FontFormatting.SS_SUB, fontFormatting.getEscapementType()); + fontFormatting.setEscapementType(FontFormatting.SS_SUPER); + assertEquals(FontFormatting.SS_SUPER, fontFormatting.getEscapementType()); + fontFormatting.setEscapementType(FontFormatting.SS_NONE); + assertEquals(FontFormatting.SS_NONE, fontFormatting.getEscapementType()); + + fontFormatting.setEscapementTypeModified(false); + assertFalse(fontFormatting.isEscapementTypeModified()); + fontFormatting.setEscapementTypeModified(true); + assertTrue(fontFormatting.isEscapementTypeModified()); + + fontFormatting.setFontCancellationModified(false); + assertFalse(fontFormatting.isFontCancellationModified()); + fontFormatting.setFontCancellationModified(true); + assertTrue(fontFormatting.isFontCancellationModified()); + + fontFormatting.setFontColorIndex((short)10); + assertEquals(10,fontFormatting.getFontColorIndex()); + + fontFormatting.setFontCondenseModified(false); + assertFalse(fontFormatting.isFontCondenseModified()); + fontFormatting.setFontCondenseModified(true); + assertTrue(fontFormatting.isFontCondenseModified()); + + fontFormatting.setFontHeight((short)100); + assertEquals(100,fontFormatting.getFontHeight()); + + fontFormatting.setFontOutlineModified(false); + assertFalse(fontFormatting.isFontOutlineModified()); + fontFormatting.setFontOutlineModified(true); + assertTrue(fontFormatting.isFontOutlineModified()); + + fontFormatting.setFontShadowModified(false); + assertFalse(fontFormatting.isFontShadowModified()); + fontFormatting.setFontShadowModified(true); + assertTrue(fontFormatting.isFontShadowModified()); + + fontFormatting.setFontStyleModified(false); + assertFalse(fontFormatting.isFontStyleModified()); + fontFormatting.setFontStyleModified(true); + assertTrue(fontFormatting.isFontStyleModified()); + + fontFormatting.setItalic(false); + assertFalse(fontFormatting.isItalic()); + fontFormatting.setItalic(true); + assertTrue(fontFormatting.isItalic()); + + fontFormatting.setOutline(false); + assertFalse(fontFormatting.isOutlineOn()); + fontFormatting.setOutline(true); + assertTrue(fontFormatting.isOutlineOn()); + + fontFormatting.setShadow(false); + assertFalse(fontFormatting.isShadowOn()); + fontFormatting.setShadow(true); + assertTrue(fontFormatting.isShadowOn()); + + fontFormatting.setStrikeout(false); + assertFalse(fontFormatting.isStruckout()); + fontFormatting.setStrikeout(true); + assertTrue(fontFormatting.isStruckout()); + + fontFormatting.setUnderlineType(FontFormatting.U_DOUBLE_ACCOUNTING); + assertEquals(FontFormatting.U_DOUBLE_ACCOUNTING, fontFormatting.getUnderlineType()); + + fontFormatting.setUnderlineTypeModified(false); + assertFalse(fontFormatting.isUnderlineTypeModified()); + fontFormatting.setUnderlineTypeModified(true); + assertTrue(fontFormatting.isUnderlineTypeModified()); + } + + + public static void main(String[] ignored_args) + { + System.out.println("Testing org.apache.poi.hssf.record.CFRuleRecord"); + junit.textui.TestRunner.run(TestCFRuleRecord.class); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java new file mode 100644 index 0000000000..332c99209f --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java @@ -0,0 +1,111 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.aggregates; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.CFHeaderRecord; +import org.apache.poi.hssf.record.CFRuleRecord; +import org.apache.poi.hssf.record.RecordFactory; +import org.apache.poi.hssf.record.cf.CellRange; + +/** + * Tests the serialization and deserialization of the CFRecordsAggregate + * class works correctly. + * + * @author Dmitriy Kumshayev + */ +public class TestCFRecordsAggregate + extends TestCase +{ + + public TestCFRecordsAggregate(String name) + { + super(name); + } + + public void testCFRecordsAggregate() + { + CFRecordsAggregate record = new CFRecordsAggregate(); + List recs = new ArrayList(); + CFHeaderRecord header = new CFHeaderRecord(); + CFRuleRecord rule1 = new CFRuleRecord(); + CFRuleRecord rule2 = new CFRuleRecord(); + CFRuleRecord rule3 = new CFRuleRecord(); + header.setNumberOfConditionalFormats(3); + CellRange range1 = new CellRange(0,1,(short)0,(short)0); + CellRange range2 = new CellRange(0,1,(short)2,(short)2); + List cellRanges = new ArrayList(); + cellRanges.add(range1); + cellRanges.add(range2); + header.setCellRanges(cellRanges); + recs.add(header); + recs.add(rule1); + recs.add(rule2); + recs.add(rule3); + record = CFRecordsAggregate.createCFAggregate(recs, 0); + + // Serialize + byte [] serializedRecord = record.serialize(); + InputStream in = new ByteArrayInputStream(serializedRecord); + + //Parse + recs = RecordFactory.createRecords(in); + + // Verify + assertNotNull(recs); + assertEquals(4, recs.size()); + + header = (CFHeaderRecord)recs.get(0); + rule1 = (CFRuleRecord)recs.get(1); + rule2 = (CFRuleRecord)recs.get(2); + rule3 = (CFRuleRecord)recs.get(3); + cellRanges = header.getCellRanges(); + + assertEquals(2, cellRanges.size()); + assertEquals(3, header.getNumberOfConditionalFormats()); + + record = CFRecordsAggregate.createCFAggregate(recs, 0); + + record = record.cloneCFAggregate(); + + assertNotNull(record.getHeader()); + assertEquals(3,record.getRules().size()); + + header = record.getHeader(); + rule1 = (CFRuleRecord)record.getRules().get(0); + rule2 = (CFRuleRecord)record.getRules().get(1); + rule3 = (CFRuleRecord)record.getRules().get(2); + cellRanges = header.getCellRanges(); + + assertEquals(2, cellRanges.size()); + assertEquals(3, header.getNumberOfConditionalFormats()); + } + + public static void main(String[] ignored_args) + { + System.out.println("Testing org.apache.poi.hssf.record.aggregates.CFRecordsAggregate"); + junit.textui.TestRunner.run(TestCFRecordsAggregate.class); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java b/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java new file mode 100644 index 0000000000..f9857fb248 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java @@ -0,0 +1,139 @@ +/* ==================================================================== +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.cf; + +import junit.framework.TestCase; + +/** + * Tests CellRange operations. + */ +public class TestCellRange extends TestCase +{ + private static final CellRange biggest = new CellRange(0, -1,(short) 0,(short)-1); + private static final CellRange tenthColumn = new CellRange(0, -1,(short)10,(short)10); + private static final CellRange tenthRow = new CellRange(10,10,(short) 0,(short)-1); + private static final CellRange box10x10 = new CellRange(0, 10,(short) 0,(short)10); + private static final CellRange box9x9 = new CellRange(0, 9,(short) 0,(short) 9); + private static final CellRange box10to20c = new CellRange(0, 10,(short)10,(short)20); + private static final CellRange oneCell = new CellRange(10,10,(short)10,(short)10); + + boolean [][] contanis = new boolean[][] + { + // biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell + /*biggest */ new boolean[]{true, true , true , true , true , true , true}, + /*tenthColumn*/ new boolean[]{false, true , false, false, false, false, true}, + /*tenthRow */ new boolean[]{false, false, true , false, false, false, true}, + /*box10x10 */ new boolean[]{false, false, false, true , true , false, true}, + /*box9x9 */ new boolean[]{false, false, false, false, true , false, false}, + /*box10to20c */ new boolean[]{false, false, false, false, false, true , true}, + /*oneCell */ new boolean[]{false, false, false, false, false, false, true}, + } ; + + + public void testContainsMethod() + { + CellRange [] ranges = new CellRange[]{biggest,tenthColumn,tenthRow,box10x10,box9x9,box10to20c,oneCell}; + testContainsMethod(contanis,ranges); + } + + private void testContainsMethod(boolean[][]contains,CellRange[] ranges) + { + for(int i=0; i!=ranges.length;i++) + { + for(int j=0; j!=ranges.length;j++) + { + assertEquals("("+i+","+j+"): ",contains[i][j],ranges[i].contains(ranges[j])); + } + } + } + + private static final CellRange col1 = new CellRange(0, -1,(short) 1,(short)1); + private static final CellRange col2 = new CellRange(0, -1,(short) 2,(short)2); + private static final CellRange row1 = new CellRange(1, 1,(short) 0,(short)-1); + private static final CellRange row2 = new CellRange(2, 2,(short) 0,(short)-1); + + private static final CellRange box0 = new CellRange( 0, 2,(short) 0,(short)2); + private static final CellRange box1 = new CellRange( 0, 1,(short) 0,(short)1); + private static final CellRange box2 = new CellRange( 0, 1,(short) 2,(short)3); + private static final CellRange box3 = new CellRange( 2, 3,(short) 0,(short)1); + private static final CellRange box4 = new CellRange( 2, 3,(short) 2,(short)3); + private static final CellRange box5 = new CellRange( 1, 3,(short) 1,(short)3); + + public void testHasSharedBorderMethod() + { + assertFalse(col1.hasSharedBorder(col1)); + assertFalse(col2.hasSharedBorder(col2)); + assertTrue(col1.hasSharedBorder(col2)); + assertTrue(col2.hasSharedBorder(col1)); + + assertFalse(row1.hasSharedBorder(row1)); + assertFalse(row2.hasSharedBorder(row2)); + assertTrue(row1.hasSharedBorder(row2)); + assertTrue(row2.hasSharedBorder(row1)); + + assertFalse(row1.hasSharedBorder(col1)); + assertFalse(row1.hasSharedBorder(col2)); + assertFalse(col1.hasSharedBorder(row1)); + assertFalse(col2.hasSharedBorder(row1)); + assertFalse(row2.hasSharedBorder(col1)); + assertFalse(row2.hasSharedBorder(col2)); + assertFalse(col1.hasSharedBorder(row2)); + assertFalse(col2.hasSharedBorder(row2)); + assertTrue(col2.hasSharedBorder(col1)); + + assertFalse(box1.hasSharedBorder(box1)); + assertTrue(box1.hasSharedBorder(box2)); + assertTrue(box1.hasSharedBorder(box3)); + assertFalse(box1.hasSharedBorder(box4)); + + assertTrue(box2.hasSharedBorder(box1)); + assertFalse(box2.hasSharedBorder(box2)); + assertFalse(box2.hasSharedBorder(box3)); + assertTrue(box2.hasSharedBorder(box4)); + + assertTrue(box3.hasSharedBorder(box1)); + assertFalse(box3.hasSharedBorder(box2)); + assertFalse(box3.hasSharedBorder(box3)); + assertTrue(box3.hasSharedBorder(box4)); + + assertFalse(box4.hasSharedBorder(box1)); + assertTrue(box4.hasSharedBorder(box2)); + assertTrue(box4.hasSharedBorder(box3)); + assertFalse(box4.hasSharedBorder(box4)); + } + + public void testIntersectMethod() + { + assertEquals( CellRange.OVERLAP,box0.intersect(box5)); + assertEquals( CellRange.OVERLAP,box5.intersect(box0)); + assertEquals(CellRange.NO_INTERSECTION,box1.intersect(box4)); + assertEquals(CellRange.NO_INTERSECTION,box4.intersect(box1)); + assertEquals(CellRange.NO_INTERSECTION,box2.intersect(box3)); + assertEquals(CellRange.NO_INTERSECTION,box3.intersect(box2)); + assertEquals(CellRange.INSIDE,box0.intersect(box1)); + assertEquals(CellRange.INSIDE,box0.intersect(box0)); + assertEquals(CellRange.ENCLOSES,box1.intersect(box0)); + assertEquals(CellRange.INSIDE,tenthColumn.intersect(oneCell)); + assertEquals(CellRange.ENCLOSES,oneCell.intersect(tenthColumn)); + assertEquals(CellRange.OVERLAP,tenthColumn.intersect(tenthRow)); + assertEquals(CellRange.OVERLAP,tenthRow.intersect(tenthColumn)); + assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn)); + assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow)); + } + +}