<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1-final" date="2008-06-??">
+ <action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
+ <action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
+ <action dev="POI-DEVELOPERS" type="fix">45110 - Fixed TextShape.resizeToFitText() to properly resize TextShape</action>
+ <action dev="POI-DEVELOPERS" type="fix">45091 - Fixed serialization of RefN~ tokens. Simplified Ptg class hierarchy</action>
<action dev="POI-DEVELOPERS" type="fix">45133 - Fixed OBJ Record (5Dh) to pad the sub-record data to a 4-byte boundary</action>
<action dev="POI-DEVELOPERS" type="fix">45145 - Fixed Sheet to always enforce RowRecordsAggregate before ValueRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="fix">45123 - Fixed SharedFormulaRecord.convertSharedFormulas() to propagate token operand classes</action>
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.1-final" date="2008-06-??">
+ <action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
+ <action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
+ <action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
+ <action dev="POI-DEVELOPERS" type="fix">45110 - Fixed TextShape.resizeToFitText() to properly resize TextShape</action>
+ <action dev="POI-DEVELOPERS" type="fix">45091 - Fixed serialization of RefN~ tokens. Simplified Ptg class hierarchy</action>
<action dev="POI-DEVELOPERS" type="fix">45133 - Fixed OBJ Record (5Dh) to pad the sub-record data to a 4-byte boundary</action>
<action dev="POI-DEVELOPERS" type="fix">45145 - Fixed Sheet to always enforce RowRecordsAggregate before ValueRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="fix">45123 - Fixed SharedFormulaRecord.convertSharedFormulas() to propagate token operand classes</action>
return maxDgId;
}
+ public void setMaxDrawingGroupId(int id){
+ maxDgId = id;
+ }
+
public FileIdCluster[] getFileIdClusters()
{
return field_5_fileIdClusters;
* parse results.
* This class is recommended only for single threaded use.
*
- * If you only have a usermodel.HSSFWorkbook, and not a
+ * If you only have a usermodel.Workbook, and not a
* model.Workbook, then use the convenience method on
* usermodel.HSSFFormulaEvaluator
*/
boolean cellRef = CELL_REFERENCE_PATTERN.matcher(name).matches();
if (cellRef) {
- return new ReferencePtg(name);
+ return new RefPtg(name);
}
for(int i = 0; i < book.getNumberOfNames(); i++) {
FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase());
int numArgs = args.length;
if(fm == null) {
- if (namePtg == null) {
- throw new IllegalStateException("NamePtg must be supplied for external functions");
- }
+ if (namePtg == null) {
+ throw new IllegalStateException("NamePtg must be supplied for external functions");
+ }
// must be external function
ParseNode[] allArgs = new ParseNode[numArgs+1];
allArgs[0] = new ParseNode(namePtg);
}
if (namePtg != null) {
- throw new IllegalStateException("NamePtg no applicable to internal functions");
- }
+ throw new IllegalStateException("NamePtg no applicable to internal functions");
+ }
boolean isVarArgs = !fm.hasFixedArgsLength();
int funcIx = fm.getIndex();
validateNumArgs(args.length, fm);
SkipWhite();
if (isArgumentDelimiter(look)) {
if (missedPrevArg) {
- temp.add(new ParseNode(new MissingArgPtg()));
+ temp.add(new ParseNode(MissingArgPtg.instance));
numArgs++;
}
if (look == ')') {
/** Parse and Translate a Math Factor */
private ParseNode powerFactor() {
- ParseNode result = percentFactor();
+ ParseNode result = percentFactor();
while(true) {
SkipWhite();
if(look != '^') {
}
Match('^');
ParseNode other = percentFactor();
- result = new ParseNode(new PowerPtg(), result, other);
+ result = new ParseNode(PowerPtg.instance, result, other);
}
}
private ParseNode percentFactor() {
- ParseNode result = parseSimpleFactor();
+ ParseNode result = parseSimpleFactor();
while(true) {
SkipWhite();
if(look != '%') {
return result;
}
Match('%');
- result = new ParseNode(new PercentPtg(), result);
+ result = new ParseNode(PercentPtg.instance, result);
}
}
return new ParseNode(parseErrorLiteral());
case '-':
Match('-');
- return new ParseNode(new UnaryMinusPtg(), powerFactor());
+ return new ParseNode(UnaryMinusPtg.instance, powerFactor());
case '+':
Match('+');
- return new ParseNode(new UnaryPlusPtg(), powerFactor());
+ return new ParseNode(UnaryPlusPtg.instance, powerFactor());
case '(':
Match('(');
ParseNode inside = comparisonExpression();
Match(')');
- return new ParseNode(new ParenthesisPtg(), inside);
+ return new ParseNode(ParenthesisPtg.instance, inside);
case '"':
return new ParseNode(parseStringLiteral());
}
/** Parse and Translate a Math Term */
private ParseNode Term() {
- ParseNode result = powerFactor();
+ ParseNode result = powerFactor();
while(true) {
SkipWhite();
Ptg operator;
switch(look) {
case '*':
Match('*');
- operator = new MultiplyPtg();
+ operator = MultiplyPtg.instance;
break;
case '/':
Match('/');
- operator = new DividePtg();
+ operator = DividePtg.instance;
break;
default:
return result; // finished with Term
}
private ParseNode comparisonExpression() {
- ParseNode result = concatExpression();
+ ParseNode result = concatExpression();
while (true) {
SkipWhite();
switch(look) {
private Ptg getComparisonToken() {
if(look == '=') {
Match(look);
- return new EqualPtg();
+ return EqualPtg.instance;
}
boolean isGreater = look == '>';
Match(look);
if(isGreater) {
if(look == '=') {
Match('=');
- return new GreaterEqualPtg();
+ return GreaterEqualPtg.instance;
}
- return new GreaterThanPtg();
+ return GreaterThanPtg.instance;
}
switch(look) {
case '=':
Match('=');
- return new LessEqualPtg();
+ return LessEqualPtg.instance;
case '>':
Match('>');
- return new NotEqualPtg();
+ return NotEqualPtg.instance;
}
- return new LessThanPtg();
+ return LessThanPtg.instance;
}
}
Match('&');
ParseNode other = additiveExpression();
- result = new ParseNode(new ConcatPtg(), result, other);
+ result = new ParseNode(ConcatPtg.instance, result, other);
}
return result;
}
/** Parse and Translate an Expression */
private ParseNode additiveExpression() {
- ParseNode result = Term();
+ ParseNode result = Term();
while (true) {
SkipWhite();
Ptg operator;
switch(look) {
case '+':
Match('+');
- operator = new AddPtg();
+ operator = AddPtg.instance;
break;
case '-':
Match('-');
- operator = new SubtractPtg();
+ operator = SubtractPtg.instance;
break;
default:
return result; // finished with additive expression
/**
* API call to execute the parsing of the formula
- * @deprecated use Ptg[] FormulaParser.parse(String, HSSFWorkbook) directly
+ * @deprecated use Ptg[] FormulaParser.parse(String, Workbook) directly
*/
public void parse() {
pointer=0;
}
public Ptg[] getRPNPtg(int formulaType) {
- OperandClassTransformer oct = new OperandClassTransformer(formulaType);
+ OperandClassTransformer oct = new OperandClassTransformer(formulaType);
// RVA is for 'operand class': 'reference', 'value', 'array'
- oct.transformFormula(_rootNode);
+ oct.transformFormula(_rootNode);
return ParseNode.toTokenArray(_rootNode);
}
if (field_8_parsed_expr != null)
size = field_8_parsed_expr.size();
for (int i=0; i< size; i++) {
- Ptg ptg = (Ptg)((Ptg)field_8_parsed_expr.get(i)).clone();
+ Ptg ptg = ((Ptg)field_8_parsed_expr.get(i)).copy();
rec.field_8_parsed_expr.add(i, ptg);
}
rec.value_data = value_data;
}
// And then a union if we had more than one area
if(refs.length > 1) {
- ptg = new UnionPtg();
+ ptg = UnionPtg.instance;
field_13_name_definition.push(ptg);
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
}
}
if (ptg instanceof RefNPtg) {
RefNPtg refNPtg = (RefNPtg)ptg;
- ptg = new ReferencePtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+ ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
refNPtg.isRowRelative(),
refNPtg.isColRelative());
- } else if (ptg instanceof RefNVPtg) {
- RefNVPtg refNVPtg = (RefNVPtg)ptg;
- ptg = new RefVPtg(fixupRelativeRow(formulaRow,refNVPtg.getRow(),refNVPtg.isRowRelative()),
- fixupRelativeColumn(formulaColumn,refNVPtg.getColumn(),refNVPtg.isColRelative()),
- refNVPtg.isRowRelative(),
- refNVPtg.isColRelative());
- } else if (ptg instanceof RefNAPtg) {
- RefNAPtg refNAPtg = (RefNAPtg)ptg;
- ptg = new RefAPtg( fixupRelativeRow(formulaRow,refNAPtg.getRow(),refNAPtg.isRowRelative()),
- fixupRelativeColumn(formulaColumn,refNAPtg.getColumn(),refNAPtg.isColRelative()),
- refNAPtg.isRowRelative(),
- refNAPtg.isColRelative());
} else if (ptg instanceof AreaNPtg) {
AreaNPtg areaNPtg = (AreaNPtg)ptg;
ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
areaNPtg.isLastRowRelative(),
areaNPtg.isFirstColRelative(),
areaNPtg.isLastColRelative());
- } else if (ptg instanceof AreaNVPtg) {
- AreaNVPtg areaNVPtg = (AreaNVPtg)ptg;
- ptg = new AreaVPtg(fixupRelativeRow(formulaRow,areaNVPtg.getFirstRow(),areaNVPtg.isFirstRowRelative()),
- fixupRelativeRow(formulaRow,areaNVPtg.getLastRow(),areaNVPtg.isLastRowRelative()),
- fixupRelativeColumn(formulaColumn,areaNVPtg.getFirstColumn(),areaNVPtg.isFirstColRelative()),
- fixupRelativeColumn(formulaColumn,areaNVPtg.getLastColumn(),areaNVPtg.isLastColRelative()),
- areaNVPtg.isFirstRowRelative(),
- areaNVPtg.isLastRowRelative(),
- areaNVPtg.isFirstColRelative(),
- areaNVPtg.isLastColRelative());
- } else if (ptg instanceof AreaNAPtg) {
- AreaNAPtg areaNAPtg = (AreaNAPtg)ptg;
- ptg = new AreaAPtg(fixupRelativeRow(formulaRow,areaNAPtg.getFirstRow(),areaNAPtg.isFirstRowRelative()),
- fixupRelativeRow(formulaRow,areaNAPtg.getLastRow(),areaNAPtg.isLastRowRelative()),
- fixupRelativeColumn(formulaColumn,areaNAPtg.getFirstColumn(),areaNAPtg.isFirstColRelative()),
- fixupRelativeColumn(formulaColumn,areaNAPtg.getLastColumn(),areaNAPtg.isLastColRelative()),
- areaNAPtg.isFirstRowRelative(),
- areaNAPtg.isLastRowRelative(),
- areaNAPtg.isFirstColRelative(),
- areaNAPtg.isLastColRelative());
}
if (!ptg.isBaseToken()) {
ptg.setClass(originalOperandClass);
return sb.toString();
}
- public int getType() {
- return -1;
- }
-
-
-
public short getFunctionIndex() {
return field_2_fnc_index;
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Addition operator PTG the "+" binomial operator. If you need more
* explanation than that then well...We really can't help you here.
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class AddPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x03;
private final static String ADD = "+";
- /** Creates new AddPtg */
-
- public AddPtg()
- {
- }
-
- public AddPtg(RecordInputStream in)
- {
+ public static final ValueOperatorPtg instance = new AddPtg();
- // doesn't need anything
+ private AddPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
+ protected byte getSid() {
+ return sid;
}
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
-
- /** Implementation of method from Ptg */
- public String toFormulaString(Workbook book)
- {
- return "+";
- }
/** implementation of method from OperationsPtg*/
public String toFormulaString(String[] operands) {
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new AddPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
+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;
public void writeBytes( byte[] array, int offset )
{
- array[0 + offset] = (byte) ( sid + ptgClass );
+ array[0 + offset] = (byte) ( sid + getPtgClass() );
LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
return retval.toString();
}
- public byte getDefaultOperandClass()
- {
+ public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
}
-
- public Object clone()
- {
- Area3DPtg ptg = new Area3DPtg();
- ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
- ptg.field_2_first_row = field_2_first_row;
- ptg.field_3_last_row = field_3_last_row;
- ptg.field_4_first_column = field_4_first_column;
- ptg.field_5_last_column = field_5_last_column;
- ptg.setClass(ptgClass);
- return ptg;
- }
-
-
+ // TODO - one junit relies on this. remove
public boolean equals( Object o )
{
if ( this == o ) return true;
return true;
}
-
- public int hashCode()
- {
- // TODO - hashCode seems to be unused
- int result;
- result = (int) field_1_index_extern_sheet;
- result = 29 * result + (int) field_2_first_row;
- result = 29 * result + (int) field_3_last_row;
- result = 29 * result + (int) field_4_first_column;
- result = 29 * result + (int) field_5_last_column;
- return result;
- }
-
-
}
+++ /dev/null
-
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaAPtg extends AreaPtg {
- public final static short sid = 0x65;
-
- protected AreaAPtg() {
- //Required for clone methods
- }
-
- public AreaAPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
- super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
- }
-
- public AreaAPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getAreaPtgName() {
- return "AreaAPtg";
- }
-
- public Object clone() {
- AreaAPtg ptg = new AreaAPtg();
- ptg.setFirstRow(getFirstRow());
- ptg.setLastRow(getLastRow());
- ptg.setFirstColumnRaw(getFirstColumnRaw());
- ptg.setLastColumnRaw(getLastColumnRaw());
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.LittleEndian;
/**
* AreaErr - handles deleted cell area references.
*
* @author Daniel Noll (daniel at nuix dot com dot au)
*/
-public class AreaErrPtg extends AreaPtg
-{
+public final class AreaErrPtg extends OperandPtg {
public final static byte sid = 0x2b;
- private AreaErrPtg()
- {
- //Required for clone methods
- super();
- }
-
- public AreaErrPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String toString()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("AreaErrPtg\n");
- buffer.append("firstRow = " + getFirstRow()).append("\n");
- buffer.append("lastRow = " + getLastRow()).append("\n");
- buffer.append("firstCol = " + getFirstColumn()).append("\n");
- buffer.append("lastCol = " + getLastColumn()).append("\n");
- buffer.append("firstColRowRel= "
- + isFirstRowRelative()).append("\n");
- buffer.append("lastColRowRel = "
- + isLastRowRelative()).append("\n");
- buffer.append("firstColRel = " + isFirstColRelative()).append("\n");
- buffer.append("lastColRel = " + isLastColRelative()).append("\n");
- return buffer.toString();
+ public AreaErrPtg(RecordInputStream in) {
+ // 8 bytes unused:
+ in.readInt();
+ in.readInt();
}
public void writeBytes(byte [] array, int offset) {
- super.writeBytes(array, offset);
- array[offset] = (byte) (sid + ptgClass);
+ array[offset] = (byte) (sid + getPtgClass());
+ LittleEndian.putInt(array, offset+1, 0);
+ LittleEndian.putInt(array, offset+5, 0);
}
- public String toFormulaString(Workbook book)
- {
+ public String toFormulaString(Workbook book) {
return "#REF!";
}
-
- public Object clone()
- {
- AreaErrPtg ptg = new AreaErrPtg();
- ptg.setFirstRow(getFirstRow());
- ptg.setFirstColumn(getFirstColumn());
- ptg.setLastRow(getLastRow());
- ptg.setLastColumn(getLastColumn());
- ptg.setFirstColRelative(isFirstColRelative());
- ptg.setLastColRelative(isLastColRelative());
- ptg.setFirstRowRelative(isFirstRowRelative());
- ptg.setLastRowRelative(isLastRowRelative());
- ptg.setClass(ptgClass);
- return ptg;
- }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+
+ public int getSize() {
+ return 9;
+ }
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaNAPtg extends AreaPtg
-{
- public final static short sid = 0x6D;
-
- protected AreaNAPtg() {
- //Required for clone methods
- }
-
- public AreaNAPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getAreaPtgName() {
- return "AreaNAPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
-
- public Object clone() {
- throw notImplemented();
- }
-}
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
limitations under the License.
==================================================================== */
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
/**
* Specifies a rectangular area of cells A1:A4 for instance.
* @author Jason Height (jheight at chariot dot net dot au)
*/
+public final class AreaNPtg extends AreaPtgBase {
+ public final static short sid = 0x2D;
-public final class AreaNPtg extends AreaPtg
-{
- public final static short sid = 0x2D;
-
- protected AreaNPtg() {
- //Required for clone methods
- }
-
- public AreaNPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getAreaPtgName() {
- return "AreaNPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
+ public AreaNPtg(RecordInputStream in) {
+ super(in);
+ }
- public Object clone() {
- throw notImplemented();
- }
+ protected byte getSid() {
+ return sid;
+ }
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author andy
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class AreaNVPtg extends AreaPtg {
- public final static short sid = 0x4D;
-
- protected AreaNVPtg() {
- //Required for clone methods
- }
-
- public AreaNVPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getAreaPtgName() {
- return "AreaNVPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
-
- public Object clone() {
- throw notImplemented();
- }
-}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
-
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
/**
* Specifies a rectangular area of cells A1:A4 for instance.
- * @author andy
* @author Jason Height (jheight at chariot dot net dot au)
*/
-public class AreaPtg extends OperandPtg implements AreaI {
- /**
- * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
- * see similar comment in ReferencePtg
- */
- protected final RuntimeException notImplemented() {
- return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
- }
-
+public final class AreaPtg extends AreaPtgBase {
public final static short sid = 0x25;
- private final static int SIZE = 9;
- /** zero based, unsigned 16 bit */
- private int field_1_first_row;
- /** zero based, unsigned 16 bit */
- private int field_2_last_row;
- /** zero based, unsigned 8 bit */
- private int field_3_first_column;
- /** zero based, unsigned 8 bit */
- private int field_4_last_column;
-
- private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000);
- private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
- private final static BitField columnMask = BitFieldFactory.getInstance(0x3FFF);
-
- protected AreaPtg() {
- //Required for clone methods
- }
-
- public AreaPtg(String arearef) {
- AreaReference ar = new AreaReference(arearef);
- CellReference firstCell = ar.getFirstCell();
- CellReference lastCell = ar.getLastCell();
- setFirstRow(firstCell.getRow());
- setFirstColumn(firstCell.getCol());
- setLastRow(lastCell.getRow());
- setLastColumn(lastCell.getCol());
- setFirstColRelative(!firstCell.isColAbsolute());
- setLastColRelative(!lastCell.isColAbsolute());
- setFirstRowRelative(!firstCell.isRowAbsolute());
- setLastRowRelative(!lastCell.isRowAbsolute());
- }
-
- public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
- boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
-
- checkColumnBounds(firstColumn);
- checkColumnBounds(lastColumn);
- checkRowBounds(firstRow);
- checkRowBounds(lastRow);
- setFirstRow(firstRow);
- setLastRow(lastRow);
- setFirstColumn(firstColumn);
- setLastColumn(lastColumn);
- setFirstRowRelative(firstRowRelative);
- setLastRowRelative(lastRowRelative);
- setFirstColRelative(firstColRelative);
- setLastColRelative(lastColRelative);
- }
- private static void checkColumnBounds(int colIx) {
- if((colIx & 0x0FF) != colIx) {
- throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
- }
- }
- private static void checkRowBounds(int rowIx) {
- if((rowIx & 0x0FFFF) != rowIx) {
- throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
- }
+ public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+ super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
-
- public AreaPtg(RecordInputStream in)
- {
- field_1_first_row = in.readUShort();
- field_2_last_row = in.readUShort();
- field_3_first_column = in.readUShort();
- field_4_last_column = in.readUShort();
- //System.out.println(toString());
- }
-
- public String getAreaPtgName() {
- return "AreaPtg";
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName());
- sb.append(" [");
- sb.append(AreaReference.formatAsString(this));
- sb.append("]");
- return sb.toString();
- }
-
- public void writeBytes(byte [] array, int offset) {
- array[offset] = (byte) (sid + ptgClass);
- LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
- LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
- LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
- LittleEndian.putShort(array,offset+7,(short)field_4_last_column);
- }
-
- public int getSize()
- {
- return SIZE;
- }
-
- /**
- * @return the first row in the area
- */
- public int getFirstRow()
- {
- return field_1_first_row;
- }
-
- /**
- * sets the first row
- * @param rowIx number (0-based)
- */
- public void setFirstRow(int rowIx) {
- checkRowBounds(rowIx);
- field_1_first_row = rowIx;
- }
-
- /**
- * @return last row in the range (x2 in x1,y1-x2,y2)
- */
- public int getLastRow()
- {
- return field_2_last_row;
- }
-
- /**
- * @param rowIx last row number in the area
- */
- public void setLastRow(int rowIx) {
- checkRowBounds(rowIx);
- field_2_last_row = rowIx;
- }
-
- /**
- * @return the first column number in the area.
- */
- public int getFirstColumn()
- {
- return columnMask.getValue(field_3_first_column);
- }
-
- /**
- * @return the first column number + the options bit settings unstripped
- */
- public short getFirstColumnRaw()
- {
- return (short) field_3_first_column; // TODO
- }
-
- /**
- * @return whether or not the first row is a relative reference or not.
- */
- public boolean isFirstRowRelative()
- {
- return rowRelative.isSet(field_3_first_column);
+ public AreaPtg(RecordInputStream in) {
+ super(in);
}
-
- /**
- * sets the first row to relative or not
- * @param rel is relative or not.
- */
- public void setFirstRowRelative(boolean rel) {
- field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
- }
-
- /**
- * @return isrelative first column to relative or not
- */
- public boolean isFirstColRelative()
- {
- return colRelative.isSet(field_3_first_column);
- }
-
- /**
- * set whether the first column is relative
- */
- public void setFirstColRelative(boolean rel) {
- field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
- }
-
- /**
- * set the first column in the area
- */
- public void setFirstColumn(int colIx) {
- checkColumnBounds(colIx);
- field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
- }
-
- /**
- * set the first column irespective of the bitmasks
- */
- public void setFirstColumnRaw(int column)
- {
- field_3_first_column = column;
- }
-
- /**
- * @return lastcolumn in the area
- */
- public int getLastColumn()
- {
- return columnMask.getValue(field_4_last_column);
- }
-
- /**
- * @return last column and bitmask (the raw field)
- */
- public short getLastColumnRaw()
- {
- return (short) field_4_last_column;
- }
-
- /**
- * @return last row relative or not
- */
- public boolean isLastRowRelative()
- {
- return rowRelative.isSet(field_4_last_column);
- }
-
- /**
- * set whether the last row is relative or not
- * @param rel <code>true</code> if the last row relative, else
- * <code>false</code>
- */
- public void setLastRowRelative(boolean rel) {
- field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
- }
-
- /**
- * @return lastcol relative or not
- */
- public boolean isLastColRelative()
- {
- return colRelative.isSet(field_4_last_column);
- }
-
- /**
- * set whether the last column should be relative or not
- */
- public void setLastColRelative(boolean rel) {
- field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
- }
-
-
- /**
- * set the last column in the area
- */
- public void setLastColumn(int colIx) {
- checkColumnBounds(colIx);
- field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
- }
-
- /**
- * set the last column irrespective of the bitmasks
- */
- public void setLastColumnRaw(short column)
- {
- field_4_last_column = column;
- }
-
- public String toFormulaString(Workbook book) {
- return AreaReference.formatAsString(this);
- }
-
- public byte getDefaultOperandClass() {
- return Ptg.CLASS_REF;
- }
-
- public Object clone() {
- AreaPtg ptg = new AreaPtg();
- ptg.field_1_first_row = field_1_first_row;
- ptg.field_2_last_row = field_2_last_row;
- ptg.field_3_first_column = field_3_first_column;
- ptg.field_4_last_column = field_4_last_column;
- ptg.setClass(ptgClass);
- return ptg;
- }
-
+ public AreaPtg(String arearef) {
+ super(arearef);
+ }
+ protected byte getSid() {
+ return sid;
+ }
}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.util.AreaReference;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class AreaPtgBase extends OperandPtg implements AreaI {
+ /**
+ * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
+ * see similar comment in ReferencePtg
+ */
+ protected final RuntimeException notImplemented() {
+ return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
+ }
+
+ public final static short sid = 0x25;
+ private final static int SIZE = 9;
+ /** zero based, unsigned 16 bit */
+ private int field_1_first_row;
+ /** zero based, unsigned 16 bit */
+ private int field_2_last_row;
+ /** zero based, unsigned 8 bit */
+ private int field_3_first_column;
+ /** zero based, unsigned 8 bit */
+ private int field_4_last_column;
+
+ private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000);
+ private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
+ private final static BitField columnMask = BitFieldFactory.getInstance(0x3FFF);
+
+ protected AreaPtgBase(String arearef) {
+ AreaReference ar = new AreaReference(arearef);
+ CellReference firstCell = ar.getFirstCell();
+ CellReference lastCell = ar.getLastCell();
+ setFirstRow(firstCell.getRow());
+ setFirstColumn(firstCell.getCol());
+ setLastRow(lastCell.getRow());
+ setLastColumn(lastCell.getCol());
+ setFirstColRelative(!firstCell.isColAbsolute());
+ setLastColRelative(!lastCell.isColAbsolute());
+ setFirstRowRelative(!firstCell.isRowAbsolute());
+ setLastRowRelative(!lastCell.isRowAbsolute());
+ }
+
+ protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn,
+ boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+
+ checkColumnBounds(firstColumn);
+ checkColumnBounds(lastColumn);
+ checkRowBounds(firstRow);
+ checkRowBounds(lastRow);
+ setFirstRow(firstRow);
+ setLastRow(lastRow);
+ setFirstColumn(firstColumn);
+ setLastColumn(lastColumn);
+ setFirstRowRelative(firstRowRelative);
+ setLastRowRelative(lastRowRelative);
+ setFirstColRelative(firstColRelative);
+ setLastColRelative(lastColRelative);
+ }
+
+ private static void checkColumnBounds(int colIx) {
+ if((colIx & 0x0FF) != colIx) {
+ throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
+ }
+ }
+ private static void checkRowBounds(int rowIx) {
+ if((rowIx & 0x0FFFF) != rowIx) {
+ throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
+ }
+ }
+
+ protected AreaPtgBase(RecordInputStream in)
+ {
+ field_1_first_row = in.readUShort();
+ field_2_last_row = in.readUShort();
+ field_3_first_column = in.readUShort();
+ field_4_last_column = in.readUShort();
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(AreaReference.formatAsString(this));
+ sb.append("]");
+ return sb.toString();
+ }
+ protected abstract byte getSid();
+
+ public final void writeBytes(byte [] array, int offset) {
+ array[offset] = (byte) (getSid() + getPtgClass());
+ LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
+ LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
+ LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
+ LittleEndian.putShort(array,offset+7,(short)field_4_last_column);
+ }
+
+
+ public final int getSize() {
+ return SIZE;
+ }
+
+ /**
+ * @return the first row in the area
+ */
+ public final int getFirstRow() {
+ return field_1_first_row;
+ }
+
+ /**
+ * sets the first row
+ * @param rowIx number (0-based)
+ */
+ public final void setFirstRow(int rowIx) {
+ checkRowBounds(rowIx);
+ field_1_first_row = rowIx;
+ }
+
+ /**
+ * @return last row in the range (x2 in x1,y1-x2,y2)
+ */
+ public final int getLastRow() {
+ return field_2_last_row;
+ }
+
+ /**
+ * @param rowIx last row number in the area
+ */
+ public final void setLastRow(int rowIx) {
+ checkRowBounds(rowIx);
+ field_2_last_row = rowIx;
+ }
+
+ /**
+ * @return the first column number in the area.
+ */
+ public final int getFirstColumn() {
+ return columnMask.getValue(field_3_first_column);
+ }
+
+ /**
+ * @return the first column number + the options bit settings unstripped
+ */
+ public final short getFirstColumnRaw() {
+ return (short) field_3_first_column; // TODO
+ }
+
+ /**
+ * @return whether or not the first row is a relative reference or not.
+ */
+ public final boolean isFirstRowRelative() {
+ return rowRelative.isSet(field_3_first_column);
+ }
+
+ /**
+ * sets the first row to relative or not
+ * @param rel is relative or not.
+ */
+ public final void setFirstRowRelative(boolean rel) {
+ field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
+ }
+
+ /**
+ * @return isrelative first column to relative or not
+ */
+ public final boolean isFirstColRelative() {
+ return colRelative.isSet(field_3_first_column);
+ }
+
+ /**
+ * set whether the first column is relative
+ */
+ public final void setFirstColRelative(boolean rel) {
+ field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
+ }
+
+ /**
+ * set the first column in the area
+ */
+ public final void setFirstColumn(int colIx) {
+ checkColumnBounds(colIx);
+ field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
+ }
+
+ /**
+ * set the first column irrespective of the bitmasks
+ */
+ public final void setFirstColumnRaw(int column) {
+ field_3_first_column = column;
+ }
+
+ /**
+ * @return lastcolumn in the area
+ */
+ public final int getLastColumn() {
+ return columnMask.getValue(field_4_last_column);
+ }
+
+ /**
+ * @return last column and bitmask (the raw field)
+ */
+ public final short getLastColumnRaw() {
+ return (short) field_4_last_column;
+ }
+
+ /**
+ * @return last row relative or not
+ */
+ public final boolean isLastRowRelative() {
+ return rowRelative.isSet(field_4_last_column);
+ }
+
+ /**
+ * set whether the last row is relative or not
+ * @param rel <code>true</code> if the last row relative, else
+ * <code>false</code>
+ */
+ public final void setLastRowRelative(boolean rel) {
+ field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
+ }
+
+ /**
+ * @return lastcol relative or not
+ */
+ public final boolean isLastColRelative() {
+ return colRelative.isSet(field_4_last_column);
+ }
+
+ /**
+ * set whether the last column should be relative or not
+ */
+ public final void setLastColRelative(boolean rel) {
+ field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
+ }
+
+ /**
+ * set the last column in the area
+ */
+ public final void setLastColumn(int colIx) {
+ checkColumnBounds(colIx);
+ field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
+ }
+
+ /**
+ * set the last column irrespective of the bitmasks
+ */
+ public final void setLastColumnRaw(short column) {
+ field_4_last_column = column;
+ }
+
+ public String toFormulaString(Workbook book) {
+ return AreaReference.formatAsString(this);
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
+++ /dev/null
-
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 PM
- */
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Specifies a rectangular area of cells A1:A4 for instance.
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class AreaVPtg
- extends AreaPtg
-{
- public final static short sid = 0x45;
-
- protected AreaVPtg() {
- //Required for clone methods
- }
-
- public AreaVPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
- super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
- }
-
-
- public AreaVPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getAreaPtgName() {
- return "AreaVPtg";
- }
-
- public Object clone() {
- AreaVPtg ptg = new AreaVPtg();
- ptg.setFirstRow(getFirstRow());
- ptg.setLastRow(getLastRow());
- ptg.setFirstColumnRaw(getFirstColumnRaw());
- ptg.setLastColumnRaw(getLastColumnRaw());
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
*
* @author Jason Height (jheight at chariot dot net dot au)
*/
-public class ArrayPtg extends Ptg {
+public final class ArrayPtg extends Ptg {
public static final byte sid = 0x20;
private static final int RESERVED_FIELD_LEN = 7;
// TODO - fix up field visibility and subclasses
- protected byte[] field_1_reserved;
+ private byte[] field_1_reserved;
+
// data from these fields comes after the Ptg data of all tokens in current formula
- protected short token_1_columns;
- protected short token_2_rows;
- protected Object[] token_3_arrayValues;
-
- protected ArrayPtg() {
- //Required for clone methods
- }
+ private short token_1_columns;
+ private short token_2_rows;
+ private Object[] token_3_arrayValues;
- public ArrayPtg(RecordInputStream in)
- {
+ public ArrayPtg(RecordInputStream in) {
field_1_reserved = new byte[RESERVED_FIELD_LEN];
// TODO - add readFully method to RecordInputStream
for(int i=0; i< RESERVED_FIELD_LEN; i++) {
field_1_reserved[i] = in.readByte();
}
}
+ public Object[] getTokenArrayValues() {
+ return (Object[]) token_3_arrayValues.clone();
+ }
public boolean isBaseToken() {
return false;
public void writeBytes(byte[] data, int offset) {
- LittleEndian.putByte(data, offset + 0, sid + ptgClass);
+ LittleEndian.putByte(data, offset + 0, sid + getPtgClass());
System.arraycopy(field_1_reserved, 0, data, offset+1, RESERVED_FIELD_LEN);
}
}
public Object clone() {
- ArrayPtg ptg = new ArrayPtg();
+ ArrayPtg ptg = (ArrayPtg) super.clone();
ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-
- ptg.token_1_columns = token_1_columns;
- ptg.token_2_rows = token_2_rows;
ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
- ptg.setClass(ptgClass);
return ptg;
}
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ArrayPtgA - handles arrays
- *
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class ArrayPtgA extends ArrayPtg {
- public final static byte sid = 0x60;
-
- private ArrayPtgA() {
- //Required for clone methods
- }
-
- public ArrayPtgA(RecordInputStream in) {
- super(in);
- }
-
- public Object clone() {
- ArrayPtgA ptg = new ArrayPtgA();
- ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-
- ptg.token_1_columns = token_1_columns;
- ptg.token_2_rows = token_2_rows;
- ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ArrayPtg - handles arrays
- *
- * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only
- * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows.
- * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually
- * held after this. So Ptg.createParsedExpression keeps track of the number of
- * ArrayPtg elements and need to parse the data upto the FORMULA record size.
- *
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class ArrayPtgV extends ArrayPtg {
- public final static byte sid = 0x40;
-
- private ArrayPtgV() {
- //Required for clone methods
- }
-
- public ArrayPtgV(RecordInputStream in) {
- super(in);
- }
-
- public Object clone() {
- ArrayPtgV ptg = new ArrayPtgV();
- ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-
- ptg.token_1_columns = token_1_columns;
- ptg.token_2_rows = token_2_rows;
- ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
public final class BoolPtg extends ScalarConstantPtg {
public final static int SIZE = 2;
public final static byte sid = 0x1d;
- private boolean field_1_value;
-
- private BoolPtg() {
- //Required for clone methods
- }
+ private final boolean field_1_value;
public BoolPtg(RecordInputStream in)
{
field_1_value = (formulaToken.equals("TRUE"));
}
- public void setValue(boolean value)
- {
- field_1_value = value;
- }
-
public boolean getValue()
{
return field_1_value;
{
return field_1_value ? "TRUE" : "FALSE";
}
-
- public Object clone() {
- BoolPtg ptg = new BoolPtg();
- ptg.field_1_value = field_1_value;
- return ptg;
- }
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
*
* @author andy
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class ConcatPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x08;
private final static String CONCAT = "&";
- public ConcatPtg(RecordInputStream in)
- {
- // No contents
- }
-
- public ConcatPtg() {
-
- }
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
+ public static final ValueOperatorPtg instance = new ConcatPtg();
- public int getSize()
- {
- return SIZE;
+ private ConcatPtg() {
+ // enforce singleton
}
-
- public int getType()
- {
- return TYPE_BINARY;
+
+ protected byte getSid() {
+ return sid;
}
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
-
- public String toFormulaString(Workbook book)
- {
- return CONCAT;
- }
-
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new ConcatPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* This PTG implements the standard binomial divide "/"
* @author Andrew C. Oliver acoliver at apache dot org
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class DividePtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x06;
- /** Creates new AddPtg */
-
- public DividePtg()
- {
- }
-
- public DividePtg(RecordInputStream in)
- {
+ public static final ValueOperatorPtg instance = new DividePtg();
- // doesn't need anything
+ private DividePtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
+
+ protected byte getSid() {
+ return sid;
}
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- public String toFormulaString(Workbook book)
- {
- return "/";
- }
-
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(toFormulaString((Workbook)null));
+ buffer.append("/");
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- DividePtg ptg = new DividePtg();
- return ptg;
- }
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
*
* @author andy
*/
public final class EqualPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x0b;
- /** Creates new AddPtg */
-
- public EqualPtg()
- {
- }
-
- public EqualPtg(RecordInputStream in)
- {
+ public static final ValueOperatorPtg instance = new EqualPtg();
- // doesn't need anything
+ private EqualPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
+
+ protected byte getSid() {
+ return sid;
}
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
-
- public String toFormulaString(Workbook book)
- {
- return "=";
- }
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(toFormulaString((Workbook)null));
+ buffer.append("=");
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new EqualPtg();
- }
-
-
}
public static final short sid = 0x1c;
private static final int SIZE = 2;
- private int field_1_error_code;
+ private final int field_1_error_code;
/** Creates new ErrPtg */
public void writeBytes(byte [] array, int offset)
{
- array[offset] = (byte) (sid + ptgClass);
+ array[offset] = (byte) (sid + getPtgClass());
array[offset + 1] = (byte)field_1_error_code;
}
return SIZE;
}
- public Object clone() {
- return new ErrPtg(field_1_error_code);
- }
-
public int getErrorCode() {
return field_1_error_code;
}
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
* @author Jason Height (jheight at chariot dot net dot au)
* @author dmui (save existing implementation)
*/
-
public final class ExpPtg extends ControlPtg {
private final static int SIZE = 5;
public final static short sid = 0x1;
- private short field_1_first_row;
- private short field_2_first_col;
-
- /** Creates new ExpPtg */
-
- public ExpPtg()
- {
- }
-
- /** Creates new ExpPtg */
+ private final short field_1_first_row;
+ private final short field_2_first_col;
public ExpPtg(RecordInputStream in)
{
buffer.append("col = ").append(getColumn()).append("\n");
return buffer.toString();
}
-
- public Object clone() {
- ExpPtg result = new ExpPtg();
- result.field_1_first_row = field_1_first_row;
- result.field_2_first_col = field_2_first_col;
- return result;
- }
-
}
}
public void writeBytes(byte[] array, int offset) {
- array[offset+0]= (byte) (sid + ptgClass);
+ array[offset+0]= (byte) (sid + getPtgClass());
LittleEndian.putShort(array,offset+1,field_2_fnc_index);
}
return numParams;
}
- public Object clone() {
- FuncPtg ptg = new FuncPtg(field_2_fnc_index);
- ptg.setClass(ptgClass);
- return ptg;
- }
-
public int getSize() {
return SIZE;
}
public final static byte sid = 0x22;
private final static int SIZE = 4;
- private FuncVarPtg() {
- //Required for clone methods
- }
-
- /**Creates new function pointer from a byte array
+ /**Creates new function pointer from a byte array
* usually called while reading an excel file.
*/
public FuncVarPtg(RecordInputStream in) {
}
public void writeBytes(byte[] array, int offset) {
- array[offset+0]=(byte) (sid + ptgClass);
+ array[offset+0]=(byte) (sid + getPtgClass());
array[offset+1]=field_1_num_args;
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
}
return field_1_num_args;
}
- public Object clone() {
- FuncVarPtg ptg = new FuncVarPtg();
- ptg.field_1_num_args = field_1_num_args;
- ptg.field_2_fnc_index = field_2_fnc_index;
- ptg.setClass(ptgClass);
- return ptg;
- }
-
public int getSize() {
return SIZE;
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* PTG class to implement greater or equal to
public final static int SIZE = 1;
public final static byte sid = 0x0c;
- /** Creates new GreaterEqualPtg */
+ public static final ValueOperatorPtg instance = new GreaterEqualPtg();
- public GreaterEqualPtg()
- {
+ private GreaterEqualPtg() {
+ // enforce singleton
}
-
- public GreaterEqualPtg(RecordInputStream in)
- {
-
- // doesn't need anything
- }
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
+
+ protected byte getSid() {
+ return sid;
}
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- public String toFormulaString(Workbook book)
- {
- return ">=";
- }
-
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(toFormulaString((Workbook)null));
+ buffer.append(">=");
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new GreaterEqualPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* Greater than operator PTG ">"
* @author Cameron Riley (criley at ekmail.com)
*/
public final class GreaterThanPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x0D;
private final static String GREATERTHAN = ">";
- /**
- * Constructor. Creates new GreaterThanPtg
- */
- public GreaterThanPtg()
- {
- //deliberately empty
- }
+ public static final ValueOperatorPtg instance = new GreaterThanPtg();
- /**
- * Constructor. Create a new GreaterThanPtg.
- * @param in the RecordInputstream to read the record from
- */
- public GreaterThanPtg(RecordInputStream in)
- {
- //deliberately empty
+ private GreaterThanPtg() {
+ // enforce singleton
}
- /**
- * Write the sid to an array
- * @param array the array of bytes to write the sid to
- * @param offset the offset to add the sid to
- */
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- /**
- * Get the size of the sid
- * @return int the size of the sid in terms of byte additions to an array
- */
- public int getSize()
- {
- return SIZE;
- }
-
- /**
- * Get the type of PTG for Greater Than
- * @return int the identifier for the type
- */
- public int getType()
- {
- return TYPE_BINARY;
+ protected byte getSid() {
+ return sid;
}
/**
* Get the number of operands for the Less than operator
* @return int the number of operands
*/
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- /**
- * Implementation of method from Ptg
- * @param book the Sheet References
- */
- public String toFormulaString(Workbook book)
- {
- return this.GREATERTHAN;
- }
-
/**
* Implementation of method from OperationsPtg
* @param operands a String array of operands
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(this.GREATERTHAN);
+ buffer.append(GREATERTHAN);
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- /**
- * Implementation of clone method from Object
- * @return Object a clone of this class as an Object
- */
- public Object clone()
- {
- return new GreaterThanPtg();
- }
}
public final static int SIZE = 3;
public final static byte sid = 0x1e;
- private int field_1_value;
+ private final int field_1_value;
public IntPtg(RecordInputStream in) {
this(in.readUShort());
}
-
public IntPtg(int value) {
if(!isInRange(value)) {
throw new IllegalArgumentException("value is out of range: " + value);
return field_1_value;
}
-
public void writeBytes(byte [] array, int offset)
{
array[ offset + 0 ] = sid;
return String.valueOf(getValue());
}
- public Object clone() {
- return new IntPtg(field_1_value);
- }
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
package org.apache.poi.hssf.record.formula;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* @author Daniel Noll (daniel at nuix dot com dot au)
public final class IntersectionPtg extends OperationPtg {
public final static byte sid = 0x0f;
+ public static final OperationPtg instance = new IntersectionPtg();
- public IntersectionPtg()
- {
- }
-
- public IntersectionPtg(RecordInputStream in)
- {
- // doesn't need anything
+ private IntersectionPtg() {
+ // enforce singleton
}
public final boolean isBaseToken() {
array[ offset + 0 ] = sid;
}
- public Object clone()
- {
- return new IntersectionPtg();
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
/** Implementation of method from Ptg */
public String toFormulaString(Workbook book)
{
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* @author fred at stsci dot edu
*/
public final class LessEqualPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x0a;
- /**
- * Creates new LessEqualPtg
- */
- public LessEqualPtg()
- {
+ public static final ValueOperatorPtg instance = new LessEqualPtg();
+ private LessEqualPtg() {
+ // enforce singleton
}
-
- public LessEqualPtg( RecordInputStream in )
- {
- // doesn't need anything
- }
-
- public void writeBytes( byte[] array, int offset )
- {
- array[offset + 0] = sid;
+
+ protected byte getSid() {
+ return sid;
}
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- public String toFormulaString( Workbook book )
- {
- return "<=";
- }
-
- public String toFormulaString( String[] operands )
- {
+ public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append( operands[0] );
- buffer.append( toFormulaString( (Workbook) null ) );
+ buffer.append("<=");
buffer.append( operands[1] );
return buffer.toString();
}
-
- public Object clone()
- {
- return new LessEqualPtg();
- }
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Less than operator PTG "<". The SID is taken from the
* Openoffice.orgs Documentation of the Excel File Format,
* @author Cameron Riley (criley at ekmail.com)
*/
public final class LessThanPtg extends ValueOperatorPtg {
- /** the size of the Ptg */
- public final static int SIZE = 1;
-
/** the sid for the less than operator as hex */
public final static byte sid = 0x09;
/** identifier for LESS THAN char */
private final static String LESSTHAN = "<";
- /**
- * Constructor. Creates new LessThanPtg
- */
- public LessThanPtg()
- {
- //deliberately empty
- }
+ public static final ValueOperatorPtg instance = new LessThanPtg();
- /**
- * Constructor. Create a new LessThanPtg.
- * @param in the RecordInputstream to read the record from
- */
- public LessThanPtg(RecordInputStream in)
- {
- //deliberately empty
+ private LessThanPtg() {
+ // enforce singleton
}
- /**
- * Write the sid to an array
- * @param array the array of bytes to write the sid to
- * @param offset the offset to add the sid to
- */
- public void writeBytes(byte[] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- /**
- * Get the size of the sid
- * @return int the size of the sid in terms of byte additions to an array
- */
- public int getSize()
- {
- return SIZE;
- }
-
- /**
- * Get the type of PTG for Less Than
- * @return int the identifier for the type
- */
- public int getType()
- {
- return TYPE_BINARY;
+ protected byte getSid() {
+ return sid;
}
/**
* Get the number of operands for the Less than operator
* @return int the number of operands
*/
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- /**
- * Implementation of method from Ptg
- * @param book the Sheet References
- */
- public String toFormulaString(Workbook book)
- {
- return this.LESSTHAN;
- }
-
- /**
+ /**
* Implementation of method from OperationsPtg
* @param operands a String array of operands
* @return String the Formula as a String
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(this.LESSTHAN);
+ buffer.append(LESSTHAN);
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- /**
- * Implementation of clone method from Object
- * @return Object a clone of this class as an Object
- */
- public Object clone()
- {
- return new LessThanPtg();
- }
-
}
public void writeBytes(byte [] array, int offset)
{
- array[offset] = (byte) (sid + ptgClass);
+ array[offset] = (byte) (sid + getPtgClass());
LittleEndian.putInt(array, offset + 1, field_1_reserved);
LittleEndian.putShort(array, offset + 5, field_2_subex_len);
}
return ""; // TODO: Not sure how to format this. -- DN
}
- public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
- public Object clone() {
- MemAreaPtg ptg = new MemAreaPtg();
- ptg.field_1_reserved = field_1_reserved;
- ptg.field_2_subex_len = field_2_subex_len;
- return ptg;
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
}
}
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
limitations under the License.
==================================================================== */
-
-/*
- * MemErrPtg.java
- *
- * Created on November 21, 2001, 8:46 AM
- */
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
/**
*
* @author Daniel Noll (daniel at nuix dot com dot au)
*/
-public class MemErrPtg
- extends MemAreaPtg
-{
+public final class MemErrPtg extends MemAreaPtg {
public final static short sid = 0x27;
/** Creates new MemErrPtg */
{
}
- public MemErrPtg(RecordInputStream in)
- {
+ public MemErrPtg(RecordInputStream in) {
super(in);
}
- public void writeBytes(byte [] array, int offset)
- {
+ public void writeBytes(byte [] array, int offset) {
super.writeBytes(array, offset);
- array[offset] = (byte) (sid + ptgClass);
+ array[offset] = (byte) (sid + getPtgClass());
}
public String toFormulaString(Workbook book)
{
return "ERR#";
}
-
- public Object clone() {
- MemErrPtg ptg = new MemErrPtg();
- ptg.setReserved(getReserved());
- ptg.setSubexpressionLength(getSubexpressionLength());
- return ptg;
- }
}
limitations under the License.
==================================================================== */
-
-/*
- * Ptg.java
- *
- * Created on October 28, 2001, 6:30 PM
- */
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian;
/**
* @author Glen Stampoultzis (glens at apache.org)
*/
-public class MemFuncPtg extends OperandPtg {
+public final class MemFuncPtg extends OperandPtg {
public final static byte sid = 0x29;
- private short field_1_len_ref_subexpression = 0;
-
- public MemFuncPtg()
- {
- //Required for clone methods
- }
+ private final int field_1_len_ref_subexpression;
/**Creates new function pointer from a byte array
* usually called while reading an excel file.
*/
- public MemFuncPtg( RecordInputStream in )
- {
- field_1_len_ref_subexpression = in.readShort();
+ public MemFuncPtg(RecordInputStream in) {
+ this(in.readUShort());
}
- public int getSize()
+ public MemFuncPtg(int subExprLen) {
+ field_1_len_ref_subexpression = subExprLen;
+ }
+
+ public int getSize()
{
return 3;
}
public void writeBytes( byte[] array, int offset )
{
array[offset + 0] = sid ;
- LittleEndian.putShort( array, offset + 1, (short)field_1_len_ref_subexpression );
+ LittleEndian.putUShort( array, offset + 1, field_1_len_ref_subexpression );
}
public String toFormulaString(Workbook book)
public byte getDefaultOperandClass()
{
- return 0;
+ return Ptg.CLASS_REF;
}
public int getNumberOfOperands()
return field_1_len_ref_subexpression;
}
- public Object clone()
- {
- MemFuncPtg ptg = new MemFuncPtg();
- ptg.field_1_len_ref_subexpression = this.field_1_len_ref_subexpression;
- return ptg;
- }
-
public int getLenRefSubexpression()
{
return field_1_len_ref_subexpression;
}
-
- public void setLenRefSubexpression(int len)
- {
- field_1_len_ref_subexpression = (short)len;
- }
-
}
\ No newline at end of file
package org.apache.poi.hssf.record.formula;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* Missing Function Arguments
private final static int SIZE = 1;
public final static byte sid = 0x16;
- public MissingArgPtg()
+ public static final Ptg instance = new MissingArgPtg();
+ private MissingArgPtg()
{
}
-
- public MissingArgPtg(RecordInputStream in)
- {
- // doesn't need anything
- }
-
-
public void writeBytes(byte [] array, int offset)
{
{
return SIZE;
}
-
public String toFormulaString(Workbook book)
{
return " ";
}
-
- public Object clone() {
- return new MissingArgPtg();
- }
-
}
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
+package org.apache.poi.hssf.record.formula;
/**
* Implements the standard mathmatical multiplication - *
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
-
public final class MultiplyPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x05;
- /** Creates new AddPtg */
-
- public MultiplyPtg()
- {
- }
-
- public MultiplyPtg(RecordInputStream in)
- {
+ public static final ValueOperatorPtg instance = new MultiplyPtg();
- // doesn't need anything
+ private MultiplyPtg() {
+ // enforce singleton
}
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
+ protected byte getSid() {
+ return sid;
}
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
-
- public int getStringLength() {
- return 1;
- }
-
-
- public String toFormulaString(Workbook book)
- {
- return "*";
- }
-
- public String toFormulaString(Ptg [] operands)
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append(operands[ 0 ].toFormulaString((Workbook)null));
- buffer.append("*");
- buffer.append(operands[ 1 ].toFormulaString((Workbook)null));
- return buffer.toString();
- }
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]);
- buffer.append(toFormulaString((Workbook)null));
+ buffer.append("*");
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new MultiplyPtg();
- }
}
/** one-based index to defined name record */
private short field_1_label_index;
private short field_2_zero; // reserved must be 0
- boolean xtra=false;
-
-
- private NamePtg() {
- //Required for clone methods
- }
/**
* Creates new NamePtg and sets its name index to that of the corresponding defined name record
/** Creates new NamePtg */
- public NamePtg(RecordInputStream in)
- {
- //field_1_ixti = LittleEndian.getShort(data, offset);
+ public NamePtg(RecordInputStream in) {
field_1_label_index = in.readShort();
field_2_zero = in.readShort();
- //if (data[offset+6]==0) xtra=true;
}
/**
return field_1_label_index-1; // convert to zero based
}
- public void writeBytes(byte [] array, int offset)
- {
- array[offset+0]= (byte) (sid + ptgClass);
+ public void writeBytes(byte [] array, int offset) {
+ array[offset+0]= (byte) (sid + getPtgClass());
LittleEndian.putShort(array,offset+1,field_1_label_index);
LittleEndian.putShort(array,offset+3, field_2_zero);
}
- public int getSize()
- {
+ public int getSize() {
return SIZE;
}
return book.getNameName(field_1_label_index - 1);
}
- public byte getDefaultOperandClass() {return Ptg.CLASS_REF;}
-
- public Object clone() {
- NamePtg ptg = new NamePtg();
- ptg.field_1_label_index = field_1_label_index;
- ptg.field_2_zero = field_2_zero;
- return ptg;
- }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
}
private short field_3_reserved; // reserved must be 0
- private NameXPtg() {
- //Required for clone methods
- }
-
- /** Creates new NamePtg */
-
- public NameXPtg(RecordInputStream in)
- {
+ public NameXPtg(RecordInputStream in) {
field_1_ixals = in.readShort();
field_2_ilbl = in.readShort();
field_3_reserved = in.readShort();
-
- //field_2_reserved = LittleEndian.getByteArray(data, offset + 12,12);
}
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = (byte)(sid + ptgClass);
+ public void writeBytes(byte [] array, int offset) {
+ array[ offset + 0 ] = (byte)(sid + getPtgClass());
LittleEndian.putShort(array, offset + 1, field_1_ixals);
LittleEndian.putShort(array,offset+3, field_2_ilbl);
LittleEndian.putShort(array, offset + 5, field_3_reserved);
}
- public int getSize()
- {
+ public int getSize() {
return SIZE;
}
return book.resolveNameXText(field_1_ixals, field_2_ilbl-1);
}
- public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
- public Object clone() {
- NameXPtg ptg = new NameXPtg();
- ptg.field_1_ixals = field_1_ixals;
- ptg.field_3_reserved = field_3_reserved;
- ptg.field_2_ilbl = field_2_ilbl;
- ptg.setClass(ptgClass);
- return ptg;
- }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
}
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Ptg class to implement not equal
*
* @author fred at stsci dot edu
*/
public final class NotEqualPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x0e;
- /**
- * Creates new NotEqualPtg
- */
- public NotEqualPtg()
- {
- }
-
- public NotEqualPtg( RecordInputStream in )
- {
- // doesn't need anything
- }
-
- public void writeBytes( byte[] array, int offset )
- {
- array[offset + 0] = sid;
- }
+ public static final ValueOperatorPtg instance = new NotEqualPtg();
- public int getSize()
- {
- return SIZE;
+ private NotEqualPtg() {
+ // enforce singleton
}
-
- public int getType()
- {
- return TYPE_BINARY;
+
+ protected byte getSid() {
+ return sid;
}
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
- public String toFormulaString( Workbook book )
- {
- return "<>";
- }
-
- public String toFormulaString( String[] operands )
- {
+ public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append( operands[0] );
- buffer.append( toFormulaString( (Workbook) null ) );
+ buffer.append("<>");
buffer.append( operands[1] );
return buffer.toString();
}
-
- public Object clone()
- {
- return new NotEqualPtg();
- }
-
}
public final class NumberPtg extends ScalarConstantPtg {
public final static int SIZE = 9;
public final static byte sid = 0x1f;
- private double field_1_value;
-
- private NumberPtg() {
- //Required for clone methods
- }
+ private final double field_1_value;
/** Create a NumberPtg from a byte array read from disk */
public NumberPtg(RecordInputStream in)
{
- setValue(in.readDouble());
+ field_1_value = in.readDouble();
}
/** Create a NumberPtg from a string representation of the number
* @param value : String representation of a floating point number
*/
public NumberPtg(String value) {
- setValue(Double.parseDouble(value));
- }
-
-
- public void setValue(double value)
- {
- field_1_value = value;
+ field_1_value = Double.parseDouble(value);
}
{
return "" + getValue();
}
-
- public Object clone() {
- NumberPtg ptg = new NumberPtg();
- ptg.field_1_value = field_1_value;
- return ptg;
- }
}
package org.apache.poi.hssf.record.formula;
-
-
/**
* defines a Ptg that is an operation instead of an operand
* @author andy
*/
-
-public abstract class OperationPtg extends Ptg
-{
+public abstract class OperationPtg extends Ptg {
public final static int TYPE_UNARY = 0;
public final static int TYPE_BINARY = 1;
public final static int TYPE_FUNCTION = 2;
- public abstract int getType();
-
/**
* returns a string representation of the operations
* the length of the input array should equal the number returned by
*/
public abstract int getNumberOfOperands();
- public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+ public final int getType() {
+ // TODO remove "int getType();" from Eval hierarchy
+ throw new RuntimeException("remove this method");
+ }
}
private final static int SIZE = 1;
public final static byte sid = 0x15;
- public ParenthesisPtg()
- {
- }
-
- public ParenthesisPtg(RecordInputStream in)
- {
-
- // doesn't need anything
+ public static final ControlPtg instance = new ParenthesisPtg();
+ private ParenthesisPtg() {
+ // enforce singleton
}
-
-
public void writeBytes(byte [] array, int offset)
{
array[ offset + 0 ] = sid;
public String toFormulaString(String[] operands) {
return "("+operands[0]+")";
}
-
- public Object clone() {
- return new ParenthesisPtg();
- }
-
}
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
limitations under the License.
==================================================================== */
-/*
- * PercentPtg.java
- *
- * Created on March 29, 2006, 9:23 PM
- */
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Percent PTG.
*
* @author Daniel Noll (daniel at nuix.com.au)
*/
-
public final class PercentPtg extends ValueOperatorPtg {
public final static int SIZE = 1;
public final static byte sid = 0x14;
private final static String PERCENT = "%";
- /** Creates new PercentPtg */
+ public static final ValueOperatorPtg instance = new PercentPtg();
- public PercentPtg()
- {
- }
-
- public PercentPtg(RecordInputStream in)
- {
-
- // doesn't need anything
+ private PercentPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
+ protected byte getSid() {
+ return sid;
}
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return TYPE_UNARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 1;
}
-
- /** Implementation of method from Ptg */
- public String toFormulaString(Workbook book)
- {
- return "%";
- }
- /** implementation of method from OperationsPtg*/
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(PERCENT);
return buffer.toString();
}
-
- public Object clone() {
- return new PercentPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
*
* @author andy
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class PowerPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x07;
- /** Creates new AddPtg */
-
- public PowerPtg()
- {
- }
-
- public PowerPtg(RecordInputStream in)
- {
-
- // doesn't need anything
- }
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
- }
+ public static final ValueOperatorPtg instance = new PowerPtg();
- public int getType()
- {
- return TYPE_BINARY;
+ private PowerPtg() {
+ // enforce singleton
}
-
- public int getNumberOfOperands()
- {
- return 2;
+
+ protected byte getSid() {
+ return sid;
}
- public String toFormulaString(Workbook book)
- {
- return "^";
+ public int getNumberOfOperands() {
+ return 2; // TODO - 2 seems wrong (Jun 2008). Maybe this method is not relevant
}
public String toFormulaString(String[] operands) {
buffer.append(operands[ 0 ]);
- buffer.append(toFormulaString((Workbook)null));
+ buffer.append("^");
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new PowerPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
import java.util.Stack;
-import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
/**
+ * <tt>Ptg</tt> represents a syntactic token in a formula. 'PTG' is an acronym for
+ * '<b>p</b>arse <b>t</b>hin<b>g</b>'. Originally, the name referred to the single
+ * byte identifier at the start of the token, but in POI, <tt>Ptg</tt> encapsulates
+ * the whole formula token (initial byte + value data).
+ * <p/>
+ *
+ * <tt>Ptg</tt>s are logically arranged in a tree representing the structure of the
+ * parsed formula. However, in BIFF files <tt>Ptg</tt>s are written/read in
+ * <em>Reverse-Polish Notation</em> order. The RPN ordering also simplifies formula
+ * evaluation logic, so POI mostly accesses <tt>Ptg</tt>s in the same way.
*
* @author andy
* @author avik
* @author Jason Height (jheight at chariot dot net dot au)
*/
-public abstract class Ptg
-{
-
-
- /* convert infix order ptg list to rpn order ptg list
- * @return List ptgs in RPN order
- * @param infixPtgs List of ptgs in infix order
- */
-
- /* DO NOT REMOVE
- *we keep this method in case we wish to change the way we parse
- *It needs a getPrecedence in OperationsPtg
-
- public static List ptgsToRpn(List infixPtgs) {
- java.util.Stack operands = new java.util.Stack();
- java.util.List retval = new java.util.Stack();
-
- java.util.ListIterator i = infixPtgs.listIterator();
- Object p;
- OperationPtg o ;
- boolean weHaveABracket = false;
- while (i.hasNext()) {
- p=i.next();
- if (p instanceof OperationPtg) {
- if (p instanceof ParenthesisPtg) {
- if (!weHaveABracket) {
- operands.push(p);
- weHaveABracket = true;
- } else {
- o = (OperationPtg) operands.pop();
- while (!(o instanceof ParenthesisPtg)) {
- retval.add(o);
- }
- weHaveABracket = false;
- }
- } else {
-
- while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative
- retval.add(operands.pop());
- }
- operands.push(p);
- }
- } else {
- retval.add(p);
- }
- }
- while (!operands.isEmpty()) {
- if (operands.peek() instanceof ParenthesisPtg ){
- //throw some error
- } else {
- retval.add(operands.pop());
- }
- }
- return retval;
- }
- */
-
- /**
- * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
- * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
- */
- public static Stack createParsedExpressionTokens(short size, RecordInputStream in )
- {
- Stack stack = new Stack();
- int pos = 0;
- List arrayPtgs = null;
- while ( pos < size )
- {
- Ptg ptg = Ptg.createPtg( in );
- if (ptg instanceof ArrayPtg) {
- if (arrayPtgs == null)
- arrayPtgs = new ArrayList(5);
- arrayPtgs.add(ptg);
- pos += 8;
- } else pos += ptg.getSize();
- stack.push( ptg );
- }
- if(pos != size) {
- throw new RuntimeException("Ptg array size mismatch");
- }
- if (arrayPtgs != null) {
- for (int i=0;i<arrayPtgs.size();i++) {
- ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
- p.readTokenValues(in);
- }
- }
- return stack;
- }
-
- public static Ptg createPtg(RecordInputStream in) {
- byte id = in.readByte();
-
- if (id < 0x20) {
- return createBasePtg(id, in);
- }
-
- Ptg retval = createClassifiedPtg(id, in);
-
- if (id > 0x60) {
- retval.setClass(CLASS_ARRAY);
- } else if (id > 0x40) {
- retval.setClass(CLASS_VALUE);
- } else {
- retval.setClass(CLASS_REF);
- }
-
- return retval;
-
- }
+public abstract class Ptg implements Cloneable {
+
+ /* convert infix order ptg list to rpn order ptg list
+ * @return List ptgs in RPN order
+ * @param infixPtgs List of ptgs in infix order
+ */
+
+ /* DO NOT REMOVE
+ *we keep this method in case we wish to change the way we parse
+ *It needs a getPrecedence in OperationsPtg
+
+ public static List ptgsToRpn(List infixPtgs) {
+ java.util.Stack operands = new java.util.Stack();
+ java.util.List retval = new java.util.Stack();
+
+ java.util.ListIterator i = infixPtgs.listIterator();
+ Object p;
+ OperationPtg o ;
+ boolean weHaveABracket = false;
+ while (i.hasNext()) {
+ p=i.next();
+ if (p instanceof OperationPtg) {
+ if (p instanceof ParenthesisPtg) {
+ if (!weHaveABracket) {
+ operands.push(p);
+ weHaveABracket = true;
+ } else {
+ o = (OperationPtg) operands.pop();
+ while (!(o instanceof ParenthesisPtg)) {
+ retval.add(o);
+ }
+ weHaveABracket = false;
+ }
+ } else {
+
+ while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative
+ retval.add(operands.pop());
+ }
+ operands.push(p);
+ }
+ } else {
+ retval.add(p);
+ }
+ }
+ while (!operands.isEmpty()) {
+ if (operands.peek() instanceof ParenthesisPtg ){
+ //throw some error
+ } else {
+ retval.add(operands.pop());
+ }
+ }
+ return retval;
+ }
+ */
+
+ /**
+ * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
+ * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
+ */
+ public static Ptg[] readTokens(int size, RecordInputStream in) {
+ Stack temp = createParsedExpressionTokens((short)size, in);
+ return toPtgArray(temp);
+ }
+
+ /**
+ * @deprecated - use readTokens()
+ */
+ public static Stack createParsedExpressionTokens(short size, RecordInputStream in)
+ {
+ Stack stack = new Stack();
+ int pos = 0;
+ List arrayPtgs = null;
+ while ( pos < size )
+ {
+ Ptg ptg = Ptg.createPtg( in );
+ if (ptg instanceof ArrayPtg) {
+ if (arrayPtgs == null)
+ arrayPtgs = new ArrayList(5);
+ arrayPtgs.add(ptg);
+ pos += 8;
+ } else pos += ptg.getSize();
+ stack.push( ptg );
+ }
+ if(pos != size) {
+ throw new RuntimeException("Ptg array size mismatch");
+ }
+ if (arrayPtgs != null) {
+ for (int i=0;i<arrayPtgs.size();i++) {
+ ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+ p.readTokenValues(in);
+ }
+ }
+ return stack;
+ }
+
+ public static Ptg createPtg(RecordInputStream in) {
+ byte id = in.readByte();
+
+ if (id < 0x20) {
+ return createBasePtg(id, in);
+ }
+
+ Ptg retval = createClassifiedPtg(id, in);
+
+ if (id > 0x60) {
+ retval.setClass(CLASS_ARRAY);
+ } else if (id > 0x40) {
+ retval.setClass(CLASS_VALUE);
+ } else {
+ retval.setClass(CLASS_REF);
+ }
+
+ return retval;
+ }
private static Ptg createClassifiedPtg(byte id, RecordInputStream in) {
int baseId = id & 0x1F | 0x20;
- switch (baseId) {
- case FuncPtg.sid: return new FuncPtg(in); // 0x21, 0x41, 0x61
- case FuncVarPtg.sid: return new FuncVarPtg(in); // 0x22, 0x42, 0x62
- case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63
-
- case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66
- case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67
- case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69
- case RefErrorPtg.sid: return new RefErrorPtg(in);// 0x2a, 0x4a, 0x6a
- case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b
-
- case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79
- case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a
- case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b
- case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c
- case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
- }
-
-
- switch (id) {
- // TODO - why are specific subclasses needed for these Ptgs?
- case ArrayPtg.sid: return new ArrayPtg(in); // 0x20
- case ArrayPtgV.sid: return new ArrayPtgV(in); // 0x40
- case ArrayPtgA.sid: return new ArrayPtgA(in); // 0x60
-
- case ReferencePtg.sid: return new ReferencePtg(in);// 0x24
- case RefAPtg.sid: return new RefAPtg(in); // 0x64
- case RefVPtg.sid: return new RefVPtg(in); // 0x44
-
- case RefNAPtg.sid: return new RefNAPtg(in); // 0x6C
- case RefNPtg.sid: return new RefNPtg(in); // 0x2C
- case RefNVPtg.sid: return new RefNVPtg(in); // 0x4C
-
- case AreaPtg.sid: return new AreaPtg(in); // 0x25
- case AreaVPtg.sid: return new AreaVPtg(in); // 0x45
- case AreaAPtg.sid: return new AreaAPtg(in); // 0x65
-
- case AreaNAPtg.sid: return new AreaNAPtg(in); // 0x6D
- case AreaNPtg.sid: return new AreaNPtg(in); // 0x2D
- case AreaNVPtg.sid: return new AreaNVPtg(in); // 0x4D
-
- }
- throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
- Integer.toHexString(id) + " (" + ( int ) id + ")");
+ switch (baseId) {
+ case ArrayPtg.sid: return new ArrayPtg(in); // 0x20, 0x40, 0x60
+ case FuncPtg.sid: return new FuncPtg(in); // 0x21, 0x41, 0x61
+ case FuncVarPtg.sid: return new FuncVarPtg(in); // 0x22, 0x42, 0x62
+ case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63
+ case RefPtg.sid: return new RefPtg(in); // 0x24, 0x44, 0x64
+ case AreaPtg.sid: return new AreaPtg(in); // 0x25, 0x45, 0x65
+ case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66
+ case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67
+ case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69
+ case RefErrorPtg.sid: return new RefErrorPtg(in);// 0x2a, 0x4a, 0x6a
+ case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b
+ case RefNPtg.sid: return new RefNPtg(in); // 0x2c, 0x4c, 0x6c
+ case AreaNPtg.sid: return new AreaNPtg(in); // 0x2d, 0x4d, 0x6d
+
+ case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79
+ case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a
+ case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b
+ case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c
+ case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
+ }
+ throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
+ Integer.toHexString(id) + " (" + ( int ) id + ")");
}
private static Ptg createBasePtg(byte id, RecordInputStream in) {
switch(id) {
- case 0x00: return new UnknownPtg(); // TODO - not a real Ptg
- case ExpPtg.sid: return new ExpPtg(in); // 0x01
- case AddPtg.sid: return new AddPtg(in); // 0x03
- case SubtractPtg.sid: return new SubtractPtg(in); // 0x04
- case MultiplyPtg.sid: return new MultiplyPtg(in); // 0x05
- case DividePtg.sid: return new DividePtg(in); // 0x06
- case PowerPtg.sid: return new PowerPtg(in); // 0x07
- case ConcatPtg.sid: return new ConcatPtg(in); // 0x08
- case LessThanPtg.sid: return new LessThanPtg(in); // 0x09
- case LessEqualPtg.sid: return new LessEqualPtg(in); // 0x0a
- case EqualPtg.sid: return new EqualPtg(in); // 0x0b
- case GreaterEqualPtg.sid: return new GreaterEqualPtg(in);// 0x0c
- case GreaterThanPtg.sid: return new GreaterThanPtg(in); // 0x0d
- case NotEqualPtg.sid: return new NotEqualPtg(in); // 0x0e
- case IntersectionPtg.sid: return new IntersectionPtg(in);// 0x0f
- case UnionPtg.sid: return new UnionPtg(in); // 0x10
- case RangePtg.sid: return new RangePtg(in); // 0x11
- case UnaryPlusPtg.sid: return new UnaryPlusPtg(in); // 0x12
- case UnaryMinusPtg.sid: return new UnaryMinusPtg(in); // 0x13
- case PercentPtg.sid: return new PercentPtg(in); // 0x14
- case ParenthesisPtg.sid: return new ParenthesisPtg(in); // 0x15
- case MissingArgPtg.sid: return new MissingArgPtg(in); // 0x16
- case StringPtg.sid: return new StringPtg(in); // 0x17
- case AttrPtg.sid:
- case 0x1a: return new AttrPtg(in); // 0x19
- case ErrPtg.sid: return new ErrPtg(in); // 0x1c
- case BoolPtg.sid: return new BoolPtg(in); // 0x1d
- case IntPtg.sid: return new IntPtg(in); // 0x1e
- case NumberPtg.sid: return new NumberPtg(in); // 0x1f
+ case 0x00: return new UnknownPtg(); // TODO - not a real Ptg
+ case ExpPtg.sid: return new ExpPtg(in); // 0x01
+ case AddPtg.sid: return AddPtg.instance; // 0x03
+ case SubtractPtg.sid: return SubtractPtg.instance; // 0x04
+ case MultiplyPtg.sid: return MultiplyPtg.instance; // 0x05
+ case DividePtg.sid: return DividePtg.instance; // 0x06
+ case PowerPtg.sid: return PowerPtg.instance; // 0x07
+ case ConcatPtg.sid: return ConcatPtg.instance; // 0x08
+ case LessThanPtg.sid: return LessThanPtg.instance; // 0x09
+ case LessEqualPtg.sid: return LessEqualPtg.instance; // 0x0a
+ case EqualPtg.sid: return EqualPtg.instance; // 0x0b
+ case GreaterEqualPtg.sid: return GreaterEqualPtg.instance;// 0x0c
+ case GreaterThanPtg.sid: return GreaterThanPtg.instance; // 0x0d
+ case NotEqualPtg.sid: return NotEqualPtg.instance; // 0x0e
+ case IntersectionPtg.sid: return IntersectionPtg.instance;// 0x0f
+ case UnionPtg.sid: return UnionPtg.instance; // 0x10
+ case RangePtg.sid: return RangePtg.instance; // 0x11
+ case UnaryPlusPtg.sid: return UnaryPlusPtg.instance; // 0x12
+ case UnaryMinusPtg.sid: return UnaryMinusPtg.instance; // 0x13
+ case PercentPtg.sid: return PercentPtg.instance; // 0x14
+ case ParenthesisPtg.sid: return ParenthesisPtg.instance; // 0x15
+ case MissingArgPtg.sid: return MissingArgPtg.instance; // 0x16
+
+ case StringPtg.sid: return new StringPtg(in); // 0x17
+ case AttrPtg.sid:
+ case 0x1a: return new AttrPtg(in); // 0x19
+ case ErrPtg.sid: return new ErrPtg(in); // 0x1c
+ case BoolPtg.sid: return new BoolPtg(in); // 0x1d
+ case IntPtg.sid: return new IntPtg(in); // 0x1e
+ case NumberPtg.sid: return new NumberPtg(in); // 0x1f
}
throw new RuntimeException("Unexpected base token id (" + id + ")");
}
- /**
- *
- *
- */
+ /**
+ *
+ *
+ */
public static int getEncodedSize(Stack ptgs) {
return getEncodedSize(toPtgArray(ptgs));
}
+ /**
+ * @return a distinct copy of this <tt>Ptg</tt> if the class is mutable, or the same instance
+ * if the class is immutable.
+ */
+ public final Ptg copy() {
+ // TODO - all base tokens are logically immutable, but AttrPtg needs some clean-up
+ if (this instanceof ValueOperatorPtg) {
+ return this;
+ }
+ if (this instanceof ScalarConstantPtg) {
+ return this;
+ }
+ return (Ptg) clone();
+ }
+
+ protected Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
private static Ptg[] toPtgArray(List l) {
Ptg[] result = new Ptg[l.size()];
l.toArray(result);
return result;
}
- private static Stack createStack(Ptg[] formulaTokens) {
+ private static Stack createStack(Ptg[] formulaTokens) {
Stack result = new Stack();
for (int i = 0; i < formulaTokens.length; i++) {
result.add(formulaTokens[i]);
}
return result;
}
+ /**
+ * Writes the ptgs to the data buffer, starting at the specified offset.
+ *
+ * <br/>
+ * The 2 byte encode length field is <b>not</b> written by this method.
+ * @return number of bytes written
+ */
+ public static int serializePtgs(Ptg[] ptgs, byte[] data, int offset) {
+ return serializePtgStack(createStack(ptgs), data, offset);
+ }
+
+ /**
+ * @deprecated use serializePtgs()
+ */
+ public static int serializePtgStack(Stack expression, byte[] array, int offset) {
+ int pos = 0;
+ int size = 0;
+ if (expression != null)
+ size = expression.size();
+
+ List arrayPtgs = null;
+
+ for (int k = 0; k < size; k++) {
+ Ptg ptg = ( Ptg ) expression.get(k);
+
+ ptg.writeBytes(array, pos + offset);
+ if (ptg instanceof ArrayPtg) {
+ if (arrayPtgs == null)
+ arrayPtgs = new ArrayList(5);
+ arrayPtgs.add(ptg);
+ pos += 8;
+ } else pos += ptg.getSize();
+ }
+ if (arrayPtgs != null) {
+ for (int i=0;i<arrayPtgs.size();i++) {
+ ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+ pos += p.writeTokenValueBytes(array, pos + offset);
+ }
+ }
+ return pos;
+ }
- public static int serializePtgStack(Stack expression, byte[] array, int offset) {
- int pos = 0;
- int size = 0;
- if (expression != null)
- size = expression.size();
-
- List arrayPtgs = null;
-
- for (int k = 0; k < size; k++) {
- Ptg ptg = ( Ptg ) expression.get(k);
-
- ptg.writeBytes(array, pos + offset);
- if (ptg instanceof ArrayPtg) {
- if (arrayPtgs == null)
- arrayPtgs = new ArrayList(5);
- arrayPtgs.add(ptg);
- pos += 8;
- } else pos += ptg.getSize();
- }
- if (arrayPtgs != null) {
- for (int i=0;i<arrayPtgs.size();i++) {
- ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
- pos += p.writeTokenValueBytes(array, pos + offset);
- }
- }
- return pos;
- }
-
- /**
- * @return the encoded length of this Ptg, including the initial Ptg type identifier byte.
- */
- public abstract int getSize();
-
- /**
- * @return the encoded length of this Ptg, not including the initial Ptg type identifier byte.
- */
+ /**
+ * @return the encoded length of this Ptg, including the initial Ptg type identifier byte.
+ */
+ public abstract int getSize();
+
+ /**
+ * @return the encoded length of this Ptg, not including the initial Ptg type identifier byte.
+ */
// public abstract int getDataSize();
- public final byte [] getBytes()
- {
- int size = getSize();
- byte[] bytes = new byte[ size ];
-
- writeBytes(bytes, 0);
- return bytes;
- }
- /** write this Ptg to a byte array*/
- public abstract void writeBytes(byte [] array, int offset);
-
- /**
- * return a string representation of this token alone
- */
- public abstract String toFormulaString(Workbook book);
- /**
- * dump a debug representation (hexdump) to a string
- */
- public String toDebugString() {
- byte[] ba = new byte[getSize()];
- String retval=null;
- writeBytes(ba,0);
- try {
- retval = org.apache.poi.util.HexDump.dump(ba,0,0);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return retval;
- }
-
- /** Overridden toString method to ensure object hash is not printed.
- * This helps get rid of gratuitous diffs when comparing two dumps
- * Subclasses may output more relevant information by overriding this method
- **/
- public String toString(){
- return this.getClass().toString();
- }
-
- public static final byte CLASS_REF = 0x00;
- public static final byte CLASS_VALUE = 0x20;
- public static final byte CLASS_ARRAY = 0x40;
-
- protected byte ptgClass = CLASS_REF; //base ptg
-
- public void setClass(byte thePtgClass) {
- if (isBaseToken()) {
- throw new RuntimeException("setClass should not be called on a base token");
- }
- ptgClass = thePtgClass;
- }
-
- /**
- * @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
- */
- public byte getPtgClass() {
- return ptgClass;
- }
-
- public abstract byte getDefaultOperandClass();
-
- public abstract Object clone();
-
-
- /**
- * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
- */
- public abstract boolean isBaseToken();
+ public final byte [] getBytes()
+ {
+ int size = getSize();
+ byte[] bytes = new byte[ size ];
+
+ writeBytes(bytes, 0);
+ return bytes;
+ }
+ /** write this Ptg to a byte array*/
+ public abstract void writeBytes(byte [] array, int offset);
+
+ /**
+ * return a string representation of this token alone
+ */
+ public abstract String toFormulaString(Workbook book);
+ /**
+ * dump a debug representation (hexdump) to a string
+ */
+ public final String toDebugString() {
+ byte[] ba = new byte[getSize()];
+ String retval=null;
+ writeBytes(ba,0);
+ try {
+ retval = org.apache.poi.util.HexDump.dump(ba,0,0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return retval;
+ }
+
+ /** Overridden toString method to ensure object hash is not printed.
+ * This helps get rid of gratuitous diffs when comparing two dumps
+ * Subclasses may output more relevant information by overriding this method
+ **/
+ public String toString(){
+ return this.getClass().toString();
+ }
+
+ public static final byte CLASS_REF = 0x00;
+ public static final byte CLASS_VALUE = 0x20;
+ public static final byte CLASS_ARRAY = 0x40;
+
+ private byte ptgClass = CLASS_REF; //base ptg
+
+ public final void setClass(byte thePtgClass) {
+ if (isBaseToken()) {
+ throw new RuntimeException("setClass should not be called on a base token");
+ }
+ ptgClass = thePtgClass;
+ }
+
+ /**
+ * @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
+ */
+ public final byte getPtgClass() {
+ return ptgClass;
+ }
+
+ public abstract byte getDefaultOperandClass();
+
+ /**
+ * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
+ */
+ public abstract boolean isBaseToken();
}
package org.apache.poi.hssf.record.formula;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* @author Daniel Noll (daniel at nuix dot com dot au)
public final static int SIZE = 1;
public final static byte sid = 0x11;
- public RangePtg()
- {
- }
+ public static final OperationPtg instance = new RangePtg();
- public RangePtg(RecordInputStream in)
- {
- // No contents
+ private RangePtg() {
+ // enforce singleton
}
public final boolean isBaseToken() {
return true;
}
-
public int getSize()
{
return SIZE;
array[ offset + 0 ] = sid;
}
- public Object clone()
- {
- return new RangePtg();
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- /** Implementation of method from Ptg */
public String toFormulaString(Workbook book)
{
return ":";
}
public void writeBytes(byte [] array, int offset) {
- array[ 0 + offset ] = (byte) (sid + ptgClass);
+ array[ 0 + offset ] = (byte) (sid + getPtgClass());
LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
LittleEndian.putShort(array, 3 + offset , (short)getRow());
LittleEndian.putShort(array, 5 + offset , (short)getColumnRaw());
return retval.toString();
}
- public byte getDefaultOperandClass() {return Ptg.CLASS_REF;}
-
- public Object clone() {
- Ref3DPtg ptg = new Ref3DPtg();
- ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
- ptg.field_2_row = field_2_row;
- ptg.field_3_column = field_3_column;
- ptg.setClass(ptgClass);
- return ptg;
- }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * RefNAPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class RefAPtg extends ReferencePtg {
- public final static byte sid = 0x64;
-
- protected RefAPtg() {
- super();
- }
-
- public RefAPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
- super(row, column, isRowRelative, isColumnRelative);
- }
-
- public RefAPtg(RecordInputStream in)
- {
- super(in);
- }
-
-
- public String getRefPtgName() {
- return "RefAPtg";
- }
-
- public Object clone() {
- RefAPtg ptg = new RefAPtg();
- ptg.setRow(getRow());
- ptg.setColumnRaw(getColumnRaw());
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.LittleEndian;
/**
* RefError - handles deleted cell reference
public final static byte sid = 0x2a;
private int field_1_reserved;
- private RefErrorPtg() {
- //Required for clone methods
- }
-
public RefErrorPtg(RecordInputStream in)
{
field_1_reserved = in.readInt();
public void writeBytes(byte [] array, int offset)
{
- array[offset] = (byte) (sid + ptgClass);
+ array[offset] = (byte) (sid + getPtgClass());
LittleEndian.putInt(array,offset+1,field_1_reserved);
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
}
-
- public Object clone() {
- RefErrorPtg ptg = new RefErrorPtg();
- ptg.field_1_reserved = field_1_reserved;
- ptg.setClass(ptgClass);
- return ptg;
- }
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * RefNAPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class RefNAPtg extends ReferencePtg
-{
- public final static byte sid = 0x6C;
-
- protected RefNAPtg() {
- //Required for clone methods
- }
-
- public RefNAPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getRefPtgName() {
- return "RefNAPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
-
- public Object clone() {
- throw notImplemented();
- }
-}
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
/**
* RefNPtg
* @author Jason Height (jheight at apache dot com)
*/
-public final class RefNPtg extends ReferencePtg
-{
+public final class RefNPtg extends RefPtgBase {
public final static byte sid = 0x2C;
- protected RefNPtg() {
- //Required for clone methods
- }
-
/** Creates new ValueReferencePtg */
- public RefNPtg(RecordInputStream in)
- {
+ public RefNPtg(RecordInputStream in) {
super(in);
}
-
- public String getRefPtgName() {
- return "RefNPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
-
- public Object clone() {
- throw notImplemented();
+
+ protected byte getSid() {
+ return sid;
}
}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * RefNVPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-
-public final class RefNVPtg extends ReferencePtg {
- public final static byte sid = 0x4C;
-
- protected RefNVPtg() {
- //Required for clone methods
- }
-
- /** Creates new ValueReferencePtg */
-
- public RefNVPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getRefPtgName() {
- return "RefNVPtg";
- }
-
- public String toFormulaString(Workbook book)
- {
- throw notImplemented();
- }
-
- public Object clone() {
- throw notImplemented();
- }
-}
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record.formula;\r
+\r
+import org.apache.poi.hssf.record.RecordInputStream;\r
+\r
+/**\r
+ * ReferencePtg - handles references (such as A1, A2, IA4)\r
+ * @author Andrew C. Oliver (acoliver@apache.org)\r
+ * @author Jason Height (jheight at chariot dot net dot au)\r
+ */\r
+public final class RefPtg extends RefPtgBase {\r
+ public final static byte sid = 0x24;\r
+\r
+ /**\r
+ * Takes in a String representation of a cell reference and fills out the\r
+ * numeric fields.\r
+ */\r
+ public RefPtg(String cellref) {\r
+ super(cellref);\r
+ }\r
+\r
+ public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {\r
+ setRow(row);\r
+ setColumn(column);\r
+ setRowRelative(isRowRelative);\r
+ setColRelative(isColumnRelative);\r
+ }\r
+\r
+ public RefPtg(RecordInputStream in) {\r
+ super(in);\r
+ }\r
+\r
+ protected byte getSid() {\r
+ return sid;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * ReferencePtgBase - handles references (such as A1, A2, IA4)
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class RefPtgBase extends OperandPtg {
+
+ private final static int SIZE = 5;
+ private final static int MAX_ROW_NUMBER = 65536;
+
+ /** The row index - zero based unsigned 16 bit value */
+ private int field_1_row;
+ /** Field 2
+ * - lower 8 bits is the zero based unsigned byte column index
+ * - bit 16 - isRowRelative
+ * - bit 15 - isColumnRelative
+ */
+ private int field_2_col;
+ private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
+ private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
+ private static final BitField column = BitFieldFactory.getInstance(0x00FF);
+
+ protected RefPtgBase() {
+ //Required for clone methods
+ }
+
+ /**
+ * Takes in a String representation of a cell reference and fills out the
+ * numeric fields.
+ */
+ protected RefPtgBase(String cellref) {
+ CellReference c= new CellReference(cellref);
+ setRow(c.getRow());
+ setColumn(c.getCol());
+ setColRelative(!c.isColAbsolute());
+ setRowRelative(!c.isRowAbsolute());
+ }
+
+ protected RefPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ setRow(row);
+ setColumn(column);
+ setRowRelative(isRowRelative);
+ setColRelative(isColumnRelative);
+ }
+
+ protected RefPtgBase(RecordInputStream in) {
+ field_1_row = in.readUShort();
+ field_2_col = in.readUShort();
+ }
+
+ public final String toString() {
+ CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(cr.formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public final void writeBytes(byte [] array, int offset) {
+ array[offset] = (byte) (getSid() + getPtgClass());
+
+ LittleEndian.putShort(array, offset+1, (short)field_1_row);
+ LittleEndian.putShort(array, offset+3, (short)field_2_col);
+ }
+
+ protected abstract byte getSid();
+
+ public final void setRow(int row) {
+ if(row < 0 || row >= MAX_ROW_NUMBER) {
+ throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
+ }
+ field_1_row = row;
+ }
+
+ /**
+ * Returns the row number as a short, which will be
+ * wrapped (negative) for values between 32769 and 65535
+ */
+ public final int getRow(){
+ return field_1_row;
+ }
+ /**
+ * Returns the row number as an int, between 0 and 65535
+ */
+ public final int getRowAsInt() {
+ return field_1_row;
+ }
+
+ public final boolean isRowRelative() {
+ return rowRelative.isSet(field_2_col);
+ }
+
+ public final void setRowRelative(boolean rel) {
+ field_2_col=rowRelative.setBoolean(field_2_col,rel);
+ }
+
+ public final boolean isColRelative() {
+ return colRelative.isSet(field_2_col);
+ }
+
+ public final void setColRelative(boolean rel) {
+ field_2_col=colRelative.setBoolean(field_2_col,rel);
+ }
+
+ public final void setColumnRawX(int col) { // TODO
+ field_2_col = col;
+ }
+
+ public int getColumnRawX() { // TODO
+ return field_2_col;
+ }
+
+ public final void setColumn(int col) {
+ if(col < 0 || col >= 0x100) {
+ throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
+ }
+ field_2_col = column.setValue(field_2_col, col);
+ }
+
+ public final int getColumn() {
+ return column.getValue(field_2_col);
+ }
+
+ public final int getSize() {
+ return SIZE;
+ }
+
+ public final String toFormulaString(Workbook book) {
+ //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
+ return (new CellReference(getRowAsInt(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString();
+ }
+
+ public final byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * RefVPtg
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public final class RefVPtg extends ReferencePtg {
- public final static byte sid = 0x44;
-
- protected RefVPtg() {
- super();
- }
-
- public RefVPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
- super(row, column, isRowRelative, isColumnRelative);
- setClass(CLASS_VALUE);
- }
-
-
- /** Creates new ValueReferencePtg */
-
- public RefVPtg(RecordInputStream in)
- {
- super(in);
- }
-
- public String getRefPtgName() {
- return "RefVPtg";
- }
-
- public Object clone() {
- RefVPtg ptg = new RefVPtg();
- ptg.setRow(getRow());
- ptg.setColumnRaw(getColumnRaw());
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.formula;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
-
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * ReferencePtg - handles references (such as A1, A2, IA4)
- * @author Andrew C. Oliver (acoliver@apache.org)
- * @author Jason Height (jheight at chariot dot net dot au)
- */
-public class ReferencePtg extends OperandPtg {
- /**
- * TODO - (May-2008) fix subclasses of ReferencePtg 'RefN~' which are used in shared formulas.
- * (See bugzilla 44921)
- * The 'RefN~' instances do not work properly, and are expected to be converted by
- * SharedFormulaRecord.convertSharedFormulas().
- * This conversion currently does not take place for formulas of named ranges, conditional
- * format rules and data validation rules.
- * Furthermore, conversion is probably not appropriate in those instances.
- */
- protected final RuntimeException notImplemented() {
- return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
- }
-
- private final static int SIZE = 5;
- public final static byte sid = 0x24;
- private final static int MAX_ROW_NUMBER = 65536;
-
- /** The row index - zero based unsigned 16 bit value */
- private int field_1_row;
- /** Field 2
- * - lower 8 bits is the zero based unsigned byte column index
- * - bit 16 - isRowRelative
- * - bit 15 - isColumnRelative
- */
- private int field_2_col;
- private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
- private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
- private static final BitField column = BitFieldFactory.getInstance(0x00FF);
-
- protected ReferencePtg() {
- //Required for clone methods
- }
-
- /**
- * Takes in a String represnetation of a cell reference and fills out the
- * numeric fields.
- */
- public ReferencePtg(String cellref) {
- CellReference c= new CellReference(cellref);
- setRow(c.getRow());
- setColumn(c.getCol());
- setColRelative(!c.isColAbsolute());
- setRowRelative(!c.isRowAbsolute());
- }
-
- public ReferencePtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
- setRow(row);
- setColumn(column);
- setRowRelative(isRowRelative);
- setColRelative(isColumnRelative);
- }
-
- /** Creates new ValueReferencePtg */
-
- public ReferencePtg(RecordInputStream in)
- {
- field_1_row = in.readUShort();
- field_2_col = in.readUShort();
- }
-
- public String getRefPtgName() {
- return "ReferencePtg";
- }
-
- public String toString() {
- CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName());
- sb.append(" [");
- sb.append(cr.formatAsString());
- sb.append("]");
- return sb.toString();
- }
-
- public void writeBytes(byte [] array, int offset)
- {
- array[offset] = (byte) (sid + ptgClass);
-
- LittleEndian.putShort(array, offset+1, (short)field_1_row);
- LittleEndian.putShort(array, offset+3, (short)field_2_col);
- }
-
- public void setRow(int row)
- {
- if(row < 0 || row >= MAX_ROW_NUMBER) {
- throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
- }
- field_1_row = row;
- }
-
- /**
- * Returns the row number as a short, which will be
- * wrapped (negative) for values between 32769 and 65535
- */
- public int getRow()
- {
- return field_1_row;
- }
- /**
- * Returns the row number as an int, between 0 and 65535
- */
- public int getRowAsInt()
- {
- if(field_1_row < 0) {
- return field_1_row + MAX_ROW_NUMBER;
- }
- return field_1_row;
- }
-
- public boolean isRowRelative()
- {
- return rowRelative.isSet(field_2_col);
- }
-
- public void setRowRelative(boolean rel) {
- field_2_col=rowRelative.setBoolean(field_2_col,rel);
- }
-
- public boolean isColRelative()
- {
- return colRelative.isSet(field_2_col);
- }
-
- public void setColRelative(boolean rel) {
- field_2_col=colRelative.setBoolean(field_2_col,rel);
- }
-
- public void setColumnRaw(int col)
- {
- field_2_col = col;
- }
-
- public int getColumnRaw()
- {
- return field_2_col;
- }
-
- public void setColumn(int col)
- {
- if(col < 0 || col > 0x100) {
- throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
- }
- field_2_col = column.setValue(field_2_col, col);
- }
-
- public int getColumn() {
- return column.getValue(field_2_col);
- }
-
- public int getSize()
- {
- return SIZE;
- }
-
- public String toFormulaString(Workbook book)
- {
- //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
- return (new CellReference(getRowAsInt(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString();
- }
-
- public byte getDefaultOperandClass() {
- return Ptg.CLASS_REF;
- }
-
- public Object clone() {
- ReferencePtg ptg = new ReferencePtg();
- ptg.field_1_row = field_1_row;
- ptg.field_2_col = field_2_col;
- ptg.setClass(ptgClass);
- return ptg;
- }
-}
public final byte getDefaultOperandClass() {\r
return Ptg.CLASS_VALUE;\r
}\r
- \r
}\r
* NOTE: OO doc says 16bit length, but BiffViewer says 8 Book says something
* totally different, so don't look there!
*/
- private int field_1_length;
- private byte field_2_options;
- private String field_3_string;
+ private final int field_1_length;
+ private final byte field_2_options;
+ private final String field_3_string;
- private StringPtg() {
- // Required for clone methods
- }
-
- /** Create a StringPtg from a byte array read from disk */
+ /** Create a StringPtg from a stream */
public StringPtg(RecordInputStream in) {
field_1_length = in.readUByte();
field_2_options = in.readByte();
throw new IllegalArgumentException(
"String literals in formulas can't be bigger than 255 characters ASCII");
}
- field_2_options = 0;
- field_2_options = (byte) fHighByte.setBoolean(field_2_options, StringUtil
- .hasMultibyte(value));
+ field_2_options = (byte) fHighByte.setBoolean(0, StringUtil.hasMultibyte(value));
field_3_string = value;
field_1_length = value.length(); // for the moment, we support only ASCII strings in formulas we create
}
return sb.toString();
}
- public Object clone() {
- StringPtg ptg = new StringPtg();
- ptg.field_1_length = field_1_length;
- ptg.field_2_options = field_2_options;
- ptg.field_3_string = field_3_string;
- return ptg;
- }
-
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
package org.apache.poi.hssf.record.formula;
-import java.util.List;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
*
* @author andy
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class SubtractPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x04;
- public SubtractPtg()
- {
- }
-
- public SubtractPtg(RecordInputStream in)
- {
+ public static final ValueOperatorPtg instance = new SubtractPtg();
- // doesn't need anything
+ private SubtractPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
+
+ protected byte getSid() {
+ return sid;
}
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 2;
}
-
- public String toFormulaString(Workbook book)
- {
- return "-";
- }
-
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 1 ]);
return buffer.toString();
}
-
- public Object clone() {
- return new SubtractPtg();
- }
}
package org.apache.poi.hssf.record.formula;
-import java.util.List;
-
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Unary Plus operator
* does not have any effect on the operand
* @author Avik Sengupta
*/
-
public final class UnaryMinusPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x13;
private final static String MINUS = "-";
- /** Creates new AddPtg */
+ public static final ValueOperatorPtg instance = new UnaryMinusPtg();
- public UnaryMinusPtg()
- {
- }
-
- public UnaryMinusPtg(RecordInputStream in)
- {
-
- // doesn't need anything
+ private UnaryMinusPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return this.TYPE_UNARY;
+ protected byte getSid() {
+ return sid;
}
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 1;
}
- /** Implementation of method from Ptg */
- public String toFormulaString(Workbook book)
- {
- return "+";
- }
-
/** implementation of method from OperationsPtg*/
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0]);
return buffer.toString();
}
-
- public Object clone() {
- return new UnaryPlusPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
-import java.util.List;
-
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
/**
* Unary Plus operator
* does not have any effect on the operand
* @author Avik Sengupta
*/
-
public final class UnaryPlusPtg extends ValueOperatorPtg {
- public final static int SIZE = 1;
public final static byte sid = 0x12;
private final static String ADD = "+";
- /** Creates new AddPtg */
+ public static final ValueOperatorPtg instance = new UnaryPlusPtg();
- public UnaryPlusPtg()
- {
- }
-
- public UnaryPlusPtg(RecordInputStream in)
- {
-
- // doesn't need anything
+ private UnaryPlusPtg() {
+ // enforce singleton
}
-
- public void writeBytes(byte [] array, int offset)
- {
- array[ offset + 0 ] = sid;
- }
-
- public int getSize()
- {
- return SIZE;
- }
-
- public int getType()
- {
- return this.TYPE_UNARY;
+ protected byte getSid() {
+ return sid;
}
- public int getNumberOfOperands()
- {
+ public int getNumberOfOperands() {
return 1;
}
- /** Implementation of method from Ptg */
- public String toFormulaString(Workbook book)
- {
- return "+";
- }
-
/** implementation of method from OperationsPtg*/
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0]);
return buffer.toString();
}
-
- public Object clone() {
- return new UnaryPlusPtg();
- }
-
}
package org.apache.poi.hssf.record.formula;
import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
/**
* @author Glen Stampoultzis (glens at apache.org)
public final class UnionPtg extends OperationPtg {
public final static byte sid = 0x10;
+ public static final OperationPtg instance = new UnionPtg();
- public UnionPtg()
- {
- }
-
- public UnionPtg(RecordInputStream in)
- {
- // doesn't need anything
+ private UnionPtg() {
+ // enforce singleton
}
public final boolean isBaseToken() {
array[ offset + 0 ] = sid;
}
- public Object clone()
- {
- return new UnionPtg();
- }
-
- public int getType()
- {
- return TYPE_BINARY;
- }
-
- /** Implementation of method from Ptg */
public String toFormulaString(Workbook book)
{
return ",";
package org.apache.poi.hssf.record.formula;
+import org.apache.poi.ss.usermodel.Workbook;
+
/**
* Common superclass of all value operators.
* Subclasses include all unary and binary operators except for the reference operators (IntersectionPtg, RangePtg, UnionPtg)
public abstract class ValueOperatorPtg extends OperationPtg {
/**
- * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classifed)
+ * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classified)
*/
public final boolean isBaseToken() {
return true;
}
+
public final byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}
+
+ public final void writeBytes(byte[] array, int offset) {
+ array[offset + 0] = getSid();
+ }
+
+ protected abstract byte getSid();
+
+ public final int getSize() {
+ return 1;
+ }
+ public final String toFormulaString(Workbook book) {
+ // TODO - prune this method out of the hierarchy
+ throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
+ }
}
package org.apache.poi.hssf.record.formula.eval;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
/**
* @author adeshmukh
public final class Ref2DEval implements RefEval {
private final ValueEval value;
- private final ReferencePtg delegate;
+ private final RefPtg delegate;
- public Ref2DEval(ReferencePtg ptg, ValueEval ve) {
+ public Ref2DEval(RefPtg ptg, ValueEval ve) {
if(ve == null) {
throw new IllegalArgumentException("ve must not be null");
}
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
+import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Iterator;
public static final int PICTURE_TYPE_PNG = HSSFWorkbook.PICTURE_TYPE_PNG; // PNG
public static final int PICTURE_TYPE_DIB = HSSFWorkbook.PICTURE_TYPE_DIB; // Windows DIB
+ /**
+ * width of 1px in columns with default width in units of 1/256 of a character width
+ */
+ private static final float PX_DEFAULT = 32.00f;
+ /**
+ * width of 1px in columns with overridden width in units of 1/256 of a character width
+ */
+ private static final float PX_MODIFIED = 36.56f;
+
+ /**
+ * Height of 1px of a row
+ */
+ private static final int PX_ROW = 15;
+
int pictureIndex;
HSSFPatriarch patriarch;
* @since POI 3.0.2
*/
public HSSFClientAnchor getPreferredSize(){
- HSSFClientAnchor anchor = new HSSFClientAnchor();
-
- EscherBSERecord bse = (EscherBSERecord)patriarch.sheet.book.getBSERecord(pictureIndex);
- byte[] data = bse.getBlipRecord().getPicturedata();
- int type = bse.getBlipTypeWin32();
- switch (type){
- //we can calculate the preferred size only for JPEG and PNG
- //other formats like WMF, EMF and PICT are not supported in Java
- case HSSFWorkbook.PICTURE_TYPE_JPEG:
- case HSSFWorkbook.PICTURE_TYPE_PNG:
- BufferedImage img = null;
- ImageReader r = null;
- try {
- //read the image using javax.imageio.*
- ImageInputStream iis = ImageIO.createImageInputStream( new ByteArrayInputStream(data) );
- Iterator i = ImageIO.getImageReaders( iis );
- r = (ImageReader) i.next();
- r.setInput( iis );
- img = r.read(0);
-
- int[] dpi = getResolution(r);
- int imgWidth = img.getWidth()*96/dpi[0];
- int imgHeight = img.getHeight()*96/dpi[1];
+ HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
- //Excel measures cells in units of 1/256th of a character width.
- //The cell width calculated based on this info is always "off".
- //A better approach seems to be to use empirically obtained cell width and row height
- int cellwidth = 64;
- int rowheight = 17;
+ Dimension size = getImageDimension();
- int col2 = imgWidth/cellwidth;
- int row2 = imgHeight/rowheight;
+ float w = 0;
- int dx2 = (int)((float)(imgWidth % cellwidth)/cellwidth * 1024);
- int dy2 = (int)((float)(imgHeight % rowheight)/rowheight * 256);
+ //space in the leftmost cell
+ w += getColumnWidthInPixels(anchor.col1)*(1 - anchor.dx1/1024);
+ short col2 = (short)(anchor.col1 + 1);
+ int dx2 = 0;
- anchor.setCol2((short)col2);
- anchor.setDx2(dx2);
+ while(w < size.width){
+ w += getColumnWidthInPixels(col2++);
+ }
- anchor.setRow2(row2);
- anchor.setDy2(dy2);
+ if(w > size.width) {
+ //calculate dx2, offset in the rightmost cell
+ col2--;
+ float cw = getColumnWidthInPixels(col2);
+ float delta = w - size.width;
+ dx2 = (int)((cw-delta)/cw*1024);
+ }
+ anchor.col2 = col2;
+ anchor.dx2 = dx2;
- } catch (IOException e){
- //silently return if ImageIO failed to read the image
- log.log(POILogger.WARN, e);
- img = null;
- }
+ float h = 0;
+ h += (1 - anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
+ int row2 = anchor.row1 + 1;
+ int dy2 = 0;
- break;
+ while(h < size.height){
+ h += getRowHeightInPixels(row2++);
+ }
+ if(h > size.height) {
+ row2--;
+ float ch = getRowHeightInPixels(row2);
+ float delta = h - size.height;
+ dy2 = (int)((ch-delta)/ch*256);
}
+ anchor.row2 = row2;
+ anchor.dy2 = dy2;
+
return anchor;
}
+ private float getColumnWidthInPixels(short column){
+
+ short cw = patriarch.sheet.getColumnWidth(column);
+ float px = getPixelWidth(column);
+
+ return cw/px;
+ }
+
+ private float getRowHeightInPixels(int i){
+
+ HSSFRow row = patriarch.sheet.getRow(i);
+ float height;
+ if(row != null) height = row.getHeight();
+ else height = patriarch.sheet.getDefaultRowHeight();
+
+ return height/PX_ROW;
+ }
+
+ private float getPixelWidth(short column){
+
+ int def = patriarch.sheet.getDefaultColumnWidth()*256;
+ short cw = patriarch.sheet.getColumnWidth(column);
+
+ return cw == def ? PX_DEFAULT : PX_MODIFIED;
+ }
+
/**
* The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
* Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
return new int[]{hdpi, vdpi};
}
+ /**
+ * Return the dimension of this image
+ *
+ * @return image dimension
+ */
+ public Dimension getImageDimension(){
+ EscherBSERecord bse = patriarch.sheet.book.getBSERecord(pictureIndex);
+ byte[] data = bse.getBlipRecord().getPicturedata();
+ int type = bse.getBlipTypeWin32();
+ Dimension size = new Dimension();
+
+ switch (type){
+ //we can calculate the preferred size only for JPEG and PNG
+ //other formats like WMF, EMF and PICT are not supported in Java
+ case HSSFWorkbook.PICTURE_TYPE_JPEG:
+ case HSSFWorkbook.PICTURE_TYPE_PNG:
+ case HSSFWorkbook.PICTURE_TYPE_DIB:
+ try {
+ //read the image using javax.imageio.*
+ ImageInputStream iis = ImageIO.createImageInputStream( new ByteArrayInputStream(data) );
+ Iterator i = ImageIO.getImageReaders( iis );
+ ImageReader r = (ImageReader) i.next();
+ r.setInput( iis );
+ BufferedImage img = r.read(0);
+
+ int[] dpi = getResolution(r);
+ size.width = img.getWidth()*96/dpi[0];
+ size.height = img.getHeight()*96/dpi[1];
+
+ } catch (IOException e){
+ //silently return if ImageIO failed to read the image
+ log.log(POILogger.WARN, e);
+ }
+
+ break;
+ }
+ return size;
+ }
}
import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
import org.apache.poi.hssf.util.HSSFDataValidation;
import org.apache.poi.hssf.util.PaneInformation;
Ptg[] ptgs = fp.getRPNPtg();
boolean changed = false;
for(int i=0; i<ptgs.length; i++) {
- if(ptgs[i] instanceof ReferencePtg) {
- ReferencePtg rptg = (ReferencePtg)ptgs[i];
+ if(ptgs[i] instanceof RefPtg) {
+ RefPtg rptg = (RefPtg)ptgs[i];
if(startRow <= rptg.getRowAsInt() &&
rptg.getRowAsInt() <= endRow) {
// References a row that moved
if (settingRowAndColumn)
{
- MemFuncPtg memFuncPtg = new MemFuncPtg();
- memFuncPtg.setLenRefSubexpression(23);
- ptgs.add(memFuncPtg);
+ ptgs.add(new MemFuncPtg(23)); // TODO - where did constant '23' come from?
}
if (startColumn >= 0)
{
}
if (settingRowAndColumn)
{
- UnionPtg unionPtg = new UnionPtg();
- ptgs.add(unionPtg);
+ ptgs.add(UnionPtg.instance);
}
nameRecord.setNameDefinition(ptgs);
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.StringPtg;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.record.formula.UnknownPtg;
// since we don't know how to handle these yet :(
Ptg ptg = ptgs[i];
-<<<<<<< .mine
if (ptg instanceof ControlPtg) {
// skip Parentheses, Attr, etc
continue;
}
-=======
- if (ptg instanceof ControlPtg) {
- // skip Parentheses, Attr, etc
- continue;
- }
->>>>>>> .r663896
if (ptg instanceof MemErrPtg) { continue; }
if (ptg instanceof MissingArgPtg) { continue; }
if (ptg instanceof NamePtg) {
Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet);
stack.push(opresult);
}
- else if (ptg instanceof ReferencePtg) {
- ReferencePtg refPtg = (ReferencePtg) ptg;
+ else if (ptg instanceof RefPtg) {
+ RefPtg refPtg = (RefPtg) ptg;
int colIx = refPtg.getColumn();
int rowIx = refPtg.getRow();
Row row = sheet.getRow(rowIx);
/**
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
- * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
+ * one of: Area3DPtg, AreaPtg, RefPtg, Ref3DPtg, IntPtg, NumberPtg,
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
* passed here!
*
Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
- else if (ptg instanceof ReferencePtg) {
+ else if (ptg instanceof RefPtg) {
Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
}
/**
- * Creates a Ref2DEval for ReferencePtg.
+ * Creates a Ref2DEval for RefPtg.
* Non existent cells are treated as RefEvals containing BlankEval.
*/
- private static Ref2DEval createRef2DEval(ReferencePtg ptg, Cell cell,
+ private static Ref2DEval createRef2DEval(RefPtg ptg, Cell cell,
Row row, Sheet sheet, Workbook workbook) {
if (cell == null) {
return new Ref2DEval(ptg, BlankEval.INSTANCE);
--- /dev/null
+package org.apache.poi.hslf.blip;\r
+\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+import org.apache.poi.hslf.model.Picture;\r
+import org.apache.poi.util.POILogger;\r
+import org.apache.poi.util.POILogFactory;\r
+\r
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+import javax.imageio.ImageIO;\r
+import java.awt.*;\r
+import java.awt.image.BufferedImage;\r
+import java.io.ByteArrayInputStream;\r
+\r
+/**\r
+ * Creates BufferedImage using javax.imageio.ImageIO and draws it in the specified graphics.\r
+ *\r
+ * @author Yegor Kozlov.\r
+ */\r
+public class BitmapPainter implements ImagePainter {\r
+ protected POILogger logger = POILogFactory.getLogger(this.getClass());\r
+\r
+ public void paint(Graphics2D graphics, PictureData pict, Picture parent) {\r
+ BufferedImage img;\r
+ try {\r
+ img = ImageIO.read(new ByteArrayInputStream(pict.getData()));\r
+ }\r
+ catch (Exception e){\r
+ logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType());\r
+ return;\r
+ }\r
+ Rectangle anchor = parent.getAnchor();\r
+ Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH);\r
+ graphics.drawImage(scaledImg, anchor.x, anchor.y, null);\r
+ }\r
+\r
+}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.blip;\r
+\r
+import org.apache.poi.hslf.model.Picture;\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+\r
+import java.awt.*;\r
+\r
+/**\r
+ * A common interface for objects that can render ppt picture data.\r
+ * <p>\r
+ * Subclasses can redefine it and use third-party libraries for actual rendering,\r
+ * for example, Bitmaps can be rendered using javax.imageio.* , WMF can be rendered using Apache Batik,\r
+ * PICT can be rendered using Apple QuickTime API for Java, etc.\r
+ * </p>\r
+ *\r
+ * A typical usage is as follows:\r
+ * <code>\r
+ * public WMFPaiter implements ImagePainter{\r
+ * public void paint(Graphics2D graphics, PictureData pict, Picture parent){\r
+ * DataInputStream is = new DataInputStream(new ByteArrayInputStream(pict.getData()));\r
+ * org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore wmfStore =\r
+ * new org.apache.batik.transcoder.wmf.tosvg.WMFRecordStore();\r
+ * try {\r
+ * wmfStore.read(is);\r
+ * } catch (IOException e){\r
+ * return;\r
+ * }\r
+ *\r
+ * Rectangle anchor = parent.getAnchor();\r
+ * float scale = (float)anchor.width/wmfStore.getWidthPixels();\r
+ *\r
+ * org.apache.batik.transcoder.wmf.tosvg.WMFPainter painter =\r
+ * new org.apache.batik.transcoder.wmf.tosvg.WMFPainter(wmfStore, 0, 0, scale);\r
+ * graphics.translate(anchor.x, anchor.y);\r
+ * painter.paint(graphics);\r
+ * }\r
+ * }\r
+ * PictureData.setImagePainter(Picture.WMF, new WMFPaiter());\r
+ * ...\r
+ * </code>\r
+ * Subsequent calls of Slide.draw(Graphics gr) will use WMFPaiter for WMF images.\r
+ *\r
+ * @author Yegor Kozlov.\r
+ */\r
+public interface ImagePainter {\r
+\r
+ /**\r
+ * Paints the specified picture data\r
+ *\r
+ * @param graphics the graphics to paintb into\r
+ * @param pict the data to paint\r
+ * @param parent the shapes that owns the picture data\r
+ */\r
+ public void paint(Graphics2D graphics, PictureData pict, Picture parent);\r
+}\r
if(!(shape instanceof TextShape)) return false;
TextShape tx = (TextShape)shape;
- TextRun run = tx.getTextRun();
- if(run == null) return false;
-
- Record[] records = run._records;
- for (int i = 0; i < records.length; i++) {
- int type = (int)records[i].getRecordType();
- if (type == RecordTypes.BaseTextPropAtom.typeID ||
- type == RecordTypes.DateTimeMCAtom.typeID ||
- type == RecordTypes.GenericDateMCAtom.typeID ||
- type == RecordTypes.FooterMCAtom.typeID ||
- type == RecordTypes.SlideNumberMCAtom.typeID
- ) return true;
-
- }
- return false;
+ return tx.getPlaceholderAtom() != null;
}
/**
public PictureData getPictureData(){
SlideShow ppt = getSheet().getSlideShow();
PictureData[] pict = ppt.getPictureData();
- Document doc = ppt.getDocumentRecord();
- EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
- List lst = bstore.getChildRecords();
- int idx = getPictureIndex();
- if (idx == 0){
+ EscherBSERecord bse = getEscherBSERecord();
+ if (bse == null){
logger.log(POILogger.ERROR, "no reference to picture data found ");
} else {
- EscherBSERecord bse = (EscherBSERecord)lst.get(idx-1);
for ( int i = 0; i < pict.length; i++ ) {
if (pict[i].getOffset() == bse.getOffset()){
return pict[i];
return null;
}
+ protected EscherBSERecord getEscherBSERecord(){
+ SlideShow ppt = getSheet().getSlideShow();
+ Document doc = ppt.getDocumentRecord();
+ EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
+ EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+
+ List lst = bstore.getChildRecords();
+ int idx = getPictureIndex();
+ if (idx == 0){
+ return null;
+ } else {
+ return (EscherBSERecord)lst.get(idx-1);
+ }
+ }
+
/**
* Name of this picture.
*
*/
protected void afterInsert(Sheet sh){
super.afterInsert(sh);
+
+ EscherBSERecord bse = getEscherBSERecord();
+ bse.setRef(bse.getRef() + 1);
+
java.awt.Rectangle anchor = getAnchor();
if (anchor.equals(new java.awt.Rectangle())){
setDefaultSize();
ShapePainter.paint(this, graphics);
PictureData data = getPictureData();
- if (data instanceof Bitmap){
- BufferedImage img = null;
- try {
- img = ImageIO.read(new ByteArrayInputStream(data.getData()));
- }
- catch (Exception e){
- logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + data.getType());
- return;
- }
- Rectangle anchor = getAnchor();
- Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH);
- graphics.drawImage(scaledImg, anchor.x, anchor.y, null);
- } else {
- logger.log(POILogger.WARN, "Rendering of metafiles is not yet supported. image.type: " + (data == null ? "NA" : data.getClass().getName()));
- }
+ data.draw(graphics, this);
+
graphics.setTransform(at);
}
}
import org.apache.poi.ddf.*;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.hslf.record.Record;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
/**
* An abstract simple (non-group) shape.
ShapePainter.paint(this, graphics);
graphics.setTransform(at);
}
+
+ /**
+ * Find a record in the underlying EscherClientDataRecord
+ *
+ * @param recordType type of the record to search
+ */
+ protected Record getClientDataRecord(int recordType) {
+ Record oep = null;
+ EscherContainerRecord spContainer = getSpContainer();
+ for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
+ EscherRecord obj = (EscherRecord) it.next();
+ if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
+ byte[] data = obj.serialize();
+ Record[] records = Record.findChildRecords(data, 8, data.length - 8);
+ for (int j = 0; j < records.length; j++) {
+ if (records[j].getRecordType() == recordType) {
+ return records[j];
+ }
+ }
+ }
+ }
+ return oep;
+ }
+
}
int dgId = dgg.getMaxDrawingGroupId() + 1;
dg.setOptions((short)(dgId << 4));
dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
+ dgg.setMaxDrawingGroupId(dgId);
for (Iterator it = dgContainer.getChildContainers().iterator(); it.hasNext(); ) {
EscherContainerRecord c = (EscherContainerRecord)it.next();
String ns = s.replaceAll("\\r?\\n", "\r");
return ns;
}
+
+ /**
+ * Returns records that make up this text run
+ *
+ * @return text run records
+ */
+ public Record[] getRecords(){
+ return _records;
+ }
}
-\r
-/* ====================================================================\r
- Licensed to the Apache Software Foundation (ASF) under one or more\r
- contributor license agreements. See the NOTICE file distributed with\r
- this work for additional information regarding copyright ownership.\r
- The ASF licenses this file to You under the Apache License, Version 2.0\r
- (the "License"); you may not use this file except in compliance with\r
- the License. You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.hslf.model;\r
-\r
-import org.apache.poi.ddf.*;\r
-import org.apache.poi.hslf.record.*;\r
-import org.apache.poi.hslf.usermodel.RichTextRun;\r
-import org.apache.poi.hslf.exceptions.HSLFException;\r
-import org.apache.poi.util.POILogger;\r
-\r
-import java.awt.*;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.font.FontRenderContext;\r
-import java.awt.font.TextLayout;\r
-import java.io.IOException;\r
-\r
-/**\r
- * A common superclass of all shapes that can hold text.\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-public abstract class TextShape extends SimpleShape {\r
-\r
- /**\r
- * How to anchor the text\r
- */\r
- public static final int AnchorTop = 0;\r
- public static final int AnchorMiddle = 1;\r
- public static final int AnchorBottom = 2;\r
- public static final int AnchorTopCentered = 3;\r
- public static final int AnchorMiddleCentered = 4;\r
- public static final int AnchorBottomCentered = 5;\r
- public static final int AnchorTopBaseline = 6;\r
- public static final int AnchorBottomBaseline = 7;\r
- public static final int AnchorTopCenteredBaseline = 8;\r
- public static final int AnchorBottomCenteredBaseline = 9;\r
-\r
- /**\r
- * How to wrap the text\r
- */\r
- public static final int WrapSquare = 0;\r
- public static final int WrapByPoints = 1;\r
- public static final int WrapNone = 2;\r
- public static final int WrapTopBottom = 3;\r
- public static final int WrapThrough = 4;\r
-\r
- /**\r
- * How to align the text\r
- */\r
- public static final int AlignLeft = 0;\r
- public static final int AlignCenter = 1;\r
- public static final int AlignRight = 2;\r
- public static final int AlignJustify = 3;\r
-\r
- /**\r
- * TextRun object which holds actual text and format data\r
- */\r
- protected TextRun _txtrun;\r
-\r
- /**\r
- * Escher container which holds text attributes such as\r
- * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.\r
- */\r
- protected EscherTextboxWrapper _txtbox;\r
-\r
- /**\r
- * Used to calculate text bounds\r
- */\r
- protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);\r
-\r
- /**\r
- * Create a TextBox object and initialize it from the supplied Record container.\r
- * \r
- * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape\r
- * @param parent the parent of the shape\r
- */\r
- protected TextShape(EscherContainerRecord escherRecord, Shape parent){\r
- super(escherRecord, parent);\r
-\r
- }\r
-\r
- /**\r
- * Create a new TextBox. This constructor is used when a new shape is created.\r
- *\r
- * @param parent the parent of this Shape. For example, if this text box is a cell\r
- * in a table then the parent is Table.\r
- */\r
- public TextShape(Shape parent){\r
- super(null, parent);\r
- _escherContainer = createSpContainer(parent instanceof ShapeGroup);\r
- }\r
-\r
- /**\r
- * Create a new TextBox. This constructor is used when a new shape is created.\r
- *\r
- */\r
- public TextShape(){\r
- this(null);\r
- }\r
-\r
- public TextRun createTextRun(){\r
- _txtbox = getEscherTextboxWrapper();\r
- if(_txtbox == null) _txtbox = new EscherTextboxWrapper();\r
-\r
- _txtrun = getTextRun();\r
- if(_txtrun == null){\r
- TextHeaderAtom tha = new TextHeaderAtom();\r
- tha.setParentRecord(_txtbox);\r
- _txtbox.appendChildRecord(tha);\r
-\r
- TextCharsAtom tca = new TextCharsAtom();\r
- _txtbox.appendChildRecord(tca);\r
-\r
- StyleTextPropAtom sta = new StyleTextPropAtom(0);\r
- _txtbox.appendChildRecord(sta);\r
-\r
- _txtrun = new TextRun(tha,tca,sta);\r
- _txtrun.setText("");\r
-\r
- _escherContainer.addChildRecord(_txtbox.getEscherRecord());\r
-\r
- setDefaultTextProperties(_txtrun);\r
- }\r
-\r
- return _txtrun;\r
- }\r
-\r
- /**\r
- * Set default properties for the TextRun.\r
- * Depending on the text and shape type the defaults are different:\r
- * TextBox: align=left, valign=top\r
- * AutoShape: align=center, valign=middle\r
- *\r
- */\r
- protected void setDefaultTextProperties(TextRun _txtrun){\r
-\r
- }\r
-\r
- /**\r
- * Returns the text contained in this text frame.\r
- *\r
- * @return the text string for this textbox.\r
- */\r
- public String getText(){\r
- TextRun tx = getTextRun();\r
- return tx == null ? null : tx.getText();\r
- }\r
-\r
- /**\r
- * Sets the text contained in this text frame.\r
- *\r
- * @param text the text string used by this object.\r
- */\r
- public void setText(String text){\r
- TextRun tx = getTextRun();\r
- if(tx == null){\r
- tx = createTextRun();\r
- }\r
- tx.setText(text);\r
- setTextId(text.hashCode());\r
- }\r
-\r
- /**\r
- * When a textbox is added to a sheet we need to tell upper-level\r
- * <code>PPDrawing</code> about it.\r
- *\r
- * @param sh the sheet we are adding to\r
- */\r
- protected void afterInsert(Sheet sh){\r
- super.afterInsert(sh);\r
-\r
- EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();\r
- if(_txtbox != null){\r
- PPDrawing ppdrawing = sh.getPPDrawing();\r
- ppdrawing.addTextboxWrapper(_txtbox);\r
- // Ensure the escher layer knows about the added records\r
- try {\r
- _txtbox.writeOut(null);\r
- } catch (IOException e){\r
- throw new HSLFException(e);\r
- }\r
- if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();\r
- }\r
- }\r
-\r
- protected EscherTextboxWrapper getEscherTextboxWrapper(){\r
- if(_txtbox == null){\r
- EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);\r
- if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);\r
- }\r
- return _txtbox;\r
- }\r
- /**\r
- * Adjust the size of the TextShape so it encompasses the text inside it.\r
- *\r
- * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.\r
- */\r
- public Rectangle2D resizeToFitText(){\r
- String txt = getText();\r
- if(txt == null || txt.length() == 0) return new Rectangle2D.Float();\r
-\r
- RichTextRun rt = getTextRun().getRichTextRuns()[0];\r
- int size = rt.getFontSize();\r
- int style = 0;\r
- if (rt.isBold()) style |= Font.BOLD;\r
- if (rt.isItalic()) style |= Font.ITALIC;\r
- String fntname = rt.getFontName();\r
- Font font = new Font(fntname, style, size);\r
-\r
- float width = 0, height = 0;\r
- String[] lines = txt.split("\r");\r
- for (int i = 0; i < lines.length; i++) {\r
- if(lines[i].length() == 0) continue;\r
-\r
- TextLayout layout = new TextLayout(lines[i], font, _frc);\r
-\r
- width = Math.max(width, layout.getAdvance());\r
-\r
- /**\r
- * Even if top and bottom margins are set to 0 PowerPoint\r
- * always sets extra space between the text and its bounding box.\r
- *\r
- * The approximation height = ascent*2 works good enough in most cases\r
- */\r
- height = Math.max(height, 2*layout.getAscent());\r
- }\r
-\r
- width += getMarginLeft() + getMarginRight();\r
- height += getMarginTop() + getMarginBottom();\r
-\r
- Rectangle2D anchor = getAnchor2D();\r
- anchor.setRect(anchor.getX(), anchor.getY(), width, height);\r
- setAnchor(anchor);\r
-\r
- return anchor;\r
- }\r
-\r
- /**\r
- * Returns the type of vertical alignment for the text.\r
- * One of the <code>Anchor*</code> constants defined in this class.\r
- *\r
- * @return the type of alignment\r
- */\r
- public int getVerticalAlignment(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);\r
- int valign = TextShape.AnchorTop;\r
- if (prop == null){\r
- /**\r
- * If vertical alignment was not found in the shape properties then try to\r
- * fetch the master shape and search for the align property there.\r
- */\r
- int type = getTextRun().getRunType();\r
- MasterSheet master = getSheet().getMasterSheet();\r
- if(master != null){\r
- TextShape masterShape = master.getPlaceholder(type);\r
- if(masterShape != null) valign = masterShape.getVerticalAlignment();\r
- } else {\r
- //not found in the master sheet. Use the hardcoded defaults.\r
- switch (type){\r
- case TextHeaderAtom.TITLE_TYPE:\r
- case TextHeaderAtom.CENTER_TITLE_TYPE:\r
- valign = TextShape.AnchorMiddle;\r
- break;\r
- default:\r
- valign = TextShape.AnchorTop;\r
- break;\r
- }\r
- }\r
- } else {\r
- valign = prop.getPropertyValue();\r
- }\r
- return valign;\r
- }\r
-\r
- /**\r
- * Sets the type of vertical alignment for the text.\r
- * One of the <code>Anchor*</code> constants defined in this class.\r
- *\r
- * @param align - the type of alignment\r
- */\r
- public void setVerticalAlignment(int align){\r
- setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);\r
- }\r
-\r
- /**\r
- * Sets the type of horizontal alignment for the text.\r
- * One of the <code>Align*</code> constants defined in this class.\r
- *\r
- * @param align - the type of horizontal alignment\r
- */\r
- public void setHorizontalAlignment(int align){\r
- TextRun tx = getTextRun();\r
- if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);\r
- }\r
-\r
- /**\r
- * Gets the type of horizontal alignment for the text.\r
- * One of the <code>Align*</code> constants defined in this class.\r
- *\r
- * @return align - the type of horizontal alignment\r
- */\r
- public int getHorizontalAlignment(){\r
- TextRun tx = getTextRun();\r
- return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();\r
- }\r
-\r
- /**\r
- * Returns the distance (in points) between the bottom of the text frame\r
- * and the bottom of the inscribed rectangle of the shape that contains the text.\r
- * Default value is 1/20 inch.\r
- *\r
- * @return the botom margin\r
- */\r
- public float getMarginBottom(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);\r
- int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();\r
- return (float)val/EMU_PER_POINT;\r
- }\r
-\r
- /**\r
- * Sets the botom margin.\r
- * @see #getMarginBottom()\r
- *\r
- * @param margin the bottom margin\r
- */\r
- public void setMarginBottom(float margin){\r
- setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));\r
- }\r
-\r
- /**\r
- * Returns the distance (in points) between the left edge of the text frame\r
- * and the left edge of the inscribed rectangle of the shape that contains\r
- * the text.\r
- * Default value is 1/10 inch.\r
- *\r
- * @return the left margin\r
- */\r
- public float getMarginLeft(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);\r
- int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();\r
- return (float)val/EMU_PER_POINT;\r
- }\r
-\r
- /**\r
- * Sets the left margin.\r
- * @see #getMarginLeft()\r
- *\r
- * @param margin the left margin\r
- */\r
- public void setMarginLeft(float margin){\r
- setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));\r
- }\r
-\r
- /**\r
- * Returns the distance (in points) between the right edge of the\r
- * text frame and the right edge of the inscribed rectangle of the shape\r
- * that contains the text.\r
- * Default value is 1/10 inch.\r
- *\r
- * @return the right margin\r
- */\r
- public float getMarginRight(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);\r
- int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();\r
- return (float)val/EMU_PER_POINT;\r
- }\r
-\r
- /**\r
- * Sets the right margin.\r
- * @see #getMarginRight()\r
- *\r
- * @param margin the right margin\r
- */\r
- public void setMarginRight(float margin){\r
- setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));\r
- }\r
-\r
- /**\r
- * Returns the distance (in points) between the top of the text frame\r
- * and the top of the inscribed rectangle of the shape that contains the text.\r
- * Default value is 1/20 inch.\r
- *\r
- * @return the top margin\r
- */\r
- public float getMarginTop(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);\r
- int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();\r
- return (float)val/EMU_PER_POINT;\r
- }\r
-\r
- /**\r
- * Sets the top margin.\r
- * @see #getMarginTop()\r
- *\r
- * @param margin the top margin\r
- */\r
- public void setMarginTop(float margin){\r
- setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));\r
- }\r
-\r
-\r
- /**\r
- * Returns the value indicating word wrap.\r
- *\r
- * @return the value indicating word wrap.\r
- * Must be one of the <code>Wrap*</code> constants defined in this class.\r
- */\r
- public int getWordWrap(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);\r
- return prop == null ? WrapSquare : prop.getPropertyValue();\r
- }\r
-\r
- /**\r
- * Specifies how the text should be wrapped\r
- *\r
- * @param wrap the value indicating how the text should be wrapped.\r
- * Must be one of the <code>Wrap*</code> constants defined in this class.\r
- */\r
- public void setWordWrap(int wrap){\r
- setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);\r
- }\r
-\r
- /**\r
- * @return id for the text.\r
- */\r
- public int getTextId(){\r
- EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);\r
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);\r
- return prop == null ? 0 : prop.getPropertyValue();\r
- }\r
-\r
- /**\r
- * Sets text ID\r
- *\r
- * @param id of the text\r
- */\r
- public void setTextId(int id){\r
- setEscherProperty(EscherProperties.TEXT__TEXTID, id);\r
- }\r
-\r
- /**\r
- * @return the TextRun object for this text box\r
- */\r
- public TextRun getTextRun(){\r
- if(_txtrun == null) initTextRun();\r
- return _txtrun;\r
- }\r
-\r
- public void setSheet(Sheet sheet) {\r
- _sheet = sheet;\r
-\r
- // Initialize _txtrun object.\r
- // (We can't do it in the constructor because the sheet\r
- // is not assigned then, it's only built once we have\r
- // all the records)\r
- TextRun tx = getTextRun();\r
- if (tx != null) {\r
- // Supply the sheet to our child RichTextRuns\r
- tx.setSheet(_sheet);\r
- RichTextRun[] rt = tx.getRichTextRuns();\r
- for (int i = 0; i < rt.length; i++) {\r
- rt[i].supplySlideShow(_sheet.getSlideShow());\r
- }\r
- }\r
-\r
- }\r
-\r
- protected void initTextRun(){\r
- EscherTextboxWrapper txtbox = getEscherTextboxWrapper();\r
- Sheet sheet = getSheet();\r
-\r
- if(sheet == null || txtbox == null) return;\r
-\r
- OutlineTextRefAtom ota = null;\r
-\r
- Record[] child = txtbox.getChildRecords();\r
- for (int i = 0; i < child.length; i++) {\r
- if (child[i] instanceof OutlineTextRefAtom) {\r
- ota = (OutlineTextRefAtom)child[i];\r
- break;\r
- }\r
- }\r
-\r
- TextRun[] runs = _sheet.getTextRuns();\r
- if (ota != null) {\r
- int idx = ota.getTextIndex();\r
- for (int i = 0; i < runs.length; i++) {\r
- if(runs[i].getIndex() == idx){\r
- _txtrun = runs[i];\r
- break;\r
- }\r
- }\r
- if(_txtrun == null) {\r
- logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);\r
- }\r
- } else {\r
- int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();\r
- if(runs != null) for (int i = 0; i < runs.length; i++) {\r
- if(runs[i].getShapeId() == shapeId){\r
- _txtrun = runs[i];\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- public void draw(Graphics2D graphics){\r
- AffineTransform at = graphics.getTransform();\r
- ShapePainter.paint(this, graphics);\r
- new TextPainter(this).paint(graphics);\r
- graphics.setTransform(at);\r
- }\r
-\r
-}\r
+
+/* ====================================================================
+ 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.hslf.model;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.RichTextRun;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.POILogger;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.AffineTransform;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A common superclass of all shapes that can hold text.
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class TextShape extends SimpleShape {
+
+ /**
+ * How to anchor the text
+ */
+ public static final int AnchorTop = 0;
+ public static final int AnchorMiddle = 1;
+ public static final int AnchorBottom = 2;
+ public static final int AnchorTopCentered = 3;
+ public static final int AnchorMiddleCentered = 4;
+ public static final int AnchorBottomCentered = 5;
+ public static final int AnchorTopBaseline = 6;
+ public static final int AnchorBottomBaseline = 7;
+ public static final int AnchorTopCenteredBaseline = 8;
+ public static final int AnchorBottomCenteredBaseline = 9;
+
+ /**
+ * How to wrap the text
+ */
+ public static final int WrapSquare = 0;
+ public static final int WrapByPoints = 1;
+ public static final int WrapNone = 2;
+ public static final int WrapTopBottom = 3;
+ public static final int WrapThrough = 4;
+
+ /**
+ * How to align the text
+ */
+ public static final int AlignLeft = 0;
+ public static final int AlignCenter = 1;
+ public static final int AlignRight = 2;
+ public static final int AlignJustify = 3;
+
+ /**
+ * TextRun object which holds actual text and format data
+ */
+ protected TextRun _txtrun;
+
+ /**
+ * Escher container which holds text attributes such as
+ * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
+ */
+ protected EscherTextboxWrapper _txtbox;
+
+ /**
+ * Used to calculate text bounds
+ */
+ protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
+
+ /**
+ * Create a TextBox object and initialize it from the supplied Record container.
+ *
+ * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
+ * @param parent the parent of the shape
+ */
+ protected TextShape(EscherContainerRecord escherRecord, Shape parent){
+ super(escherRecord, parent);
+
+ }
+
+ /**
+ * Create a new TextBox. This constructor is used when a new shape is created.
+ *
+ * @param parent the parent of this Shape. For example, if this text box is a cell
+ * in a table then the parent is Table.
+ */
+ public TextShape(Shape parent){
+ super(null, parent);
+ _escherContainer = createSpContainer(parent instanceof ShapeGroup);
+ }
+
+ /**
+ * Create a new TextBox. This constructor is used when a new shape is created.
+ *
+ */
+ public TextShape(){
+ this(null);
+ }
+
+ public TextRun createTextRun(){
+ _txtbox = getEscherTextboxWrapper();
+ if(_txtbox == null) _txtbox = new EscherTextboxWrapper();
+
+ _txtrun = getTextRun();
+ if(_txtrun == null){
+ TextHeaderAtom tha = new TextHeaderAtom();
+ tha.setParentRecord(_txtbox);
+ _txtbox.appendChildRecord(tha);
+
+ TextCharsAtom tca = new TextCharsAtom();
+ _txtbox.appendChildRecord(tca);
+
+ StyleTextPropAtom sta = new StyleTextPropAtom(0);
+ _txtbox.appendChildRecord(sta);
+
+ _txtrun = new TextRun(tha,tca,sta);
+ _txtrun.setText("");
+
+ _escherContainer.addChildRecord(_txtbox.getEscherRecord());
+
+ setDefaultTextProperties(_txtrun);
+ }
+
+ return _txtrun;
+ }
+
+ /**
+ * Set default properties for the TextRun.
+ * Depending on the text and shape type the defaults are different:
+ * TextBox: align=left, valign=top
+ * AutoShape: align=center, valign=middle
+ *
+ */
+ protected void setDefaultTextProperties(TextRun _txtrun){
+
+ }
+
+ /**
+ * Returns the text contained in this text frame.
+ *
+ * @return the text string for this textbox.
+ */
+ public String getText(){
+ TextRun tx = getTextRun();
+ return tx == null ? null : tx.getText();
+ }
+
+ /**
+ * Sets the text contained in this text frame.
+ *
+ * @param text the text string used by this object.
+ */
+ public void setText(String text){
+ TextRun tx = getTextRun();
+ if(tx == null){
+ tx = createTextRun();
+ }
+ tx.setText(text);
+ setTextId(text.hashCode());
+ }
+
+ /**
+ * When a textbox is added to a sheet we need to tell upper-level
+ * <code>PPDrawing</code> about it.
+ *
+ * @param sh the sheet we are adding to
+ */
+ protected void afterInsert(Sheet sh){
+ super.afterInsert(sh);
+
+ EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
+ if(_txtbox != null){
+ PPDrawing ppdrawing = sh.getPPDrawing();
+ ppdrawing.addTextboxWrapper(_txtbox);
+ // Ensure the escher layer knows about the added records
+ try {
+ _txtbox.writeOut(null);
+ } catch (IOException e){
+ throw new HSLFException(e);
+ }
+ if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
+ }
+ }
+
+ protected EscherTextboxWrapper getEscherTextboxWrapper(){
+ if(_txtbox == null){
+ EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
+ if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
+ }
+ return _txtbox;
+ }
+ /**
+ * Adjust the size of the TextShape so it encompasses the text inside it.
+ *
+ * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.
+ */
+ public Rectangle2D resizeToFitText(){
+ String txt = getText();
+ if(txt == null || txt.length() == 0) return new Rectangle2D.Float();
+
+ RichTextRun rt = getTextRun().getRichTextRuns()[0];
+ int size = rt.getFontSize();
+ int style = 0;
+ if (rt.isBold()) style |= Font.BOLD;
+ if (rt.isItalic()) style |= Font.ITALIC;
+ String fntname = rt.getFontName();
+ Font font = new Font(fntname, style, size);
+
+ float width = 0, height = 0, leading = 0;
+ String[] lines = txt.split("\n");
+ for (int i = 0; i < lines.length; i++) {
+ if(lines[i].length() == 0) continue;
+
+ TextLayout layout = new TextLayout(lines[i], font, _frc);
+
+ leading = Math.max(leading, layout.getLeading());
+ width = Math.max(width, layout.getAdvance());
+ height = Math.max(height, (height + (layout.getDescent() + layout.getAscent())));
+ }
+
+ // add one character to width
+ Rectangle2D charBounds = font.getMaxCharBounds(_frc);
+ width += getMarginLeft() + getMarginRight() + charBounds.getWidth();
+
+ // add leading to height
+ height += getMarginTop() + getMarginBottom() + leading;
+
+ Rectangle2D anchor = getAnchor2D();
+ anchor.setRect(anchor.getX(), anchor.getY(), width, height);
+ setAnchor(anchor);
+
+ return anchor;
+ }
+
+ /**
+ * Returns the type of vertical alignment for the text.
+ * One of the <code>Anchor*</code> constants defined in this class.
+ *
+ * @return the type of alignment
+ */
+ public int getVerticalAlignment(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
+ int valign = TextShape.AnchorTop;
+ if (prop == null){
+ /**
+ * If vertical alignment was not found in the shape properties then try to
+ * fetch the master shape and search for the align property there.
+ */
+ int type = getTextRun().getRunType();
+ MasterSheet master = getSheet().getMasterSheet();
+ if(master != null){
+ TextShape masterShape = master.getPlaceholder(type);
+ if(masterShape != null) valign = masterShape.getVerticalAlignment();
+ } else {
+ //not found in the master sheet. Use the hardcoded defaults.
+ switch (type){
+ case TextHeaderAtom.TITLE_TYPE:
+ case TextHeaderAtom.CENTER_TITLE_TYPE:
+ valign = TextShape.AnchorMiddle;
+ break;
+ default:
+ valign = TextShape.AnchorTop;
+ break;
+ }
+ }
+ } else {
+ valign = prop.getPropertyValue();
+ }
+ return valign;
+ }
+
+ /**
+ * Sets the type of vertical alignment for the text.
+ * One of the <code>Anchor*</code> constants defined in this class.
+ *
+ * @param align - the type of alignment
+ */
+ public void setVerticalAlignment(int align){
+ setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);
+ }
+
+ /**
+ * Sets the type of horizontal alignment for the text.
+ * One of the <code>Align*</code> constants defined in this class.
+ *
+ * @param align - the type of horizontal alignment
+ */
+ public void setHorizontalAlignment(int align){
+ TextRun tx = getTextRun();
+ if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);
+ }
+
+ /**
+ * Gets the type of horizontal alignment for the text.
+ * One of the <code>Align*</code> constants defined in this class.
+ *
+ * @return align - the type of horizontal alignment
+ */
+ public int getHorizontalAlignment(){
+ TextRun tx = getTextRun();
+ return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();
+ }
+
+ /**
+ * Returns the distance (in points) between the bottom of the text frame
+ * and the bottom of the inscribed rectangle of the shape that contains the text.
+ * Default value is 1/20 inch.
+ *
+ * @return the botom margin
+ */
+ public float getMarginBottom(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+ int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+ return (float)val/EMU_PER_POINT;
+ }
+
+ /**
+ * Sets the botom margin.
+ * @see #getMarginBottom()
+ *
+ * @param margin the bottom margin
+ */
+ public void setMarginBottom(float margin){
+ setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
+ }
+
+ /**
+ * Returns the distance (in points) between the left edge of the text frame
+ * and the left edge of the inscribed rectangle of the shape that contains
+ * the text.
+ * Default value is 1/10 inch.
+ *
+ * @return the left margin
+ */
+ public float getMarginLeft(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+ int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+ return (float)val/EMU_PER_POINT;
+ }
+
+ /**
+ * Sets the left margin.
+ * @see #getMarginLeft()
+ *
+ * @param margin the left margin
+ */
+ public void setMarginLeft(float margin){
+ setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
+ }
+
+ /**
+ * Returns the distance (in points) between the right edge of the
+ * text frame and the right edge of the inscribed rectangle of the shape
+ * that contains the text.
+ * Default value is 1/10 inch.
+ *
+ * @return the right margin
+ */
+ public float getMarginRight(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
+ int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
+ return (float)val/EMU_PER_POINT;
+ }
+
+ /**
+ * Sets the right margin.
+ * @see #getMarginRight()
+ *
+ * @param margin the right margin
+ */
+ public void setMarginRight(float margin){
+ setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
+ }
+
+ /**
+ * Returns the distance (in points) between the top of the text frame
+ * and the top of the inscribed rectangle of the shape that contains the text.
+ * Default value is 1/20 inch.
+ *
+ * @return the top margin
+ */
+ public float getMarginTop(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
+ int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
+ return (float)val/EMU_PER_POINT;
+ }
+
+ /**
+ * Sets the top margin.
+ * @see #getMarginTop()
+ *
+ * @param margin the top margin
+ */
+ public void setMarginTop(float margin){
+ setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
+ }
+
+
+ /**
+ * Returns the value indicating word wrap.
+ *
+ * @return the value indicating word wrap.
+ * Must be one of the <code>Wrap*</code> constants defined in this class.
+ */
+ public int getWordWrap(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
+ return prop == null ? WrapSquare : prop.getPropertyValue();
+ }
+
+ /**
+ * Specifies how the text should be wrapped
+ *
+ * @param wrap the value indicating how the text should be wrapped.
+ * Must be one of the <code>Wrap*</code> constants defined in this class.
+ */
+ public void setWordWrap(int wrap){
+ setEscherProperty(EscherProperties.TEXT__WRAPTEXT, wrap);
+ }
+
+ /**
+ * @return id for the text.
+ */
+ public int getTextId(){
+ EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
+ return prop == null ? 0 : prop.getPropertyValue();
+ }
+
+ /**
+ * Sets text ID
+ *
+ * @param id of the text
+ */
+ public void setTextId(int id){
+ setEscherProperty(EscherProperties.TEXT__TEXTID, id);
+ }
+
+ /**
+ * @return the TextRun object for this text box
+ */
+ public TextRun getTextRun(){
+ if(_txtrun == null) initTextRun();
+ return _txtrun;
+ }
+
+ public void setSheet(Sheet sheet) {
+ _sheet = sheet;
+
+ // Initialize _txtrun object.
+ // (We can't do it in the constructor because the sheet
+ // is not assigned then, it's only built once we have
+ // all the records)
+ TextRun tx = getTextRun();
+ if (tx != null) {
+ // Supply the sheet to our child RichTextRuns
+ tx.setSheet(_sheet);
+ RichTextRun[] rt = tx.getRichTextRuns();
+ for (int i = 0; i < rt.length; i++) {
+ rt[i].supplySlideShow(_sheet.getSlideShow());
+ }
+ }
+
+ }
+
+ protected void initTextRun(){
+ EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
+ Sheet sheet = getSheet();
+
+ if(sheet == null || txtbox == null) return;
+
+ OutlineTextRefAtom ota = null;
+
+ Record[] child = txtbox.getChildRecords();
+ for (int i = 0; i < child.length; i++) {
+ if (child[i] instanceof OutlineTextRefAtom) {
+ ota = (OutlineTextRefAtom)child[i];
+ break;
+ }
+ }
+
+ TextRun[] runs = _sheet.getTextRuns();
+ if (ota != null) {
+ int idx = ota.getTextIndex();
+ for (int i = 0; i < runs.length; i++) {
+ if(runs[i].getIndex() == idx){
+ _txtrun = runs[i];
+ break;
+ }
+ }
+ if(_txtrun == null) {
+ logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
+ }
+ } else {
+ int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
+ if(runs != null) for (int i = 0; i < runs.length; i++) {
+ if(runs[i].getShapeId() == shapeId){
+ _txtrun = runs[i];
+ break;
+ }
+ }
+ }
+ }
+
+ public void draw(Graphics2D graphics){
+ AffineTransform at = graphics.getTransform();
+ ShapePainter.paint(this, graphics);
+ new TextPainter(this).paint(graphics);
+ graphics.setTransform(at);
+ }
+
+ /**
+ * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder.
+ *
+ * @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
+ */
+ public OEPlaceholderAtom getPlaceholderAtom(){
+ return (OEPlaceholderAtom)getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
+ }
+
+}
new TextProp(2, 0x4000, "spaceafter"),
new TextProp(2, 0x8000, "para_unknown_4"),
new TextProp(2, 0x10000, "para_unknown_5"),
- new TextProp(2, 0xE0000, "para_unknown_6"),
+ new TextProp(2, 0xA0000, "para_unknown_6"),
new TextProp(2, 0x200000, "para_unknown_7")
};
/** All the different kinds of character properties we might handle */
/**
* For the Text Style Properties (StyleTextProp) Atom
*/
- protected StyleTextPropAtom(byte[] source, int start, int len) {
+ public StyleTextPropAtom(byte[] source, int start, int len) {
// Sanity Checking - we're always at least 8+10 bytes long
if(len < 18) {
len = 18;
package org.apache.poi.hslf.usermodel;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
import org.apache.poi.hslf.model.Picture;
import org.apache.poi.hslf.blip.*;
import org.apache.poi.hslf.exceptions.HSLFException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.awt.*;
/**
* A class that represents image data contained in a slide show.
*/
public abstract class PictureData {
+ protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
/**
* Size of the image checksum calculated using MD5 algorithm.
*/
protected static final int CHECKSUM_SIZE = 16;
- /**
- * Binary data of the picture
- */
+ /**
+ * Binary data of the picture
+ */
private byte[] rawdata;
- /**
- * The offset to the picture in the stream
- */
- protected int offset;
+ /**
+ * The offset to the picture in the stream
+ */
+ protected int offset;
/**
* Returns type of this picture.
*/
protected abstract int getSignature();
+ protected static ImagePainter[] painters = new ImagePainter[8];
+ static {
+ PictureData.setImagePainter(Picture.PNG, new BitmapPainter());
+ PictureData.setImagePainter(Picture.JPEG, new BitmapPainter());
+ PictureData.setImagePainter(Picture.DIB, new BitmapPainter());
+ }
+
/**
* Returns the raw binary data of this Picture excluding the first 8 bytes
* which hold image signature and size of the image data.
return getData().length;
}
+ public void draw(Graphics2D graphics, Picture parent){
+ ImagePainter painter = painters[getType()];
+ if(painter != null) painter.paint(graphics, this, parent);
+ else logger.log(POILogger.WARN, "Rendering is not supported: " + getClass().getName());
+ }
+
+ /**
+ * Register ImagePainter for the specified image type
+ *
+ * @param type image type, must be one of the static constants defined in the <code>Picture<code> class.
+ * @param painter
+ */
+ public static void setImagePainter(int type, ImagePainter painter){
+ painters[type] = painter;
+ }
+
+ /**
+ * Return ImagePainter for the specified image type
+ *
+ * @param type blip type, must be one of the static constants defined in the <code>Picture<code> class.
+ * @return ImagePainter for the specified image type
+ */
+ public static ImagePainter getImagePainter(int type){
+ return painters[type];
+ }
+
}
else if (format == Picture.WMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
else if (format == Picture.PICT) bse.setBlipTypeWin32((byte)Picture.WMF);
- bse.setRef(1);
+ bse.setRef(0);
bse.setOffset(offset);
bstore.addChildRecord(bse);
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import junit.framework.*;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.File;\r
+import java.awt.*;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.usermodel.PictureData;\r
+import org.apache.poi.hslf.HSLFSlideShow;\r
+import org.apache.poi.hslf.blip.ImagePainter;\r
+import org.apache.poi.hslf.blip.BitmapPainter;\r
+import org.apache.poi.ddf.EscherBSERecord;\r
+\r
+/**\r
+ * Test Picture shape.\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestImagePainter extends TestCase {\r
+\r
+ private static class CustomImagePainer implements ImagePainter{\r
+ public void paint(Graphics2D graphics, PictureData pict, Picture parent){\r
+ //do noting\r
+ }\r
+\r
+ }\r
+\r
+ public void testImagePainter() throws Exception {\r
+\r
+ ImagePainter pntr = PictureData.getImagePainter(Picture.PNG);\r
+ assertTrue(PictureData.getImagePainter(Picture.PNG) instanceof BitmapPainter);\r
+ assertTrue(PictureData.getImagePainter(Picture.JPEG) instanceof BitmapPainter);\r
+ assertTrue(PictureData.getImagePainter(Picture.DIB) instanceof BitmapPainter);\r
+\r
+ PictureData.setImagePainter(Picture.WMF, new CustomImagePainer());\r
+ assertTrue(PictureData.getImagePainter(Picture.WMF) instanceof CustomImagePainer);\r
+ }\r
+\r
+}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hslf.model;\r
+\r
+import junit.framework.*;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.File;\r
+import java.awt.*;\r
+\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.hslf.HSLFSlideShow;\r
+import org.apache.poi.ddf.EscherBSERecord;\r
+\r
+/**\r
+ * Test Picture shape.\r
+ * \r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestPicture extends TestCase {\r
+\r
+ /**\r
+ * Test that the reference count of a blip is incremented every time the picture is inserted.\r
+ * This is important when the same image appears multiple times in a slide show.\r
+ *\r
+ */\r
+ public void testMultiplePictures() throws Exception {\r
+ String cwd = System.getProperty("HSLF.testdata.path");\r
+ SlideShow ppt = new SlideShow();\r
+\r
+ Slide s = ppt.createSlide();\r
+ Slide s2 = ppt.createSlide();\r
+ Slide s3 = ppt.createSlide();\r
+\r
+ int idx = ppt.addPicture(new File(cwd, "clock.jpg"), Picture.JPEG);\r
+ Picture pict = new Picture(idx);\r
+ Picture pict2 = new Picture(idx);\r
+ Picture pict3 = new Picture(idx);\r
+\r
+ pict.setAnchor(new Rectangle(10,10,100,100));\r
+ s.addShape(pict);\r
+ EscherBSERecord bse1 = pict.getEscherBSERecord();\r
+ assertEquals(1, bse1.getRef());\r
+\r
+ pict2.setAnchor(new Rectangle(10,10,100,100));\r
+ s2.addShape(pict2);\r
+ EscherBSERecord bse2 = pict.getEscherBSERecord();\r
+ assertSame(bse1, bse2);\r
+ assertEquals(2, bse1.getRef());\r
+\r
+ pict3.setAnchor(new Rectangle(10,10,100,100));\r
+ s3.addShape(pict3);\r
+ EscherBSERecord bse3 = pict.getEscherBSERecord();\r
+ assertSame(bse2, bse3);\r
+ assertEquals(3, bse1.getRef());\r
+\r
+ }\r
+\r
+}\r
import org.apache.poi.hssf.record.formula.PercentPtg;
import org.apache.poi.hssf.record.formula.PowerPtg;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.StringPtg;
import org.apache.poi.hssf.record.formula.SubtractPtg;
import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
public void testUnaryMinus() {
Ptg[] ptgs = parseFormula("-A1");
assertEquals(2, ptgs.length);
- assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+ assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
assertTrue("second ptg is Minus",ptgs[1] instanceof UnaryMinusPtg);
}
public void testUnaryPlus() {
Ptg[] ptgs = parseFormula("+A1");
assertEquals(2, ptgs.length);
- assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+ assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
assertTrue("second ptg is Plus",ptgs[1] instanceof UnaryPlusPtg);
}
Class[] expClss;
expClss = new Class[] {
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrIf
MissingArgPtg.class,
AttrPtg.class, // tAttrSkip
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrSkip
FuncVarPtg.class,
};
// FormulaParser strips spaces anyway
assertEquals("4", formulaString);
- ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, new AddPtg()};
+ ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, AddPtg.instance, };
formulaString = FormulaParser.toFormulaString(null, ptgs);
assertEquals("3+4", formulaString);
}
Ptg[] ptgs = {
// Excel would probably have put tMissArg here
new IntPtg(1),
- new DividePtg(),
+ DividePtg.instance,
};
try {
FormulaParser.toFormulaString(null, ptgs);
import org.apache.poi.hssf.record.formula.MultiplyPtg;
import org.apache.poi.hssf.record.formula.NotEqualPtg;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.StringPtg;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
Class[] expClss;
expClss = new Class[] {
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrIf
IntPtg.class,
AttrPtg.class, // tAttrSkip
Class[] expClss;
expClss = new Class[] {
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrIf
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrSkip
FuncVarPtg.class,
};
Class[] expClss;
expClss = new Class[] {
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // tAttrIf
- ReferencePtg.class,
+ RefPtg.class,
IntPtg.class,
MultiplyPtg.class,
- ReferencePtg.class,
+ RefPtg.class,
IntPtg.class,
AddPtg.class,
FuncPtg.class,
AttrPtg.class, // tAttrSkip
- ReferencePtg.class,
- ReferencePtg.class,
+ RefPtg.class,
+ RefPtg.class,
FuncPtg.class,
AttrPtg.class, // tAttrSkip
expClss = new Class[] {
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // A tAttrIf
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // B tAttrIf
IntPtg.class,
AttrPtg.class, // B tAttrSkip
AttrPtg.class, // B tAttrSkip
FuncVarPtg.class,
AttrPtg.class, // A tAttrSkip
- ReferencePtg.class,
+ RefPtg.class,
AttrPtg.class, // C tAttrIf
IntPtg.class,
AttrPtg.class, // C tAttrSkip
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtgBase;
import org.apache.poi.hssf.usermodel.FormulaExtractor;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
for (int i = 0; i < nExcelTokens; i++) {
Ptg poiPtg = poiPtgs[i];
Ptg excelPtg = excelPtgs[i];
- if (!areTokenClassesSame(poiPtg, excelPtg)) {
+ if (excelPtg.getClass() != poiPtg.getClass()) {
hasMismatch = true;
sb.append(" mismatch token type[" + i + "] " + getShortClassName(excelPtg) + " "
+ getOperandClassName(excelPtg) + " - " + getShortClassName(poiPtg) + " "
}
}
- private boolean areTokenClassesSame(Ptg poiPtg, Ptg excelPtg) {
- if (excelPtg.getClass() == poiPtg.getClass()) {
- return true;
- }
- if (poiPtg.getClass() == ReferencePtg.class) {
- // TODO - remove funny subclasses of ReferencePtg
- return excelPtg instanceof ReferencePtg;
- }
- return false;
- }
-
private String getShortClassName(Object o) {
String cn = o.getClass().getName();
int pos = cn.lastIndexOf('.');
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.FuncVarPtg;
import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
/**
* Tests the serialization and deserialization of the FormulaRecord
assertEquals(9, ptgs.size());
assertEquals(IntPtg.class, ptgs.get(0).getClass());
assertEquals(AttrPtg.class, ptgs.get(1).getClass());
- assertEquals(ReferencePtg.class, ptgs.get(2).getClass());
+ assertEquals(RefPtg.class, ptgs.get(2).getClass());
assertEquals(AttrPtg.class, ptgs.get(3).getClass());
- assertEquals(ReferencePtg.class, ptgs.get(4).getClass());
+ assertEquals(RefPtg.class, ptgs.get(4).getClass());
assertEquals(AttrPtg.class, ptgs.get(5).getClass());
- assertEquals(ReferencePtg.class, ptgs.get(6).getClass());
+ assertEquals(RefPtg.class, ptgs.get(6).getClass());
assertEquals(AttrPtg.class, ptgs.get(7).getClass());
assertEquals(FuncVarPtg.class, ptgs.get(8).getClass());
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.RefAPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
/**
* @author Josh Micich
Stack convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
- RefAPtg refPtg = (RefAPtg) convertedFormula.get(1);
+ RefPtg refPtg = (RefPtg) convertedFormula.get(1);
assertEquals("$C101", refPtg.toFormulaString(null));
if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
throw new AssertionFailedError("Identified bug 45123");
*/
public void testReadWriteTokenValueBytes() {
- ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+ ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
assertEquals(3, ptg.getColumnCount());
assertEquals(2, ptg.getRowCount());
- Object[] values = ptg.token_3_arrayValues;
+ Object[] values = ptg.getTokenArrayValues();
assertEquals(6, values.length);
* Excel stores array elements column by column. This test makes sure POI does the same.
*/
public void testElementOrdering() {
- ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+ ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
assertEquals(3, ptg.getColumnCount());
assertEquals(2, ptg.getRowCount());
package org.apache.poi.hssf.record.formula;
+import java.util.Arrays;
+import java.util.Stack;
+
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
- * Tests for {@link ReferencePtg}.
+ * Tests for {@link RefPtg}.
*/
public final class TestReferencePtg extends TestCase {
/**
throw e;
}
}
+ private static final byte[] tRefN_data = {
+ 0x2C, 33, 44, 55, 66,
+ };
+ public void testReadWrite_tRefN_bug45091() {
+ TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
+ Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
+ byte[] outData = new byte[5];
+ Ptg.serializePtgStack(ptgs, outData, 0);
+ if (outData[0] == 0x24) {
+ throw new AssertionFailedError("Identified bug 45091");
+ }
+ assertTrue(Arrays.equals(tRefN_data, outData));
+ }
}
arg,
};
- PercentEval opEval = new PercentEval(new PercentPtg());
+ PercentEval opEval = new PercentEval(PercentPtg.instance);
double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1);
assertEquals(expectedResult, result, 0);
* The code for handling column operands had been copy-pasted from the row handling code.
*/
public void testColumnOperand() {
-
+
short firstRow = (short)8;
short lastRow = (short)12;
short colNum = (short)5;
Eval[] args = {
areaEval,
};
-
- double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(new UnaryPlusPtg()), args, 10, (short)20);
-
+
+ double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
+
assertEquals(35, result, 0);
}
-
}
package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
* Creates a single RefEval (with value zero)
*/
public static RefEval createRefEval(String refStr) {
- return new Ref2DEval(new ReferencePtg(refStr), ZERO);
+ return new Ref2DEval(new RefPtg(refStr), ZERO);
}
}
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
};
Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values);
- Ref2DEval criteriaArg = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(25));
+ Ref2DEval criteriaArg = new Ref2DEval(new RefPtg("A1"), new NumberEval(25));
Eval[] args= { arg0, criteriaArg, };
double actual = NumericFunctionInvoker.invoke(new Countif(), args);
package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.Area2DEval;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
// startPos is 1x1 area ref, numChars is cell ref
AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } );
- RefEval reNumChars = new Ref2DEval(new ReferencePtg("B1"), new NumberEval(3));
+ RefEval reNumChars = new Ref2DEval(new RefPtg("B1"), new NumberEval(3));
confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
public void testScalarSimple() {
- RefEval refEval = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(3));
+ RefEval refEval = new Ref2DEval(new RefPtg("A1"), new NumberEval(3));
Eval[] args = {
refEval,
new NumberEval(2),
package org.apache.poi.hssf.record.formula.functions;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
* where cell A1 has the specified innerValue
*/
private Eval invokeTWithReference(ValueEval innerValue) {
- Eval arg = new Ref2DEval(new ReferencePtg((short)1, (short)1, false, false), innerValue);
+ Eval arg = new Ref2DEval(new RefPtg((short)1, (short)1, false, false), innerValue);
return invokeT(arg);
}