bug 61474,github-81: add FormulaShifter.createForColumnShift and ShiftMode.ColumnMove

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1814254 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2017-11-04 05:29:52 +00:00
parent 40ae87fd36
commit 0e540db89b
2 changed files with 369 additions and 52 deletions

View File

@ -43,6 +43,7 @@ public final class FormulaShifter {
private static enum ShiftMode {
RowMove,
RowCopy,
ColumnMove,
SheetMove,
}
@ -116,6 +117,14 @@ public final class FormulaShifter {
return new FormulaShifter(externSheetIndex, sheetName, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove, ShiftMode.RowCopy, version);
}
/**
* @since POI 4.0.0
*/
public static FormulaShifter createForColumnShift(int externSheetIndex, String sheetName, int firstMovedColumnIndex, int lastMovedColumnIndex, int numberOfColumnsToMove,
SpreadsheetVersion version) {
return new FormulaShifter(externSheetIndex, sheetName, firstMovedColumnIndex, lastMovedColumnIndex, numberOfColumnsToMove, ShiftMode.ColumnMove, version);
}
public static FormulaShifter createForSheetShift(int srcSheetIndex, int dstSheetIndex) {
return new FormulaShifter(srcSheetIndex, dstSheetIndex);
}
@ -156,6 +165,8 @@ public final class FormulaShifter {
// * row copy on same sheet
// * row copy between different sheetsin the same workbook
return adjustPtgDueToRowCopy(ptg);
case ColumnMove:
return adjustPtgDueToColumnMove(ptg, currentExternSheetIx);
case SheetMove:
return adjustPtgDueToSheetMove(ptg);
default:
@ -264,6 +275,66 @@ public final class FormulaShifter {
return null;
}
/**
* @return in-place modified ptg (if column move would cause Ptg to change),
* deleted ref ptg (if column move causes an error),
* or null (if no Ptg change is needed)
*/
private Ptg adjustPtgDueToColumnMove(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 columnMoveRefPtg(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 columnMoveRefPtg(rptg);
}
if(ptg instanceof Ref3DPxg) {
Ref3DPxg rpxg = (Ref3DPxg)ptg;
if (rpxg.getExternalWorkbookNumber() > 0 ||
! _sheetName.equals(rpxg.getSheetName())) {
// only move 3D refs that refer to the sheet with cells being moved
return null;
}
return columnMoveRefPtg(rpxg);
}
if(ptg instanceof Area2DPtgBase) {
if (currentExternSheetIx != _externSheetIndex) {
// local refs on other sheets are unaffected
return ptg;
}
return columnMoveAreaPtg((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 columnMoveAreaPtg(aptg);
}
if(ptg instanceof Area3DPxg) {
Area3DPxg apxg = (Area3DPxg)ptg;
if (apxg.getExternalWorkbookNumber() > 0 ||
! _sheetName.equals(apxg.getSheetName())) {
// only move 3D refs that refer to the sheet with cells being moved
return null;
}
return columnMoveAreaPtg(apxg);
}
return null;
}
private Ptg adjustPtgDueToSheetMove(Ptg ptg) {
if(ptg instanceof Ref3DPtg) {
@ -522,6 +593,161 @@ public final class FormulaShifter {
return changed ? aptg : null;
}
private Ptg columnMoveRefPtg(RefPtgBase rptg) {
int refColumn = rptg.getColumn();
if (_firstMovedIndex <= refColumn && refColumn <= _lastMovedIndex) {
// Columns being moved completely enclose the ref.
// - move the area ref along with the columns regardless of destination
rptg.setColumn(refColumn + _amountToMove);
return rptg;
}
// else rules for adjusting area may also depend on the destination of the moved columns
int destFirstColumnIndex = _firstMovedIndex + _amountToMove;
int destLastColumnIndex = _lastMovedIndex + _amountToMove;
// ref is outside source columns
// check for clashes with destination
if (destLastColumnIndex < refColumn || refColumn < destFirstColumnIndex) {
// destination columns are completely outside ref
return null;
}
if (destFirstColumnIndex <= refColumn && refColumn <= destLastColumnIndex) {
// destination columns enclose the area (possibly exactly)
return createDeletedRef(rptg);
}
throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " +
_lastMovedIndex + ", " + _amountToMove + ", " + refColumn + ", " + refColumn + ")");
}
private Ptg columnMoveAreaPtg(AreaPtgBase aptg) {
int aFirstColumn = aptg.getFirstColumn();
int aLastColumn = aptg.getLastColumn();
if (_firstMovedIndex <= aFirstColumn && aLastColumn <= _lastMovedIndex) {
// Columns being moved completely enclose the area ref.
// - move the area ref along with the columns regardless of destination
aptg.setFirstColumn(aFirstColumn + _amountToMove);
aptg.setLastColumn(aLastColumn + _amountToMove);
return aptg;
}
// else rules for adjusting area may also depend on the destination of the moved columns
int destFirstColumnIndex = _firstMovedIndex + _amountToMove;
int destLastColumnIndex = _lastMovedIndex + _amountToMove;
if (aFirstColumn < _firstMovedIndex && _lastMovedIndex < aLastColumn) {
// Columns moved were originally *completely* within the area ref
// If the destination of the columns overlaps either the top
// or bottom of the area ref there will be a change
if (destFirstColumnIndex < aFirstColumn && aFirstColumn <= destLastColumnIndex) {
// truncate the top of the area by the moved columns
aptg.setFirstColumn(destLastColumnIndex+1);
return aptg;
} else if (destFirstColumnIndex <= aLastColumn && aLastColumn < destLastColumnIndex) {
// truncate the bottom of the area by the moved columns
aptg.setLastColumn(destFirstColumnIndex-1);
return aptg;
}
// else - columns have moved completely outside the area ref,
// or still remain completely within the area ref
return null; // - no change to the area
}
if (_firstMovedIndex <= aFirstColumn && aFirstColumn <= _lastMovedIndex) {
// Columns moved include the first column of the area ref, but not the last column
// btw: (aLastColumn > _lastMovedIndex)
if (_amountToMove < 0) {
// simple case - expand area by shifting top upward
aptg.setFirstColumn(aFirstColumn + _amountToMove);
return aptg;
}
if (destFirstColumnIndex > aLastColumn) {
// in this case, excel ignores the column move
return null;
}
int newFirstColumnIx = aFirstColumn + _amountToMove;
if (destLastColumnIndex < aLastColumn) {
// end of area is preserved (will remain exact same column)
// the top area column is moved simply
aptg.setFirstColumn(newFirstColumnIx);
return aptg;
}
// else - bottom area column has been replaced - both area top and bottom may move now
int areaRemainingTopColumnIx = _lastMovedIndex + 1;
if (destFirstColumnIndex > areaRemainingTopColumnIx) {
// old top column of area has moved deep within the area, and exposed a new top column
newFirstColumnIx = areaRemainingTopColumnIx;
}
aptg.setFirstColumn(newFirstColumnIx);
aptg.setLastColumn(Math.max(aLastColumn, destLastColumnIndex));
return aptg;
}
if (_firstMovedIndex <= aLastColumn && aLastColumn <= _lastMovedIndex) {
// Columns moved include the last column of the area ref, but not the first
// btw: (aFirstColumn < _firstMovedIndex)
if (_amountToMove > 0) {
// simple case - expand area by shifting bottom downward
aptg.setLastColumn(aLastColumn + _amountToMove);
return aptg;
}
if (destLastColumnIndex < aFirstColumn) {
// in this case, excel ignores the column move
return null;
}
int newLastColumnIx = aLastColumn + _amountToMove;
if (destFirstColumnIndex > aFirstColumn) {
// top of area is preserved (will remain exact same column)
// the bottom area column is moved simply
aptg.setLastColumn(newLastColumnIx);
return aptg;
}
// else - top area column has been replaced - both area top and bottom may move now
int areaRemainingBottomColumnIx = _firstMovedIndex - 1;
if (destLastColumnIndex < areaRemainingBottomColumnIx) {
// old bottom column of area has moved up deep within the area, and exposed a new bottom column
newLastColumnIx = areaRemainingBottomColumnIx;
}
aptg.setFirstColumn(Math.min(aFirstColumn, destFirstColumnIndex));
aptg.setLastColumn(newLastColumnIx);
return aptg;
}
// else source columns include none of the columns of the area ref
// check for clashes with destination
if (destLastColumnIndex < aFirstColumn || aLastColumn < destFirstColumnIndex) {
// destination columns are completely outside area ref
return null;
}
if (destFirstColumnIndex <= aFirstColumn && aLastColumn <= destLastColumnIndex) {
// destination columns enclose the area (possibly exactly)
return createDeletedRef(aptg);
}
if (aFirstColumn <= destFirstColumnIndex && destLastColumnIndex <= aLastColumn) {
// destination columns are within area ref (possibly exact on top or bottom, but not both)
return null; // - no change to area
}
if (destFirstColumnIndex < aFirstColumn && aFirstColumn <= destLastColumnIndex) {
// dest columns overlap top of area
// - truncate the top
aptg.setFirstColumn(destLastColumnIndex+1);
return aptg;
}
if (destFirstColumnIndex <= aLastColumn && aLastColumn < destLastColumnIndex) {
// dest columns overlap bottom of area
// - truncate the bottom
aptg.setLastColumn(destFirstColumnIndex-1);
return aptg;
}
throw new IllegalStateException("Situation not covered: (" + _firstMovedIndex + ", " +
_lastMovedIndex + ", " + _amountToMove + ", " + aFirstColumn + ", " + aLastColumn + ")");
}
private static Ptg createDeletedRef(Ptg ptg) {
if (ptg instanceof RefPtg) {
return new RefErrorPtg();

View File

@ -48,61 +48,101 @@ public final class TestFormulaShifter {
public void testShiftAreasSourceRows() {
// all these operations are on an area ref spanning rows 10 to 20
AreaPtg aptg = createAreaPtg(10, 20);
AreaPtg aptg = createAreaPtgRow(10, 20);
confirmAreaShift(aptg, 9, 21, 20, 30, 40);
confirmAreaShift(aptg, 10, 21, 20, 30, 40);
confirmAreaShift(aptg, 9, 20, 20, 30, 40);
confirmAreaRowShift(aptg, 9, 21, 20, 30, 40);
confirmAreaRowShift(aptg, 10, 21, 20, 30, 40);
confirmAreaRowShift(aptg, 9, 20, 20, 30, 40);
confirmAreaShift(aptg, 8, 11, -3, 7, 20); // simple expansion of top
confirmAreaRowShift(aptg, 8, 11, -3, 7, 20); // simple expansion of top
// rows containing area top being shifted down:
confirmAreaShift(aptg, 8, 11, 3, 13, 20);
confirmAreaShift(aptg, 8, 11, 7, 17, 20);
confirmAreaShift(aptg, 8, 11, 8, 18, 20);
confirmAreaShift(aptg, 8, 11, 9, 12, 20); // note behaviour changes here
confirmAreaShift(aptg, 8, 11, 10, 12, 21);
confirmAreaShift(aptg, 8, 11, 12, 12, 23);
confirmAreaShift(aptg, 8, 11, 13, 10, 20); // ignored
confirmAreaRowShift(aptg, 8, 11, 3, 13, 20);
confirmAreaRowShift(aptg, 8, 11, 7, 17, 20);
confirmAreaRowShift(aptg, 8, 11, 8, 18, 20);
confirmAreaRowShift(aptg, 8, 11, 9, 12, 20); // note behaviour changes here
confirmAreaRowShift(aptg, 8, 11, 10, 12, 21);
confirmAreaRowShift(aptg, 8, 11, 12, 12, 23);
confirmAreaRowShift(aptg, 8, 11, 13, 10, 20); // ignored
// rows from within being moved:
confirmAreaShift(aptg, 12, 16, 3, 10, 20); // stay within - no change
confirmAreaShift(aptg, 11, 19, 20, 10, 20); // move completely out - no change
confirmAreaShift(aptg, 16, 17, -6, 10, 20); // moved exactly to top - no change
confirmAreaShift(aptg, 16, 17, -7, 11, 20); // truncation at top
confirmAreaShift(aptg, 12, 16, 4, 10, 20); // moved exactly to bottom - no change
confirmAreaShift(aptg, 12, 16, 6, 10, 17); // truncation at bottom
confirmAreaRowShift(aptg, 12, 16, 3, 10, 20); // stay within - no change
confirmAreaRowShift(aptg, 11, 19, 20, 10, 20); // move completely out - no change
confirmAreaRowShift(aptg, 16, 17, -6, 10, 20); // moved exactly to top - no change
confirmAreaRowShift(aptg, 16, 17, -7, 11, 20); // truncation at top
confirmAreaRowShift(aptg, 12, 16, 4, 10, 20); // moved exactly to bottom - no change
confirmAreaRowShift(aptg, 12, 16, 6, 10, 17); // truncation at bottom
// rows containing area bottom being shifted up:
confirmAreaShift(aptg, 18, 22, -1, 10, 19); // simple contraction at bottom
confirmAreaShift(aptg, 18, 22, -7, 10, 13); // simple contraction at bottom
confirmAreaShift(aptg, 18, 22, -8, 10, 17); // top calculated differently here
confirmAreaShift(aptg, 18, 22, -9, 9, 17);
confirmAreaShift(aptg, 18, 22,-15, 10, 20); // no change because range would be turned inside out
confirmAreaShift(aptg, 15, 19, -7, 13, 20); // dest truncates top (even though src is from inside range)
confirmAreaShift(aptg, 19, 23,-12, 7, 18); // complex: src encloses bottom, dest encloses top
confirmAreaRowShift(aptg, 18, 22, -1, 10, 19); // simple contraction at bottom
confirmAreaRowShift(aptg, 18, 22, -7, 10, 13); // simple contraction at bottom
confirmAreaRowShift(aptg, 18, 22, -8, 10, 17); // top calculated differently here
confirmAreaRowShift(aptg, 18, 22, -9, 9, 17);
confirmAreaRowShift(aptg, 18, 22,-15, 10, 20); // no change because range would be turned inside out
confirmAreaRowShift(aptg, 15, 19, -7, 13, 20); // dest truncates top (even though src is from inside range)
confirmAreaRowShift(aptg, 19, 23,-12, 7, 18); // complex: src encloses bottom, dest encloses top
confirmAreaShift(aptg, 18, 22, 5, 10, 25); // simple expansion at bottom
confirmAreaRowShift(aptg, 18, 22, 5, 10, 25); // simple expansion at bottom
}
@Test
public void testShiftAreasSourceColumns() {
// all these operations are on an area ref spanning columns 10 to 20
AreaPtg aptg = createAreaPtgColumn(10, 20);
confirmAreaColumnShift(aptg, 9, 21, 20, 30, 40);
confirmAreaColumnShift(aptg, 10, 21, 20, 30, 40);
confirmAreaColumnShift(aptg, 9, 20, 20, 30, 40);
confirmAreaColumnShift(aptg, 8, 11, -3, 7, 20); // simple expansion of top
// columns containing area top being shifted down:
confirmAreaColumnShift(aptg, 8, 11, 3, 13, 20);
confirmAreaColumnShift(aptg, 8, 11, 7, 17, 20);
confirmAreaColumnShift(aptg, 8, 11, 8, 18, 20);
confirmAreaColumnShift(aptg, 8, 11, 9, 12, 20); // note behaviour changes here
confirmAreaColumnShift(aptg, 8, 11, 10, 12, 21);
confirmAreaColumnShift(aptg, 8, 11, 12, 12, 23);
confirmAreaColumnShift(aptg, 8, 11, 13, 10, 20); // ignored
// columns from within being moved:
confirmAreaColumnShift(aptg, 12, 16, 3, 10, 20); // stay within - no change
confirmAreaColumnShift(aptg, 11, 19, 20, 10, 20); // move completely out - no change
confirmAreaColumnShift(aptg, 16, 17, -6, 10, 20); // moved exactly to top - no change
confirmAreaColumnShift(aptg, 16, 17, -7, 11, 20); // truncation at top
confirmAreaColumnShift(aptg, 12, 16, 4, 10, 20); // moved exactly to bottom - no change
confirmAreaColumnShift(aptg, 12, 16, 6, 10, 17); // truncation at bottom
// columns containing area bottom being shifted up:
confirmAreaColumnShift(aptg, 18, 22, -1, 10, 19); // simple contraction at bottom
confirmAreaColumnShift(aptg, 18, 22, -7, 10, 13); // simple contraction at bottom
confirmAreaColumnShift(aptg, 18, 22, -8, 10, 17); // top calculated differently here
confirmAreaColumnShift(aptg, 18, 22, -9, 9, 17);
confirmAreaColumnShift(aptg, 18, 22,-15, 10, 20); // no change because range would be turned inside out
confirmAreaColumnShift(aptg, 15, 19, -7, 13, 20); // dest truncates top (even though src is from inside range)
confirmAreaColumnShift(aptg, 19, 23,-12, 7, 18); // complex: src encloses bottom, dest encloses top
confirmAreaColumnShift(aptg, 18, 22, 5, 10, 25); // simple expansion at bottom
}
@Test
public void testCopyAreasSourceRowsRelRel() {
// all these operations are on an area ref spanning rows 10 to 20
final AreaPtg aptg = createAreaPtg(10, 20, true, true);
final AreaPtg aptg = createAreaPtgRow(10, 20, true, true);
confirmAreaCopy(aptg, 0, 30, 20, 30, 40, true);
confirmAreaCopy(aptg, 15, 25, -15, -1, -1, true); //DeletedRef
confirmAreaRowCopy(aptg, 0, 30, 20, 30, 40, true);
confirmAreaRowCopy(aptg, 15, 25, -15, -1, -1, true); //DeletedRef
}
@Test
public void testCopyAreasSourceRowsRelAbs() {
// all these operations are on an area ref spanning rows 10 to 20
final AreaPtg aptg = createAreaPtg(10, 20, true, false);
final AreaPtg aptg = createAreaPtgRow(10, 20, true, false);
// Only first row should move
confirmAreaCopy(aptg, 0, 30, 20, 20, 30, true);
confirmAreaCopy(aptg, 15, 25, -15, -1, -1, true); //DeletedRef
confirmAreaRowCopy(aptg, 0, 30, 20, 20, 30, true);
confirmAreaRowCopy(aptg, 15, 25, -15, -1, -1, true); //DeletedRef
}
@Test
@ -114,11 +154,11 @@ public final class TestFormulaShifter {
// in the workbook need to track the row shift
// all these operations are on an area ref spanning rows 10 to 20
final AreaPtg aptg = createAreaPtg(10, 20, false, true);
final AreaPtg aptg = createAreaPtgRow(10, 20, false, true);
// Only last row should move
confirmAreaCopy(aptg, 0, 30, 20, 10, 40, true);
confirmAreaCopy(aptg, 15, 25, -15, 5, 10, true); //sortTopLeftToBottomRight swapped firstRow and lastRow because firstRow is absolute
confirmAreaRowCopy(aptg, 0, 30, 20, 10, 40, true);
confirmAreaRowCopy(aptg, 15, 25, -15, 5, 10, true); //sortTopLeftToBottomRight swapped firstRow and lastRow because firstRow is absolute
}
@Test
@ -130,11 +170,11 @@ public final class TestFormulaShifter {
// in the workbook need to track the row shift
// all these operations are on an area ref spanning rows 10 to 20
final AreaPtg aptg = createAreaPtg(10, 20, false, false);
final AreaPtg aptg = createAreaPtgRow(10, 20, false, false);
//AbsFirstRow AbsLastRow references should't change when copied to a different row
confirmAreaCopy(aptg, 0, 30, 20, 10, 20, false);
confirmAreaCopy(aptg, 15, 25, -15, 10, 20, false);
confirmAreaRowCopy(aptg, 0, 30, 20, 10, 20, false);
confirmAreaRowCopy(aptg, 15, 25, -15, 10, 20, false);
}
/**
@ -144,20 +184,41 @@ public final class TestFormulaShifter {
@Test
public void testShiftAreasDestRows() {
// all these operations are on an area ref spanning rows 20 to 25
AreaPtg aptg = createAreaPtg(20, 25);
AreaPtg aptg = createAreaPtgRow(20, 25);
// no change because no overlap:
confirmAreaShift(aptg, 5, 10, 9, 20, 25);
confirmAreaShift(aptg, 5, 10, 21, 20, 25);
confirmAreaRowShift(aptg, 5, 10, 9, 20, 25);
confirmAreaRowShift(aptg, 5, 10, 21, 20, 25);
confirmAreaShift(aptg, 11, 14, 10, 20, 25);
confirmAreaRowShift(aptg, 11, 14, 10, 20, 25);
confirmAreaShift(aptg, 7, 17, 10, -1, -1); // converted to DeletedAreaRef
confirmAreaShift(aptg, 5, 15, 7, 23, 25); // truncation at top
confirmAreaShift(aptg, 13, 16, 10, 20, 22); // truncation at bottom
confirmAreaRowShift(aptg, 7, 17, 10, -1, -1); // converted to DeletedAreaRef
confirmAreaRowShift(aptg, 5, 15, 7, 23, 25); // truncation at top
confirmAreaRowShift(aptg, 13, 16, 10, 20, 22); // truncation at bottom
}
private static void confirmAreaShift(AreaPtg aptg,
/**
* Tests what happens to an area ref when some outside columns are moved to overlap
* that area ref
*/
@Test
public void testShiftAreasDestColumns() {
// all these operations are on an area ref spanning columns 20 to 25
AreaPtg aptg = createAreaPtgColumn(20, 25);
// no change because no overlap:
confirmAreaColumnShift(aptg, 5, 10, 9, 20, 25);
confirmAreaColumnShift(aptg, 5, 10, 21, 20, 25);
confirmAreaColumnShift(aptg, 11, 14, 10, 20, 25);
confirmAreaColumnShift(aptg, 7, 17, 10, -1, -1); // converted to DeletedAreaRef
confirmAreaColumnShift(aptg, 5, 15, 7, 23, 25); // truncation at top
confirmAreaColumnShift(aptg, 13, 16, 10, 20, 22); // truncation at bottom
}
private static void confirmAreaRowShift(
AreaPtg aptg,
int firstRowMoved, int lastRowMoved, int numberRowsMoved,
int expectedAreaFirstRow, int expectedAreaLastRow) {
@ -177,11 +238,33 @@ public final class TestFormulaShifter {
assertEquals(expectedAreaLastRow, copyPtg.getLastRow());
}
private static void confirmAreaColumnShift(
AreaPtg aptg,
int firstColumnMoved, int lastColumnMoved, int numberColumnsMoved,
int expectedAreaFirstColumn, int expectedAreaLastColumn) {
FormulaShifter fs = FormulaShifter.createForColumnShift(0, "", firstColumnMoved, lastColumnMoved, numberColumnsMoved, SpreadsheetVersion.EXCEL2007);
boolean expectedChanged = aptg.getFirstColumn() != expectedAreaFirstColumn || aptg.getLastColumn() != expectedAreaLastColumn;
AreaPtg copyPtg = (AreaPtg) aptg.copy(); // clone so we can re-use aptg in calling method
Ptg[] ptgs = { copyPtg, };
boolean actualChanged = fs.adjustFormula(ptgs, 0);
if (expectedAreaFirstColumn < 0) {
assertEquals(AreaErrPtg.class, ptgs[0].getClass());
return;
}
assertEquals(expectedChanged, actualChanged);
assertEquals(copyPtg, ptgs[0]); // expected to change in place (although this is not a strict requirement)
assertEquals(expectedAreaFirstColumn, copyPtg.getFirstColumn());
assertEquals(expectedAreaLastColumn, copyPtg.getLastColumn());
}
private static void confirmAreaCopy(AreaPtg aptg,
int firstRowCopied, int lastRowCopied, int rowOffset,
int expectedFirstRow, int expectedLastRow, boolean expectedChanged) {
private static void confirmAreaRowCopy(AreaPtg aptg,
int firstRowCopied, int lastRowCopied, int rowOffset,
int expectedFirstRow, int expectedLastRow, boolean expectedChanged) {
final AreaPtg copyPtg = (AreaPtg) aptg.copy(); // clone so we can re-use aptg in calling method
final Ptg[] ptgs = { copyPtg, };
@ -202,14 +285,22 @@ public final class TestFormulaShifter {
}
private static AreaPtg createAreaPtg(int initialAreaFirstRow, int initialAreaLastRow) {
return createAreaPtg(initialAreaFirstRow, initialAreaLastRow, false, false);
private static AreaPtg createAreaPtgRow(int initialAreaFirstRow, int initialAreaLastRow) {
return createAreaPtgRow(initialAreaFirstRow, initialAreaLastRow, false, false);
}
private static AreaPtg createAreaPtgColumn(int initialAreaFirstColumn, int initialAreaLastColumn) {
return createAreaPtgColumn(initialAreaFirstColumn, initialAreaLastColumn, false, false);
}
private static AreaPtg createAreaPtg(int initialAreaFirstRow, int initialAreaLastRow, boolean firstRowRelative, boolean lastRowRelative) {
private static AreaPtg createAreaPtgRow(int initialAreaFirstRow, int initialAreaLastRow, boolean firstRowRelative, boolean lastRowRelative) {
return new AreaPtg(initialAreaFirstRow, initialAreaLastRow, 2, 5, firstRowRelative, lastRowRelative, false, false);
}
private static AreaPtg createAreaPtgColumn(int initialAreaFirstColumn, int initialAreaLastColumn, boolean firstColumnRelative, boolean lastColumnRelative) {
return new AreaPtg(2, 5, initialAreaFirstColumn, initialAreaLastColumn, false, false, firstColumnRelative, lastColumnRelative);
}
@Test
public void testShiftSheet() {
// 4 sheets, move a sheet from pos 2 to pos 0, i.e. current 0 becomes 1, current 1 becomes pos 2