*/
public List<CellRangeAddress[]> shiftRowsRange(int startRow, int endRow, int n, int lCol, int rCol,
boolean copyRowHeight, boolean resetOriginalRowHeight, boolean moveComments, boolean clearRest, int copyOrigin) {
//prepare source format row
final int srcRownum = n <= 0 ? -1 : copyOrigin == Range.FORMAT_RIGHTBELOW ? startRow : copyOrigin == Range.FORMAT_LEFTABOVE ? startRow - 1 : -1;
final HSSFRow srcRow = srcRownum >= 0 ? getRow(srcRownum) : null;
final Map<Integer, Cell> srcCells = srcRow != null ? BookHelper.copyRowCells(srcRow, lCol, rCol) : null;
final short srcHeight = srcRow != null ? srcRow.getHeight() : -1;
final HSSFCellStyle srcStyle = srcRow != null ? srcRow.getRowStyle() : null;
final int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
if (endRow < 0) {
endRow = maxrow;
}
if (n > 0) {
if (startRow > endRow ) { //nothing to do
return Collections.emptyList();
}
} else {
if ((startRow + n) > endRow) { //nothing to do
return Collections.emptyList();
}
}
int s, inc;
if (n < 0) {
s = startRow;
inc = 1;
} else {
s = endRow;
inc = -1;
}
NoteRecord[] noteRecs;
if (moveComments) {
noteRecs = _helper.getInternalSheet().getNoteRecords();
} else {
noteRecs = NoteRecord.EMPTY_ARRAY;
}
final int maxcol = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
final List<CellRangeAddress[]> shiftedRanges = BookHelper.shiftMergedRegion(this, startRow, lCol, endRow, rCol, n, false);
final boolean wholeRow = lCol == 0 && rCol == maxcol;
if (wholeRow) {
_helper.getInternalSheet().getPageSettings().shiftRowBreaks(startRow, endRow, n);
}
for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum <= maxrow; rowNum += inc ) {
HSSFRow row = getRow( rowNum );
// notify all cells in this row that we are going to shift them,
// it can throw IllegalStateException if the operation is not allowed, for example,
// if the row contains cells included in a multi-cell array formula
if(row != null) notifyRowShifting(row); //TODO: add lCol, rCol information
final int newRowNum = rowNum + n;
final boolean inbound = newRowNum >= 0 && newRowNum <= maxrow;
if (!inbound) {
if (row != null) {
if (wholeRow) {
if (resetOriginalRowHeight) {
row.setHeight((short)-1); //default height
}
new HSSFRowHelper(row).removeAllCells();
} else {
removeCells(row, lCol, rCol);
}
}
continue;
}
HSSFRow row2Replace = getRow( rowNum + n );
if (row != null) {
if ( row2Replace == null )
row2Replace = createRow( rowNum + n );
// Remove all the old cells from the row we'll
// be writing too, before we start overwriting
// any cells. This avoids issues with cells
// changing type, and records not being correctly
// overwritten
if (wholeRow) {
new HSSFRowHelper(row2Replace).removeAllCells();
} else {
removeCells(row2Replace, lCol, rCol);
}
} else {
// If this row doesn't exist, shall also remove
// the empty destination row
if (row2Replace != null) {
if (wholeRow) {
removeRow(row2Replace);
} else {
removeCells(row2Replace, lCol, rCol);
}
}
continue; // Nothing to do for this row
}
// Fix up row heights if required
if (wholeRow) {
if (copyRowHeight) {
row2Replace.setHeight(row.getHeight());
}
if (resetOriginalRowHeight) {
row.setHeight((short)0xff);
}
}
// Copy each cell from the source row to
// the destination row
if (wholeRow) {
for(Iterator<Cell> cells = row.cellIterator(); cells.hasNext(); ) {
HSSFCell cell = (HSSFCell)cells.next();
row.removeCell( cell );
CellValueRecordInterface cellRecord = new HSSFCellHelper(cell).getCellValueRecord();
cellRecord.setRow( rowNum + n );
new HSSFRowHelper(row2Replace).createCellFromRecord( cellRecord );
_helper.getInternalSheet().addValueRecord( rowNum + n, cellRecord );
}
// Now zap all the cells in the source row
new HSSFRowHelper(row).removeAllCells();
} else {
final int startCol = Math.max(row.getFirstCellNum(), lCol);
final int endCol = Math.min(row.getLastCellNum(), rCol);
for(int col = startCol; col <= endCol; ++col) {
HSSFCell cell = (HSSFCell)row.getCell(col);
if (cell == null) {
continue;
}
row.removeCell( cell );
CellValueRecordInterface cellRecord = new HSSFCellHelper(cell).getCellValueRecord();
cellRecord.setRow( rowNum + n );
new HSSFRowHelper(row2Replace).createCellFromRecord( cellRecord );
_helper.getInternalSheet().addValueRecord( rowNum + n, cellRecord );
}
// Now zap the cells in the source row
removeCells(row, lCol, rCol);
}
// Move comments from the source row to the
// destination row. Note that comments can
// exist for cells which are null
if(moveComments) {
// This code would get simpler if NoteRecords could be organised by HSSFRow.
for(int i=noteRecs.length-1; i>=0; i--) {
NoteRecord nr = noteRecs[i];
if (nr.getRow() != rowNum || nr.getColumn() < lCol || nr.getColumn() > rCol) {
continue;
}
HSSFComment comment = getCellComment(rowNum, nr.getColumn());
if (comment != null) {
comment.setRow(rowNum + n);
}
}
}
}
//handle inserted rows
if (srcRow != null) {
final int row2 = Math.min(startRow + n - 1, SpreadsheetVersion.EXCEL97.getLastRowIndex());
for(int rownum = startRow; rownum <= row2; ++rownum) {
HSSFRow row = getRow(rownum);
if (row == null) {
row = createRow(rownum);
}
if (wholeRow) {
row.setHeight(srcHeight);
row.setRowStyle((HSSFCellStyle)BookHelper.copyFromStyleExceptBorder(getBook(), srcStyle));
}
if (srcCells != null) {
for(Entry<Integer, Cell> cellEntry : srcCells.entrySet()) {
final int colnum = cellEntry.getKey().intValue();
final Cell srcCell = cellEntry.getValue();
final CellStyle cellStyle = srcCell.getCellStyle();
Cell dstCell = row.getCell(colnum);
if (dstCell == null) {
dstCell = row.createCell(colnum);
}
dstCell.setCellStyle(BookHelper.copyFromStyleExceptBorder(getBook(), cellStyle));
}
}
}
}
// Shift Hyperlinks which have been moved
shiftHyperlinks(startRow, endRow, n, lCol, rCol, 0);
//special case1: endRow < startRow
//special case2: (endRow - startRow + 1) < ABS(n)
if (n < 0) {
if (endRow < startRow) { //special case1
final int orgStartRow = startRow + n;
for ( int rowNum = orgStartRow; rowNum >= orgStartRow && rowNum <= endRow && rowNum >= 0 && rowNum <= maxrow; ++rowNum) {
final HSSFRow row = getRow( rowNum );
if (row != null) {
if (wholeRow) {
removeRow(row);
} else {
removeCells(row, lCol, rCol);
}
}
}
removeHyperlinks(orgStartRow, endRow, lCol, rCol);
} else if (clearRest) { //special case 2
final int orgStartRow = endRow + n + 1;
if (orgStartRow <= startRow) {
for ( int rowNum = orgStartRow; rowNum >= orgStartRow && rowNum <= startRow && rowNum >= 0 && rowNum <= maxrow; ++rowNum) {
final HSSFRow row = getRow( rowNum );
if (row != null) {
if (wholeRow) {
removeRow(row);
} else {
removeCells(row, lCol, rCol);