package org.apache.poi.hssf.record;
import org.apache.poi.hssf.model.HSSFFormulaParser;
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.usermodel.HSSFSheet;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
public abstract class CFRuleBase extends StandardRecord implements Cloneable {
public static final class ComparisonOperator {
public static final byte NO_COMPARISON = 0;
public static final byte BETWEEN = 1;
public static final byte NOT_BETWEEN = 2;
public static final byte EQUAL = 3;
public static final byte NOT_EQUAL = 4;
public static final byte GT = 5;
public static final byte LT = 6;
public static final byte GE = 7;
public static final byte LE = 8;
private static final byte max_operator = 8;
}
protected static final POILogger logger = POILogFactory.getLogger(CFRuleBase.class);
private byte condition_type;
public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;
public static final byte CONDITION_TYPE_FORMULA = 2;
public static final byte CONDITION_TYPE_COLOR_SCALE = 3;
public static final byte CONDITION_TYPE_DATA_BAR = 4;
public static final byte CONDITION_TYPE_FILTER = 5;
public static final byte CONDITION_TYPE_ICON_SET = 6;
private byte comparison_operator;
public static final int TEMPLATE_CELL_VALUE = 0x0000;
public static final int TEMPLATE_FORMULA = 0x0001;
public static final int TEMPLATE_COLOR_SCALE_FORMATTING = 0x0002;
public static final int TEMPLATE_DATA_BAR_FORMATTING = 0x0003;
public static final int TEMPLATE_ICON_SET_FORMATTING = 0x0004;
public static final int TEMPLATE_FILTER = 0x0005;
public static final int TEMPLATE_UNIQUE_VALUES = 0x0007;
public static final int TEMPLATE_CONTAINS_TEXT = 0x0008;
public static final int TEMPLATE_CONTAINS_BLANKS = 0x0009;
public static final int TEMPLATE_CONTAINS_NO_BLANKS = 0x000A;
public static final int TEMPLATE_CONTAINS_ERRORS = 0x000B;
public static final int TEMPLATE_CONTAINS_NO_ERRORS = 0x000C;
public static final int TEMPLATE_TODAY = 0x000F;
public static final int TEMPLATE_TOMORROW = 0x0010;
public static final int TEMPLATE_YESTERDAY = 0x0011;
public static final int TEMPLATE_LAST_7_DAYS = 0x0012;
public static final int TEMPLATE_LAST_MONTH = 0x0013;
public static final int TEMPLATE_NEXT_MONTH = 0x0014;
public static final int TEMPLATE_THIS_WEEK = 0x0015;
public static final int TEMPLATE_NEXT_WEEK = 0x0016;
public static final int TEMPLATE_LAST_WEEK = 0x0017;
public static final int TEMPLATE_THIS_MONTH = 0x0018;
public static final int TEMPLATE_ABOVE_AVERAGE = 0x0019;
public static final int TEMPLATE_BELOW_AVERAGE = 0x001A;
public static final int TEMPLATE_DUPLICATE_VALUES = 0x001B;
public static final int TEMPLATE_ABOVE_OR_EQUAL_TO_AVERAGE = 0x001D;
public static final int TEMPLATE_BELOW_OR_EQUAL_TO_AVERAGE = 0x001E;
static final BitField modificationBits = bf(0x003FFFFF);
static final BitField alignHor = bf(0x00000001);
static final BitField alignVer = bf(0x00000002);
static final BitField alignWrap = bf(0x00000004);
static final BitField alignRot = bf(0x00000008);
static final BitField alignJustLast = bf(0x00000010);
static final BitField alignIndent = bf(0x00000020);
static final BitField alignShrin = bf(0x00000040);
static final BitField mergeCell = bf(0x00000080);
static final BitField protLocked = bf(0x00000100);
static final BitField protHidden = bf(0x00000200);
static final BitField bordLeft = bf(0x00000400);
static final BitField bordRight = bf(0x00000800);
static final BitField bordTop = bf(0x00001000);
static final BitField bordBot = bf(0x00002000);
static final BitField bordTlBr = bf(0x00004000);
static final BitField bordBlTr = bf(0x00008000);
static final BitField pattStyle = bf(0x00010000);
static final BitField pattCol = bf(0x00020000);
static final BitField pattBgCol = bf(0x00040000);
static final BitField notUsed2 = bf(0x00380000);
static final BitField undocumented = bf(0x03C00000);
static final BitField fmtBlockBits = bf(0x7C000000);
static final BitField font = bf(0x04000000);
static final BitField align = bf(0x08000000);
static final BitField bord = bf(0x10000000);
static final BitField patt = bf(0x20000000);
static final BitField prot = bf(0x40000000);
static final BitField alignTextDir = bf(0x80000000);
private static BitField bf(int i) {
return BitFieldFactory.getInstance(i);
}
protected int formatting_options;
protected short formatting_not_used;
protected FontFormatting _fontFormatting;
protected BorderFormatting _borderFormatting;
protected PatternFormatting _patternFormatting;
private Formula formula1;
private Formula formula2;
protected CFRuleBase(byte conditionType, byte comparisonOperation) {
setConditionType(conditionType);
setComparisonOperation(comparisonOperation);
formula1 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
formula2 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
}
protected CFRuleBase(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) {
this(conditionType, comparisonOperation);
this.formula1 = Formula.create(formula1);
this.formula2 = Formula.create(formula2);
}
protected CFRuleBase() {}
protected int readFormatOptions(RecordInputStream in) {
formatting_options = in.readInt();
formatting_not_used = in.readShort();
int len = 6;
if (containsFontFormattingBlock()) {
_fontFormatting = new FontFormatting(in);
len += _fontFormatting.getDataLength();
}
if (containsBorderFormattingBlock()) {
_borderFormatting = new BorderFormatting(in);
len += _borderFormatting.getDataLength();
}
if (containsPatternFormattingBlock()) {
_patternFormatting = new PatternFormatting(in);
len += _patternFormatting.getDataLength();
}
return len;
}
public byte getConditionType() {
return condition_type;
}
protected void setConditionType(byte condition_type) {
if ((this instanceof CFRuleRecord)) {
if (condition_type == CONDITION_TYPE_CELL_VALUE_IS ||
condition_type == CONDITION_TYPE_FORMULA) {
} else {
throw new IllegalArgumentException("CFRuleRecord only accepts Value-Is and Formula types");
}
}
this.condition_type = condition_type;
}
public void setComparisonOperation(byte operation) {
if (operation < 0 || operation > ComparisonOperator.max_operator)
throw new IllegalArgumentException(
"Valid operators are only in the range 0 to " +ComparisonOperator.max_operator);
this.comparison_operator = operation;
}
public byte getComparisonOperation() {
return comparison_operator;
}
public boolean containsFontFormattingBlock() {
return getOptionFlag(font);
}
public void setFontFormatting(FontFormatting fontFormatting) {
_fontFormatting = fontFormatting;
setOptionFlag(fontFormatting != null, font);
}
public FontFormatting getFontFormatting() {
if( containsFontFormattingBlock()) {
return _fontFormatting;
}
return null;
}
public boolean containsAlignFormattingBlock() {
return getOptionFlag(align);
}
public void setAlignFormattingUnchanged() {
setOptionFlag(false,align);
}
public boolean containsBorderFormattingBlock() {
return getOptionFlag(bord);
}
public void setBorderFormatting(BorderFormatting borderFormatting) {
_borderFormatting = borderFormatting;
setOptionFlag(borderFormatting != null, bord);
}
public BorderFormatting getBorderFormatting() {
if( containsBorderFormattingBlock()) {
return _borderFormatting;
}
return null;
}
public boolean containsPatternFormattingBlock() {
return getOptionFlag(patt);
}
public void setPatternFormatting(PatternFormatting patternFormatting) {
_patternFormatting = patternFormatting;
setOptionFlag(patternFormatting!=null, patt);
}
public PatternFormatting getPatternFormatting() {
if( containsPatternFormattingBlock())
{
return _patternFormatting;
}
return null;
}
public boolean containsProtectionFormattingBlock() {
return getOptionFlag(prot);
}
public void setProtectionFormattingUnchanged() {
setOptionFlag(false,prot);
}
public int getOptions() {
return formatting_options;
}
private boolean isModified(BitField field) {
return !field.isSet(formatting_options);
}
private void setModified(boolean modified, BitField field) {
formatting_options = field.setBoolean(formatting_options, !modified);
}
public boolean isLeftBorderModified() {
return isModified(bordLeft);
}
public void setLeftBorderModified(boolean modified) {
setModified(modified,bordLeft);
}
public boolean isRightBorderModified() {
return isModified(bordRight);
}
public void setRightBorderModified(boolean modified)
{
setModified(modified,bordRight);
}
public boolean isTopBorderModified() {
return isModified(bordTop);
}
public void setTopBorderModified(boolean modified) {
setModified(modified,bordTop);
}
public boolean isBottomBorderModified() {
return isModified(bordBot);
}
public void setBottomBorderModified(boolean modified) {
setModified(modified,bordBot);
}
public boolean isTopLeftBottomRightBorderModified() {
return isModified(bordTlBr);
}
public void setTopLeftBottomRightBorderModified(boolean modified) {
setModified(modified,bordTlBr);
}
public boolean isBottomLeftTopRightBorderModified() {
return isModified(bordBlTr);
}
public void setBottomLeftTopRightBorderModified(boolean modified) {
setModified(modified,bordBlTr);
}
public boolean isPatternStyleModified() {
return isModified(pattStyle);
}
public void setPatternStyleModified(boolean modified) {
setModified(modified,pattStyle);
}
public boolean isPatternColorModified() {
return isModified(pattCol);
}
public void setPatternColorModified(boolean modified) {
setModified(modified,pattCol);
}
public boolean isPatternBackgroundColorModified() {
return isModified(pattBgCol);
}
public void setPatternBackgroundColorModified(boolean modified) {
setModified(modified,pattBgCol);
}
private boolean getOptionFlag(BitField field) {
return field.isSet(formatting_options);
}
private void setOptionFlag(boolean flag, BitField field) {
formatting_options = field.setBoolean(formatting_options, flag);
}
protected int getFormattingBlockSize() {
return 6 +
(containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+
(containsBorderFormattingBlock()?8:0)+
(containsPatternFormattingBlock()?4:0);
}
protected void serializeFormattingBlock(LittleEndianOutput out) {
out.writeInt(formatting_options);
out.writeShort(formatting_not_used);
if (containsFontFormattingBlock()) {
byte[] fontFormattingRawRecord = _fontFormatting.getRawRecord();
out.write(fontFormattingRawRecord);
}
if (containsBorderFormattingBlock()) {
_borderFormatting.serialize(out);
}
if (containsPatternFormattingBlock()) {
_patternFormatting.serialize(out);
}
}
public Ptg[] getParsedExpression1() {
return formula1.getTokens();
}
public void setParsedExpression1(Ptg[] ptgs) {
formula1 = Formula.create(ptgs);
}
protected Formula getFormula1() {
return formula1;
}
protected void setFormula1(Formula formula1) {
this.formula1 = formula1;
}
public Ptg[] getParsedExpression2() {
return Formula.getTokens(formula2);
}
public void setParsedExpression2(Ptg[] ptgs) {
formula2 = Formula.create(ptgs);
}
protected Formula getFormula2() {
return formula2;
}
protected void setFormula2(Formula formula2) {
this.formula2 = formula2;
}
protected static int getFormulaSize(Formula formula) {
return formula.getEncodedTokenSize();
}
public static Ptg[] parseFormula(String formula, HSSFSheet sheet) {
if(formula == null) {
return null;
}
int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
return HSSFFormulaParser.parse(formula, sheet.getWorkbook(), FormulaType.CELL, sheetIndex);
}
protected void copyTo(CFRuleBase rec) {
rec.condition_type = condition_type;
rec.comparison_operator = comparison_operator;
rec.formatting_options = formatting_options;
rec.formatting_not_used = formatting_not_used;
if (containsFontFormattingBlock()) {
rec._fontFormatting = _fontFormatting.clone();
}
if (containsBorderFormattingBlock()) {
rec._borderFormatting = _borderFormatting.clone();
}
if (containsPatternFormattingBlock()) {
rec._patternFormatting = (PatternFormatting) _patternFormatting.clone();
}
rec.setFormula1(getFormula1().copy());
rec.setFormula2(getFormula2().copy());
}
@Override
public abstract CFRuleBase clone();
}