*/
public List<CellRangeAddress[]> shiftRowsOnly(int startRow, int endRow, int n,
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, srcRow.getFirstCellNum(), srcRow.getLastCellNum()) : null;
final short srcHeight = srcRow != null ? srcRow.getHeight() : -1;
final HSSFCellStyle srcStyle = srcRow != null ? srcRow.getRowStyle() : null;
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 int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
final List<CellRangeAddress[]> shiftedRanges = BookHelper.shiftMergedRegion(this, startRow, 0, endRow, maxcol, n, false);
_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);
final int newRowNum = rowNum + n;
final boolean inbound = newRowNum >= 0 && newRowNum <= maxrow;
if (!inbound) {
if (row != null) {
if (resetOriginalRowHeight) {
row.setHeight((short)-1);
}
new HSSFRowHelper(row).removeAllCells();
}
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
new HSSFRowHelper(row2Replace).removeAllCells();
} else {
// If this row doesn't exist, shall also remove
// the empty destination row
if (row2Replace != null) {
removeRow(row2Replace);
}
continue; // Nothing to do for this row
}
// Fix up row heights if required
if (copyRowHeight) {
row2Replace.setHeight(row.getHeight());
}
if (resetOriginalRowHeight) {
row.setHeight((short)0xff);
}
// Copy each cell from the source row to
// the destination row
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();
// 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) {
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);
}
row.setHeight(srcHeight); //height
if (srcStyle != null) {
row.setRowStyle((HSSFCellStyle)BookHelper.copyFromStyleExceptBorder(getBook(), srcStyle));//style
}
if (srcCells != null) {
for (Entry<Integer, Cell> cellEntry : srcCells.entrySet()) {
final Cell srcCell = cellEntry.getValue();
final CellStyle cellStyle = srcCell.getCellStyle();
final int c = cellEntry.getKey().intValue();
Cell cell = row.getCell(c);
if (cell == null) {
cell = row.createCell(c);
}
cell.setCellStyle(BookHelper.copyFromStyleExceptBorder(getBook(), cellStyle));
}
}
}
}
// Shift Hyperlinks which have been moved
shiftHyperlinks(startRow, endRow, n, 0, maxcol, 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) {
removeRow(row);
}
}
removeHyperlinks(orgStartRow, endRow, 0, maxcol);
} 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) {
removeRow(row);
}
}
removeHyperlinks(orgStartRow, startRow, 0, maxcol);