aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorJosh Micich <josh@apache.org>2008-09-17 21:23:58 +0000
committerJosh Micich <josh@apache.org>2008-09-17 21:23:58 +0000
commitfe820eed5c4aba26347a7d117ffd9f4d052552de (patch)
treea2b0e4ea093222e951842a3d89928ad3113ad42b /src/java
parent3ed09846f965e2f382f3149a1520fdc5e9b29d86 (diff)
downloadpoi-fe820eed5c4aba26347a7d117ffd9f4d052552de.tar.gz
poi-fe820eed5c4aba26347a7d117ffd9f4d052552de.zip
merged 696038 from trunk - (Fix for bug 45780 - update area refs during HSSFSheet.shiftRows())
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@696453 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/poi/hssf/model/Sheet.java50
-rw-r--r--src/java/org/apache/poi/hssf/record/NameRecord.java4
-rw-r--r--src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java4
-rw-r--r--src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java21
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java20
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java43
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java12
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java8
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java44
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/FormulaShifter.java294
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java68
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java104
-rwxr-xr-xsrc/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java39
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/RefNPtg.java18
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/RefPtg.java40
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java57
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFCell.java8
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFName.java12
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java88
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java48
20 files changed, 611 insertions, 371 deletions
diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java
index 8bbc30435a..164399939a 100644
--- a/src/java/org/apache/poi/hssf/model/Sheet.java
+++ b/src/java/org/apache/poi/hssf/model/Sheet.java
@@ -62,7 +62,6 @@ import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
-import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
import org.apache.poi.hssf.record.aggregates.RecordAggregate;
@@ -127,7 +126,8 @@ public final class Sheet implements Model {
/*package*/ColumnInfoRecordsAggregate _columnInfos;
/** the DimensionsRecord is always present */
private DimensionsRecord _dimensions;
- protected RowRecordsAggregate _rowsAggregate = null;
+ /** always present */
+ protected RowRecordsAggregate _rowsAggregate;
private DataValidityTable _dataValidityTable= null;
private ConditionalFormattingTable condFormatting;
@@ -329,10 +329,13 @@ public final class Sheet implements Model {
if (retval.windowTwo == null) {
throw new RuntimeException("WINDOW2 was not found");
}
+ if (retval._rowsAggregate == null) {
+ retval._rowsAggregate = new RowRecordsAggregate();
+ records.add(retval.dimsloc + 1, retval._rowsAggregate);
+ }
// put merged cells table in the right place (regardless of where the first MergedCellsRecord was found */
RecordOrderer.addNewSheetRecord(records, retval._mergedCellsTable);
retval.records = records;
- retval.checkRows();
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
return retval;
@@ -441,6 +444,8 @@ public final class Sheet implements Model {
retval._dimensions = createDimensions();
records.add(retval._dimensions);
retval.dimsloc = records.size()-1;
+ retval._rowsAggregate = new RowRecordsAggregate();
+ records.add(retval._rowsAggregate);
// 'Sheet View Settings'
records.add(retval.windowTwo = retval.createWindowTwo());
retval.selection = createSelection();
@@ -456,14 +461,10 @@ public final class Sheet implements Model {
return retval;
}
- private void checkRows()
- {
- if (_rowsAggregate == null)
- {
- _rowsAggregate = new RowRecordsAggregate();
- records.add(dimsloc + 1, _rowsAggregate);
- }
+ public RowRecordsAggregate getRowsAggregate() {
+ return _rowsAggregate;
}
+
private MergedCellsTable getMergedRecords() {
// always present
return _mergedCellsTable;
@@ -624,13 +625,6 @@ public final class Sheet implements Model {
}
/**
- * Create a row record. (does not add it to the records contained in this sheet)
- */
- private static RowRecord createRow(int row) {
- return RowRecordsAggregate.createRow( row );
- }
-
- /**
* Adds a value record to the sheet's contained binary records
* (i.e. LabelSSTRecord or NumberRecord).
* <P>
@@ -714,7 +708,6 @@ public final class Sheet implements Model {
public void addRow(RowRecord row)
{
- checkRows();
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "addRow ");
DimensionsRecord d = _dimensions;
@@ -748,7 +741,6 @@ public final class Sheet implements Model {
* @param row the row record to remove
*/
public void removeRow(RowRecord row) {
- checkRows();
_rowsAggregate.removeRow(row);
}
@@ -1295,7 +1287,7 @@ public final class Sheet implements Model {
}
/**
- * Returns the first occurance of a record matching a particular sid.
+ * Returns the first occurrence of a record matching a particular sid.
*/
public Record findFirstRecordBySid(short sid)
@@ -1781,13 +1773,12 @@ public final class Sheet implements Model {
public void groupRowRange(int fromRow, int toRow, boolean indent)
{
- checkRows();
for (int rowNum = fromRow; rowNum <= toRow; rowNum++)
{
RowRecord row = getRow( rowNum );
if (row == null)
{
- row = createRow( rowNum );
+ row = RowRecordsAggregate.createRow(rowNum);
addRow( row );
}
int level = row.getOutlineLevel();
@@ -1817,17 +1808,6 @@ public final class Sheet implements Model {
guts.setLeftRowGutter( (short) ( 29 + (12 * (maxLevel)) ) );
}
- public void setRowGroupCollapsed( int row, boolean collapse )
- {
- if (collapse)
- {
- _rowsAggregate.collapseRow( row );
- }
- else
- {
- _rowsAggregate.expandRow( row );
- }
- }
public DataValidityTable getOrCreateDataValidityTable() {
if (_dataValidityTable == null) {
DataValidityTable result = new DataValidityTable();
@@ -1836,8 +1816,4 @@ public final class Sheet implements Model {
}
return _dataValidityTable;
}
-
- public FormulaRecordAggregate createFormula(int row, int col) {
- return _rowsAggregate.createFormula(row, col);
- }
}
diff --git a/src/java/org/apache/poi/hssf/record/NameRecord.java b/src/java/org/apache/poi/hssf/record/NameRecord.java
index 0716c448d8..215c20feec 100644
--- a/src/java/org/apache/poi/hssf/record/NameRecord.java
+++ b/src/java/org/apache/poi/hssf/record/NameRecord.java
@@ -537,9 +537,7 @@ public final class NameRecord extends Record {
temp.add(ptg);
}
} else {
- Ptg ptg = new Ref3DPtg();
- ((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex);
- ((Ref3DPtg) ptg).setArea(ref);
+ Ref3DPtg ptg = new Ref3DPtg(ra.getFromCell(), externSheetIndex);
temp.add(ptg);
}
Ptg[] ptgs = new Ptg[temp.size()];
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
index c5bbc31199..c7610de1ea 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
@@ -35,6 +35,7 @@ import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.TableRecord;
import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.formula.FormulaShifter;
/**
*
@@ -507,4 +508,7 @@ public final class RowRecordsAggregate extends RecordAggregate {
fr.setColumn((short) col);
return new FormulaRecordAggregate(fr, null, _sharedValueManager);
}
+ public void updateFormulasAfterRowShift(FormulaShifter formulaShifter, int currentExternSheetIndex) {
+ _valuesAgg.updateFormulasAfterRowShift(formulaShifter, currentExternSheetIndex);
+ }
}
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
index 4552be797a..a9b1de2531 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
@@ -28,6 +28,8 @@ import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
+import org.apache.poi.hssf.record.formula.FormulaShifter;
+import org.apache.poi.hssf.record.formula.Ptg;
/**
*
@@ -225,6 +227,25 @@ public final class ValueRecordsAggregate {
}
}
+ public void updateFormulasAfterRowShift(FormulaShifter shifter, int currentExternSheetIndex) {
+ for (int i = 0; i < records.length; i++) {
+ CellValueRecordInterface[] rowCells = records[i];
+ if (rowCells == null) {
+ continue;
+ }
+ for (int j = 0; j < rowCells.length; j++) {
+ CellValueRecordInterface cell = rowCells[j];
+ if (cell instanceof FormulaRecordAggregate) {
+ FormulaRecord fr = ((FormulaRecordAggregate)cell).getFormulaRecord();
+ Ptg[] ptgs = fr.getParsedExpression(); // needs clone() inside this getter?
+ if (shifter.adjustFormula(ptgs, currentExternSheetIndex)) {
+ fr.setParsedExpression(ptgs);
+ }
+ }
+ }
+ }
+ }
+
public CellValueRecordInterface[] getValueRecords() {
List temp = new ArrayList();
diff --git a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
index 2183cc2dd0..0c97d03d29 100644
--- a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
@@ -90,24 +90,6 @@ public final class Area3DPtg extends AreaPtgBase {
* formulas. The sheet name will get properly delimited if required.
*/
public String toFormulaString(Workbook book) {
- // First do the sheet name
- StringBuffer retval = new StringBuffer();
- String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
- if(sheetName != null) {
- if(sheetName.length() == 0) {
- // What excel does if sheet has been deleted
- sheetName = "#REF";
- retval.append(sheetName);
- } else {
- // Normal
- SheetNameFormatter.appendFormat(retval, sheetName);
- }
- retval.append( '!' );
- }
-
- // Now the normal area bit
- retval.append(formatReferenceAsString());
-
- return retval.toString();
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
}
}
diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
index f1af9b68d1..1387e76856 100644
--- a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
@@ -18,6 +18,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.ErrorConstants;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.LittleEndian;
@@ -27,23 +28,31 @@ import org.apache.poi.util.LittleEndian;
* @author Daniel Noll (daniel at nuix dot com dot au)
*/
public final class AreaErrPtg extends OperandPtg {
- public final static byte sid = 0x2b;
-
- public AreaErrPtg(RecordInputStream in) {
- // 8 bytes unused:
- in.readInt();
- in.readInt();
- }
-
- public void writeBytes(byte [] array, int offset) {
- array[offset] = (byte) (sid + getPtgClass());
- LittleEndian.putInt(array, offset+1, 0);
- LittleEndian.putInt(array, offset+5, 0);
- }
-
- public String toFormulaString(Workbook book) {
- return "#REF!";
- }
+ public final static byte sid = 0x2B;
+ private final int unused1;
+ private final int unused2;
+
+ public AreaErrPtg() {
+ unused1 = 0;
+ unused2 = 0;
+ }
+
+ public AreaErrPtg(RecordInputStream in) {
+ // 8 bytes unused:
+ unused1 = in.readInt();
+ unused2 = in.readInt();
+ }
+
+ public void writeBytes(byte[] array, int offset) {
+ LittleEndian.putByte(array, offset + 0, sid + getPtgClass());
+ LittleEndian.putInt(array, offset + 1, unused1);
+ LittleEndian.putInt(array, offset + 5, unused2);
+ }
+
+
+ public String toFormulaString(Workbook book) {
+ return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+ }
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
diff --git a/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
index a1c5b3db59..92506dfbe7 100644
--- a/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
@@ -35,13 +35,21 @@ public final class DeletedArea3DPtg extends OperandPtg {
private final int unused1;
private final int unused2;
- public DeletedArea3DPtg( RecordInputStream in) {
+ public DeletedArea3DPtg(int externSheetIndex) {
+ field_1_index_extern_sheet = externSheetIndex;
+ unused1 = 0;
+ unused2 = 0;
+ }
+
+ public DeletedArea3DPtg(RecordInputStream in) {
field_1_index_extern_sheet = in.readUShort();
unused1 = in.readInt();
unused2 = in.readInt();
}
+
public String toFormulaString(Workbook book) {
- return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
+ ErrorConstants.getText(ErrorConstants.ERROR_REF));
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
diff --git a/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
index 9312b2d766..900a48fe8e 100644
--- a/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
@@ -41,8 +41,14 @@ public final class DeletedRef3DPtg extends OperandPtg {
unused1 = in.readInt();
}
+ public DeletedRef3DPtg(int externSheetIndex) {
+ field_1_index_extern_sheet = externSheetIndex;
+ unused1 = 0;
+ }
+
public String toFormulaString(Workbook book) {
- return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
+ ErrorConstants.getText(ErrorConstants.ERROR_REF));
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
diff --git a/src/java/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java b/src/java/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java
new file mode 100644
index 0000000000..b928931b09
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java
@@ -0,0 +1,44 @@
+/* ====================================================================
+ 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.ss.usermodel.Workbook;
+
+/**
+ * @author Josh Micich
+ */
+final class ExternSheetNameResolver {
+
+ private ExternSheetNameResolver() {
+ // no instances of this class
+ }
+
+ public static String prependSheetName(Workbook book, int field_1_index_extern_sheet, String cellRefText) {
+ String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
+ StringBuffer sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
+ if (sheetName.length() < 1) {
+ // What excel does if sheet has been deleted
+ sb.append("#REF"); // note - '!' added just once below
+ } else {
+ SheetNameFormatter.appendFormat(sb, sheetName);
+ }
+ sb.append('!');
+ sb.append(cellRefText);
+ return sb.toString();
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/FormulaShifter.java b/src/java/org/apache/poi/hssf/record/formula/FormulaShifter.java
new file mode 100644
index 0000000000..87683d64ee
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/FormulaShifter.java
@@ -0,0 +1,294 @@
+/* ====================================================================
+ 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;
+
+
+/**
+ * @author Josh Micich
+ */
+public final class FormulaShifter {
+
+ /**
+ * Extern sheet index of sheet where moving is occurring
+ */
+ private final int _externSheetIndex;
+ private final int _firstMovedIndex;
+ private final int _lastMovedIndex;
+ private final int _amountToMove;
+
+ private FormulaShifter(int externSheetIndex, int firstMovedIndex, int lastMovedIndex, int amountToMove) {
+ if (amountToMove == 0) {
+ throw new IllegalArgumentException("amountToMove must not be zero");
+ }
+ if (firstMovedIndex > lastMovedIndex) {
+ throw new IllegalArgumentException("firstMovedIndex, lastMovedIndex out of order");
+ }
+ _externSheetIndex = externSheetIndex;
+ _firstMovedIndex = firstMovedIndex;
+ _lastMovedIndex = lastMovedIndex;
+ _amountToMove = amountToMove;
+ }
+
+ public static FormulaShifter createForRowShift(int externSheetIndex, int firstMovedRowIndex, int lastMovedRowIndex, int numberOfRowsToMove) {
+ return new FormulaShifter(externSheetIndex, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(_firstMovedIndex);
+ sb.append(_lastMovedIndex);
+ sb.append(_amountToMove);
+ return sb.toString();
+ }
+
+ /**
+ * @param ptgs - if necessary, will get modified by this method
+ * @param currentExternSheetIx - the extern sheet index of the sheet that contains the formula being adjusted
+ * @return <code>true</code> if a change was made to the formula tokens
+ */
+ public boolean adjustFormula(Ptg[] ptgs, int currentExternSheetIx) {
+ boolean refsWereChanged = false;
+ for(int i=0; i<ptgs.length; i++) {
+ Ptg newPtg = adjustPtg(ptgs[i], currentExternSheetIx);
+ if (newPtg != null) {
+ refsWereChanged = true;
+ ptgs[i] = newPtg;
+ }
+ }
+ return refsWereChanged;
+ }
+
+ private Ptg adjustPtg(Ptg ptg, int currentExternSheetIx) {
+ return adjustPtgDueToRowMove(ptg, currentExternSheetIx);
+ }
+ /**
+ * @return <code>true</code> if this Ptg needed to be changed
+ */
+ private Ptg adjustPtgDueToRowMove(Ptg ptg, int currentExternSheetIx) {
+ if(ptg instanceof RefPtg) {
+ if (currentExternSheetIx != _externSheetIndex) {
+ // local refs on other sheets are unaffected
+ return null;
+ }
+ RefPtg rptg = (RefPtg)ptg;
+ return rowMoveRefPtg(rptg);
+ }
+ if(ptg instanceof Ref3DPtg) {
+ Ref3DPtg rptg = (Ref3DPtg)ptg;
+ if (_externSheetIndex != rptg.getExternSheetIndex()) {
+ // only move 3D refs that refer to the sheet with cells being moved
+ // (currentExternSheetIx is irrelevant)
+ return null;
+ }
+ return rowMoveRefPtg(rptg);
+ }
+ if(ptg instanceof Area2DPtgBase) {
+ if (currentExternSheetIx != _externSheetIndex) {
+ // local refs on other sheets are unaffected
+ return ptg;
+ }
+ return rowMoveAreaPtg((Area2DPtgBase)ptg);
+ }
+ if(ptg instanceof Area3DPtg) {
+ Area3DPtg aptg = (Area3DPtg)ptg;
+ if (_externSheetIndex != aptg.getExternSheetIndex()) {
+ // only move 3D refs that refer to the sheet with cells being moved
+ // (currentExternSheetIx is irrelevant)
+ return null;
+ }
+ return rowMoveAreaPtg(aptg);
+ }
+ return null;
+ }
+
+ private Ptg rowMoveRefPtg(RefPtgBase rptg) {
+ int refRow = rptg.getRow();
+ if (_firstMovedIndex <= refRow && refRow <= _lastMovedIndex) {
+ // Rows being moved completely enclose the ref.
+ // - move the area ref along with the rows regardless of destination
+ rptg.setRow(refRow + _amountToMove);
+ return rptg;
+ }
+ // else rules for adjusting area may also depend on the destination of the moved rows
+
+ int destFirstRowIndex = _firstMovedIndex + _amountToMove;
+ int destLastRowIndex = _lastMovedIndex + _amountToMove;
+
+ // ref is outside source rows
+ // check for clashes with destination
+
+ if (destLastRowIndex < refRow || refRow < destFirstRowIndex) {
+ // destination rows are completely outside ref
+ return null;
+ }
+
+ if (destFirstRowIndex <= refRow && refRow <= destLastRowIndex) {
+ // destination rows enclose the area (possibly exactly)
+ return createDeletedRef(rptg);
+ }
+ throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " +
+ _lastMovedIndex + ", " + _amountToMove + ", " + refRow + ", " + refRow + ")");
+ }
+
+ private Ptg rowMoveAreaPtg(AreaPtgBase aptg) {
+ int aFirstRow = aptg.getFirstRow();
+ int aLastRow = aptg.getLastRow();
+ if (_firstMovedIndex <= aFirstRow && aLastRow <= _lastMovedIndex) {
+ // Rows being moved completely enclose the area ref.
+ // - move the area ref along with the rows regardless of destination
+ aptg.setFirstRow(aFirstRow + _amountToMove);
+ aptg.setLastRow(aLastRow + _amountToMove);
+ return aptg;
+ }
+ // else rules for adjusting area may also depend on the destination of the moved rows
+
+ int destFirstRowIndex = _firstMovedIndex + _amountToMove;
+ int destLastRowIndex = _lastMovedIndex + _amountToMove;
+
+ if (aFirstRow < _firstMovedIndex && _lastMovedIndex < aLastRow) {
+ // Rows moved were originally *completely* within the area ref
+
+ // If the destination of the rows overlaps either the top
+ // or bottom of the area ref there will be a change
+ if (destFirstRowIndex < aFirstRow && aFirstRow <= destLastRowIndex) {
+ // truncate the top of the area by the moved rows
+ aptg.setFirstRow(destLastRowIndex+1);
+ return aptg;
+ } else if (destFirstRowIndex <= aLastRow && aLastRow < destLastRowIndex) {
+ // truncate the bottom of the area by the moved rows
+ aptg.setLastRow(destFirstRowIndex-1);
+ return aptg;
+ }
+ // else - rows have moved completely outside the area ref,
+ // or still remain completely within the area ref
+ return null; // - no change to the area
+ }
+ if (_firstMovedIndex <= aFirstRow && aFirstRow <= _lastMovedIndex) {
+ // Rows moved include the first row of the area ref, but not the last row
+ // btw: (aLastRow > _lastMovedIndex)
+ if (_amountToMove < 0) {
+ // simple case - expand area by shifting top upward
+ aptg.setFirstRow(aFirstRow + _amountToMove);
+ return aptg;
+ }
+ if (destFirstRowIndex > aLastRow) {
+ // in this case, excel ignores the row move
+ return null;
+ }
+ int newFirstRowIx = aFirstRow + _amountToMove;
+ if (destLastRowIndex < aLastRow) {
+ // end of area is preserved (will remain exact same row)
+ // the top area row is moved simply
+ aptg.setFirstRow(newFirstRowIx);
+ return aptg;
+ }
+ // else - bottom area row has been replaced - both area top and bottom may move now
+ int areaRemainingTopRowIx = _lastMovedIndex + 1;
+ if (destFirstRowIndex > areaRemainingTopRowIx) {
+ // old top row of area has moved deep within the area, and exposed a new top row
+ newFirstRowIx = areaRemainingTopRowIx;
+ }
+ aptg.setFirstRow(newFirstRowIx);
+ aptg.setLastRow(Math.max(aLastRow, destLastRowIndex));
+ return aptg;
+ }
+ if (_firstMovedIndex <= aLastRow && aLastRow <= _lastMovedIndex) {
+ // Rows moved include the last row of the area ref, but not the first
+ // btw: (aFirstRow < _firstMovedIndex)
+ if (_amountToMove > 0) {
+ // simple case - expand area by shifting bottom downward
+ aptg.setLastRow(aLastRow + _amountToMove);
+ return aptg;
+ }
+ if (destLastRowIndex < aFirstRow) {
+ // in this case, excel ignores the row move
+ return null;
+ }
+ int newLastRowIx = aLastRow + _amountToMove;
+ if (destFirstRowIndex > aFirstRow) {
+ // top of area is preserved (will remain exact same row)
+ // the bottom area row is moved simply
+ aptg.setLastRow(newLastRowIx);
+ return aptg;
+ }
+ // else - top area row has been replaced - both area top and bottom may move now
+ int areaRemainingBottomRowIx = _firstMovedIndex - 1;
+ if (destLastRowIndex < areaRemainingBottomRowIx) {
+ // old bottom row of area has moved up deep within the area, and exposed a new bottom row
+ newLastRowIx = areaRemainingBottomRowIx;
+ }
+ aptg.setFirstRow(Math.min(aFirstRow, destFirstRowIndex));
+ aptg.setLastRow(newLastRowIx);
+ return aptg;
+ }
+ // else source rows include none of the rows of the area ref
+ // check for clashes with destination
+
+ if (destLastRowIndex < aFirstRow || aLastRow < destFirstRowIndex) {
+ // destination rows are completely outside area ref
+ return null;
+ }
+
+ if (destFirstRowIndex <= aFirstRow && aLastRow <= destLastRowIndex) {
+ // destination rows enclose the area (possibly exactly)
+ return createDeletedRef(aptg);
+ }
+
+ if (aFirstRow <= destFirstRowIndex && destLastRowIndex <= aLastRow) {
+ // destination rows are within area ref (possibly exact on top or bottom, but not both)
+ return null; // - no change to area
+ }
+
+ if (destFirstRowIndex < aFirstRow && aFirstRow <= destLastRowIndex) {
+ // dest rows overlap top of area
+ // - truncate the top
+ aptg.setFirstRow(destLastRowIndex+1);
+ return aptg;
+ }
+ if (destFirstRowIndex < aLastRow && aLastRow <= destLastRowIndex) {
+ // dest rows overlap bottom of area
+ // - truncate the bottom
+ aptg.setLastRow(destFirstRowIndex-1);
+ return aptg;
+ }
+ throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " +
+ _lastMovedIndex + ", " + _amountToMove + ", " + aFirstRow + ", " + aLastRow + ")");
+ }
+
+ private static Ptg createDeletedRef(Ptg ptg) {
+ if (ptg instanceof RefPtg) {
+ return new RefErrorPtg();
+ }
+ if (ptg instanceof Ref3DPtg) {
+ Ref3DPtg rptg = (Ref3DPtg) ptg;
+ return new DeletedRef3DPtg(rptg.getExternSheetIndex());
+ }
+ if (ptg instanceof AreaPtg) {
+ return new AreaErrPtg();
+ }
+ if (ptg instanceof Area3DPtg) {
+ Area3DPtg area3DPtg = (Area3DPtg) ptg;
+ return new DeletedArea3DPtg(area3DPtg.getExternSheetIndex());
+ }
+
+ throw new IllegalArgumentException("Unexpected ref ptg class (" + ptg.getClass().getName() + ")");
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java
new file mode 100644
index 0000000000..2fff41d6b7
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java
@@ -0,0 +1,68 @@
+/* ====================================================================
+ 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;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * @author Josh Micich
+ */
+abstract class Ref2DPtgBase extends RefPtgBase {
+ private final static int SIZE = 5;
+
+ /**
+ * Takes in a String representation of a cell reference and fills out the
+ * numeric fields.
+ */
+ protected Ref2DPtgBase(String cellref) {
+ super(cellref);
+ }
+
+ protected Ref2DPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ setRow(row);
+ setColumn(column);
+ setRowRelative(isRowRelative);
+ setColRelative(isColumnRelative);
+ }
+
+ protected Ref2DPtgBase(RecordInputStream in) {
+ readCoordinates(in);
+ }
+ public final void writeBytes(byte [] array, int offset) {
+ LittleEndian.putByte(array, offset+0, getSid() + getPtgClass());
+ writeCoordinates(array, offset+1);
+ }
+ public final String toFormulaString(Workbook book) {
+ return formatReferenceAsString();
+ }
+
+ protected abstract byte getSid();
+ public final int getSize() {
+ return SIZE;
+ }
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
index e72cbbc30a..308e9f0b53 100644
--- a/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
@@ -18,12 +18,8 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.RangeAddress;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.ss.util.SheetReferences;
-import org.apache.poi.util.BitField;
-import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndian;
/**
@@ -34,49 +30,36 @@ import org.apache.poi.util.LittleEndian;
* @author Jason Height (jheight at chariot dot net dot au)
* @version 1.0-pre
*/
-public final class Ref3DPtg extends OperandPtg {
+public final class Ref3DPtg extends RefPtgBase {
public final static byte sid = 0x3a;
- private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
- private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
-
private final static int SIZE = 7; // 6 + 1 for Ptg
private int field_1_index_extern_sheet;
- /** The row index - zero based unsigned 16 bit value */
- private int field_2_row;
- /** Field 2
- * - lower 8 bits is the zero based unsigned byte column index
- * - bit 16 - isRowRelative
- * - bit 15 - isColumnRelative
- */
- private int field_3_column;
/** Creates new AreaPtg */
public Ref3DPtg() {}
public Ref3DPtg(RecordInputStream in) {
field_1_index_extern_sheet = in.readShort();
- field_2_row = in.readShort();
- field_3_column = in.readShort();
+ readCoordinates(in);
}
public Ref3DPtg(String cellref, short externIdx ) {
CellReference c= new CellReference(cellref);
setRow(c.getRow());
- setColumn((short)c.getCol());
+ setColumn(c.getCol());
setColRelative(!c.isColAbsolute());
setRowRelative(!c.isRowAbsolute());
setExternSheetIndex(externIdx);
}
public String toString() {
- CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(),!isColRelative());
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append("sheetIx=").append(getExternSheetIndex());
sb.append(" ! ");
- sb.append(cr.formatAsString());
+ sb.append(formatReferenceAsString());
sb.append("]");
return sb.toString();
}
@@ -84,8 +67,7 @@ public final class Ref3DPtg extends OperandPtg {
public void writeBytes(byte [] array, int offset) {
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());
+ writeCoordinates(array, offset+3);
}
public int getSize() {
@@ -100,83 +82,11 @@ public final class Ref3DPtg extends OperandPtg {
field_1_index_extern_sheet = index;
}
- public int getRow() {
- return field_2_row;
- }
-
- public void setRow(int row) {
- field_2_row = row;
- }
-
- public int getColumn() {
- return field_3_column & 0xFF;
- }
-
- public int getColumnRaw() {
- return field_3_column;
- }
-
- public boolean isRowRelative()
- {
- return rowRelative.isSet(field_3_column);
- }
-
- public void setRowRelative(boolean rel) {
- field_3_column=rowRelative.setBoolean(field_3_column,rel);
- }
-
- public boolean isColRelative()
- {
- return colRelative.isSet(field_3_column);
- }
-
- public void setColRelative(boolean rel) {
- field_3_column=colRelative.setBoolean(field_3_column,rel);
- }
- public void setColumn(short column) {
- field_3_column &= 0xFF00;
- field_3_column |= column & 0xFF;
- }
-
- public void setColumnRaw(short column) {
- field_3_column = column;
- }
-
- /* public String getArea(){
- RangeAddress ra = new RangeAddress("");
-
- String result = (ra.numTo26Sys(getColumn()) + (getRow() + 1));
-
- return result;
- }*/
-
- public void setArea(String ref){
- RangeAddress ra = new RangeAddress(ref);
-
- String from = ra.getFromCell();
-
- setColumn((short) (ra.getXPosition(from) -1));
- setRow((short) (ra.getYPosition(from) -1));
-
- }
-
/**
* @return text representation of this cell reference that can be used in text
* formulas. The sheet name will get properly delimited if required.
*/
- public String toFormulaString(Workbook book)
- {
- StringBuffer retval = new StringBuffer();
- String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
- if(sheetName != null) {
- SheetNameFormatter.appendFormat(retval, sheetName);
- retval.append( '!' );
- }
- retval.append((new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).formatAsString());
- return retval.toString();
+ public String toFormulaString(Workbook book) {
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
}
-
- public byte getDefaultOperandClass() {
- return Ptg.CLASS_REF;
- }
}
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
index 6adbe43c51..a3030e1bd7 100755
--- a/src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
@@ -18,6 +18,7 @@
package org.apache.poi.hssf.record.formula;
import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.usermodel.ErrorConstants;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.LittleEndian;
@@ -28,48 +29,32 @@ import org.apache.poi.util.LittleEndian;
public final class RefErrorPtg extends OperandPtg {
private final static int SIZE = 5;
- public final static byte sid = 0x2a;
+ public final static byte sid = 0x2A;
private int field_1_reserved;
- public RefErrorPtg(RecordInputStream in)
- {
+ public RefErrorPtg() {
+ field_1_reserved = 0;
+ }
+ public RefErrorPtg(RecordInputStream in) {
field_1_reserved = in.readInt();
-
}
- public String toString()
- {
- StringBuffer buffer = new StringBuffer("[RefError]\n");
-
- buffer.append("reserved = ").append(getReserved()).append("\n");
- return buffer.toString();
+ public String toString() {
+ return getClass().getName();
}
- public void writeBytes(byte [] array, int offset)
- {
- array[offset] = (byte) (sid + getPtgClass());
+ public void writeBytes(byte [] array, int offset) {
+ LittleEndian.putByte(array, offset+0, sid + getPtgClass());
LittleEndian.putInt(array,offset+1,field_1_reserved);
}
- public void setReserved(int reserved)
- {
- field_1_reserved = reserved;
- }
-
- public int getReserved()
- {
- return field_1_reserved;
- }
-
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 "#REF!";
+ public String toFormulaString(Workbook book) {
+ return ErrorConstants.getText(ErrorConstants.ERROR_REF);
}
public byte getDefaultOperandClass() {
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefNPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefNPtg.java
index 5ef4a413b3..07114265d0 100644
--- a/src/java/org/apache/poi/hssf/record/formula/RefNPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/RefNPtg.java
@@ -23,16 +23,14 @@ import org.apache.poi.hssf.record.RecordInputStream;
* RefNPtg
* @author Jason Height (jheight at apache dot com)
*/
-public final class RefNPtg extends RefPtgBase {
- public final static byte sid = 0x2C;
+public final class RefNPtg extends Ref2DPtgBase {
+ public final static byte sid = 0x2C;
- /** Creates new ValueReferencePtg */
+ public RefNPtg(RecordInputStream in) {
+ super(in);
+ }
- public RefNPtg(RecordInputStream in) {
- super(in);
- }
-
- protected byte getSid() {
- return sid;
- }
+ protected byte getSid() {
+ return sid;
+ }
}
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefPtg.java b/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
index a324ce70f9..94a1b3301c 100644
--- a/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
@@ -24,30 +24,26 @@ import org.apache.poi.hssf.record.RecordInputStream;
* @author Andrew C. Oliver (acoliver@apache.org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
-public final class RefPtg extends RefPtgBase {
- public final static byte sid = 0x24;
-
- /**
- * Takes in a String representation of a cell reference and fills out the
- * numeric fields.
- */
- public RefPtg(String cellref) {
- super(cellref);
- }
-
- public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
- setRow(row);
- setColumn(column);
- setRowRelative(isRowRelative);
- setColRelative(isColumnRelative);
- }
-
- public RefPtg(RecordInputStream in) {
- super(in);
- }
+public final class RefPtg extends Ref2DPtgBase {
+ public final static byte sid = 0x24;
+
+ /**
+ * Takes in a String representation of a cell reference and fills out the
+ * numeric fields.
+ */
+ public RefPtg(String cellref) {
+ super(cellref);
+ }
+
+ public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ super(row, column, isRowRelative, isColumnRelative);
+ }
+
+ public RefPtg(RecordInputStream in) {
+ super(in);
+ }
protected byte getSid() {
return sid;
}
-
}
diff --git a/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
index 33dff9ec04..f04ec0ac8f 100644
--- a/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
+++ b/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
@@ -17,13 +17,11 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.util.CellReference;
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;
+import org.apache.poi.util.LittleEndian;
/**
* ReferencePtgBase - handles references (such as A1, A2, IA4)
@@ -32,7 +30,6 @@ import org.apache.poi.hssf.record.RecordInputStream;
*/
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 */
@@ -70,29 +67,14 @@ public abstract class RefPtgBase extends OperandPtg {
setColRelative(isColumnRelative);
}
- protected RefPtgBase(RecordInputStream in) {
+ protected final void readCoordinates(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 final void writeCoordinates(byte[] array, int offset) {
+ LittleEndian.putUShort(array, offset + 0, field_1_row);
+ LittleEndian.putUShort(array, offset + 2, field_2_col);
}
-
- protected abstract byte getSid();
public final void setRow(int row) {
if(row < 0 || row >= MAX_ROW_NUMBER) {
@@ -102,18 +84,11 @@ public abstract class RefPtgBase extends OperandPtg {
}
/**
- * Returns the row number as a short, which will be
- * wrapped (negative) for values between 32769 and 65535
+ * @return the row number as an int, between 0 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);
@@ -135,20 +110,16 @@ public abstract class RefPtgBase extends OperandPtg {
if(col < 0 || col >= 0x100) {
throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
}
- field_2_col = column.setValue(field_2_col, col);
+ 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;
+ return column.getValue(field_2_col);
}
-
- 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();
+ protected final String formatReferenceAsString() {
+ // Only make cell references as needed. Memory is an issue
+ CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(), !isColRelative());
+ return cr.formatAsString();
}
public final byte getDefaultOperandClass() {
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index 1f88cce2bd..4fbedb8745 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -300,7 +300,7 @@ public class HSSFCell implements Cell {
FormulaRecordAggregate frec;
if (cellType != this.cellType) {
- frec = sheet.getSheet().createFormula(row, col);
+ frec = sheet.getSheet().getRowsAggregate().createFormula(row, col);
} else {
frec = (FormulaRecordAggregate) record;
frec.setRow(row);
@@ -600,12 +600,6 @@ public class HSSFCell implements Cell {
Ptg[] ptgs = FormulaParser.parse(formula, book);
frec.setParsedExpression(ptgs);
}
- /* package */ void setFormulaOnly(Ptg[] ptgs) {
- if (ptgs == null) {
- throw new IllegalArgumentException("ptgs must not be null");
- }
- ((FormulaRecordAggregate)record).getFormulaRecord().setParsedExpression(ptgs);
- }
public String getCellFormula() {
return FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
index 4fde9e6cc3..6de2293794 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java
@@ -126,8 +126,16 @@ public class HSSFName implements Name {
* @return true if the name refers to a deleted cell, false otherwise
*/
public boolean isDeleted(){
- String ref = getReference();
- return "#REF!".endsWith(ref);
+ String formulaText = getReference();
+ if (formulaText.startsWith("#REF!")) {
+ // sheet deleted
+ return true;
+ }
+ if (formulaText.endsWith("#REF!")) {
+ // cell range deleted
+ return true;
+ }
+ return false;
}
public boolean isFunctionName() {
return _definedNameRec.isFunctionName();
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index 4d6a1f7253..231942f440 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -31,7 +31,6 @@ import java.util.List;
import java.util.TreeMap;
import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.CellValueRecordInterface;
@@ -43,8 +42,7 @@ import org.apache.poi.hssf.record.SCLRecord;
import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.hssf.record.formula.FormulaShifter;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
@@ -1180,33 +1178,26 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* @param resetOriginalRowHeight whether to set the original row's height to the default
* @param moveComments whether to move comments at the same time as the cells they are attached to
*/
- public void shiftRows( int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments)
- {
- int s, e, inc;
- if ( n < 0 )
- {
+ public void shiftRows(int startRow, int endRow, int n,
+ boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments) {
+ int s, inc;
+ if (n < 0) {
s = startRow;
- e = endRow;
inc = 1;
- }
- else
- {
+ } else {
s = endRow;
- e = startRow;
inc = -1;
}
shiftMerged(startRow, endRow, n, true);
sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n);
- for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc )
- {
+ for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc ) {
HSSFRow row = getRow( rowNum );
HSSFRow row2Replace = getRow( rowNum + n );
if ( row2Replace == null )
row2Replace = createRow( rowNum + n );
- HSSFCell cell;
// Remove all the old cells from the row we'll
// be writing too, before we start overwriting
@@ -1236,7 +1227,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
// Copy each cell from the source row to
// the destination row
for(Iterator cells = row.cellIterator(); cells.hasNext(); ) {
- cell = (HSSFCell)cells.next();
+ HSSFCell cell = (HSSFCell)cells.next();
row.removeCell( cell );
CellValueRecordInterface cellRecord = cell.getCellValueRecord();
cellRecord.setRow( rowNum + n );
@@ -1263,49 +1254,21 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
// Update any formulas on this sheet that point to
// rows which have been moved
- updateFormulasAfterShift(startRow, endRow, n);
- }
-
- /**
- * Called by shiftRows to update formulas on this sheet
- * to point to the new location of moved rows
- */
- private void updateFormulasAfterShift(int startRow, int endRow, int n) {
- // Need to look at every cell on the sheet
- // Not just those that were moved
- Iterator ri = rowIterator();
- while(ri.hasNext()) {
- HSSFRow r = (HSSFRow)ri.next();
- Iterator ci = r.cellIterator();
- while(ci.hasNext()) {
- HSSFCell c = (HSSFCell)ci.next();
- if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
- // Since it's a formula cell, process the
- // formula string, and look to see if
- // it contains any references
-
- // Look for references, and update if needed
- Ptg[] ptgs = FormulaParser.parse(c.getCellFormula(), workbook);
- boolean changed = false;
- for(int i=0; i<ptgs.length; i++) {
- if(ptgs[i] instanceof RefPtg) {
- RefPtg rptg = (RefPtg)ptgs[i];
- if(startRow <= rptg.getRowAsInt() &&
- rptg.getRowAsInt() <= endRow) {
- // References a row that moved
- rptg.setRow(rptg.getRowAsInt() + n);
- changed = true;
- }
- }
- }
- // If any references were changed, then
- // re-create the formula string
- if(changed) {
- c.setFormulaOnly(ptgs);
- }
- }
+ int sheetIndex = workbook.getSheetIndex(this);
+ short externSheetIndex = book.checkExternSheet(sheetIndex);
+ FormulaShifter shifter = FormulaShifter.createForRowShift(externSheetIndex, startRow, endRow, n);
+ sheet.getRowsAggregate().updateFormulasAfterRowShift(shifter, externSheetIndex);
+
+ int nSheets = workbook.getNumberOfSheets();
+ for(int i=0; i<nSheets; i++) {
+ Sheet otherSheet = workbook.getSheetAt(i).getSheet();
+ if (otherSheet == this.sheet) {
+ continue;
}
+ short otherExtSheetIx = book.checkExternSheet(i);
+ otherSheet.getRowsAggregate().updateFormulasAfterRowShift(shifter, otherExtSheetIx);
}
+ // TODO - adjust formulas in named ranges
}
protected void insertChartRecords( List records )
@@ -1652,9 +1615,12 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
sheet.groupRowRange( fromRow, toRow, false );
}
- public void setRowGroupCollapsed( int row, boolean collapse )
- {
- sheet.setRowGroupCollapsed( row, collapse );
+ public void setRowGroupCollapsed(int rowIndex, boolean collapse) {
+ if (collapse) {
+ sheet.getRowsAggregate().collapseRow(rowIndex);
+ } else {
+ sheet.getRowsAggregate().expandRow(rowIndex);
+ }
}
/**
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index b0da561fae..83bae3e43b 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -678,10 +678,35 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
* if needed.
* Used by some of the more obscure formula and
* named range things.
+ * @deprecated for POI internal use only (formula parsing). This method is likely to
+ * be removed in future versions of POI.
*/
public int getExternalSheetIndex(int internalSheetIndex) {
return workbook.checkExternSheet(internalSheetIndex);
}
+ /**
+ * @deprecated for POI internal use only (formula rendering). This method is likely to
+ * be removed in future versions of POI.
+ */
+ public String findSheetNameFromExternSheet(int externSheetIndex){
+ // TODO - don't expose internal ugliness like externSheet indexes to the user model API
+ return workbook.findSheetNameFromExternSheet(externSheetIndex);
+ }
+ /**
+ * @deprecated for POI internal use only (formula rendering). This method is likely to
+ * be removed in future versions of POI.
+ *
+ * @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table
+ * @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record
+ * @return the string representation of the defined or external name
+ */
+ public String resolveNameXText(int refIndex, int definedNameIndex) {
+ // TODO - make this less cryptic / move elsewhere
+ return workbook.resolveNameXText(refIndex, definedNameIndex);
+ }
+
+
+
/**
* create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and returns
@@ -866,15 +891,6 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
}
/**
- * @deprecated for POI internal use only (formula rendering). This method is likely to
- * be removed in future versions of POI.
- */
- public String findSheetNameFromExternSheet(int externSheetIndex){
- // TODO - don't expose internal ugliness like externSheet indexes to the user model API
- return workbook.findSheetNameFromExternSheet(externSheetIndex);
- }
-
- /**
* Removes sheet at the given index.<p/>
*
* Care must be taken if the removed sheet is the currently active or only selected sheet in
@@ -1385,20 +1401,6 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
}
/**
- * @deprecated for POI internal use only (formula rendering). This method is likely to
- * be removed in future versions of POI.
- *
- * @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table
- * @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record
- * @return the string representation of the defined or external name
- */
- public String resolveNameXText(int refIndex, int definedNameIndex) {
- // TODO - make this less cryptic / move elsewhere
- return workbook.resolveNameXText(refIndex, definedNameIndex);
- }
-
-
- /**
* Sets the printarea for the sheet provided
* <p>
* i.e. Reference = $A$1:$B$2