]> source.dussan.org Git - poi.git/commitdiff
Bug 56017: fix shifting comments with shifted rows and move some more tests into...
authorDominik Stadler <centic@apache.org>
Sun, 15 Mar 2015 20:52:55 +0000 (20:52 +0000)
committerDominik Stadler <centic@apache.org>
Sun, 15 Mar 2015 20:52:55 +0000 (20:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1666843 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheetShiftRows.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java

index 5fdd3aa2c8054951855d561101029f941ca1dc2c..51ef179e661e146e6b0b4ce9b194094b8c7ae196 100644 (file)
@@ -145,9 +145,17 @@ public class XSSFComment implements Comment {
                _comment.setRef(newRef);
       _comments.referenceUpdated(oldRef, _comment);
       
-        if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row)));
+        if(_vmlShape != null) {
+               _vmlShape.getClientDataArray(0).setRowArray(0, 
+                               new BigInteger(String.valueOf(row)));
+               
+            // There is a very odd xmlbeans bug when changing the row
+            //  arrays which can lead to corrupt pointer
+            // This call seems to fix them again... See bug #50795
+            _vmlShape.getClientDataList().toString();
+        }
     }
-       
+    
     /**
      * @return the rich text string of the comment
      */
index 6a48bf00056e1864cdb9212625db73f1fcda2bc9..f24a331940fb14a5d69efa30d786cd955f4476a1 100644 (file)
@@ -25,11 +25,13 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedMap;
 import java.util.TreeMap;
 
 import javax.xml.namespace.QName;
@@ -131,7 +133,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     protected CTSheet sheet;
     protected CTWorksheet worksheet;
 
-    private TreeMap<Integer, XSSFRow> _rows;
+    private SortedMap<Integer, XSSFRow> _rows;
     private List<XSSFHyperlink> hyperlinks;
     private ColumnHelper columnHelper;
     private CommentsTable sheetComments;
@@ -140,7 +142,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      * Master shared formula is the first formula in a group of shared formulas is saved in the f element.
      */
     private Map<Integer, CTCellFormula> sharedFormulas;
-    private TreeMap<String,XSSFTable> tables;
+    private SortedMap<String,XSSFTable> tables;
     private List<CellRangeAddress> arrayFormulas;
     private XSSFDataValidationHelper dataValidationHelper;
 
@@ -2555,38 +2557,87 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      */
     @Override
     @SuppressWarnings("deprecation") //YK: getXYZArray() array accessors are deprecated in xmlbeans with JDK 1.5 support
-    public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
-        // first remove all rows which will be overwritten
+    public void shiftRows(int startRow, int endRow, final int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
+       XSSFVMLDrawing vml = getVMLDrawing(false);
+
+       // first remove all rows which will be overwritten
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             XSSFRow row = (XSSFRow)it.next();
             int rownum = row.getRowNum();
 
             // check if we should remove this row as it will be overwritten by the data later
-            if (removeRow(startRow, endRow, n, rownum)) {
+            if (shouldRemoveRow(startRow, endRow, n, rownum)) {
                 // remove row from worksheet.getSheetData row array
                 int idx = _rows.headMap(row.getRowNum()).size();
                 worksheet.getSheetData().removeRow(idx);
+
                 // remove row from _rows
                 it.remove();
+
+                // also remove any comments associated with this row
+                if(sheetComments != null){
+                    CTCommentList lst = sheetComments.getCTComments().getCommentList();
+                    for (CTComment comment : lst.getCommentArray()) {
+                       String strRef = comment.getRef();
+                       CellReference ref = new CellReference(strRef);
+
+                       // is this comment part of the current row?
+                       if(ref.getRow() == rownum) {
+                            sheetComments.removeComment(strRef);
+                            vml.removeCommentShape(ref.getRow(), ref.getCol());
+                       }
+                    }
+                }
             }
         }
 
         // then do the actual moving and also adjust comments/rowHeight
+        // we need to sort it in a way so the shifting does not mess up the structures, 
+        // i.e. when shifting down, start from down and go up, when shifting up, vice-versa
+        SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<XSSFComment, Integer>(new Comparator<XSSFComment>() {
+                       public int compare(XSSFComment o1, XSSFComment o2) {
+                               int row1 = new CellReference(o1.getCTComment().getRef()).getRow();
+                               int row2 = new CellReference(o2.getCTComment().getRef()).getRow();
+                               
+                               if(row1 == row2) {
+                                       return 0;
+                               }
+
+                               // when shifting down, sort higher row-values first
+                               if(n > 0) {
+                                       return row1 < row2 ? 1 : -1;
+                               } else {
+                                       // sort lower-row values first when shifting up
+                                       return row1 > row2 ? 1 : -1;
+                               }
+                       }
+               });
+        
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             XSSFRow row = (XSSFRow)it.next();
             int rownum = row.getRowNum();
 
             if(sheetComments != null){
-                //TODO shift Note's anchor in the associated /xl/drawing/vmlDrawings#.vml
-                CTCommentList lst = sheetComments.getCTComments().getCommentList();
-                for (CTComment comment : lst.getCommentArray()) {
-                    String oldRef = comment.getRef();
-                    CellReference ref = new CellReference(oldRef);
-                    if(ref.getRow() == rownum){
-                        ref = new CellReference(rownum + n, ref.getCol());
-                        comment.setRef(ref.formatAsString());
-                        sheetComments.referenceUpdated(oldRef, comment);
-                    }
+               // calculate the new rownum
+               int newrownum = shiftedRowNum(startRow, endRow, n, rownum);
+               
+               // is there a change necessary for the current row?
+               if(newrownum != rownum) {
+                    CTCommentList lst = sheetComments.getCTComments().getCommentList();
+                    for (CTComment comment : lst.getCommentArray()) {
+                       String oldRef = comment.getRef();
+                       CellReference ref = new CellReference(oldRef);
+                       
+                       // is this comment part of the current row?
+                       if(ref.getRow() == rownum) {
+                               XSSFComment xssfComment = new XSSFComment(sheetComments, comment,
+                                    vml == null ? null : vml.findCommentShape(rownum, ref.getCol()));
+                               
+                               // we should not perform the shifting right here as we would then find
+                               // already shifted comments and would shift them again...
+                               commentsToShift.put(xssfComment, newrownum);
+                        }
+                       }
                 }
             }
 
@@ -2598,6 +2649,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
 
             row.shift(n);
         }
+        
+        // adjust all the affected comment-structures now
+        // the Map is sorted and thus provides them in the order that we need here, 
+        // i.e. from down to up if shifting down, vice-versa otherwise
+        for(Map.Entry<XSSFComment, Integer> entry : commentsToShift.entrySet()) {
+               entry.getKey().setRow(entry.getValue());
+        }
+        
         XSSFRowShifter rowShifter = new XSSFRowShifter(this);
 
         int sheetIndex = getWorkbook().getSheetIndex(this);
@@ -2611,13 +2670,40 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         rowShifter.updateConditionalFormatting(shifter);
 
         //rebuild the _rows map
-        TreeMap<Integer, XSSFRow> map = new TreeMap<Integer, XSSFRow>();
+        SortedMap<Integer, XSSFRow> map = new TreeMap<Integer, XSSFRow>();
         for(XSSFRow r : _rows.values()) {
             map.put(r.getRowNum(), r);
         }
         _rows = map;
     }
 
+    private int shiftedRowNum(int startRow, int endRow, int n, int rownum) {
+               // no change if before any affected row
+       if(rownum < startRow && (n > 0 || (startRow - rownum) > n)) {
+                       return rownum;
+               }
+               
+       // no change if after any affected row
+       if(rownum > endRow && (n < 0 || (rownum - endRow) > n)) {
+               return rownum;
+       }
+       
+       // row before and things are moved up
+       if(rownum < startRow) {
+               // row is moved down by the shifting
+               return rownum + (endRow - startRow);
+       }
+       
+       // row is after and things are moved down
+       if(rownum > endRow) {
+               // row is moved up by the shifting
+               return rownum - (endRow - startRow);
+       }
+       
+       // row is part of the shifted block
+               return rownum + n;
+       }
+
     /**
      * Location of the top left visible cell Location of the top left visible cell in the bottom right
      * pane (when in Left-to-Right mode).
@@ -2873,7 +2959,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
     }
 
-    private boolean removeRow(int startRow, int endRow, int n, int rownum) {
+    private boolean shouldRemoveRow(int startRow, int endRow, int n, int rownum) {
         // is this row in the target-window where the moved rows will land?
         if (rownum >= (startRow + n) && rownum <= (endRow + n)) {
             // only remove it if the current row is not part of the data that is copied
index 2cf660955ed56c36a0cbbb985bde4292ed5803a7..ad3c4438305749541a646b4437857c2d116c51f8 100644 (file)
@@ -89,6 +89,13 @@ public class TestSXSSFSheet extends BaseTestSheet {
         super.bug35084();
     }
 
+    @Test
+    public void getCellComment() throws IOException {
+       // TODO: reading cell comments via Sheet does not work currently as it tries 
+       // to access the underlying sheet for this, but comments are stored as
+       // properties on Cells...
+    }
+    
     @Override
     @Test
     public void defaultColumnStyle() {
index d8f56f84e329fc213c738db44f563dfd7b2d821e..785af694d1b39b7433546aa7c285275e8f511a70 100644 (file)
@@ -36,21 +36,17 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.ss.usermodel.AutoFilter;
 import org.apache.poi.ss.usermodel.BaseTestSheet;
 import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CreationHelper;
-import org.apache.poi.ss.usermodel.RichTextString;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.AreaReference;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
-import org.apache.poi.xssf.SXSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.CalculationChain;
 import org.apache.poi.xssf.model.CommentsTable;
 import org.apache.poi.xssf.model.StylesTable;
-import org.apache.poi.xssf.streaming.SXSSFSheet;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
 import org.junit.Test;
@@ -60,8 +56,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 @SuppressWarnings("resource")
 public final class TestXSSFSheet extends BaseTestSheet {
 
-    private static final int ROW_COUNT = 40000;
-
     public TestXSSFSheet() {
         super(XSSFITestDataProvider.instance);
     }
@@ -188,39 +182,6 @@ public final class TestXSSFSheet extends BaseTestSheet {
         assertTrue(col.getBestFit());
     }
 
-    /**
-     * XSSFSheet autoSizeColumn() on empty RichTextString fails
-     */
-    @Test
-    public void bug48325() {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet("Test");
-        CreationHelper factory = wb.getCreationHelper();
-
-        XSSFRow row = sheet.createRow(0);
-        XSSFCell cell = row.createCell(0);
-
-        XSSFFont font = wb.createFont();
-        RichTextString rts = factory.createRichTextString("");
-        rts.applyFont(font);
-        cell.setCellValue(rts);
-
-        sheet.autoSizeColumn(0);
-    }
-
-    @Test
-    public void getCellComment() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet();
-        XSSFDrawing dg = sheet.createDrawingPatriarch();
-        XSSFComment comment = dg.createCellComment(new XSSFClientAnchor());
-        XSSFCell cell = sheet.createRow(9).createCell(2);
-        comment.setAuthor("test C10 author");
-        cell.setCellComment(comment);
-
-        assertNotNull(sheet.getCellComment(9, 2));
-        assertEquals("test C10 author", sheet.getCellComment(9, 2).getAuthor());
-    }
 
     @Test
     public void setCellComment() {
@@ -268,16 +229,6 @@ public final class TestXSSFSheet extends BaseTestSheet {
         assertEquals(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane());
     }
 
-    @Test
-    public void newMergedRegionAt() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet();
-        CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
-        sheet.addMergedRegion(region);
-        assertEquals("B2:D4", sheet.getMergedRegion(0).formatAsString());
-        assertEquals(1, sheet.getNumMergedRegions());
-    }
-
     @Test
     public void removeMergedRegion_lowlevel() {
         XSSFWorkbook workbook = new XSSFWorkbook();
@@ -1244,53 +1195,6 @@ public final class TestXSSFSheet extends BaseTestSheet {
         }
     }
 
-    @Test
-    public void showInPaneManyRowsBug55248() {
-        XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = workbook.createSheet("Sheet 1");
-
-        sheet.showInPane(0, 0);
-
-        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
-            sheet.createRow(i);
-            sheet.showInPane(i, 0);
-            // this one fails: sheet.showInPane((short)i, 0);
-        }
-
-        int i = 0;
-        sheet.showInPane(i, i);
-
-        XSSFWorkbook wb = XSSFTestDataSamples.writeOutAndReadBack(workbook);
-        checkRowCount(wb);
-    }
-
-    @Test
-    public void showInPaneManyRowsBug55248SXSSF() {
-        SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook());
-        SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet("Sheet 1");
-
-        sheet.showInPane(0, 0);
-
-        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
-            sheet.createRow(i);
-            sheet.showInPane(i, 0);
-            // this one fails: sheet.showInPane((short)i, 0);
-        }
-
-        int i = 0;
-        sheet.showInPane(i, i);
-
-        Workbook wb = SXSSFITestDataProvider.instance.writeOutAndReadBack(workbook);
-        checkRowCount(wb);
-    }
-
-    private void checkRowCount(Workbook wb) {
-        assertNotNull(wb);
-        final Sheet sh = wb.getSheet("Sheet 1");
-        assertNotNull(sh);
-        assertEquals(ROW_COUNT-1, sh.getLastRowNum());
-    }
-
     @Test
     public void bug55745() throws Exception {
         XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55745.xlsx");
@@ -1472,16 +1376,4 @@ public final class TestXSSFSheet extends BaseTestSheet {
         XSSFSheet sheet = wb.createSheet();
         assertNotNull(sheet.createComment());
     }
-    
-    @Test
-    public void testRightToLeft() {
-        XSSFWorkbook wb = new XSSFWorkbook();
-        XSSFSheet sheet = wb.createSheet();
-
-        assertFalse(sheet.isRightToLeft());
-        sheet.setRightToLeft(true);
-        assertTrue(sheet.isRightToLeft());
-        sheet.setRightToLeft(false);
-        assertFalse(sheet.isRightToLeft());
-    }
 }
\ No newline at end of file
index e949dd13dd9a5eee65bc605653c8b5e34dc7af26..e915ee0d4d00ddb800010c72f94a38431b5fe7eb 100644 (file)
@@ -25,7 +25,6 @@ import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellUtil;
 import org.apache.poi.xssf.XSSFITestDataProvider;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -44,11 +43,6 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
         // TODO - support shifting of page breaks
     }
 
-    @Override
-       public void testShiftWithComments() { // disabled test from superclass
-        // TODO - support shifting of comments.
-    }
-
        public void testBug54524() throws IOException {
         XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("54524.xlsx");
         XSSFSheet sheet = workbook.getSheetAt(0);
@@ -61,7 +55,6 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
                cell = CellUtil.getCell(sheet.getRow(3), 0);
                assertEquals("X", cell.getStringCellValue());
        }
-       
 
        public void testBug53798() throws IOException {
                // NOTE that for HSSF (.xls) negative shifts combined with positive ones do work as expected  
@@ -189,19 +182,6 @@ public final class TestXSSFSheetShiftRows extends BaseTestSheetShiftRows {
         assertEquals("Amdocs:\ntest\n", comment.getString().getString());
        }
 
-       public void testBug55280() throws IOException {
-        Workbook w = new XSSFWorkbook();
-        try {
-            Sheet s = w.createSheet();
-            for (int row = 0; row < 5000; ++row)
-                s.addMergedRegion(new CellRangeAddress(row, row, 0, 3));
-
-            s.shiftRows(0, 4999, 1);        // takes a long time...
-        } finally {
-            w.close();
-        }
-       }
-
     public void test57171() throws Exception {
            Workbook wb = XSSFTestDataSamples.openSampleWorkbook("57171_57163_57165.xlsx");
         assertEquals(5, wb.getActiveSheetIndex());
index 480235f5e17b11f56c93ec585b2ab7d31833afce..55f9795e311950d60a59aa2bbe2c50c668d9ec54 100644 (file)
 
 package org.apache.poi.ss.usermodel;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.*;
 
+import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
@@ -41,13 +37,15 @@ import org.junit.rules.ExpectedException;
  * {@link org.apache.poi.hssf.usermodel.HSSFCell}
  */
 public abstract class BaseTestSheet {
+    private static final int ROW_COUNT = 40000;
+
     @Rule
     public ExpectedException thrown = ExpectedException.none();
     
     private final ITestDataProvider _testDataProvider;
 
     protected BaseTestSheet(ITestDataProvider testDataProvider) {
-    _testDataProvider = testDataProvider;
+       _testDataProvider = testDataProvider;
     }
 
     @Test
@@ -851,22 +849,126 @@ public abstract class BaseTestSheet {
     }
 
     @Test
-    public void bug55723_Rows() {
-        HSSFWorkbook wb = new HSSFWorkbook();
+    public void bug55723_Rows() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
         Sheet sheet = wb.createSheet();
 
         CellRangeAddress range = CellRangeAddress.valueOf("A4:B55000");
         AutoFilter filter = sheet.setAutoFilter(range);
         assertNotNull(filter);
+        
+        wb.close();
     }
 
     @Test
-    public void bug55723d_RowsOver65k() {
-        HSSFWorkbook wb = new HSSFWorkbook();
+    public void bug55723d_RowsOver65k() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
         Sheet sheet = wb.createSheet();
 
         CellRangeAddress range = CellRangeAddress.valueOf("A4:B75000");
         AutoFilter filter = sheet.setAutoFilter(range);
         assertNotNull(filter);
+        
+        wb.close();
+    }
+
+    /**
+     * XSSFSheet autoSizeColumn() on empty RichTextString fails
+     * @throws IOException 
+     */
+    @Test
+    public void bug48325() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Test");
+        CreationHelper factory = wb.getCreationHelper();
+
+        Row row = sheet.createRow(0);
+        Cell cell = row.createCell(0);
+
+        Font font = wb.createFont();
+        RichTextString rts = factory.createRichTextString("");
+        rts.applyFont(font);
+        cell.setCellValue(rts);
+
+        sheet.autoSizeColumn(0);
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(wb));
+        
+        wb.close();
+    }
+
+    @Test
+    public void getCellComment() throws IOException {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet();
+        Drawing dg = sheet.createDrawingPatriarch();
+        Comment comment = dg.createCellComment(workbook.getCreationHelper().createClientAnchor());
+        Cell cell = sheet.createRow(9).createCell(2);
+        comment.setAuthor("test C10 author");
+        cell.setCellComment(comment);
+
+        assertNotNull(sheet.getCellComment(9, 2));
+        assertEquals("test C10 author", sheet.getCellComment(9, 2).getAuthor());
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(workbook));
+        
+        workbook.close();
+    }
+
+
+    @Test
+    public void newMergedRegionAt() throws IOException {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet();
+        CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
+        sheet.addMergedRegion(region);
+        assertEquals("B2:D4", sheet.getMergedRegion(0).formatAsString());
+        assertEquals(1, sheet.getNumMergedRegions());
+        
+        assertNotNull(_testDataProvider.writeOutAndReadBack(workbook));
+        
+        workbook.close();
+    }
+
+    @Test
+    public void showInPaneManyRowsBug55248() {
+        Workbook workbook = _testDataProvider.createWorkbook();
+        Sheet sheet = workbook.createSheet("Sheet 1");
+
+        sheet.showInPane(0, 0);
+
+        for(int i = ROW_COUNT/2;i < ROW_COUNT;i++) {
+            sheet.createRow(i);
+            sheet.showInPane(i, 0);
+            // this one fails: sheet.showInPane((short)i, 0);
+        }
+
+        int i = 0;
+        sheet.showInPane(i, i);
+
+        Workbook wb = _testDataProvider.writeOutAndReadBack(workbook);
+        checkRowCount(wb);
+    }
+
+    private void checkRowCount(Workbook wb) {
+        assertNotNull(wb);
+        final Sheet sh = wb.getSheet("Sheet 1");
+        assertNotNull(sh);
+        assertEquals(ROW_COUNT-1, sh.getLastRowNum());
+    }
+    
+    
+    @Test
+    public void testRightToLeft() throws IOException {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet();
+
+        assertFalse(sheet.isRightToLeft());
+        sheet.setRightToLeft(true);
+        assertTrue(sheet.isRightToLeft());
+        sheet.setRightToLeft(false);
+        assertFalse(sheet.isRightToLeft());
+        
+        wb.close();
     }
 }
index 9146db75210b45fab95c9dbf265b4c15059f9dae..4c9d25de074b2e1b489c6dd54c7f8d45ab4cb5ad 100644 (file)
 
 package org.apache.poi.ss.usermodel;
 
+import java.io.IOException;
+
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
@@ -134,8 +137,7 @@ public abstract class BaseTestSheetShiftRows extends TestCase {
         assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6));
     }
 
-    public void testShiftWithComments() { // TODO - enable XSSF test
-
+    public void testShiftWithComments() {
         Workbook wb = _testDataProvider.openSampleWorkbook("comments." + _testDataProvider.getStandardFileNameExtension());
 
         Sheet sheet = wb.getSheet("Sheet1");
@@ -154,6 +156,8 @@ public abstract class BaseTestSheetShiftRows extends TestCase {
         String comment4 = sheet.getCellComment(3,0).getString().getString();
         assertEquals(comment4,"comment top row4 (index3)\n");
 
+        //Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb);
+
         // Shifting all but first line down to test comments shifting
         sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true);
 
@@ -191,6 +195,26 @@ public abstract class BaseTestSheetShiftRows extends TestCase {
         assertEquals(comment3,comment3_shifted);
         comment4_shifted = sheet.getCellComment(4,0).getString().getString();
         assertEquals(comment4,comment4_shifted);
+
+        // Shifting back up again, now two rows
+        sheet.shiftRows(2, sheet.getLastRowNum(), -2, true, true);
+
+        // TODO: it seems HSSFSheet does not correctly remove comments from rows that are overwritten
+        // by shifting rows...
+        if(!(wb instanceof HSSFWorkbook)) {
+               assertEquals(2, sheet.getLastRowNum());
+               
+               // Verify comments are in the position expected
+               assertNull("Had: " + (sheet.getCellComment(0,0) == null ? "null" : sheet.getCellComment(0,0).getString()),
+                               sheet.getCellComment(0,0));
+               assertNotNull(sheet.getCellComment(1,0));
+               assertNotNull(sheet.getCellComment(2,0));
+        }
+
+        comment1 = sheet.getCellComment(1,0).getString().getString();
+        assertEquals(comment1,"comment top row3 (index2)\n");
+        String comment2 = sheet.getCellComment(2,0).getString().getString();
+        assertEquals(comment2,"comment top row4 (index3)\n");
     }
 
     public final void testShiftWithNames() {
@@ -378,6 +402,19 @@ public abstract class BaseTestSheetShiftRows extends TestCase {
 
         assertEquals("SUM(G29:I29)", sheet.getRow(28).getCell(9).getCellFormula());
         assertEquals("SUM(G30:I30)", sheet.getRow(29).getCell(9).getCellFormula());
-
     }
+
+       public void testBug55280() throws IOException {
+        Workbook w = _testDataProvider.createWorkbook();
+        try {
+            Sheet s = w.createSheet();
+            for (int row = 0; row < 5000; ++row)
+                s.addMergedRegion(new CellRangeAddress(row, row, 0, 3));
+
+            s.shiftRows(0, 4999, 1);        // takes a long time...
+        } finally {
+            w.close();
+        }
+       }
+
 }
\ No newline at end of file