]> source.dussan.org Git - poi.git/commitdiff
Consolidating various duplicates of CellRangeAddress
authorJosh Micich <josh@apache.org>
Mon, 4 Aug 2008 08:00:11 +0000 (08:00 +0000)
committerJosh Micich <josh@apache.org>
Mon, 4 Aug 2008 08:00:11 +0000 (08:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@682282 13f79535-47bb-0310-9956-ffa450edef68

26 files changed:
src/contrib/src/org/apache/poi/hssf/usermodel/contrib/HSSFRegionUtil.java
src/java/org/apache/poi/hssf/dev/HSSF.java
src/java/org/apache/poi/hssf/model/Sheet.java
src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
src/java/org/apache/poi/hssf/record/DVRecord.java
src/java/org/apache/poi/hssf/record/MergeCellsRecord.java
src/java/org/apache/poi/hssf/record/SelectionRecord.java
src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java
src/java/org/apache/poi/hssf/record/cf/CellRange.java [deleted file]
src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
src/java/org/apache/poi/hssf/util/CellRangeAddress.java
src/java/org/apache/poi/hssf/util/CellRangeAddressList.java
src/java/org/apache/poi/hssf/util/Region.java
src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java
src/testcases/org/apache/poi/hssf/record/TestMergeCellsRecord.java
src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java
src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
src/testcases/org/apache/poi/hssf/usermodel/TestCloneSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java

index 0a71600ed884eb8fb40b3a1542535b5e86bd4dfc..fda8759fd292744cf0afcacb3fde29326a7ac386 100644 (file)
@@ -21,197 +21,257 @@ import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.Region;
 
 /**
- *  Various utility functions that make working with a region of cells easier.
- *
- *@author     Eric Pugh epugh@upstate.com
- *@since      July 29, 2002
+ * Various utility functions that make working with a region of cells easier.
+ * 
+ * @author Eric Pugh epugh@upstate.com
  */
-public final class HSSFRegionUtil
-{
-
-  /**  Constructor for the HSSFRegionUtil object */
-  private HSSFRegionUtil() {
-      // no instances of this class
-  }
-
-  /**
-   *  Sets the left border for a region of cells by manipulating the cell style
-   *  of the individual cells on the left
-   *
-   *@param  border                 The new border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setBorderLeft( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int rowStart = region.getRowFrom();
-    int rowEnd = region.getRowTo();
-    int column = region.getColumnFrom();
-
-    for ( int i = rowStart; i <= rowEnd; i++ ) {
-      HSSFRow row = HSSFCellUtil.getRow( i, sheet );
-      HSSFCell cell = HSSFCellUtil.getCell( row, column );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.BORDER_LEFT, new Short( border ) );
-    }
-  }
-
-  /**
-   *  Sets the leftBorderColor attribute of the HSSFRegionUtil object
-   *
-   *@param  color                  The color of the border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setLeftBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int rowStart = region.getRowFrom();
-    int rowEnd = region.getRowTo();
-    int column = region.getColumnFrom();
-
-    for ( int i = rowStart; i <= rowEnd; i++ ) {
-      HSSFRow row = HSSFCellUtil.getRow( i, sheet );
-      HSSFCell cell = HSSFCellUtil.getCell( row, column );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.LEFT_BORDER_COLOR, new Short( color ) );
-    }
-  }
-
-  /**
-   *  Sets the borderRight attribute of the HSSFRegionUtil object
-   *
-   *@param  border                 The new border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setBorderRight( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int rowStart = region.getRowFrom();
-    int rowEnd = region.getRowTo();
-    int column = region.getColumnTo();
-
-    for ( int i = rowStart; i <= rowEnd; i++ ) {
-      HSSFRow row = HSSFCellUtil.getRow( i, sheet );
-      HSSFCell cell = HSSFCellUtil.getCell( row, column );
-
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.BORDER_RIGHT, new Short( border ) );
-    }
-  }
-
-  /**
-   *  Sets the rightBorderColor attribute of the HSSFRegionUtil object
-   *
-   *@param  color                  The color of the border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setRightBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int rowStart = region.getRowFrom();
-    int rowEnd = region.getRowTo();
-    int column = region.getColumnTo();
-
-    for ( int i = rowStart; i <= rowEnd; i++ ) {
-      HSSFRow row = HSSFCellUtil.getRow( i, sheet );
-      HSSFCell cell = HSSFCellUtil.getCell( row, column );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.RIGHT_BORDER_COLOR, new Short( color ) );
-    }
-  }
-
-  /**
-   *  Sets the borderBottom attribute of the HSSFRegionUtil object
-   *
-   *@param  border                 The new border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setBorderBottom( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int colStart = region.getColumnFrom();
-    int colEnd = region.getColumnTo();
-    int rowIndex = region.getRowTo();
-    HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
-    for ( int i = colStart; i <= colEnd; i++ ) {
-
-      HSSFCell cell = HSSFCellUtil.getCell( row, i );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.BORDER_BOTTOM, new Short( border ) );
-    }
-  }
-
-  /**
-   *  Sets the bottomBorderColor attribute of the HSSFRegionUtil object
-   *
-   *@param  color                  The color of the border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setBottomBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int colStart = region.getColumnFrom();
-    int colEnd = region.getColumnTo();
-    int rowIndex = region.getRowTo();
-    HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
-    for ( int i = colStart; i <= colEnd; i++ ) {
-      HSSFCell cell = HSSFCellUtil.getCell( row, i );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.BOTTOM_BORDER_COLOR, new Short( color ) );
-    }
-  }
-
-  /**
-   *  Sets the borderBottom attribute of the HSSFRegionUtil object
-   *
-   *@param  border                 The new border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setBorderTop( short border, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int colStart = region.getColumnFrom();
-    int colEnd = region.getColumnTo();
-    int rowIndex = region.getRowFrom();
-    HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
-    for ( int i = colStart; i <= colEnd; i++ ) {
-
-      HSSFCell cell = HSSFCellUtil.getCell( row, i );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.BORDER_TOP, new Short( border ) );
-    }
-  }
-
-  /**
-   *  Sets the topBorderColor attribute of the HSSFRegionUtil object
-   *
-   *@param  color                  The color of the border
-   *@param  region                 The region that should have the border
-   *@param  workbook               The workbook that the region is on.
-   *@param  sheet                  The sheet that the region is on.
-   */
-  public static void setTopBorderColor( short color, Region region, HSSFSheet sheet, HSSFWorkbook workbook )
-  {
-    int colStart = region.getColumnFrom();
-    int colEnd = region.getColumnTo();
-    int rowIndex = region.getRowFrom();
-    HSSFRow row = HSSFCellUtil.getRow( rowIndex, sheet );
-    for ( int i = colStart; i <= colEnd; i++ ) {
-      HSSFCell cell = HSSFCellUtil.getCell( row, i );
-      HSSFCellUtil.setCellStyleProperty(
-          cell, workbook, HSSFCellUtil.TOP_BORDER_COLOR, new Short( color ) );
-    }
-  }
-}
+public final class HSSFRegionUtil {
+
+       private HSSFRegionUtil() {
+               // no instances of this class
+       }
+       /**
+        * For setting the same property on many cells to the same value
+        */
+       private static final class CellPropertySetter {
+
+               private final HSSFWorkbook _workbook;
+               private final String _propertyName;
+               private final Short _propertyValue;
+
+               public CellPropertySetter(HSSFWorkbook workbook, String propertyName, int value) {
+                       _workbook = workbook;
+                       _propertyName = propertyName;
+                       _propertyValue = new Short((short)value);
+               }
+               public void setProperty(HSSFRow row, int column) {
+                       HSSFCell cell = HSSFCellUtil.getCell(row, column);
+                       HSSFCellUtil.setCellStyleProperty(cell, _workbook, _propertyName, _propertyValue);
+               }
+       }
+
+       private static CellRangeAddress toCRA(Region region) {
+               return Region.convertToCellRangeAddress(region);
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setBorderLeft(short border, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setBorderLeft(border, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the left border for a region of cells by manipulating the cell style
+        * of the individual cells on the left
+        * 
+        * @param border The new border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setBorderLeft(int border, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int rowStart = region.getFirstRow();
+               int rowEnd = region.getLastRow();
+               int column = region.getFirstColumn();
+
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.BORDER_LEFT, border);
+               for (int i = rowStart; i <= rowEnd; i++) {
+                       cps.setProperty(HSSFCellUtil.getRow(i, sheet), column);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setLeftBorderColor(short color, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setLeftBorderColor(color, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the leftBorderColor attribute of the HSSFRegionUtil object
+        * 
+        * @param color The color of the border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setLeftBorderColor(int color, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int rowStart = region.getFirstRow();
+               int rowEnd = region.getLastRow();
+               int column = region.getFirstColumn();
 
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.LEFT_BORDER_COLOR, color);
+               for (int i = rowStart; i <= rowEnd; i++) {
+                       cps.setProperty(HSSFCellUtil.getRow(i, sheet), column);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setBorderRight(short border, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setBorderRight(border, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the borderRight attribute of the HSSFRegionUtil object
+        * 
+        * @param border The new border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setBorderRight(int border, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int rowStart = region.getFirstRow();
+               int rowEnd = region.getLastRow();
+               int column = region.getLastColumn();
+
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.BORDER_RIGHT, border);
+               for (int i = rowStart; i <= rowEnd; i++) {
+                       cps.setProperty(HSSFCellUtil.getRow(i, sheet), column);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setRightBorderColor(short color, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setRightBorderColor(color, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the rightBorderColor attribute of the HSSFRegionUtil object
+        * 
+        * @param color The color of the border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setRightBorderColor(int color, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int rowStart = region.getFirstRow();
+               int rowEnd = region.getLastRow();
+               int column = region.getLastColumn();
+
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.RIGHT_BORDER_COLOR, color);
+               for (int i = rowStart; i <= rowEnd; i++) {
+                       cps.setProperty(HSSFCellUtil.getRow(i, sheet), column);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setBorderBottom(short border, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setBorderBottom(border, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the borderBottom attribute of the HSSFRegionUtil object
+        * 
+        * @param border The new border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setBorderBottom(int border, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int colStart = region.getFirstColumn();
+               int colEnd = region.getLastColumn();
+               int rowIndex = region.getLastRow();
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.BORDER_BOTTOM, border);
+               HSSFRow row = HSSFCellUtil.getRow(rowIndex, sheet);
+               for (int i = colStart; i <= colEnd; i++) {
+                       cps.setProperty(row, i);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setBottomBorderColor(short color, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setBottomBorderColor(color, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the bottomBorderColor attribute of the HSSFRegionUtil object
+        * 
+        * @param color The color of the border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setBottomBorderColor(int color, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int colStart = region.getFirstColumn();
+               int colEnd = region.getLastColumn();
+               int rowIndex = region.getLastRow();
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.BOTTOM_BORDER_COLOR, color);
+               HSSFRow row = HSSFCellUtil.getRow(rowIndex, sheet);
+               for (int i = colStart; i <= colEnd; i++) {
+                       cps.setProperty(row, i);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setBorderTop(short border, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setBorderTop(border, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the borderBottom attribute of the HSSFRegionUtil object
+        * 
+        * @param border The new border
+        * @param region The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setBorderTop(int border, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int colStart = region.getFirstColumn();
+               int colEnd = region.getLastColumn();
+               int rowIndex = region.getFirstRow();
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.BORDER_TOP, border);
+               HSSFRow row = HSSFCellUtil.getRow(rowIndex, sheet);
+               for (int i = colStart; i <= colEnd; i++) {
+                       cps.setProperty(row, i);
+               }
+       }
+
+       /**
+        * @deprecated (Aug 2008) use {@link CellRangeAddress} instead of {@link Region}
+        */
+       public static void setTopBorderColor(short color, Region region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               setTopBorderColor(color, toCRA(region), sheet, workbook);
+       }
+       /**
+        * Sets the topBorderColor attribute of the HSSFRegionUtil object
+        * 
+        * @param color The color of the border
+        * @param region  The region that should have the border
+        * @param workbook The workbook that the region is on.
+        * @param sheet The sheet that the region is on.
+        */
+       public static void setTopBorderColor(int color, CellRangeAddress region, HSSFSheet sheet,
+                       HSSFWorkbook workbook) {
+               int colStart = region.getFirstColumn();
+               int colEnd = region.getLastColumn();
+               int rowIndex = region.getFirstRow();
+               CellPropertySetter cps = new CellPropertySetter(workbook, HSSFCellUtil.TOP_BORDER_COLOR, color);
+               HSSFRow row = HSSFCellUtil.getRow(rowIndex, sheet);
+               for (int i = colStart; i <= colEnd; i++) {
+                       cps.setProperty(row, i);
+               }
+       }
+}
index 7dddca966a3afdd368e53f7c042f032dd7aa2211..b7d4bbbca6aba295158c78d7cdbd4c23d14ef4f5 100644 (file)
 
 package org.apache.poi.hssf.dev;
 
-import java.io.IOException;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFDataFormat;
+import org.apache.poi.hssf.usermodel.HSSFFont;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.hssf.usermodel.*;
-import org.apache.poi.hssf.util.*;
 
 /**
  * File for HSSF testing/examples
@@ -126,7 +133,7 @@ public class HSSF
                 }
                 c = r.createCell(( short ) (cellnum + 1),
                                  HSSFCell.CELL_TYPE_STRING);
-                c.setCellValue("TEST");
+                c.setCellValue(new HSSFRichTextString("TEST"));
                 s.setColumnWidth(( short ) (cellnum + 1),
                                  ( short ) ((50 * 8) / (( double ) 1 / 20)));
                 if ((rownum % 2) == 0)
@@ -148,10 +155,8 @@ public class HSSF
             // c.setCellValue(0);
             c.setCellStyle(cs3);
         }
-        s.addMergedRegion(new Region(( short ) 0, ( short ) 0, ( short ) 3,
-                                     ( short ) 3));
-        s.addMergedRegion(new Region(( short ) 100, ( short ) 100,
-                                     ( short ) 110, ( short ) 110));
+        s.addMergedRegion(new CellRangeAddress(0, 3, 0, 3));
+        s.addMergedRegion(new CellRangeAddress(100, 110, 100, 110));
 
         // end draw thick black border
         // create a sheet, set its title then delete it
index 9959dbfb26a5d0eb5a61c7806903ac2c3da68aaa..993dfd7b312bec081cb4f37078a8f54dec9ee0ce 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.PaneInformation;
 
 import org.apache.poi.util.POILogFactory;
@@ -515,7 +516,7 @@ public final class Sheet implements Model {
         }
     }
 
-    public int addMergedRegion(int rowFrom, short colFrom, int rowTo, short colTo) {
+    public int addMergedRegion(int rowFrom, int colFrom, int rowTo, int colTo) {
         // Validate input
         if (rowTo < rowFrom) {
             throw new IllegalArgumentException("The 'to' row (" + rowTo
@@ -585,7 +586,7 @@ public final class Sheet implements Model {
         }
     }
 
-    public MergeCellsRecord.MergedRegion getMergedRegionAt(int index)
+    public CellRangeAddress getMergedRegionAt(int index)
     {
         //safety checks
         if (index >= numMergedRegions || mergedRecords.size() == 0)
@@ -1634,13 +1635,7 @@ public final class Sheet implements Model {
      * Creates the Selection record and sets it to nothing selected
     */
     private static SelectionRecord createSelection() {
-        SelectionRecord retval = new SelectionRecord();
-
-        retval.setPane(( byte ) 0x3);
-        retval.setActiveCellCol(( short ) 0x0);
-        retval.setActiveCellRow(( short ) 0x0);
-        retval.setNumRefs(( short ) 0x0);
-        return retval;
+        return new SelectionRecord(0, 0);
     }
 
     public short getTopRow()
@@ -1701,18 +1696,14 @@ public final class Sheet implements Model {
     }
 
     /**
-     * Returns the active column
-     *
      * @see org.apache.poi.hssf.record.SelectionRecord
-     * @return row the active column index
+     * @return column of the active cell
      */
-    public short getActiveCellCol()
-    {
-        if (selection == null)
-        {
-            return (short) 0;
+    public short getActiveCellCol() {
+        if (selection == null) {
+            return 0;
         }
-        return selection.getActiveCellCol();
+        return (short)selection.getActiveCellCol();
     }
 
     /**
@@ -1731,9 +1722,7 @@ public final class Sheet implements Model {
     }
 
     private static  MergeCellsRecord createMergedCells() {
-        MergeCellsRecord retval = new MergeCellsRecord();
-        retval.setNumAreas(( short ) 0);
-        return retval;
+        return new MergeCellsRecord();
     }
 
     /**
index d74d54ab1732d6c82239d8e5db751d252846346c..70d4101fa0a4d88aed46b9c2005f1e687d275b13 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.hssf.record.cf.CellRange;
-import org.apache.poi.hssf.util.Region;
+import org.apache.poi.hssf.record.cf.CellRangeUtil;
+import org.apache.poi.hssf.util.CellRangeAddress;
+import org.apache.poi.hssf.util.CellRangeAddressList;
 import org.apache.poi.util.LittleEndian;
 
 /**
- * Conditional Formatting Header record (CFHEADER)
+ * Conditional Formatting Header record CFHEADER (0x1B0)
  * 
  * @author Dmitriy Kumshayev
  */
-public final class CFHeaderRecord extends Record
-{
+public final class CFHeaderRecord extends Record {
        public static final short sid = 0x1B0;
 
-       private static final CellRange[] EMPTY_CELL_RANGE_ARRAY = { };
-
        private int field_1_numcf;
        private int field_2_need_recalculation;
-       private CellRange field_3_enclosing_cell_range;
-       private CellRange[] field_4_cell_ranges;
+       private CellRangeAddress field_3_enclosing_cell_range;
+       private CellRangeAddressList field_4_cell_ranges;
 
        /** Creates new CFHeaderRecord */
        public CFHeaderRecord()
        {
-               field_4_cell_ranges = EMPTY_CELL_RANGE_ARRAY;
+               field_4_cell_ranges = new CellRangeAddressList();
        }
-       public CFHeaderRecord(Region[] regions)
+       public CFHeaderRecord(CellRangeAddress[] regions)
        {
-               CellRange[] unmergedRanges = CellRange.convertRegionsToCellRanges(regions);
-               CellRange[] mergeCellRanges = CellRange.mergeCellRanges(unmergedRanges);
+               CellRangeAddress[] unmergedRanges = regions;
+               CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges);
                setCellRanges(mergeCellRanges);
        }
 
@@ -58,14 +56,8 @@ public final class CFHeaderRecord extends Record
        {
                field_1_numcf = in.readShort();
                field_2_need_recalculation = in.readShort();
-               field_3_enclosing_cell_range = new CellRange(in.readUShort(), in.readUShort(), in.readUShort(), in.readUShort());
-               int numCellRanges = in.readShort();
-               CellRange[] crs = new CellRange[numCellRanges];
-               for( int i=0; i<numCellRanges; i++)
-               {
-                       crs[i] = new CellRange(in.readUShort(),in.readUShort(),in.readUShort(),in.readUShort());
-               }
-               field_4_cell_ranges = crs;
+               field_3_enclosing_cell_range = new CellRangeAddress(in);
+               field_4_cell_ranges = new CellRangeAddressList(in);
        }
        
        public int getNumberOfConditionalFormats()
@@ -87,14 +79,14 @@ public final class CFHeaderRecord extends Record
                field_2_need_recalculation=b?1:0;
        }
        
-       public CellRange getEnclosingCellRange()
+       public CellRangeAddress getEnclosingCellRange()
        {
                return field_3_enclosing_cell_range;
        }
 
-       public void setEnclosingCellRange( CellRange cr)
+       public void setEnclosingCellRange(CellRangeAddress cr)
        {
-               field_3_enclosing_cell_range = cr.cloneCellRange();
+               field_3_enclosing_cell_range = cr;
        }
 
        /**
@@ -102,24 +94,26 @@ public final class CFHeaderRecord extends Record
         * modify the enclosing cell range accordingly.
         * @param List cellRanges - list of CellRange objects
         */
-       public void setCellRanges(CellRange[] cellRanges)
+       public void setCellRanges(CellRangeAddress[] cellRanges)
        {
                if(cellRanges == null)
                {
                        throw new IllegalArgumentException("cellRanges must not be null");
                }
-               field_4_cell_ranges = (CellRange[]) cellRanges.clone();
-               CellRange enclosingRange = null;
+               CellRangeAddressList cral = new CellRangeAddressList();
+               CellRangeAddress enclosingRange = null;
                for (int i = 0; i < cellRanges.length; i++)
                {
-                       enclosingRange = cellRanges[i].createEnclosingCellRange(enclosingRange);
+                       CellRangeAddress cr = cellRanges[i];
+                       enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange);
+                       cral.addCellRangeAddress(cr);
                }
-               field_3_enclosing_cell_range=enclosingRange;
+               field_3_enclosing_cell_range = enclosingRange;
+               field_4_cell_ranges = cral;
        }
        
-       public CellRange[] getCellRanges()
-       {
-               return (CellRange[]) field_4_cell_ranges.clone();
+       public CellRangeAddress[] getCellRanges() {
+               return field_4_cell_ranges.getCellRangeAddresses();
        }
 
        public String toString()
@@ -131,50 +125,39 @@ public final class CFHeaderRecord extends Record
                buffer.append(" .numCF                  = ").append(getNumberOfConditionalFormats()).append("\n");
                buffer.append(" .needRecalc        = ").append(getNeedRecalculation()).append("\n");
                buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
-               if( field_4_cell_ranges.length>0)
+               buffer.append(" .cfranges=[");
+               for( int i=0; i<field_4_cell_ranges.countRanges(); i++)
                {
-                       buffer.append(" .cfranges=[");
-                       for( int i=0; i<field_4_cell_ranges.length; i++)
-                       {
-                               buffer.append(i==0?"":",").append(field_4_cell_ranges[i].toString());
-                       }
-                       buffer.append("]\n");
+                       buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
                }
+               buffer.append("]\n");
                buffer.append("[/CFHEADER]\n");
                return buffer.toString();
        }
 
+       private int getDataSize() {
+               return 4 // 2 short fields
+                       + CellRangeAddress.ENCODED_SIZE
+                       + field_4_cell_ranges.getSize();
+       }
+       
        /**
         * @return byte array containing instance data
         */
-
-       public int serialize(int offset, byte[] data)
-       {
-               int recordsize = getRecordSize();
+       public int serialize(int offset, byte[] data) {
+               int dataSize = getDataSize();
                
-               LittleEndian.putShort(data, 0 + offset, sid);
-               LittleEndian.putShort(data, 2 + offset, (short) (recordsize-4));
-               LittleEndian.putShort(data, 4 + offset, (short) field_1_numcf);
-               LittleEndian.putShort(data, 6 + offset, (short) field_2_need_recalculation);
-               LittleEndian.putShort(data, 8 + offset, (short) field_3_enclosing_cell_range.getFirstRow());
-               LittleEndian.putShort(data, 10 + offset, (short) field_3_enclosing_cell_range.getLastRow());
-               LittleEndian.putShort(data, 12 + offset, (short) field_3_enclosing_cell_range.getFirstColumn());
-               LittleEndian.putShort(data, 14 + offset, (short) field_3_enclosing_cell_range.getLastColumn());
-               LittleEndian.putShort(data, 16 + offset, (short) field_4_cell_ranges.length);
-               for( int i=0 ; i!=field_4_cell_ranges.length; i++)
-               {
-                       CellRange cr = field_4_cell_ranges[i];
-                       LittleEndian.putShort(data, 18 + 0 + 8 * i + offset, (short) cr.getFirstRow());
-                       LittleEndian.putShort(data, 18 + 2 + 8 * i + offset, (short) cr.getLastRow());
-                       LittleEndian.putShort(data, 18 + 4 + 8 * i + offset, (short) cr.getFirstColumn());
-                       LittleEndian.putShort(data, 18 + 6 + 8 * i + offset, (short) cr.getLastColumn());
-               }
-               return getRecordSize();
+               LittleEndian.putUShort(data, 0 + offset, sid);
+               LittleEndian.putUShort(data, 2 + offset, dataSize);
+               LittleEndian.putUShort(data, 4 + offset, field_1_numcf);
+               LittleEndian.putUShort(data, 6 + offset, field_2_need_recalculation);
+               field_3_enclosing_cell_range.serialize(8 + offset, data);
+               field_4_cell_ranges.serialize(16 + offset, data);
+               return 4 + dataSize;
        }
 
-       public int getRecordSize()
-       {
-               return 18+8*field_4_cell_ranges.length;
+       public int getRecordSize() {
+               return 4 + getDataSize();
        }
 
        /**
@@ -204,11 +187,7 @@ public final class CFHeaderRecord extends Record
                result.field_1_numcf = field_1_numcf;
                result.field_2_need_recalculation = field_2_need_recalculation;
                result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
-               CellRange[] crs = new CellRange[field_4_cell_ranges.length];
-               for (int i = 0; i < crs.length; i++) {
-                       crs[i] = field_4_cell_ranges[i].cloneCellRange();
-               }
-               result.field_4_cell_ranges = crs;
+               result.field_4_cell_ranges = field_4_cell_ranges.copy();
                return result;
        }
 }
index a90730ee55c262f04fb2682d778a4a655cf57f4a..6f319e028226438a71fc1f1a5436247b9a71354b 100644 (file)
@@ -227,7 +227,7 @@ public final class DVRecord extends Record {
                appendFormula(sb, "Formula 1:",  _formula1);
                appendFormula(sb, "Formula 2:",  _formula2);
                sb.append("Regions: ");
-               int nRegions = _regions.getADDRStructureNumber();
+               int nRegions = _regions.countRanges();
                for(int i=0; i<nRegions; i++) {
                        if (i>0) {
                                sb.append(", ");
index 41d8170dff26e6f058396dd886137bf3df8489ea..bf41d2fc91277f6301452e57c579b99fd3108126 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-
+import org.apache.poi.hssf.util.CellRangeAddress;
+import org.apache.poi.hssf.util.CellRangeAddressList;
 import org.apache.poi.util.LittleEndian;
 
 /**
- * Title: Merged Cells Record
- * <br>
+ * Title: Merged Cells Record (0x00E5)
+ * <br/>
  * Description:  Optional record defining a square area of cells to "merged" into
  *               one cell. <br>
  * REFERENCE:  NONE (UNDOCUMENTED PRESENTLY) <br>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @version 2.0-pre
  */
-public class MergeCellsRecord
-    extends Record
-{
-    public final static short sid = 0xe5;
-    private ArrayList         field_2_regions;
+public final class MergeCellsRecord extends Record {
+    public final static short sid = 0x00E5;
+    private CellRangeAddressList _regions;
 
-    public MergeCellsRecord()
-    {
+    /** 
+     * Creates an empty <tt>MergedCellsRecord</tt>
+     */
+    public MergeCellsRecord() {
+       _regions = new CellRangeAddressList();
     }
 
     /**
      * Constructs a MergedCellsRecord and sets its fields appropriately
      * @param in the RecordInputstream to read the record from
      */
-
-    public MergeCellsRecord(RecordInputStream in)
-    {
+    public MergeCellsRecord(RecordInputStream in) {
         super(in);
     }
 
-    protected void fillFields(RecordInputStream in)
-    {
-        short numAreas    = in.readShort();
-        field_2_regions   = new ArrayList(numAreas + 10);
-
-        for (int k = 0; k < numAreas; k++)
-        {
-            MergedRegion region =
-                new MergedRegion(in.readShort(), in.readShort(),
-                                 in.readShort(), in.readShort());
-
-            field_2_regions.add(region);
-        }
+    protected void fillFields(RecordInputStream in) {
+       _regions = new CellRangeAddressList(in);
     }
 
     /**
@@ -73,27 +58,8 @@ public class MergeCellsRecord
      * ahead and delete the record.
      * @return number of areas
      */
-
-    public short getNumAreas()
-    {
-        //if the array size is larger than a short (65536), the record can't hold that many merges anyway
-        if (field_2_regions == null) return 0;
-        return (short)field_2_regions.size();
-    }
-
-    /**
-     * set the number of merged areas.  You do not need to call this if you use addArea,
-     * it will be incremented automatically or decremented when an area is removed.  If
-     * you are setting this to 0 then you are a terrible person.  Just remove the record.
-     * (just kidding about you being a terrible person..hehe)
-     * @deprecated We now link the size to the actual array of merged regions
-     * @see #getNumAreas()
-     * @param numareas  number of areas
-     */
-
-    public void setNumAreas(short numareas)
-    {
-        
+    public short getNumAreas() {
+        return (short)_regions.countRanges();
     }
 
     /**
@@ -101,178 +67,84 @@ public class MergeCellsRecord
      * be correct provided you do not add ahead of or remove ahead of it  (in which case
      * you should increment or decrement appropriately....in other words its an arrayList)
      *
-     * @param rowfrom - the upper left hand corner's row
-     * @param colfrom - the upper left hand corner's col
-     * @param rowto - the lower right hand corner's row
-     * @param colto - the lower right hand corner's col
+     * @param firstRow - the upper left hand corner's row
+     * @param firstCol - the upper left hand corner's col
+     * @param lastRow - the lower right hand corner's row
+     * @param lastCol - the lower right hand corner's col
      * @return new index of said area (don't depend on it if you add/remove)
      */
-
-    //public int addArea(short rowfrom, short colfrom, short rowto, short colto)
-    public int addArea(int rowfrom, short colfrom, int rowto, short colto)
-    {
-        if (field_2_regions == null)
-        {
-            field_2_regions = new ArrayList(10);
-        }
-        MergedRegion region = new MergedRegion(rowfrom, rowto, colfrom,
-                                               colto);
-
-        field_2_regions.add(region);
-        return field_2_regions.size() - 1;
+    public void addArea(int firstRow, int firstCol, int lastRow, int lastCol) {
+       _regions.addCellRangeAddress(firstRow, firstCol, lastRow, lastCol);
     }
 
     /**
      * essentially unmerge the cells in the "area" stored at the passed in index
-     * @param area index
+     * @param areaIndex
      */
-
-    public void removeAreaAt(int area)
-    {
-        field_2_regions.remove(area);
+    public void removeAreaAt(int areaIndex) {
+        _regions.remove(areaIndex);
     }
 
     /**
-     * return the MergedRegion at the given index.
-     *
-     * @return MergedRegion representing the area that is Merged (r1,c1 - r2,c2)
+     * @return MergedRegion at the given index representing the area that is Merged (r1,c1 - r2,c2)
      */
-
-    public MergedRegion getAreaAt(int index)
-    {
-        return ( MergedRegion ) field_2_regions.get(index);
+    public CellRangeAddress getAreaAt(int index) {
+        return _regions.getCellRangeAddress(index);
     }
 
-    public int getRecordSize()
-    {
-        int retValue;
-
-        retValue = 6 + (8 * field_2_regions.size());
-        return retValue;
+    public int getRecordSize() {
+       return 4 + _regions.getSize();
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        int recordsize = getRecordSize();
-        int pos        = 6;
+    public int serialize(int offset, byte [] data) {
+        int dataSize = _regions.getSize();
 
         LittleEndian.putShort(data, offset + 0, sid);
-        LittleEndian.putShort(data, offset + 2, ( short ) (recordsize - 4));
-        LittleEndian.putShort(data, offset + 4, getNumAreas());
-        for (int k = 0; k < getNumAreas(); k++)
-        {
-            MergedRegion region = getAreaAt(k);
-
-            //LittleEndian.putShort(data, offset + pos, region.row_from);
-            LittleEndian.putShort(data, offset + pos, ( short ) region.row_from);
-            pos += 2;
-            //LittleEndian.putShort(data, offset + pos, region.row_to);
-            LittleEndian.putShort(data, offset + pos, ( short ) region.row_to);
-            pos += 2;
-            LittleEndian.putShort(data, offset + pos, region.col_from);
-            pos += 2;
-            LittleEndian.putShort(data, offset + pos, region.col_to);
-            pos += 2;
-        }
-        return recordsize;
+        LittleEndian.putUShort(data, offset + 2, dataSize);
+        _regions.serialize(offset + 4, data);
+        return 4 + dataSize;
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer retval = new StringBuffer();
 
         retval.append("[MERGEDCELLS]").append("\n");
         retval.append("     .sid        =").append(sid).append("\n");
         retval.append("     .numregions =").append(getNumAreas())
             .append("\n");
-        for (int k = 0; k < getNumAreas(); k++)
-        {
-            MergedRegion region = ( MergedRegion ) field_2_regions.get(k);
+        for (int k = 0; k < _regions.countRanges(); k++) {
+            CellRangeAddress region = _regions.getCellRangeAddress(k);
 
-            retval.append("     .rowfrom    =").append(region.row_from)
+            retval.append("     .rowfrom    =").append(region.getFirstRow())
                 .append("\n");
-            retval.append("     .colfrom    =").append(region.col_from)
+            retval.append("     .colfrom    =").append(region.getFirstColumn())
                 .append("\n");
-            retval.append("     .rowto      =").append(region.row_to)
+            retval.append("     .rowto      =").append(region.getLastRow())
                 .append("\n");
-            retval.append("     .colto      =").append(region.col_to)
+            retval.append("     .colto      =").append(region.getLastColumn())
                 .append("\n");
         }
         retval.append("[MERGEDCELLS]").append("\n");
         return retval.toString();
     }
 
-    protected void validateSid(short id)
-    {
-        if (id != sid)
-        {
+    protected void validateSid(short id) {
+        if (id != sid) {
             throw new RecordFormatException("NOT A MERGEDCELLS RECORD!! "
                                             + id);
         }
     }
 
-    /**
-     * this is a low level representation of a MergedRegion of cells.  It is an
-     * inner class because we do not want it used without reference to this class.
-     *
-     */
-
-    public class MergedRegion
-    {
-
-        /**
-         * create a merged region all in one stroke.
-         */
-
-        //public MergedRegion(short row_from, short row_to, short col_from,
-        public MergedRegion(int row_from, int row_to, short col_from,
-                            short col_to)
-        {
-            this.row_from = row_from;
-            this.row_to   = row_to;
-            this.col_from = col_from;
-            this.col_to   = col_to;
-        }
-
-        /**
-         * upper lefthand corner row
-         */
-
-        //public short row_from;
-        public int row_from;
-
-        /**
-         * lower right hand corner row
-         */
-
-        //public short row_to;
-        public int row_to;
-
-        /**
-         * upper right hand corner col
-         */
-
-        public short col_from;
-
-        /**
-         * lower right hand corner col
-         */
-
-        public short col_to;
-    }
-
     public Object clone() {
         MergeCellsRecord rec = new MergeCellsRecord();        
-        rec.field_2_regions = new ArrayList();
-        Iterator iterator = field_2_regions.iterator();
-        while (iterator.hasNext()) {
-           MergedRegion oldRegion = (MergedRegion)iterator.next();
-           rec.addArea(oldRegion.row_from, oldRegion.col_from, oldRegion.row_to, oldRegion.col_to);
+        for (int k = 0; k < _regions.countRanges(); k++) {
+            CellRangeAddress oldRegion = _regions.getCellRangeAddress(k);
+           rec.addArea(oldRegion.getFirstRow(), oldRegion.getFirstColumn(), 
+                          oldRegion.getLastRow(), oldRegion.getLastColumn());
         }
         
         return rec;
index 8ad4d0cefa6a11443262a4d86b2754f968aec003..2f36ea644ff862539715e413faf5df551cba8a08 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
-import java.util.*;
-
 import org.apache.poi.util.LittleEndian;
 
 /**
- * Title:        Selection Record<P>
+ * Title:        Selection Record (0x001D)<P>
  * Description:  shows the user's selection on the sheet
  *               for write set num refs to 0<P>
  *
- * TODO :  Fully implement reference subrecords.
  * REFERENCE:  PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Jason Height (jheight at chariot dot net dot au)
  * @author Glen Stampoultzis (glens at apache.org)
  */
+public final class SelectionRecord extends Record {
+    public final static short sid = 0x001D;
+    private byte        field_1_pane;
+    private int         field_2_row_active_cell;
+    private int         field_3_col_active_cell;
+    private int         field_4_active_cell_ref_index;
+    private Reference[] field_6_refs;
 
-public class SelectionRecord
-    extends Record
-{
-    public final static short sid = 0x1d;
-    private byte              field_1_pane;
-    //private short             field_2_row_active_cell;
-    private int             field_2_row_active_cell;
-    private short             field_3_col_active_cell;
-    private short             field_4_ref_active_cell;
-    private short             field_5_num_refs;
-    private ArrayList         field_6_refs;     // not used yet
-
+    /**
+     *  Note - column values are 8-bit so cannot use <tt>CellRangeAddressList</tt>
+     */
     public class Reference {
-      private short field_1_first_row;
-      private short field_2_last_row;
-      private byte field_3_first_column;
-      private byte field_4_last_column;
-      
-      Reference(RecordInputStream in) {
-        field_1_first_row = in.readShort();
-        field_2_last_row = in.readShort();
-        field_3_first_column = in.readByte();
-        field_4_last_column = in.readByte();
-      }
+        /* package */ static final int ENCODED_SIZE = 6;
+        private int _firstRow;
+               private int _lastRow;
+               private int _firstCol;
+               private int _lastCol;
       
-      public short getFirstRow() {
-         return field_1_first_row;
-      }
-      
-      public short getLastRow() {
-         return field_2_last_row;
-      }
-      
-      public byte getFirstColumn() {
-         return field_3_first_column;
-      }
-      
-      public byte getLastColumn() {
-         return field_4_last_column;
-      }
+               /* package */ Reference(int firstRow, int lastRow, int firstColumn, int lastColumn) {
+                       _firstRow = firstRow;
+                       _lastRow = lastRow;
+                       _firstCol = firstColumn;
+                       _lastCol = lastColumn;
+               }
+               /* package */ Reference(RecordInputStream in) {
+                   this(in.readUShort(), in.readUShort(), in.readUByte(), in.readUByte());
+               }
+               public void serialize(int offset, byte[] data) {
+                       LittleEndian.putUShort(data, offset + 0, _firstRow);
+                       LittleEndian.putUShort(data, offset + 2, _lastRow);
+                       LittleEndian.putByte(data, offset + 4, _firstCol);
+                       LittleEndian.putByte(data, offset + 6, _lastCol);
+               }
+
+               public int getFirstRow() {
+                   return _firstRow;
+               }
+               public int getLastRow() {
+                   return _lastRow;
+               }
+               public int getFirstColumn() {
+                   return _firstCol;
+               }
+               public int getLastColumn() {
+                   return _lastCol;
+               }
     }
 
-    public SelectionRecord()
-    {
+    /**
+     * Creates a default selection record (cell A1, in pane ID 3)
+     */
+    public SelectionRecord(int activeCellRow, int activeCellCol) {
+       field_1_pane = 3; // pane id 3 is always present.  see OOO sec 5.75 'PANE'
+       field_2_row_active_cell = activeCellRow;
+       field_3_col_active_cell = activeCellCol;
+       field_4_active_cell_ref_index = 0;
+       field_6_refs = new Reference[] {
+               new Reference(activeCellRow, activeCellRow, activeCellCol, activeCellCol),
+       };
     }
 
     /**
@@ -86,41 +95,33 @@ public class SelectionRecord
      * @param in the RecordInputstream to read the record from
      */
 
-    public SelectionRecord(RecordInputStream in)
-    {
+    public SelectionRecord(RecordInputStream in) {
         super(in);
     }
 
-    protected void validateSid(short id)
-    {
-        if (id != sid)
-        {
+    protected void validateSid(short id) {
+        if (id != sid) {
             throw new RecordFormatException("NOT A valid Selection RECORD");
         }
     }
 
-    protected void fillFields(RecordInputStream in)
-    {
+    protected void fillFields(RecordInputStream in) {
         field_1_pane            = in.readByte();
-        //field_2_row_active_cell = LittleEndian.getShort(data, 1 + offset);
         field_2_row_active_cell = in.readUShort();
         field_3_col_active_cell = in.readShort();
-        field_4_ref_active_cell = in.readShort();
-        field_5_num_refs        = in.readShort();
+        field_4_active_cell_ref_index = in.readShort();
+        int field_5_num_refs    = in.readUShort();
         
-        field_6_refs = new ArrayList(field_5_num_refs);
-        for (int i=0; i<field_5_num_refs; i++) {
-          field_6_refs.add(new Reference(in));
-        }
+        field_6_refs = new Reference[field_5_num_refs];
+        for (int i = 0; i < field_6_refs.length; i++) {
+               field_6_refs[i] = new Reference(in);
+               }
     }
 
     /**
      * set which window pane this is for
-     * @param pane
      */
-
-    public void setPane(byte pane)
-    {
+    public void setPane(byte pane) {
         field_1_pane = pane;
     }
 
@@ -128,10 +129,7 @@ public class SelectionRecord
      * set the active cell's row
      * @param row number of active cell
      */
-
-    //public void setActiveCellRow(short row)
-    public void setActiveCellRow(int row)
-    {
+    public void setActiveCellRow(int row) {
         field_2_row_active_cell = row;
     }
 
@@ -139,9 +137,7 @@ public class SelectionRecord
      * set the active cell's col
      * @param col number of active cell
      */
-
-    public void setActiveCellCol(short col)
-    {
+    public void setActiveCellCol(short col) {
         field_3_col_active_cell = col;
     }
 
@@ -149,29 +145,14 @@ public class SelectionRecord
      * set the active cell's reference number
      * @param ref number of active cell
      */
-
-    public void setActiveCellRef(short ref)
-    {
-        field_4_ref_active_cell = ref;
-    }
-
-    /**
-     * set the number of cell refs (we don't support selection so set to 0
-     * @param refs - number of references
-     */
-
-    public void setNumRefs(short refs)
-    {
-        field_5_num_refs = refs;
+    public void setActiveCellRef(short ref) {
+        field_4_active_cell_ref_index = ref;
     }
 
     /**
-     * get which window pane this is for
-     * @return pane
+     * @return the pane ID which window pane this is for
      */
-
-    public byte getPane()
-    {
+    public byte getPane() {
         return field_1_pane;
     }
 
@@ -179,10 +160,7 @@ public class SelectionRecord
      * get the active cell's row
      * @return row number of active cell
      */
-
-    //public short getActiveCellRow()
-    public int getActiveCellRow()
-    {
+    public int getActiveCellRow() {
         return field_2_row_active_cell;
     }
 
@@ -190,9 +168,7 @@ public class SelectionRecord
      * get the active cell's col
      * @return col number of active cell
      */
-
-    public short getActiveCellCol()
-    {
+    public int getActiveCellCol() {
         return field_3_col_active_cell;
     }
 
@@ -200,20 +176,8 @@ public class SelectionRecord
      * get the active cell's reference number
      * @return ref number of active cell
      */
-
-    public short getActiveCellRef()
-    {
-        return field_4_ref_active_cell;
-    }
-
-    /**
-     * get the number of cell refs (we don't support selection so set to 0
-     * @return refs - number of references
-     */
-
-    public short getNumRefs()
-    {
-        return field_5_num_refs;
+    public int getActiveCellRef() {
+        return (short)field_4_active_cell_ref_index;
     }
 
     public String toString()
@@ -230,47 +194,44 @@ public class SelectionRecord
         buffer.append("    .activecellref   = ")
             .append(Integer.toHexString(getActiveCellRef())).append("\n");
         buffer.append("    .numrefs         = ")
-            .append(Integer.toHexString(getNumRefs())).append("\n");
+            .append(Integer.toHexString(field_6_refs.length)).append("\n");
         buffer.append("[/SELECTION]\n");
         return buffer.toString();
     }
-
-//hacked to provide one cell reference to 0,0 - 0,0
-    public int serialize(int offset, byte [] data)
-    {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, ( short ) 15);
-        data[ 4 + offset ] = getPane();
-        //LittleEndian.putShort(data, 5 + offset, getActiveCellRow());
-        LittleEndian.putShort(data, 5 + offset, ( short ) getActiveCellRow());
-        LittleEndian.putShort(data, 7 + offset, getActiveCellCol());
-        LittleEndian.putShort(data, 9 + offset, getActiveCellRef());
-        LittleEndian.putShort(data, 11 + offset, ( short ) 1);
-        LittleEndian.putShort(data, 13 + offset, ( short ) getActiveCellRow());
-        LittleEndian.putShort(data, 15 + offset, ( short ) getActiveCellRow());
-        data[ 17 + offset ] = (byte)getActiveCellCol();
-        data[ 18 + offset ] = (byte)getActiveCellCol();
-        return getRecordSize();
+    private int getDataSize() {
+       return 9 // 1 byte + 4 shorts 
+               + field_6_refs.length * Reference.ENCODED_SIZE;
+    }
+    public int serialize(int offset, byte [] data) {
+       int dataSize = getDataSize();
+        LittleEndian.putUShort(data, 0 + offset, sid);
+        LittleEndian.putUShort(data, 2 + offset, dataSize);
+        LittleEndian.putByte(data, 4 + offset,  getPane());
+        LittleEndian.putUShort(data, 5 + offset, getActiveCellRow());
+        LittleEndian.putUShort(data, 7 + offset, getActiveCellCol());
+        LittleEndian.putUShort(data, 9 + offset, getActiveCellRef());
+        int nRefs = field_6_refs.length;
+        LittleEndian.putUShort(data, 11 + offset, nRefs);
+        for (int i = 0; i < field_6_refs.length; i++) {
+                       Reference r = field_6_refs[i];
+                       r.serialize(offset + 13 + i * Reference.ENCODED_SIZE, data);
+               }
+        return 4 + dataSize;
     }
 
-    public int getRecordSize()
-    {
-        return 19;
+    public int getRecordSize() {
+        return 4 + getDataSize();
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
     public Object clone() {
-      SelectionRecord rec = new SelectionRecord();
-      rec.field_1_pane = field_1_pane;
-      rec.field_2_row_active_cell = field_2_row_active_cell;
-      rec.field_3_col_active_cell = field_3_col_active_cell;
-      rec.field_4_ref_active_cell = field_4_ref_active_cell;
-      rec.field_5_num_refs = field_5_num_refs;
-      rec.field_6_refs = field_6_refs;
-      return rec;
+        SelectionRecord rec = new SelectionRecord(field_2_row_active_cell, field_3_col_active_cell);
+        rec.field_1_pane = field_1_pane;
+        rec.field_4_active_cell_ref_index = field_4_active_cell_ref_index;
+        rec.field_6_refs = field_6_refs;
+        return rec;
     }
 }
index 81154ebb22c5a43893bb85c1c5d9b2ba956259af..71754db9612b66e3cd192565a9299d74958c9016 100644 (file)
@@ -24,7 +24,7 @@ import org.apache.poi.hssf.record.CFHeaderRecord;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.Region;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -68,7 +68,7 @@ public final class CFRecordsAggregate extends Record
                }
        }
 
-       public CFRecordsAggregate(Region[] regions, CFRuleRecord[] rules) {
+       public CFRecordsAggregate(CellRangeAddress[] regions, CFRuleRecord[] rules) {
                this(new CFHeaderRecord(regions), rules);
        }
 
diff --git a/src/java/org/apache/poi/hssf/record/cf/CellRange.java b/src/java/org/apache/poi/hssf/record/cf/CellRange.java
deleted file mode 100644 (file)
index f45b79b..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.cf;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.poi.hssf.util.Region;
-
-/**
- * 
- * @author Dmitriy Kumshayev
- */
-public final class CellRange
-{
-       /** max 65536 rows in BIFF8 */
-       private static final int LAST_ROW_INDEX = 0x00FFFF; 
-       /** max 256 columns in BIFF8 */
-       private static final int LAST_COLUMN_INDEX = 0x00FF;
-
-       private static final Region[] EMPTY_REGION_ARRAY = { };
-       
-       private int _firstRow;
-       private int _lastRow;
-       private int _firstColumn;
-       private int _lastColumn;
-       
-       /**
-        * 
-        * @param firstRow
-        * @param lastRow pass <tt>-1</tt> for full column ranges
-        * @param firstColumn
-        * @param lastColumn  pass <tt>-1</tt> for full row ranges
-        */
-       public CellRange(int firstRow, int lastRow, int firstColumn, int lastColumn)
-       {
-               if(!isValid(firstRow, lastRow, firstColumn, lastColumn)) {
-                       throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow 
-                                       + ", " + firstColumn + ", " + lastColumn + ")");
-               }
-               _firstRow = firstRow;
-               _lastRow = convertM1ToMax(lastRow, LAST_ROW_INDEX);
-               _firstColumn = firstColumn;
-               _lastColumn = convertM1ToMax(lastColumn, LAST_COLUMN_INDEX);
-       }
-       
-       /** 
-        * Range arithmetic is easier when using a large positive number for 'max row or column' 
-        * instead of <tt>-1</tt>. 
-        */
-       private static int convertM1ToMax(int lastIx, int maxIndex) {
-               if(lastIx < 0) {
-                       return maxIndex;
-               }
-               return lastIx;
-       }
-
-       public boolean isFullColumnRange() {
-               return _firstRow == 0 && _lastRow == LAST_ROW_INDEX;
-       }
-       public boolean isFullRowRange() {
-               return _firstColumn == 0 && _lastColumn == LAST_COLUMN_INDEX;
-       }
-       
-       private static CellRange createFromRegion(Region r) {
-               return new CellRange(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo());
-       }
-
-       private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
-       {
-               if(lastRow < 0 || lastRow > LAST_ROW_INDEX) {
-                       return false;
-               }
-               if(firstRow < 0 || firstRow > LAST_ROW_INDEX) {
-                       return false;
-               }
-               
-               if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) {
-                       return false;
-               }
-               if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) {
-                       return false;
-               }
-               return true;
-       }
-       
-       public int getFirstRow()
-       {
-               return _firstRow;
-       }
-       public int getLastRow()
-       {
-               return _lastRow;
-       }
-       public int getFirstColumn()
-       {
-               return _firstColumn;
-       }
-       public int getLastColumn()
-       {
-               return _lastColumn;
-       }
-       
-       public static final int NO_INTERSECTION = 1;
-       public static final int OVERLAP = 2;
-       /** first range is within the second range */
-       public static final int INSIDE = 3;
-       /** first range encloses or is equal to the second */
-       public static final int ENCLOSES = 4;
-       
-       /**
-        * Intersect this range with the specified range.
-        * 
-        * @param another - the specified range
-        * @return code which reflects how the specified range is related to this range.<br/>
-        * Possible return codes are:   
-        *              NO_INTERSECTION - the specified range is outside of this range;<br/> 
-        *              OVERLAP - both ranges partially overlap;<br/>
-        *              INSIDE - the specified range is inside of this one<br/>
-        *              ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
-        */
-       public int intersect(CellRange another )
-       {
-               
-               int firstRow = another.getFirstRow();
-               int lastRow  = another.getLastRow();
-               int firstCol = another.getFirstColumn();
-               int lastCol  = another.getLastColumn();
-               
-               if
-               ( 
-                               gt(getFirstRow(),lastRow) || 
-                               lt(getLastRow(),firstRow) ||
-                               gt(getFirstColumn(),lastCol) || 
-                               lt(getLastColumn(),firstCol) 
-               )
-               {
-                       return NO_INTERSECTION;
-               }
-               else if( contains(another) )
-               {
-                       return INSIDE;
-               }
-               else if( another.contains(this))
-               {
-                       return ENCLOSES;
-               }
-               else
-               {
-                       return OVERLAP;
-               }
-                       
-       }
-       
-       /**
-        * Do all possible cell merges between cells of the list so that:<br>
-        *      <li>if a cell range is completely inside of another cell range, it gets removed from the list 
-        *      <li>if two cells have a shared border, merge them into one bigger cell range
-        * @param cellRangeList
-        * @return updated List of cell ranges
-        */
-       public static CellRange[] mergeCellRanges(CellRange[] cellRanges) {
-               if(cellRanges.length < 1) {
-                       return cellRanges;
-               }
-               List temp = mergeCellRanges(Arrays.asList(cellRanges));
-               return toArray(temp);
-       }
-       private static List mergeCellRanges(List cellRangeList)
-       {
-
-               while(cellRangeList.size() > 1)
-               {
-                       boolean somethingGotMerged = false;
-                       
-                       for( int i=0; i<cellRangeList.size(); i++)
-                       {
-                               CellRange range1 = (CellRange)cellRangeList.get(i);
-                               for( int j=i+1; j<cellRangeList.size(); j++)
-                               {
-                                       CellRange range2 = (CellRange)cellRangeList.get(j);
-                                       
-                                       CellRange[] mergeResult = mergeRanges(range1, range2);
-                                       if(mergeResult == null) {
-                                               continue;
-                                       }
-                                       somethingGotMerged = true;
-                                       // overwrite range1 with first result 
-                                       cellRangeList.set(i, mergeResult[0]);
-                                       // remove range2
-                                       cellRangeList.remove(j--);
-                                       // add any extra results beyond the first
-                                       for(int k=1; k<mergeResult.length; k++) {
-                                               j++;
-                                               cellRangeList.add(j, mergeResult[k]);
-                                       }
-                               }
-                       }
-                       if(!somethingGotMerged) {
-                               break;
-                       }
-               }
-               
-
-               return cellRangeList;
-       }
-       
-       /**
-        * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
-        */
-       private static CellRange[] mergeRanges(CellRange range1, CellRange range2) {
-               
-               int x = range1.intersect(range2);
-               switch(x)
-               {
-                       case CellRange.NO_INTERSECTION: 
-                               if( range1.hasExactSharedBorder(range2))
-                               {
-                                       return new CellRange[] { range1.createEnclosingCellRange(range2), };
-                               }
-                               // else - No intersection and no shared border: do nothing 
-                               return null;
-                       case CellRange.OVERLAP:
-                               return resolveRangeOverlap(range1, range2);
-                       case CellRange.INSIDE:
-                               // Remove range2, since it is completely inside of range1
-                               return new CellRange[] { range1, };
-                       case CellRange.ENCLOSES:
-                               // range2 encloses range1, so replace it with the enclosing one
-                               return new CellRange[] { range2, };
-               }
-               throw new RuntimeException("unexpected intersection result (" + x + ")");
-       }
-       
-       // TODO - write junit test for this
-       static CellRange[] resolveRangeOverlap(CellRange rangeA, CellRange rangeB) {
-               
-               if(rangeA.isFullColumnRange()) {
-                       if(rangeB.isFullRowRange()) {
-                               // Excel seems to leave these unresolved
-                               return null;
-                       }
-                       return rangeA.sliceUp(rangeB);
-               }
-               if(rangeA.isFullRowRange()) {
-                       if(rangeB.isFullColumnRange()) {
-                               // Excel seems to leave these unresolved
-                               return null;
-                       }
-                       return rangeA.sliceUp(rangeB);
-               }
-               if(rangeB.isFullColumnRange()) {
-                       return rangeB.sliceUp(rangeA);
-               }
-               if(rangeB.isFullRowRange()) {
-                       return rangeB.sliceUp(rangeA);
-               }
-               return rangeA.sliceUp(rangeB);
-       }
-
-       /**
-        * @param range never a full row or full column range
-        * @return an array including <b>this</b> <tt>CellRange</tt> and all parts of <tt>range</tt> 
-        * outside of this range  
-        */
-       private CellRange[] sliceUp(CellRange range) {
-               
-               List temp = new ArrayList();
-               
-               // Chop up range horizontally and vertically
-               temp.add(range);
-               if(!isFullColumnRange()) {
-                       temp = cutHorizontally(_firstRow, temp);
-                       temp = cutHorizontally(_lastRow+1, temp);
-               }
-               if(!isFullRowRange()) {
-                       temp = cutVertically(_firstColumn, temp);
-                       temp = cutVertically(_lastColumn+1, temp);
-               }
-               CellRange[] crParts = toArray(temp);
-
-               // form result array
-               temp.clear();
-               temp.add(this);
-               
-               for (int i = 0; i < crParts.length; i++) {
-                       CellRange crPart = crParts[i];
-                       // only include parts that are not enclosed by this
-                       if(intersect(crPart) != ENCLOSES) {
-                               temp.add(crPart);
-                       }
-               }
-               return toArray(temp);
-       }
-
-       private static List cutHorizontally(int cutRow, List input) {
-               
-               List result = new ArrayList();
-               CellRange[] crs = toArray(input);
-               for (int i = 0; i < crs.length; i++) {
-                       CellRange cr = crs[i];
-                       if(cr._firstRow < cutRow && cutRow < cr._lastRow) {
-                               result.add(new CellRange(cr._firstRow, cutRow, cr._firstColumn, cr._lastColumn));
-                               result.add(new CellRange(cutRow+1, cr._lastRow, cr._firstColumn, cr._lastColumn));
-                       } else {
-                               result.add(cr);
-                       }
-               }
-               return result;
-       }
-       private static List cutVertically(int cutColumn, List input) {
-               
-               List result = new ArrayList();
-               CellRange[] crs = toArray(input);
-               for (int i = 0; i < crs.length; i++) {
-                       CellRange cr = crs[i];
-                       if(cr._firstColumn < cutColumn && cutColumn < cr._lastColumn) {
-                               result.add(new CellRange(cr._firstRow, cr._lastRow, cr._firstColumn, cutColumn));
-                               result.add(new CellRange(cr._firstRow, cr._lastRow, cutColumn+1, cr._lastColumn));
-                       } else {
-                               result.add(cr);
-                       }
-               }
-               return result;
-       }
-
-
-       private static CellRange[] toArray(List temp) {
-               CellRange[] result = new CellRange[temp.size()];
-               temp.toArray(result);
-               return result;
-       }
-
-       /**
-        * Convert array of regions to a List of CellRange objects
-        *  
-        * @param regions
-        * @return List of CellRange objects
-        */
-       public static CellRange[] convertRegionsToCellRanges(Region[] regions)
-       {
-               CellRange[] result = new CellRange[regions.length];
-               for( int i=0; i<regions.length; i++)
-               {
-                       result[i] = createFromRegion(regions[i]);
-               }
-               return result;
-       }
-       
-       /**
-        * Convert a List of CellRange objects to an array of regions 
-        *  
-        * @param List of CellRange objects
-        * @return regions
-        */
-       public static Region[] convertCellRangesToRegions(CellRange[] cellRanges)
-       {
-               int size = cellRanges.length;
-               if(size < 1) {
-                       return EMPTY_REGION_ARRAY;
-               }
-               
-               Region[] result = new Region[size];
-
-               for (int i = 0; i != size; i++)
-               {
-                       result[i] = cellRanges[i].convertToRegion();
-               }
-               return result;
-       }
-
-
-               
-       private Region convertToRegion() {
-               
-               return new Region(_firstRow, (short)_firstColumn, _lastRow, (short)_lastColumn);
-       }
-
-
-       /**
-        *  Check if the specified range is located inside of this cell range.
-        *  
-        * @param range
-        * @return true if this cell range contains the argument range inside if it's area
-        */
-   public boolean contains(CellRange range)
-   {
-               int firstRow = range.getFirstRow();
-               int lastRow = range.getLastRow();
-               int firstCol = range.getFirstColumn();
-               int lastCol = range.getLastColumn();
-               return le(getFirstRow(), firstRow) && ge(getLastRow(), lastRow)
-                               && le(getFirstColumn(), firstCol) && ge(getLastColumn(), lastCol);
-       }
-   
-       public boolean contains(int row, short column)
-       {
-               return le(getFirstRow(), row) && ge(getLastRow(), row)
-                               && le(getFirstColumn(), column) && ge(getLastColumn(), column);
-       }
-       
-   /**
-       * Check if the specified cell range has a shared border with the current range.
-       * 
-       * @return <code>true</code> if the ranges have a complete shared border (i.e.
-       * the two ranges together make a simple rectangular region.
-       */
-       public boolean hasExactSharedBorder(CellRange range)
-       {
-               int oFirstRow = range._firstRow;
-               int oLastRow  = range._lastRow;
-               int oFirstCol = range._firstColumn;
-               int oLastCol  = range._lastColumn;
-               
-               if (_firstRow > 0 && _firstRow-1 == oLastRow || 
-                       oFirstRow > 0 && oFirstRow-1 == _lastRow) {
-                       // ranges have a horizontal border in common
-                       // make sure columns are identical:
-                       return _firstColumn == oFirstCol && _lastColumn == oLastCol;
-               }
-
-               if (_firstColumn>0 && _firstColumn - 1 == oLastCol ||
-                       oFirstCol>0 && _lastColumn == oFirstCol -1) {
-                       // ranges have a vertical border in common
-                       // make sure rows are identical:
-                       return _firstRow == oFirstRow && _lastRow == oLastRow;
-               }
-               return false;
-       }
-       
-       /**
-        * Create an enclosing CellRange for the two cell ranges.
-        * 
-        * @return enclosing CellRange
-        */
-       public CellRange createEnclosingCellRange(CellRange range)
-       {
-               if( range == null)
-               {
-                       return cloneCellRange();
-               }
-               else
-               {
-                       CellRange cellRange = 
-                               new CellRange(
-                                       lt(range.getFirstRow(),getFirstRow())?range.getFirstRow():getFirstRow(),
-                                       gt(range.getLastRow(),getLastRow())?range.getLastRow():getLastRow(),
-                                       lt(range.getFirstColumn(),getFirstColumn())?range.getFirstColumn():getFirstColumn(),
-                                       gt(range.getLastColumn(),getLastColumn())?range.getLastColumn():getLastColumn()
-                               );
-                       return cellRange;
-               }
-       }
-       
-       public CellRange cloneCellRange()
-       {
-               return new CellRange(getFirstRow(),getLastRow(),getFirstColumn(),getLastColumn());
-       }
-
-       /**
-        * @return true if a < b
-        */
-       private static boolean lt(int a, int b)
-       {
-               return a == -1 ? false : (b == -1 ? true : a < b);
-       }
-       
-       /**
-        * @return true if a <= b
-        */
-       private static boolean le(int a, int b)
-       {
-               return a == b || lt(a,b);
-       }
-       
-       /**
-        * @return true if a > b
-        */
-       private static boolean gt(int a, int b)
-       {
-               return lt(b,a);
-       }
-
-       /**
-        * @return true if a >= b
-        */
-       private static boolean ge(int a, int b)
-       {
-               return !lt(a,b);
-       }
-       
-       public String toString()
-       {
-               return "("+getFirstRow()+","+getLastRow()+","+getFirstColumn()+","+getLastColumn()+")";
-       }
-       
-}
diff --git a/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java b/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
new file mode 100644 (file)
index 0000000..4e20fbb
--- /dev/null
@@ -0,0 +1,363 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.hssf.util.CellRangeAddress;
+
+/**
+ * 
+ * @author Dmitriy Kumshayev
+ */
+public final class CellRangeUtil
+{
+       
+       private CellRangeUtil() {
+               // no instance of this class
+       }
+       
+       public static final int NO_INTERSECTION = 1;
+       public static final int OVERLAP = 2;
+       /** first range is within the second range */
+       public static final int INSIDE = 3;
+       /** first range encloses or is equal to the second */
+       public static final int ENCLOSES = 4;
+       
+       /**
+        * Intersect this range with the specified range.
+        * 
+        * @param crB - the specified range
+        * @return code which reflects how the specified range is related to this range.<br/>
+        * Possible return codes are:   
+        *              NO_INTERSECTION - the specified range is outside of this range;<br/> 
+        *              OVERLAP - both ranges partially overlap;<br/>
+        *              INSIDE - the specified range is inside of this one<br/>
+        *              ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
+        */
+       public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
+       {
+               
+               int firstRow = crB.getFirstRow();
+               int lastRow  = crB.getLastRow();
+               int firstCol = crB.getFirstColumn();
+               int lastCol  = crB.getLastColumn();
+               
+               if
+               ( 
+                               gt(crA.getFirstRow(),lastRow) || 
+                               lt(crA.getLastRow(),firstRow) ||
+                               gt(crA.getFirstColumn(),lastCol) || 
+                               lt(crA.getLastColumn(),firstCol) 
+               )
+               {
+                       return NO_INTERSECTION;
+               }
+               else if( contains(crA, crB) )
+               {
+                       return INSIDE;
+               }
+               else if( contains(crB, crA))
+               {
+                       return ENCLOSES;
+               }
+               else
+               {
+                       return OVERLAP;
+               }
+                       
+       }
+       
+       /**
+        * Do all possible cell merges between cells of the list so that:<br>
+        *      <li>if a cell range is completely inside of another cell range, it gets removed from the list 
+        *      <li>if two cells have a shared border, merge them into one bigger cell range
+        * @param cellRangeList
+        * @return updated List of cell ranges
+        */
+       public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
+               if(cellRanges.length < 1) {
+                       return cellRanges;
+               }
+               List temp = mergeCellRanges(Arrays.asList(cellRanges));
+               return toArray(temp);
+       }
+       private static List mergeCellRanges(List cellRangeList)
+       {
+
+               while(cellRangeList.size() > 1)
+               {
+                       boolean somethingGotMerged = false;
+                       
+                       for( int i=0; i<cellRangeList.size(); i++)
+                       {
+                               CellRangeAddress range1 = (CellRangeAddress)cellRangeList.get(i);
+                               for( int j=i+1; j<cellRangeList.size(); j++)
+                               {
+                                       CellRangeAddress range2 = (CellRangeAddress)cellRangeList.get(j);
+                                       
+                                       CellRangeAddress[] mergeResult = mergeRanges(range1, range2);
+                                       if(mergeResult == null) {
+                                               continue;
+                                       }
+                                       somethingGotMerged = true;
+                                       // overwrite range1 with first result 
+                                       cellRangeList.set(i, mergeResult[0]);
+                                       // remove range2
+                                       cellRangeList.remove(j--);
+                                       // add any extra results beyond the first
+                                       for(int k=1; k<mergeResult.length; k++) {
+                                               j++;
+                                               cellRangeList.add(j, mergeResult[k]);
+                                       }
+                               }
+                       }
+                       if(!somethingGotMerged) {
+                               break;
+                       }
+               }
+               
+
+               return cellRangeList;
+       }
+       
+       /**
+        * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
+        */
+       private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
+               
+               int x = intersect(range1, range2);
+               switch(x)
+               {
+                       case CellRangeUtil.NO_INTERSECTION: 
+                               if(hasExactSharedBorder(range1, range2)) {
+                                       return new CellRangeAddress[] { createEnclosingCellRange(range1, range2), };
+                               }
+                               // else - No intersection and no shared border: do nothing 
+                               return null;
+                       case CellRangeUtil.OVERLAP:
+                               return resolveRangeOverlap(range1, range2);
+                       case CellRangeUtil.INSIDE:
+                               // Remove range2, since it is completely inside of range1
+                               return new CellRangeAddress[] { range1, };
+                       case CellRangeUtil.ENCLOSES:
+                               // range2 encloses range1, so replace it with the enclosing one
+                               return new CellRangeAddress[] { range2, };
+               }
+               throw new RuntimeException("unexpected intersection result (" + x + ")");
+       }
+       
+       // TODO - write junit test for this
+       static CellRangeAddress[] resolveRangeOverlap(CellRangeAddress rangeA, CellRangeAddress rangeB) {
+               
+               if(rangeA.isFullColumnRange()) {
+                       if(rangeA.isFullRowRange()) {
+                               // Excel seems to leave these unresolved
+                               return null;
+                       }
+                       return sliceUp(rangeA, rangeB);
+               }
+               if(rangeA.isFullRowRange()) {
+                       if(rangeB.isFullColumnRange()) {
+                               // Excel seems to leave these unresolved
+                               return null;
+                       }
+                       return sliceUp(rangeA, rangeB);
+               }
+               if(rangeB.isFullColumnRange()) {
+                       return sliceUp(rangeB, rangeA);
+               }
+               if(rangeB.isFullRowRange()) {
+                       return sliceUp(rangeB, rangeA);
+               }
+               return sliceUp(rangeA, rangeB);
+       }
+
+       /**
+        * @param crB never a full row or full column range
+        * @return an array including <b>this</b> <tt>CellRange</tt> and all parts of <tt>range</tt> 
+        * outside of this range  
+        */
+       private static CellRangeAddress[] sliceUp(CellRangeAddress crA, CellRangeAddress crB) {
+               
+               List temp = new ArrayList();
+               
+               // Chop up range horizontally and vertically
+               temp.add(crB);
+               if(!crA.isFullColumnRange()) {
+                       temp = cutHorizontally(crA.getFirstRow(), temp);
+                       temp = cutHorizontally(crA.getLastRow()+1, temp);
+               }
+               if(!crA.isFullRowRange()) {
+                       temp = cutVertically(crA.getFirstColumn(), temp);
+                       temp = cutVertically(crA.getLastColumn()+1, temp);
+               }
+               CellRangeAddress[] crParts = toArray(temp);
+
+               // form result array
+               temp.clear();
+               temp.add(crA);
+               
+               for (int i = 0; i < crParts.length; i++) {
+                       CellRangeAddress crPart = crParts[i];
+                       // only include parts that are not enclosed by this
+                       if(intersect(crA, crPart) != ENCLOSES) {
+                               temp.add(crPart);
+                       }
+               }
+               return toArray(temp);
+       }
+
+       private static List cutHorizontally(int cutRow, List input) {
+               
+               List result = new ArrayList();
+               CellRangeAddress[] crs = toArray(input);
+               for (int i = 0; i < crs.length; i++) {
+                       CellRangeAddress cr = crs[i];
+                       if(cr.getFirstRow() < cutRow && cutRow < cr.getLastRow()) {
+                               result.add(new CellRangeAddress(cr.getFirstRow(), cutRow, cr.getFirstColumn(), cr.getLastColumn()));
+                               result.add(new CellRangeAddress(cutRow+1, cr.getLastRow(), cr.getFirstColumn(), cr.getLastColumn()));
+                       } else {
+                               result.add(cr);
+                       }
+               }
+               return result;
+       }
+       private static List cutVertically(int cutColumn, List input) {
+               
+               List result = new ArrayList();
+               CellRangeAddress[] crs = toArray(input);
+               for (int i = 0; i < crs.length; i++) {
+                       CellRangeAddress cr = crs[i];
+                       if(cr.getFirstColumn() < cutColumn && cutColumn < cr.getLastColumn()) {
+                               result.add(new CellRangeAddress(cr.getFirstRow(), cr.getLastRow(), cr.getFirstColumn(), cutColumn));
+                               result.add(new CellRangeAddress(cr.getFirstRow(), cr.getLastRow(), cutColumn+1, cr.getLastColumn()));
+                       } else {
+                               result.add(cr);
+                       }
+               }
+               return result;
+       }
+
+
+       private static CellRangeAddress[] toArray(List temp) {
+               CellRangeAddress[] result = new CellRangeAddress[temp.size()];
+               temp.toArray(result);
+               return result;
+       }
+
+
+
+       /**
+        *  Check if the specified range is located inside of this cell range.
+        *  
+        * @param crB
+        * @return true if this cell range contains the argument range inside if it's area
+        */
+   public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
+   {
+               int firstRow = crB.getFirstRow();
+               int lastRow = crB.getLastRow();
+               int firstCol = crB.getFirstColumn();
+               int lastCol = crB.getLastColumn();
+               return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
+                               && le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
+       }
+       
+   /**
+       * Check if the specified cell range has a shared border with the current range.
+       * 
+       * @return <code>true</code> if the ranges have a complete shared border (i.e.
+       * the two ranges together make a simple rectangular region.
+       */
+       public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
+               int oFirstRow = crB.getFirstRow();
+               int oLastRow  = crB.getLastRow();
+               int oFirstCol = crB.getFirstColumn();
+               int oLastCol  = crB.getLastColumn();
+               
+               if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
+                       oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
+                       // ranges have a horizontal border in common
+                       // make sure columns are identical:
+                       return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
+               }
+
+               if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
+                       oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
+                       // ranges have a vertical border in common
+                       // make sure rows are identical:
+                       return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
+               }
+               return false;
+       }
+       
+       /**
+        * Create an enclosing CellRange for the two cell ranges.
+        * 
+        * @return enclosing CellRange
+        */
+       public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
+               if( crB == null) {
+                       return crA.copy();
+               }
+               
+               return
+                       new CellRangeAddress(
+                               lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
+                               gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
+                               lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
+                               gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
+                       );
+               
+       }
+       
+       /**
+        * @return true if a < b
+        */
+       private static boolean lt(int a, int b)
+       {
+               return a == -1 ? false : (b == -1 ? true : a < b);
+       }
+       
+       /**
+        * @return true if a <= b
+        */
+       private static boolean le(int a, int b)
+       {
+               return a == b || lt(a,b);
+       }
+       
+       /**
+        * @return true if a > b
+        */
+       private static boolean gt(int a, int b)
+       {
+               return lt(b,a);
+       }
+
+       /**
+        * @return true if a >= b
+        */
+       private static boolean ge(int a, int b)
+       {
+               return !lt(a,b);
+       }
+}
index 6c798abcf4f93e1314fcc83e2a0dce26459a17ad..a08c3f0c8224714760dbf3bd800734cbc7522bb6 100644 (file)
 ==================================================================== */
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFHeaderRecord;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
-import org.apache.poi.hssf.record.cf.CellRange;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.Region;
 
 /**
@@ -96,13 +95,18 @@ public final class HSSFConditionalFormatting
        }
 
        /**
-        * @return array of <tt>Region</tt>s. never <code>null</code> 
+        * @deprecated (Aug-2008) use {@link HSSFConditionalFormatting#getFormattingRanges()}
         */
        public Region[] getFormattingRegions()
        {
-               CFHeaderRecord cfh = cfAggregate.getHeader();
-               CellRange[] cellRanges = cfh.getCellRanges();
-               return CellRange.convertCellRangesToRegions(cellRanges);
+               CellRangeAddress[] cellRanges = getFormattingRanges();
+               return Region.convertCellRangesToRegions(cellRanges);
+       }
+       /**
+        * @return array of <tt>CellRangeAddress</tt>s. never <code>null</code> 
+        */
+       public CellRangeAddress[] getFormattingRanges() {
+               return cfAggregate.getHeader().getCellRanges();
        }
 
        /**
index a99e48b64e9cf17c05e36c607ae81879f9433e53..ec104ded96ee47f1fd6056eba9d0e8a3a8d8e466 100644 (file)
@@ -38,6 +38,7 @@ import org.apache.poi.hssf.record.*;
 import org.apache.poi.hssf.record.aggregates.DataValidityTable;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.hssf.util.Region;
 import org.apache.poi.util.POILogFactory;
@@ -517,20 +518,28 @@ public final class HSSFSheet {
     }
 
     /**
-     * adds a merged region of cells (hence those cells form one)
-     * @param region (rowfrom/colfrom-rowto/colto) to merge
-     * @return index of this region
+     * @deprecated (Aug-2008) use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
      */
-
     public int addMergedRegion(Region region)
     {
-        //return sheet.addMergedRegion((short) region.getRowFrom(),
         return sheet.addMergedRegion( region.getRowFrom(),
                 region.getColumnFrom(),
                 //(short) region.getRowTo(),
                 region.getRowTo(),
                 region.getColumnTo());
     }
+    /**
+     * adds a merged region of cells (hence those cells form one)
+     * @param region (rowfrom/colfrom-rowto/colto) to merge
+     * @return index of this region
+     */
+    public int addMergedRegion(CellRangeAddress region)
+    {
+        return sheet.addMergedRegion( region.getFirstRow(),
+                region.getFirstColumn(),
+                region.getLastRow(),
+                region.getLastColumn());
+    }
 
     /**
      * Whether a record must be inserted or not at generation to indicate that
@@ -567,7 +576,7 @@ public final class HSSFSheet {
 
     /**
      * TODO: Boolean not needed, remove after next release
-     * @deprecated use getVerticallyCenter() instead
+     * @deprecated (Mar-2008) use getVerticallyCenter() instead
      */
     public boolean getVerticallyCenter(boolean value) {
         return getVerticallyCenter();
@@ -632,14 +641,19 @@ public final class HSSFSheet {
     }
 
     /**
-     * gets the region at a particular index
-     * @param index of the region to fetch
-     * @return the merged region (simple eh?)
+     * @deprecated (Aug-2008) use {@link HSSFSheet#getMergedRegion(int)}
      */
-
-    public Region getMergedRegionAt(int index)
-    {
-        return new Region(sheet.getMergedRegionAt(index));
+    public Region getMergedRegionAt(int index) {
+        CellRangeAddress cra = getMergedRegion(index);
+        
+               return new Region(cra.getFirstRow(), (short)cra.getFirstColumn(), 
+                               cra.getLastRow(), (short)cra.getLastColumn());
+    }
+    /**
+     * @return the merged region at the specified index
+     */
+    public CellRangeAddress getMergedRegion(int index) {
+        return sheet.getMergedRegionAt(index);
     }
 
     /**
@@ -1072,36 +1086,43 @@ public final class HSSFSheet {
     protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) {
         List shiftedRegions = new ArrayList();
         //move merged regions completely if they fall within the new region boundaries when they are shifted
-        for (int i = 0; i < this.getNumMergedRegions(); i++) {
-             Region merged = this.getMergedRegionAt(i);
+        for (int i = 0; i < getNumMergedRegions(); i++) {
+             CellRangeAddress merged = getMergedRegion(i);
 
-             boolean inStart = (merged.getRowFrom() >= startRow || merged.getRowTo() >= startRow);
-             boolean inEnd =  (merged.getRowTo() <= endRow || merged.getRowFrom() <= endRow);
+             boolean inStart= (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
+             boolean inEnd  = (merged.getFirstRow() <= endRow   || merged.getLastRow() <= endRow);
 
-             //dont check if it's not within the shifted area
-             if (! (inStart && inEnd)) continue;
+             //don't check if it's not within the shifted area
+             if (!inStart || !inEnd) {
+                               continue;
+                        }
 
              //only shift if the region outside the shifted rows is not merged too
-             if (!merged.contains(startRow-1, (short)0) && !merged.contains(endRow+1, (short)0)){
-                 merged.setRowFrom(merged.getRowFrom()+n);
-                 merged.setRowTo(merged.getRowTo()+n);
+             if (!containsCell(merged, startRow-1, 0) && !containsCell(merged, endRow+1, 0)){
+                 merged.setFirstRow(merged.getFirstRow()+n);
+                 merged.setLastRow(merged.getLastRow()+n);
                  //have to remove/add it back
                  shiftedRegions.add(merged);
-                 this.removeMergedRegion(i);
+                 removeMergedRegion(i);
                  i = i -1; // we have to back up now since we removed one
-
              }
-
         }
 
-        //readd so it doesn't get shifted again
+        //read so it doesn't get shifted again
         Iterator iterator = shiftedRegions.iterator();
         while (iterator.hasNext()) {
-            Region region = (Region)iterator.next();
+               CellRangeAddress region = (CellRangeAddress)iterator.next();
 
             this.addMergedRegion(region);
         }
-
+    }
+    private static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
+        if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
+                && cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx)
+        {
+            return true;
+        }
+        return false;
     }
 
     /**
@@ -1720,17 +1741,20 @@ public final class HSSFSheet {
             HSSFRow row = (HSSFRow) it.next();
             HSSFCell cell = row.getCell(column);
 
-            if (cell == null) continue;
+            if (cell == null) {
+                               continue;
+                       }
 
             int colspan = 1;
             for (int i = 0 ; i < getNumMergedRegions(); i++) {
-                if (getMergedRegionAt(i).contains(row.getRowNum(), column)) {
+                CellRangeAddress region = getMergedRegion(i);
+                               if (containsCell(region, row.getRowNum(), column)) {
                        if (!useMergedCells) {
                        // If we're not using merged cells, skip this one and move on to the next. 
                                continue rows;
                        }
-                       cell = row.getCell(getMergedRegionAt(i).getColumnFrom());
-                       colspan = 1+ getMergedRegionAt(i).getColumnTo() - getMergedRegionAt(i).getColumnFrom();
+                       cell = row.getCell(region.getFirstColumn());
+                       colspan = 1 + region.getLastColumn() - region.getFirstColumn();
                 }
             }
 
index 4df94e4b527f0c5c06db568d2fe13ca1717ab54a..47cf217b267e2528cf568a232ffa8b20515ff5f1 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.usermodel;
 import org.apache.poi.hssf.model.Sheet;\r
 import org.apache.poi.hssf.record.CFRuleRecord;\r
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;\r
+import org.apache.poi.hssf.util.CellRangeAddress;\r
 import org.apache.poi.hssf.util.Region;\r
 \r
 /**\r
@@ -100,7 +101,12 @@ public final class HSSFSheetConditionalFormatting {
 \r
                return _sheet.addConditionalFormatting(cfraClone);\r
        }\r
-\r
+       /**\r
+        * @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>\r
+        */\r
+       public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) {\r
+               return addConditionalFormatting(Region.convertRegionsToCellRanges(regions), cfRules);\r
+       }\r
        /**\r
         * Allows to add a new Conditional Formatting set to the sheet.\r
         *\r
@@ -109,8 +115,7 @@ public final class HSSFSheetConditionalFormatting {
         *\r
         * @return index of the newly created Conditional Formatting object\r
         */\r
-\r
-       public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) {\r
+       public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) {\r
                if (regions == null) {\r
                        throw new IllegalArgumentException("regions must not be null");\r
                }\r
@@ -132,7 +137,7 @@ public final class HSSFSheetConditionalFormatting {
                return _sheet.addConditionalFormatting(cfra);\r
        }\r
 \r
-       public int addConditionalFormatting(Region[] regions,\r
+       public int addConditionalFormatting(CellRangeAddress[] regions,\r
                        HSSFConditionalFormattingRule rule1)\r
        {\r
                return addConditionalFormatting(regions,\r
@@ -142,7 +147,7 @@ public final class HSSFSheetConditionalFormatting {
                                });\r
        }\r
 \r
-       public int addConditionalFormatting(Region[] regions,\r
+       public int addConditionalFormatting(CellRangeAddress[] regions,\r
                        HSSFConditionalFormattingRule rule1,\r
                        HSSFConditionalFormattingRule rule2)\r
        {\r
@@ -153,18 +158,6 @@ public final class HSSFSheetConditionalFormatting {
                                });\r
        }\r
 \r
-       public int addConditionalFormatting(Region[] regions,\r
-                       HSSFConditionalFormattingRule rule1,\r
-                       HSSFConditionalFormattingRule rule2,\r
-                       HSSFConditionalFormattingRule rule3)\r
-       {\r
-               return addConditionalFormatting(regions,\r
-                               new HSSFConditionalFormattingRule[]\r
-                               {\r
-                                               rule1, rule2, rule3\r
-                               });\r
-       }\r
-\r
        /**\r
        * gets Conditional Formatting object at a particular index\r
        * \r
index 2f5d24aa02d6b190f66ad3e66483c30b8d404062..d6189c368f00beddaf1584df0cbeadb477d40e07 100644 (file)
 package org.apache.poi.hssf.util;\r
 \r
 import org.apache.poi.hssf.record.RecordInputStream;\r
+import org.apache.poi.hssf.record.SelectionRecord;\r
 import org.apache.poi.util.LittleEndian;\r
 \r
 /**\r
- * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'\r
+ * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>\r
  * \r
+ * Note - {@link SelectionRecord} uses the BIFF5 version of this structure\r
  * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)\r
  */\r
 public final class CellRangeAddress {\r
-       private static final int ENCODED_SIZE = 8;\r
+       /*\r
+        * TODO - replace  org.apache.poi.hssf.util.Region\r
+        */\r
+       public static final int ENCODED_SIZE = 8;\r
 \r
+       /** max 65536 rows in BIFF8 */\r
+       private static final int LAST_ROW_INDEX = 0x00FFFF; \r
+       /** max 256 columns in BIFF8 */\r
+       private static final int LAST_COLUMN_INDEX = 0x00FF;\r
+       \r
+       \r
        private int _firstRow;\r
        private int _firstCol;\r
        private int _lastRow;\r
        private int _lastCol;\r
 \r
-       /*\r
-        * TODO - replace other incarnations of 'Cell Range Address' throughout POI:\r
-        * org.apache.poi.hssf.util.CellRange\r
-        * org.apache.poi.hssf.record.cf.CellRange\r
-        * org.apache.poi.hssf.util.HSSFCellRangeAddress.AddrStructure\r
-        * org.apache.poi.hssf.record.MergeCellsRecord.MergedRegion\r
-        * org.apache.poi.hssf.record.SelectionRecord.Reference\r
-        * \r
-        */\r
-       \r
        public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {\r
+               if(!isValid(firstRow, lastRow, firstCol, lastCol)) {\r
+                       throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow \r
+                                       + ", " + firstCol + ", " + lastCol + ")");\r
+               }\r
                _firstRow = firstRow;\r
-               _lastRow = lastRow;\r
+               _lastRow = convertM1ToMax(lastRow, LAST_ROW_INDEX);\r
                _firstCol = firstCol;\r
-               _lastCol = lastCol;\r
+               _lastCol = convertM1ToMax(lastCol, LAST_COLUMN_INDEX);\r
+       }\r
+       private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)\r
+       {\r
+               if(lastRow < 0 || lastRow > LAST_ROW_INDEX) {\r
+                       return false;\r
+               }\r
+               if(firstRow < 0 || firstRow > LAST_ROW_INDEX) {\r
+                       return false;\r
+               }\r
+               \r
+               if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) {\r
+                       return false;\r
+               }\r
+               if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+       /** \r
+        * Range arithmetic is easier when using a large positive number for 'max row or column' \r
+        * instead of <tt>-1</tt>. \r
+        */\r
+       private static int convertM1ToMax(int lastIx, int maxIndex) {\r
+               if(lastIx < 0) {\r
+                       return maxIndex;\r
+               }\r
+               return lastIx;\r
        }\r
 \r
+       \r
+\r
        public CellRangeAddress(RecordInputStream in) {\r
                if (in.remaining() < ENCODED_SIZE) {\r
                        // Ran out of data\r
@@ -59,6 +93,12 @@ public final class CellRangeAddress {
                _firstCol = in.readUShort();\r
                _lastCol = in.readUShort();\r
        }\r
+       public boolean isFullColumnRange() {\r
+               return _firstRow == 0 && _lastRow == LAST_ROW_INDEX;\r
+       }\r
+       public boolean isFullRowRange() {\r
+               return _firstCol == 0 && _lastCol == LAST_COLUMN_INDEX;\r
+       }\r
 \r
        /**\r
         * @return column number for the upper left hand corner\r
@@ -116,15 +156,23 @@ public final class CellRangeAddress {
                _lastRow = lastRow;\r
        }\r
 \r
-       /* package */ int serialize(byte[] data, int offset) {\r
+       public int serialize(int offset, byte[] data) {\r
                LittleEndian.putUShort(data, offset + 0, _firstRow);\r
                LittleEndian.putUShort(data, offset + 2, _lastRow);\r
                LittleEndian.putUShort(data, offset + 4, _firstCol);\r
                LittleEndian.putUShort(data, offset + 6, _lastCol);\r
                return ENCODED_SIZE;\r
        }\r
+       \r
+       public CellRangeAddress copy() {\r
+               return new CellRangeAddress(_firstRow, _lastRow, _firstCol, _lastCol);\r
+       }\r
 \r
        public static int getEncodedSize(int numberOfItems) {\r
                return numberOfItems * ENCODED_SIZE;\r
        }\r
+       \r
+       public String toString() {\r
+               return getClass().getName() + " ["+_firstRow+", "+_lastRow+", "+_firstCol+", "+_lastCol+"]";\r
+       }\r
 }
\ No newline at end of file
index d52219769d9fc651a71a75a1b7e12dd00ad5e1e5..f901be4c4d31d8a96becaea15e92e3c354a0a63f 100644 (file)
@@ -74,12 +74,12 @@ public final class CellRangeAddressList {
         * 
         * @return number of ADDR structures
         */
-       public int getADDRStructureNumber() {
+       public int countRanges() {
                return _list.size();
        }
 
        /**
-        * Add an ADDR structure .
+        * Add a cell range structure.
         * 
         * @param firstRow - the upper left hand corner's row
         * @param firstCol - the upper left hand corner's col
@@ -89,7 +89,20 @@ public final class CellRangeAddressList {
         */
        public void addCellRangeAddress(int firstRow, int firstCol, int lastRow, int lastCol) {
                CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
-               _list.add(region);
+               addCellRangeAddress(region);
+       }
+       public void addCellRangeAddress(CellRangeAddress cra) {
+               _list.add(cra);
+       }
+       public CellRangeAddress remove(int rangeIndex) {
+               if (_list.isEmpty()) {
+                       throw new RuntimeException("List is empty");
+               }
+               if (rangeIndex < 0 || rangeIndex >= _list.size()) {
+                       throw new RuntimeException("Range index (" + rangeIndex 
+                                       + ") is outside allowable range (0.." + (_list.size()-1) + ")");
+               }
+               return (CellRangeAddress) _list.remove(rangeIndex);
        }
 
        /**
@@ -106,7 +119,7 @@ public final class CellRangeAddressList {
                LittleEndian.putUShort(data, offset, nItems);
                for (int k = 0; k < nItems; k++) {
                        CellRangeAddress region = (CellRangeAddress) _list.get(k);
-                       pos += region.serialize(data, offset + pos);
+                       pos += region.serialize(offset + pos, data);
                }
                return getSize();
        }
@@ -114,4 +127,19 @@ public final class CellRangeAddressList {
        public int getSize() {
                return 2 + CellRangeAddress.getEncodedSize(_list.size());
        }
+       public CellRangeAddressList copy() {
+               CellRangeAddressList result = new CellRangeAddressList();
+               
+               int nItems = _list.size();
+               for (int k = 0; k < nItems; k++) {
+                       CellRangeAddress region = (CellRangeAddress) _list.get(k);
+                       result.addCellRangeAddress(region.copy());
+               }
+               return result;
+       }
+       public CellRangeAddress[] getCellRangeAddresses() {
+               CellRangeAddress[] result = new CellRangeAddress[_list.size()];
+               _list.toArray(result);
+               return result;
+       }
 }
index 67d52eb137a512fe2e15b9bcdb15c65206b6a64d..7047cee9f3c03f3f8c75ae158613100009451667 100644 (file)
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.util;
 
-import org.apache.poi.hssf.record.MergeCellsRecord.MergedRegion;
 
 /**
  * Represents a from/to row/col square.  This is a object primitive
@@ -26,11 +24,9 @@ import org.apache.poi.hssf.record.MergeCellsRecord.MergedRegion;
  * to represent a string of characters.  Its really only useful for HSSF though.
  *
  * @author  Andrew C. Oliver acoliver at apache dot org
+ * @deprecated (Aug-2008) use {@link CellRangeAddress}
  */
-
-public class Region
-    implements Comparable
-{
+public class Region {
     private int   rowFrom;
     private short colFrom;
     private int   rowTo;
@@ -52,15 +48,6 @@ public class Region
         this.colTo   = colTo;
     }
 
-    /**
-     * special constructor (I know this is bad but it is so wrong that its right
-     * okay) that makes a region from a mergedcells's region subrecord.
-     */
-
-    public Region(MergedRegion region)
-    {
-        this(region.row_from, region.col_from, region.row_to, region.col_to);
-    }
 
     /**
      * get the upper left hand corner column number
@@ -150,72 +137,49 @@ public class Region
         this.rowTo = rowTo;
     }
 
-    /**
-     * Answers: "is the row/column inside this range?"
-     *
-     * @return <code>true</code> if the cell is in the range and
-     * <code>false</code> if it is not
-     */
-
-    public boolean contains(int row, short col)
-    {
-        if ((this.rowFrom <= row) && (this.rowTo >= row)
-                && (this.colFrom <= col) && (this.colTo >= col))
-        {
-
-//                System.out.println("Region ("+rowFrom+","+colFrom+","+rowTo+","+ 
-//                                   colTo+") does contain "+row+","+col);
-            return true;
-        }
-        return false;
-    }
-
-    public boolean equals(Region r)
-    {
-        return (compareTo(r) == 0);
-    }
 
-    /**
-     * Compares that the given region is the same less than or greater than this
-     * region.  If any regional coordiant passed in is less than this regions
-     * coordinants then a positive integer is returned.  Otherwise a negative
-     * integer is returned.
-     *
-     * @param r  region
-     * @see #compareTo(Object)
-     */
-
-    public int compareTo(Region r)
-    {
-        if ((this.getRowFrom() == r.getRowFrom())
-                && (this.getColumnFrom() == r.getColumnFrom())
-                && (this.getRowTo() == r.getRowTo())
-                && (this.getColumnTo() == r.getColumnTo()))
-        {
-            return 0;
-        }
-        if ((this.getRowFrom() < r.getRowFrom())
-                || (this.getColumnFrom() < r.getColumnFrom())
-                || (this.getRowTo() < r.getRowTo())
-                || (this.getColumnTo() < r.getColumnTo()))
-        {
-            return 1;
-        }
-        return -1;
-    }
-
-    public int compareTo(Object o)
-    {
-        return compareTo(( Region ) o);
-    }
-
-    /**
-     * @return the area contained by this region (number of cells)
-     */
-
-    public int getArea()
-    {
-        return ((1 + (getRowTo() - getRowFrom()))
-                * (1 + (getColumnTo() - getColumnFrom())));
-    }
+       /**
+        * Convert a List of CellRange objects to an array of regions 
+        *  
+        * @param List of CellRange objects
+        * @return regions
+        */
+       public static Region[] convertCellRangesToRegions(CellRangeAddress[] cellRanges) {
+               int size = cellRanges.length;
+               if(size < 1) {
+                       return new Region[0];
+               }
+               
+               Region[] result = new Region[size];
+
+               for (int i = 0; i != size; i++) {
+                       result[i] = convertToRegion(cellRanges[i]);
+               }
+               return result;
+       }
+
+
+               
+       private static Region convertToRegion(CellRangeAddress cr) {
+               
+               return new Region(cr.getFirstRow(), (short)cr.getFirstColumn(), cr.getLastRow(), (short)cr.getLastColumn());
+       }
+
+       public static CellRangeAddress[] convertRegionsToCellRanges(Region[] regions) {
+               int size = regions.length;
+               if(size < 1) {
+                       return new CellRangeAddress[0];
+               }
+               
+               CellRangeAddress[] result = new CellRangeAddress[size];
+
+               for (int i = 0; i != size; i++) {
+                       result[i] = convertToCellRangeAddress(regions[i]);
+               }
+               return result;
+       }
+
+       public static CellRangeAddress convertToCellRangeAddress(Region r) {
+               return new CellRangeAddress(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo());
+       }
 }
index e883503674bf5bcaf9d743a0a826911145c1f182..fd3dd81d0cd0a0018cfb9e57b1d9ea85e431b1c3 100644 (file)
@@ -20,7 +20,7 @@ package org.apache.poi.hssf.record;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
-import org.apache.poi.hssf.record.cf.CellRange;
+import org.apache.poi.hssf.util.CellRangeAddress;
 
 /**
  * Tests the serialization and deserialization of the TestCFHeaderRecord
@@ -34,18 +34,18 @@ public final class TestCFHeaderRecord extends TestCase
        public void testCreateCFHeaderRecord () 
        {
                CFHeaderRecord record = new CFHeaderRecord();
-               CellRange[] ranges = {
-                       new CellRange(0,0xFFFF,5,5),
-                       new CellRange(0,0xFFFF,6,6),
-                       new CellRange(0,1,0,1),
-                       new CellRange(0,1,2,3),
-                       new CellRange(2,3,0,1),
-                       new CellRange(2,3,2,3),
+               CellRangeAddress[] ranges = {
+                       new CellRangeAddress(0,0xFFFF,5,5),
+                       new CellRangeAddress(0,0xFFFF,6,6),
+                       new CellRangeAddress(0,1,0,1),
+                       new CellRangeAddress(0,1,2,3),
+                       new CellRangeAddress(2,3,0,1),
+                       new CellRangeAddress(2,3,2,3),
                };
                record.setCellRanges(ranges);
                ranges = record.getCellRanges();
                assertEquals(6,ranges.length);
-               CellRange enclosingCellRange = record.getEnclosingCellRange();
+               CellRangeAddress enclosingCellRange = record.getEnclosingCellRange();
                assertEquals(0, enclosingCellRange.getFirstRow());
                assertEquals(65535, enclosingCellRange.getLastRow());
                assertEquals(0, enclosingCellRange.getFirstColumn());
@@ -95,7 +95,7 @@ public final class TestCFHeaderRecord extends TestCase
                assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
                assertTrue(record.getNeedRecalculation());
                confirm(record.getEnclosingCellRange(), 0, 3, 0, 3);
-               CellRange[] ranges = record.getCellRanges();
+               CellRangeAddress[] ranges = record.getCellRanges();
                assertEquals(4, ranges.length);
                confirm(ranges[0], 0, 1, 0, 1);
                confirm(ranges[1], 0, 1, 2, 3);
@@ -154,7 +154,7 @@ public final class TestCFHeaderRecord extends TestCase
                assertEquals("#CFRULES", 19, record.getNumberOfConditionalFormats());
                assertFalse(record.getNeedRecalculation());
                confirm(record.getEnclosingCellRange(), 0, 65535, 0, 255);
-               CellRange[] ranges = record.getCellRanges();
+               CellRangeAddress[] ranges = record.getCellRanges();
                assertEquals(3, ranges.length);
                confirm(ranges[0], 40000, 50000, 2, 2);
                confirm(ranges[1], 0, 65535, 5, 5);
@@ -168,18 +168,11 @@ public final class TestCFHeaderRecord extends TestCase
                        assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]);
                }
        }
-       
 
-       private static void confirm(CellRange cr, int expFirstRow, int expLastRow, int expFirstCol, int expLastColumn) {
+       private static void confirm(CellRangeAddress cr, int expFirstRow, int expLastRow, int expFirstCol, int expLastColumn) {
                assertEquals("first row", expFirstRow, cr.getFirstRow());
                assertEquals("last row", expLastRow, cr.getLastRow());
                assertEquals("first column", expFirstCol, cr.getFirstColumn());
                assertEquals("last column", expLastColumn, cr.getLastColumn());
        }
-
-       public static void main(String[] ignored_args)
-       {
-               System.out.println("Testing org.apache.poi.hssf.record.CFHeaderRecord");
-               junit.textui.TestRunner.run(TestCFHeaderRecord.class);
-       }
 }
index 31ec27b7c4fa6928751963f0d24011a7f37a3e0d..fe7d26d12a9ece7cddedd6f5a4f9d7f27b50db2f 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 package org.apache.poi.hssf.record;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.hssf.record.MergeCellsRecord.MergedRegion;
+import org.apache.poi.hssf.util.CellRangeAddress;
 
 /**
  * Make sure the merge cells record behaves
  * @author Danny Mui (dmui at apache dot org)
  *
  */
-public class TestMergeCellsRecord extends TestCase {
+public final class TestMergeCellsRecord extends TestCase {
    
    /**
     * Make sure when a clone is called, we actually clone it.
@@ -40,13 +39,13 @@ public class TestMergeCellsRecord extends TestCase {
       
       assertNotSame("Merged and cloned objects are the same", merge, clone);
       
-      MergedRegion mergeRegion = merge.getAreaAt(0);
-      MergedRegion cloneRegion = clone.getAreaAt(0);
+      CellRangeAddress mergeRegion = merge.getAreaAt(0);
+      CellRangeAddress cloneRegion = clone.getAreaAt(0);
       assertNotSame("Should not point to same objects when cloning", mergeRegion, cloneRegion);
-      assertEquals("New Clone Row From doesnt match", mergeRegion.row_from, cloneRegion.row_from);
-      assertEquals("New Clone Row To doesnt match", mergeRegion.row_to, cloneRegion.row_to);
-      assertEquals("New Clone Col From doesnt match", mergeRegion.col_from, cloneRegion.col_from);
-      assertEquals("New Clone Col To doesnt match", mergeRegion.col_to, cloneRegion.col_to);      
+      assertEquals("New Clone Row From doesnt match", mergeRegion.getFirstRow(), cloneRegion.getFirstRow());
+      assertEquals("New Clone Row To doesnt match", mergeRegion.getLastRow(), cloneRegion.getLastRow());
+      assertEquals("New Clone Col From doesnt match", mergeRegion.getFirstColumn(), cloneRegion.getFirstColumn());
+      assertEquals("New Clone Col To doesnt match", mergeRegion.getLastColumn(), cloneRegion.getLastColumn());      
       
       merge.removeAreaAt(0);
       assertNotNull("Clone's item not removed", clone.getAreaAt(0));
index 2ae8230d5e95dd1f36195d6ac3c878bb80805499..2472d4d21321cd70365c93ed28146cac96626cb5 100644 (file)
@@ -28,8 +28,8 @@ import org.apache.poi.hssf.record.CFHeaderRecord;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.RecordFactory;
 import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
-import org.apache.poi.hssf.record.cf.CellRange;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.CellRangeAddress;
 
 /**
  * Tests the serialization and deserialization of the CFRecordsAggregate
@@ -49,9 +49,9 @@ public final class TestCFRecordsAggregate extends TestCase
                CFRuleRecord rule2 = CFRuleRecord.create(workbook, ComparisonOperator.BETWEEN, "2", "5");
                CFRuleRecord rule3 = CFRuleRecord.create(workbook, ComparisonOperator.GE, "100", null);
                header.setNumberOfConditionalFormats(3);
-               CellRange[] cellRanges = {
-                               new CellRange(0,1,0,0),
-                               new CellRange(0,1,2,2),
+               CellRangeAddress[] cellRanges = {
+                               new CellRangeAddress(0,1,0,0),
+                               new CellRangeAddress(0,1,2,2),
                };
                header.setCellRanges(cellRanges);
                recs.add(header);
@@ -97,11 +97,4 @@ public final class TestCFRecordsAggregate extends TestCase
                assertEquals(2, cellRanges.length);
                assertEquals(3, header.getNumberOfConditionalFormats());
        }
-
-       public static void main(String[] ignored_args)
-       {
-               System.out.println("Testing org.apache.poi.hssf.record.aggregates.CFRecordsAggregate");
-               junit.textui.TestRunner.run(TestCFRecordsAggregate.class);
-       }
-       
 }
index 2ba196d55a189951c0ffda48ac00702f0de2a8b3..dc900d91f2e4a2a778bb3cc7e0f183d2c0354e18 100644 (file)
@@ -17,6 +17,8 @@ limitations under the License.
 
 package org.apache.poi.hssf.record.cf;
 
+import org.apache.poi.hssf.util.CellRangeAddress;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
@@ -25,15 +27,15 @@ import junit.framework.TestCase;
  */
 public final class TestCellRange extends TestCase
 {
-       private static final CellRange biggest     = createCR( 0, -1, 0,-1);
-       private static final CellRange tenthColumn = createCR( 0, -1,10,10);
-       private static final CellRange tenthRow    = createCR(10, 10, 0,-1);
-       private static final CellRange box10x10    = createCR( 0, 10, 0,10);
-       private static final CellRange box9x9      = createCR( 0,  9, 0, 9);
-       private static final CellRange box10to20c  = createCR( 0, 10,10,20);
-       private static final CellRange oneCell     = createCR(10, 10,10,10);
+       private static final CellRangeAddress biggest     = createCR( 0, -1, 0,-1);
+       private static final CellRangeAddress tenthColumn = createCR( 0, -1,10,10);
+       private static final CellRangeAddress tenthRow    = createCR(10, 10, 0,-1);
+       private static final CellRangeAddress box10x10    = createCR( 0, 10, 0,10);
+       private static final CellRangeAddress box9x9      = createCR( 0,  9, 0, 9);
+       private static final CellRangeAddress box10to20c  = createCR( 0, 10,10,20);
+       private static final CellRangeAddress oneCell     = createCR(10, 10,10,10);
 
-       private static final CellRange[] sampleRanges = {
+       private static final CellRangeAddress[] sampleRanges = {
                biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell,
        };
        
@@ -54,9 +56,9 @@ public final class TestCellRange extends TestCase
         * @param lastRow pass -1 for max row index 
         * @param lastCol pass -1 for max col index
         */
-       private static CellRange createCR(int firstRow, int lastRow, int firstCol, int lastCol) {
+       private static CellRangeAddress createCR(int firstRow, int lastRow, int firstCol, int lastCol) {
                // max row & max col limit as per BIFF8
-               return new CellRange(
+               return new CellRangeAddress(
                                firstRow, 
                                lastRow == -1 ? 0xFFFF : lastRow, 
                                firstCol,
@@ -65,89 +67,89 @@ public final class TestCellRange extends TestCase
        
        public void testContainsMethod()
        {
-               CellRange [] ranges = sampleRanges;
+               CellRangeAddress [] ranges = sampleRanges;
                for(int i=0; i!=ranges.length;i++)
                {
                        for(int j=0; j!=ranges.length;j++)
                        {
                                boolean expectedResult = containsExpectedResults[i][j];
-                               assertEquals("("+i+","+j+"): ", expectedResult, ranges[i].contains(ranges[j]));
+                               assertEquals("("+i+","+j+"): ", expectedResult, CellRangeUtil.contains(ranges[i], ranges[j]));
                        }
                }
        }
 
-       private static final CellRange col1     = createCR( 0, -1, 1,1);
-       private static final CellRange col2     = createCR( 0, -1, 2,2);
-       private static final CellRange row1     = createCR( 1,  1, 0,-1);
-       private static final CellRange row2     = createCR( 2,  2, 0,-1);
+       private static final CellRangeAddress col1     = createCR( 0, -1, 1,1);
+       private static final CellRangeAddress col2     = createCR( 0, -1, 2,2);
+       private static final CellRangeAddress row1     = createCR( 1,  1, 0,-1);
+       private static final CellRangeAddress row2     = createCR( 2,  2, 0,-1);
 
-       private static final CellRange box0     = createCR( 0, 2, 0,2);
-       private static final CellRange box1     = createCR( 0, 1, 0,1);
-       private static final CellRange box2     = createCR( 0, 1, 2,3);
-       private static final CellRange box3     = createCR( 2, 3, 0,1);
-       private static final CellRange box4     = createCR( 2, 3, 2,3);
-       private static final CellRange box5     = createCR( 1, 3, 1,3);
+       private static final CellRangeAddress box0     = createCR( 0, 2, 0,2);
+       private static final CellRangeAddress box1     = createCR( 0, 1, 0,1);
+       private static final CellRangeAddress box2     = createCR( 0, 1, 2,3);
+       private static final CellRangeAddress box3     = createCR( 2, 3, 0,1);
+       private static final CellRangeAddress box4     = createCR( 2, 3, 2,3);
+       private static final CellRangeAddress box5     = createCR( 1, 3, 1,3);
 
        public void testHasSharedBorderMethod()
        {
-               assertFalse(col1.hasExactSharedBorder(col1));
-               assertFalse(col2.hasExactSharedBorder(col2));
-               assertTrue(col1.hasExactSharedBorder(col2));
-               assertTrue(col2.hasExactSharedBorder(col1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col1, col1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col2, col2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(col1, col2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(col2, col1));
 
-               assertFalse(row1.hasExactSharedBorder(row1));
-               assertFalse(row2.hasExactSharedBorder(row2));
-               assertTrue(row1.hasExactSharedBorder(row2));
-               assertTrue(row2.hasExactSharedBorder(row1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row1, row1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row2, row2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(row1, row2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(row2, row1));
                
-               assertFalse(row1.hasExactSharedBorder(col1));
-               assertFalse(row1.hasExactSharedBorder(col2));
-               assertFalse(col1.hasExactSharedBorder(row1));
-               assertFalse(col2.hasExactSharedBorder(row1));
-               assertFalse(row2.hasExactSharedBorder(col1));
-               assertFalse(row2.hasExactSharedBorder(col2));
-               assertFalse(col1.hasExactSharedBorder(row2));
-               assertFalse(col2.hasExactSharedBorder(row2));
-               assertTrue(col2.hasExactSharedBorder(col1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row1, col1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row1, col2));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col1, row1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col2, row1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row2, col1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(row2, col2));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col1, row2));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(col2, row2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(col2, col1));
                
-               assertFalse(box1.hasExactSharedBorder(box1));
-               assertTrue(box1.hasExactSharedBorder(box2));
-               assertTrue(box1.hasExactSharedBorder(box3));
-               assertFalse(box1.hasExactSharedBorder(box4));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box1, box1));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box1, box2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box1, box3));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box1, box4));
                
-               assertTrue(box2.hasExactSharedBorder(box1));
-               assertFalse(box2.hasExactSharedBorder(box2));
-               assertFalse(box2.hasExactSharedBorder(box3));
-               assertTrue(box2.hasExactSharedBorder(box4));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box2, box1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box2, box2));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box2, box3));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box2, box4));
                
-               assertTrue(box3.hasExactSharedBorder(box1));
-               assertFalse(box3.hasExactSharedBorder(box2));
-               assertFalse(box3.hasExactSharedBorder(box3));
-               assertTrue(box3.hasExactSharedBorder(box4));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box3, box1));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box3, box2));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box3, box3));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box3, box4));
                
-               assertFalse(box4.hasExactSharedBorder(box1));
-               assertTrue(box4.hasExactSharedBorder(box2));
-               assertTrue(box4.hasExactSharedBorder(box3));
-               assertFalse(box4.hasExactSharedBorder(box4));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box4, box1));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box4, box2));
+               assertTrue(CellRangeUtil.hasExactSharedBorder(box4, box3));
+               assertFalse(CellRangeUtil.hasExactSharedBorder(box4, box4));
        }
 
        public void testIntersectMethod()
        {
-               assertEquals(CellRange.OVERLAP,box0.intersect(box5));
-               assertEquals(CellRange.OVERLAP,box5.intersect(box0));
-               assertEquals(CellRange.NO_INTERSECTION,box1.intersect(box4));
-               assertEquals(CellRange.NO_INTERSECTION,box4.intersect(box1));
-               assertEquals(CellRange.NO_INTERSECTION,box2.intersect(box3));
-               assertEquals(CellRange.NO_INTERSECTION,box3.intersect(box2));
-               assertEquals(CellRange.INSIDE,box0.intersect(box1));
-               assertEquals(CellRange.INSIDE,box0.intersect(box0));
-               assertEquals(CellRange.ENCLOSES,box1.intersect(box0));
-               assertEquals(CellRange.INSIDE,tenthColumn.intersect(oneCell));
-               assertEquals(CellRange.ENCLOSES,oneCell.intersect(tenthColumn));
-               assertEquals(CellRange.OVERLAP,tenthColumn.intersect(tenthRow));
-               assertEquals(CellRange.OVERLAP,tenthRow.intersect(tenthColumn));
-               assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn));
-               assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow));
+               assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(box0, box5));
+               assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(box5, box0));
+               assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box1, box4));
+               assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box4, box1));
+               assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box2, box3));
+               assertEquals(CellRangeUtil.NO_INTERSECTION, CellRangeUtil.intersect(box3, box2));
+               assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(box0, box1));
+               assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(box0, box0));
+               assertEquals(CellRangeUtil.ENCLOSES, CellRangeUtil.intersect(box1, box0));
+               assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthColumn, oneCell));
+               assertEquals(CellRangeUtil.ENCLOSES, CellRangeUtil.intersect(oneCell, tenthColumn));
+               assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(tenthColumn, tenthRow));
+               assertEquals(CellRangeUtil.OVERLAP, CellRangeUtil.intersect(tenthRow, tenthColumn));
+               assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthColumn, tenthColumn));
+               assertEquals(CellRangeUtil.INSIDE, CellRangeUtil.intersect(tenthRow, tenthRow));
        }
        
        /**
@@ -155,7 +157,7 @@ public final class TestCellRange extends TestCase
         * =$C:$IV,$B$1:$B$8,$B$10:$B$65536,$A:$A
         */
        public void testCreate() {
-               CellRange cr;
+               CellRangeAddress cr;
                
                cr = createCR(0, -1, 2, 255); // $C:$IV
                confirmRange(cr, false, true);
@@ -172,7 +174,7 @@ public final class TestCellRange extends TestCase
                cr = createCR(0, -1, 0, 0); // $A:$A
        }
 
-       private static void confirmRange(CellRange cr, boolean isFullRow, boolean isFullColumn) {
+       private static void confirmRange(CellRangeAddress cr, boolean isFullRow, boolean isFullColumn) {
                assertEquals("isFullRowRange", isFullRow, cr.isFullRowRange());
                assertEquals("isFullColumnRange", isFullColumn, cr.isFullColumnRange());
        }
index fe201068de489cc6ff41398853cd862386a4ead8..9f68e7d25143332b1dab4bf54e062e6d2b3342b8 100644 (file)
@@ -35,6 +35,7 @@ import org.apache.poi.hssf.record.FormulaRecord;
 import org.apache.poi.hssf.record.NameRecord;
 import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.Region;
 import org.apache.poi.util.TempFile;
 
@@ -301,15 +302,14 @@ public final class TestBugs extends TestCase {
 
     /**
      * Merged regions were being removed from the parent in cloned sheets
-     * @throws Exception
      */
     public void test22720() {
        HSSFWorkbook workBook = new HSSFWorkbook();
        workBook.createSheet("TEST");
        HSSFSheet template = workBook.getSheetAt(0);
 
-       template.addMergedRegion(new Region(0, (short)0, 1, (short)2));
-       template.addMergedRegion(new Region(1, (short)0, 2, (short)2));
+       template.addMergedRegion(new CellRangeAddress(0, 1, 0, 2));
+       template.addMergedRegion(new CellRangeAddress(1, 2, 0, 2));
 
        HSSFSheet clone = workBook.cloneSheet(0);
        int originalMerged = template.getNumMergedRegions();
@@ -317,20 +317,20 @@ public final class TestBugs extends TestCase {
 
 //        remove merged regions from clone
        for (int i=template.getNumMergedRegions()-1; i>=0; i--) {
-         clone.removeMergedRegion(i);
+           clone.removeMergedRegion(i);
        }
 
       assertEquals("Original Sheet's Merged Regions were removed", originalMerged, template.getNumMergedRegions());
 //        check if template's merged regions are OK
        if (template.getNumMergedRegions()>0) {
-          // fetch the first merged region...EXCEPTION OCCURS HERE
-          template.getMergedRegionAt(0);
+            // fetch the first merged region...EXCEPTION OCCURS HERE
+            template.getMergedRegion(0);
        }
        //make sure we dont exception
 
     }
 
-    /*Tests read and write of Unicode strings in formula results
+    /**Tests read and write of Unicode strings in formula results
      * bug and testcase submitted by Sompop Kumnoonsate
      * The file contains THAI unicode characters.
      */
index a663602ed3230f12aef7a7a545846bb1769053c1..54f1685bb62113e6fd31d534612d252d77455242 100644 (file)
@@ -20,6 +20,8 @@
 package org.apache.poi.hssf.usermodel;
 
 import junit.framework.TestCase;
+
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.Region;
 
 /**
@@ -28,23 +30,15 @@ import org.apache.poi.hssf.util.Region;
  *  add that record to the sheet in the testCloneSheetBasic method. 
  * @author  avik
  */
-public class TestCloneSheet extends TestCase {
+public final class TestCloneSheet extends TestCase {
 
-       public TestCloneSheet(String arg0) {
-               super(arg0);
-       }
-       
        public void testCloneSheetBasic(){
-               try{
-                       HSSFWorkbook b = new HSSFWorkbook();
-                       HSSFSheet s = b.createSheet("Test");
-                       s.addMergedRegion(new Region((short)0,(short)0,(short)1,(short)1));
-                       HSSFSheet clonedSheet = b.cloneSheet(0);
-                       
-                       assertEquals("One merged area", 1, clonedSheet.getNumMergedRegions());
-
-               }
-               catch(Exception e){e.printStackTrace();fail(e.getMessage());}
+               HSSFWorkbook b = new HSSFWorkbook();
+               HSSFSheet s = b.createSheet("Test");
+               s.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
+               HSSFSheet clonedSheet = b.cloneSheet(0);
+               
+               assertEquals("One merged area", 1, clonedSheet.getNumMergedRegions());
        }
 
    /**
@@ -65,5 +59,4 @@ public class TestCloneSheet extends TestCase {
       
       assertTrue("Row 3 still should be broken", clone.isRowBroken(3));
    }
-   
 }
index 794d5433c3daca89541d47fb9c541b5120d1f223..20933819b40367750290c0743935ebff13766cbe 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.poi.hssf.eventmodel.ERFListener;
 import org.apache.poi.hssf.eventmodel.EventRecordFactory;
 import org.apache.poi.hssf.record.DVRecord;
 import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.CellRangeAddressList;
 import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.hssf.util.Region;
@@ -254,8 +255,7 @@ public final class TestDataValidation extends TestCase {
                        HSSFSheet sheet = _currentSheet;
                        HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows());
                        row = sheet.createRow(sheet.getPhysicalNumberOfRows());
-                       sheet.addMergedRegion(new Region((short) (sheet.getPhysicalNumberOfRows() - 1),
-                                       (short) 0, (short) (sheet.getPhysicalNumberOfRows() - 1), (short) 5));
+                       sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5));
                        HSSFCell cell = row.createCell((short) 0);
                        setCellValue(cell, strTypeDescription);
                        cell.setCellStyle(_style_3);
@@ -297,7 +297,7 @@ public final class TestDataValidation extends TestCase {
                public void createDVDescriptionRow(String strTypeDescription) {
                        HSSFSheet sheet = _currentSheet;
                        HSSFRow row = sheet.getRow(sheet.getPhysicalNumberOfRows()-1);
-                       sheet.addMergedRegion(new Region((short)(sheet.getPhysicalNumberOfRows()-1),(short)0,(short)(sheet.getPhysicalNumberOfRows()-1),(short)5));
+                       sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5));
                        HSSFCell cell = row.createCell((short)0);
                        setCellValue(cell, strTypeDescription);
                        cell.setCellStyle(_style_3);
index 405f78106e70a427fb71402cc670c7ab86319005..ab503737a88c6180c65aca872955a1d8809b672b 100644 (file)
@@ -20,8 +20,8 @@ package org.apache.poi.hssf.usermodel;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.hssf.util.HSSFColor;
-import org.apache.poi.hssf.util.Region;
 /**
  * 
  * @author Dmitriy Kumshayev
@@ -57,9 +57,8 @@ public final class TestHSSFConditionalFormatting extends TestCase
                };
 
                short col = 1;
-               Region [] regions =
-               {
-                       new Region(0,col,65535,col)
+               CellRangeAddress [] regions = {
+                       new CellRangeAddress(0, 65535, col, col)
                };
 
                sheetCF.addConditionalFormatting(regions, cfRules);
@@ -72,14 +71,14 @@ public final class TestHSSFConditionalFormatting extends TestCase
                HSSFConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);
                assertNotNull(cf);
 
-               regions = cf.getFormattingRegions();
+               regions = cf.getFormattingRanges();
                assertNotNull(regions);
                assertEquals(1, regions.length);
-               Region r = regions[0];
-               assertEquals(1, r.getColumnFrom());
-               assertEquals(1, r.getColumnTo());
-               assertEquals(0, r.getRowFrom());
-               assertEquals(65535, r.getRowTo());
+               CellRangeAddress r = regions[0];
+               assertEquals(1, r.getFirstColumn());
+               assertEquals(1, r.getLastColumn());
+               assertEquals(0, r.getFirstRow());
+               assertEquals(65535, r.getLastRow());
 
                assertEquals(2, cf.getNumberOfRules());
 
index 7fa84b853aec390be6ecac6756a9509a2523aebb..3816c4cb64ac4e2320b5c7c526683e4ded629916 100644 (file)
@@ -35,7 +35,7 @@ import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.VCenterRecord;
 import org.apache.poi.hssf.record.WSBoolRecord;
 import org.apache.poi.hssf.record.WindowTwoRecord;
-import org.apache.poi.hssf.util.Region;
+import org.apache.poi.hssf.util.CellRangeAddress;
 
 /**
  * Tests HSSFSheet.  This test case is very incomplete at the moment.
@@ -476,15 +476,15 @@ public final class TestHSSFSheet extends TestCase {
        public void testRemoveMerged() {
                HSSFWorkbook wb = new HSSFWorkbook();
                HSSFSheet sheet = wb.createSheet();
-               Region region = new Region(0, (short)0, 1, (short)1);
+               CellRangeAddress region = new CellRangeAddress(0, 1, 0, 1);
                sheet.addMergedRegion(region);
-               region = new Region(1, (short)0, 2, (short)1);
+               region = new CellRangeAddress(1, 2, 0, 1);
                sheet.addMergedRegion(region);
 
                sheet.removeMergedRegion(0);
 
-               region = sheet.getMergedRegionAt(0);
-               assertEquals("Left over region should be starting at row 1", 1, region.getRowFrom());
+               region = sheet.getMergedRegion(0);
+               assertEquals("Left over region should be starting at row 1", 1, region.getFirstRow());
 
                sheet.removeMergedRegion(0);
 
@@ -496,15 +496,15 @@ public final class TestHSSFSheet extends TestCase {
                sheet.removeMergedRegion(0);
                assertEquals("there should now be zero merged regions!", 0, sheet.getNumMergedRegions());
                //add it again!
-               region.setRowTo(4);
+               region.setLastRow(4);
 
                sheet.addMergedRegion(region);
                assertEquals("there should now be one merged region!", 1, sheet.getNumMergedRegions());
 
                //should exist now!
                assertTrue("there isn't more than one merged region in there", 1 <= sheet.getNumMergedRegions());
-               region = sheet.getMergedRegionAt(0);
-               assertEquals("the merged row to doesnt match the one we put in ", 4, region.getRowTo());
+               region = sheet.getMergedRegion(0);
+               assertEquals("the merged row to doesnt match the one we put in ", 4, region.getLastRow());
        }
 
        public void testShiftMerged() {
@@ -518,13 +518,13 @@ public final class TestHSSFSheet extends TestCase {
                cell = row.createCell((short)1);
                cell.setCellValue(new HSSFRichTextString("second row, second cell"));
 
-               Region region = new Region(1, (short)0, 1, (short)1);
+               CellRangeAddress region = new CellRangeAddress(1, 1, 0, 1);
                sheet.addMergedRegion(region);
 
                sheet.shiftRows(1, 1, 1);
 
-               region = sheet.getMergedRegionAt(0);
-               assertEquals("Merged region not moved over to row 2", 2, region.getRowFrom());
+               region = sheet.getMergedRegion(0);
+               assertEquals("Merged region not moved over to row 2", 2, region.getFirstRow());
        }
 
        /**
@@ -683,7 +683,7 @@ public final class TestHSSFSheet extends TestCase {
                assertTrue("Column autosized with only one row: wrong width", sheet.getColumnWidth((short)0) <= maxWithRow1And2);
 
                //create a region over the 2nd row and auto size the first column
-               sheet.addMergedRegion(new Region(1,(short)0,1,(short)1));
+               sheet.addMergedRegion(new CellRangeAddress(1,1,0,1));
                sheet.autoSizeColumn((short)0);
                HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb);
 
index c353e3f04e8ad768b256de0ab221b4401b76b4db..3851cab56f7638cdd0ead08816c7d2ade6501529 100644 (file)
@@ -31,7 +31,7 @@ import org.apache.poi.hssf.record.BackupRecord;
 import org.apache.poi.hssf.record.LabelSSTRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
-import org.apache.poi.hssf.util.Region;
+import org.apache.poi.hssf.util.CellRangeAddress;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.TempFile;
 
@@ -42,7 +42,7 @@ import org.apache.poi.util.TempFile;
  * @author Greg Merrill
  * @author Siggi Cherem
  */
-public class TestWorkbook extends TestCase {
+public final class TestWorkbook extends TestCase {
     private static final String LAST_NAME_KEY        = "lastName";
     private static final String FIRST_NAME_KEY       = "firstName";
     private static final String SSN_KEY              = "ssn";
@@ -260,10 +260,10 @@ public class TestWorkbook extends TestCase {
         HSSFWorkbook workbook = openSample("Employee.xls");
         HSSFSheet       sheet    = workbook.getSheetAt(0);
 
-        assertEquals(EMPLOYEE_INFORMATION, sheet.getRow(1).getCell(1).getStringCellValue());
-        assertEquals(LAST_NAME_KEY, sheet.getRow(3).getCell(2).getStringCellValue());
-        assertEquals(FIRST_NAME_KEY, sheet.getRow(4).getCell(2).getStringCellValue());
-        assertEquals(SSN_KEY, sheet.getRow(5).getCell(2).getStringCellValue());
+        assertEquals(EMPLOYEE_INFORMATION, sheet.getRow(1).getCell(1).getRichStringCellValue().getString());
+        assertEquals(LAST_NAME_KEY, sheet.getRow(3).getCell(2).getRichStringCellValue().getString());
+        assertEquals(FIRST_NAME_KEY, sheet.getRow(4).getCell(2).getRichStringCellValue().getString());
+        assertEquals(SSN_KEY, sheet.getRow(5).getCell(2).getRichStringCellValue().getString());
     }
 
     /**
@@ -318,13 +318,13 @@ public class TestWorkbook extends TestCase {
 
         sheet    = workbook.getSheetAt(0);
         cell     = sheet.getRow(0).getCell(1);
-        assertEquals(REPLACED, cell.getStringCellValue());
+        assertEquals(REPLACED, cell.getRichStringCellValue().getString());
         cell = sheet.getRow(0).getCell(0);
-        assertEquals(DO_NOT_REPLACE, cell.getStringCellValue());
+        assertEquals(DO_NOT_REPLACE, cell.getRichStringCellValue().getString());
         cell = sheet.getRow(1).getCell(0);
-        assertEquals(REPLACED, cell.getStringCellValue());
+        assertEquals(REPLACED, cell.getRichStringCellValue().getString());
         cell = sheet.getRow(1).getCell(1);
-        assertEquals(DO_NOT_REPLACE, cell.getStringCellValue());
+        assertEquals(DO_NOT_REPLACE, cell.getRichStringCellValue().getString());
     }
 
     /**
@@ -388,10 +388,10 @@ public class TestWorkbook extends TestCase {
 
         workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
         sheet    = workbook.getSheetAt(0);
-        assertEquals(EMPLOYEE_INFORMATION, sheet.getRow(1).getCell(1).getStringCellValue());
-        assertEquals(LAST_NAME_VALUE, sheet.getRow(3).getCell(2).getStringCellValue());
-        assertEquals(FIRST_NAME_VALUE, sheet.getRow(4).getCell(2).getStringCellValue());
-        assertEquals(SSN_VALUE, sheet.getRow(5).getCell(2).getStringCellValue());
+        assertEquals(EMPLOYEE_INFORMATION, sheet.getRow(1).getCell(1).getRichStringCellValue().getString());
+        assertEquals(LAST_NAME_VALUE, sheet.getRow(3).getCell(2).getRichStringCellValue().getString());
+        assertEquals(FIRST_NAME_VALUE, sheet.getRow(4).getCell(2).getRichStringCellValue().getString());
+        assertEquals(SSN_VALUE, sheet.getRow(5).getCell(2).getRichStringCellValue().getString());
     }
 
     /**
@@ -421,26 +421,17 @@ public class TestWorkbook extends TestCase {
      *             HSSFSheet last row or first row is incorrect.             <P>
      *
      */
-
-    public void testWriteModifySheetMerged()
-        throws IOException
-    {
-        File             file = TempFile.createTempFile("testWriteSheetMerged",
-                                                    ".xls");
-        FileOutputStream out  = new FileOutputStream(file);
-        FileInputStream  in   = null;
+    public void testWriteModifySheetMerged() {
         HSSFWorkbook     wb   = new HSSFWorkbook();
         HSSFSheet        s    = wb.createSheet();
-        HSSFRow          r    = null;
-        HSSFCell         c    = null;
 
         for (short rownum = ( short ) 0; rownum < 100; rownum++)
         {
-            r = s.createRow(rownum);
+            HSSFRow r = s.createRow(rownum);
 
             for (short cellnum = ( short ) 0; cellnum < 50; cellnum += 2)
             {
-                c = r.createCell(cellnum);
+                HSSFCell c = r.createCell(cellnum);
                 c.setCellValue(rownum * 10000 + cellnum
                                + ((( double ) rownum / 1000)
                                   + (( double ) cellnum / 10000)));
@@ -448,33 +439,27 @@ public class TestWorkbook extends TestCase {
                 c.setCellValue(new HSSFRichTextString("TEST"));
             }
         }
-        s.addMergedRegion(new Region(( short ) 0, ( short ) 0, ( short ) 10,
-                                     ( short ) 10));
-        s.addMergedRegion(new Region(( short ) 30, ( short ) 5, ( short ) 40,
-                                     ( short ) 15));
-        wb.write(out);
-        out.close();
+        s.addMergedRegion(new CellRangeAddress(0, 10, 0, 10));
+        s.addMergedRegion(new CellRangeAddress(30, 40, 5, 15));
         sanityChecker.checkHSSFWorkbook(wb);
-        in = new FileInputStream(file);
-        wb = new HSSFWorkbook(new POIFSFileSystem(in));
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        
         s  = wb.getSheetAt(0);
-        Region r1 = s.getMergedRegionAt(0);
-        Region r2 = s.getMergedRegionAt(1);
+        CellRangeAddress r1 = s.getMergedRegion(0);
+        CellRangeAddress r2 = s.getMergedRegion(1);
 
-        in.close();
-
-        // System.out.println(file.length());
-        // assertEquals("FILE LENGTH == 87552",file.length(), 87552);
-        // System.out.println(s.getLastRowNum());
-        assertEquals("REGION1 = 0,0,10,10", 0,
-                     new Region(( short ) 0, ( short ) 0, ( short ) 10,
-                                ( short ) 10).compareTo(r1));
-        assertEquals("REGION2 == 30,5,40,15", 0,
-                     new Region(( short ) 30, ( short ) 5, ( short ) 40,
-                                ( short ) 15).compareTo(r2));
+        confirmRegion(new CellRangeAddress(0, 10, 0, 10), r1);
+        confirmRegion(new CellRangeAddress(30, 40,5, 15), r2);
     }
 
-    /**
+    private static void confirmRegion(CellRangeAddress ra, CellRangeAddress rb) {
+               assertEquals(ra.getFirstRow(), rb.getFirstRow());
+               assertEquals(ra.getLastRow(), rb.getLastRow());
+               assertEquals(ra.getFirstColumn(), rb.getFirstColumn());
+               assertEquals(ra.getLastColumn(), rb.getLastColumn());
+       }
+
+       /**
      * Test the backup field gets set as expected.
      */