private Ptg rowMoveAreaPtg()

in poi/src/main/java/org/apache/poi/ss/formula/FormulaShifter.java [402:525]


    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 + ")");
    }