]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924...
authorNick Burch <nick@apache.org>
Sat, 9 Aug 2008 09:52:35 +0000 (09:52 +0000)
committerNick Burch <nick@apache.org>
Sat, 9 Aug 2008 09:52:35 +0000 (09:52 +0000)
https://svn.apache.org/repos/asf/poi/trunk

........
  r683758 | josh | 2008-08-08 00:49:10 +0100 (Fri, 08 Aug 2008) | 1 line

  Consolidating ValueRecordsAggregate within RowRecordsAggregate
........
  r683788 | josh | 2008-08-08 02:30:30 +0100 (Fri, 08 Aug 2008) | 1 line

  Converted RowRecordsAggregate to proper RecordAggregate
........
  r683871 | josh | 2008-08-08 07:27:06 +0100 (Fri, 08 Aug 2008) | 1 line

  Extracting PageSettingsBlock from Sheet
........
  r683880 | josh | 2008-08-08 07:56:06 +0100 (Fri, 08 Aug 2008) | 1 line

  Finished extracting PageSettingsBlock logic from Sheet
........
  r683901 | josh | 2008-08-08 09:05:07 +0100 (Fri, 08 Aug 2008) | 1 line

  Patch 45577 - Added implementations for Excel functions NOW and TODAY, added property getters to HSSFConditionalFormattingRule
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@684213 13f79535-47bb-0310-9956-ffa450edef68

27 files changed:
src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/model/RecordOrderer.java
src/java/org/apache/poi/hssf/model/RecordStream.java
src/java/org/apache/poi/hssf/model/Sheet.java
src/java/org/apache/poi/hssf/record/DBCellRecord.java
src/java/org/apache/poi/hssf/record/PrintSetupRecord.java
src/java/org/apache/poi/hssf/record/RowRecord.java
src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
src/java/org/apache/poi/hssf/record/formula/functions/Now.java
src/java/org/apache/poi/hssf/record/formula/functions/Today.java
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java
src/testcases/org/apache/poi/hssf/model/TestSheet.java
src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java
src/testcases/org/apache/poi/hssf/usermodel/SanityChecker.java
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java

index bc9a757724e0b7127f4b608de9a2444fe35aa78d..60cfd0f9f3f87601ad6bb2ff6936eb98f865defd 100644 (file)
@@ -54,7 +54,8 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="add">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
+           <action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action>
+           <action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
            <action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45472 - Fixed incorrect default row height in OpenOffice 2.3</action>
            <action dev="POI-DEVELOPERS" type="fix">44692 - HSSFPicture.resize() stretched image when there was a text next to it</action>
index 63926ec04364f6fb0bd18eff5649e1d83a575923..bc6acc93c2e52954f9e37d87cd12d3cac3134258 100644 (file)
@@ -51,7 +51,8 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="add">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
+           <action dev="POI-DEVELOPERS" type="add">45577 - Added implementations for Excel functions NOW and TODAY</action>
+           <action dev="POI-DEVELOPERS" type="fix">45582 - Fix for workbook streams with extra bytes trailing the EOFRecord</action>
            <action dev="POI-DEVELOPERS" type="add">45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45472 - Fixed incorrect default row height in OpenOffice 2.3</action>
            <action dev="POI-DEVELOPERS" type="fix">44692 - HSSFPicture.resize() stretched image when there was a text next to it</action>
index ae445597d10ee948588c5c8d942677c660b85fd0..887497a911192abb5c3f598731e6dd569af302ab 100644 (file)
@@ -29,7 +29,6 @@ import org.apache.poi.hssf.record.DimensionsRecord;
 import org.apache.poi.hssf.record.EOFRecord;
 import org.apache.poi.hssf.record.GridsetRecord;
 import org.apache.poi.hssf.record.GutsRecord;
-import org.apache.poi.hssf.record.HorizontalPageBreakRecord;
 import org.apache.poi.hssf.record.HyperlinkRecord;
 import org.apache.poi.hssf.record.IndexRecord;
 import org.apache.poi.hssf.record.IterationRecord;
@@ -44,11 +43,11 @@ import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.SaveRecalcRecord;
 import org.apache.poi.hssf.record.SelectionRecord;
 import org.apache.poi.hssf.record.UncalcedRecord;
-import org.apache.poi.hssf.record.VerticalPageBreakRecord;
 import org.apache.poi.hssf.record.WindowTwoRecord;
 import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
 import org.apache.poi.hssf.record.aggregates.DataValidityTable;
 import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
 
 /**
  * Finds correct insert positions for records in workbook streams<p/>
@@ -88,28 +87,25 @@ final class RecordOrderer {
                if (recClass == GutsRecord.class) {
                        return getGutsRecordInsertPos(records);
                }
-               if (recClass == HorizontalPageBreakRecord.class) {
-                       return getPageBreakRecordInsertPos(records, true);
-               }
-               if (recClass == VerticalPageBreakRecord.class) {
-                       return getPageBreakRecordInsertPos(records, false);
+               if (recClass == PageSettingsBlock.class) {
+                       return getPageBreakRecordInsertPos(records);
                }
                throw new RuntimeException("Unexpected record class (" + recClass.getName() + ")");
        }
 
-       private static int getPageBreakRecordInsertPos(List records, boolean isHorizonal) {
+       private static int getPageBreakRecordInsertPos(List records) {
                int dimensionsIndex = getDimensionsIndex(records);
                int i = dimensionsIndex-1;
                while (i > 0) {
                        i--;
                        Object rb = records.get(i);
-                       if (isPageBreakPriorRecord(rb, isHorizonal)) {
+                       if (isPageBreakPriorRecord(rb)) {
                                return i+1;
                        }
                }
                throw new RuntimeException("Did not find insert point for GUTS");
        }
-       private static boolean isPageBreakPriorRecord(Object rb, boolean newRecIsHorizontal) {
+       private static boolean isPageBreakPriorRecord(Object rb) {
                if (rb instanceof Record) {
                        Record record = (Record) rb;
                        switch (record.getSid()) {
@@ -132,19 +128,7 @@ final class RecordOrderer {
                                case DefaultRowHeightRecord.sid:
                                case 0x0081: // SHEETPR
                                        return true;
-                       }
-                       switch (record.getSid()) {
-                               // page settings block
-                               case HorizontalPageBreakRecord.sid:
-                                       if (!newRecIsHorizontal) {
-                                               return true;
-                                       }
-                                       return false;
-                               case VerticalPageBreakRecord.sid:
-                                       return false;
-                               // next is case HeaderRecord.sid: case FooterRecord.sid:
-                               // then more records in page settings block     
-                       
+                               // next is the 'Worksheet Protection Block'
                        }
                }
                return false;
index bec1c40e6a5daaccbd482de6d969109abcef706f..1a0687395432c56432ec997e3303e679a86eef92 100755 (executable)
@@ -59,6 +59,13 @@ public final class RecordStream {
                return _list.get(_nextIndex).getClass();
        }
 
+       public int peekNextSid() {
+               if(_nextIndex >= _list.size()) {
+                       return -1;
+               }
+               return ((Record)_list.get(_nextIndex)).getSid();
+       }
+
        public int getCountRead() {
                return _countRead;
        }
index 5e8faa092bd14addc7c1616cdf6be21fdbfbd470..750dbca238cd4203c47f1bffa9d6ae39f7bdfba3 100644 (file)
@@ -22,7 +22,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.poi.hssf.record.BOFRecord;
-import org.apache.poi.hssf.record.BottomMarginRecord;
 import org.apache.poi.hssf.record.CFHeaderRecord;
 import org.apache.poi.hssf.record.CalcCountRecord;
 import org.apache.poi.hssf.record.CalcModeRecord;
@@ -37,52 +36,38 @@ import org.apache.poi.hssf.record.DimensionsRecord;
 import org.apache.poi.hssf.record.DrawingRecord;
 import org.apache.poi.hssf.record.EOFRecord;
 import org.apache.poi.hssf.record.EscherAggregate;
-import org.apache.poi.hssf.record.FooterRecord;
 import org.apache.poi.hssf.record.GridsetRecord;
 import org.apache.poi.hssf.record.GutsRecord;
-import org.apache.poi.hssf.record.HCenterRecord;
-import org.apache.poi.hssf.record.HeaderRecord;
-import org.apache.poi.hssf.record.HorizontalPageBreakRecord;
 import org.apache.poi.hssf.record.IndexRecord;
 import org.apache.poi.hssf.record.IterationRecord;
-import org.apache.poi.hssf.record.LeftMarginRecord;
-import org.apache.poi.hssf.record.Margin;
 import org.apache.poi.hssf.record.MergeCellsRecord;
 import org.apache.poi.hssf.record.ObjRecord;
 import org.apache.poi.hssf.record.ObjectProtectRecord;
-import org.apache.poi.hssf.record.PageBreakRecord;
 import org.apache.poi.hssf.record.PaneRecord;
 import org.apache.poi.hssf.record.PasswordRecord;
 import org.apache.poi.hssf.record.PrintGridlinesRecord;
 import org.apache.poi.hssf.record.PrintHeadersRecord;
-import org.apache.poi.hssf.record.PrintSetupRecord;
 import org.apache.poi.hssf.record.ProtectRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordBase;
 import org.apache.poi.hssf.record.RefModeRecord;
-import org.apache.poi.hssf.record.RightMarginRecord;
 import org.apache.poi.hssf.record.RowRecord;
 import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.SaveRecalcRecord;
 import org.apache.poi.hssf.record.ScenarioProtectRecord;
 import org.apache.poi.hssf.record.SelectionRecord;
-import org.apache.poi.hssf.record.SharedFormulaRecord;
 import org.apache.poi.hssf.record.StringRecord;
-import org.apache.poi.hssf.record.TopMarginRecord;
 import org.apache.poi.hssf.record.UncalcedRecord;
-import org.apache.poi.hssf.record.VCenterRecord;
-import org.apache.poi.hssf.record.VerticalPageBreakRecord;
 import org.apache.poi.hssf.record.WSBoolRecord;
 import org.apache.poi.hssf.record.WindowTwoRecord;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
 import org.apache.poi.hssf.record.aggregates.DataValidityTable;
-import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
 import org.apache.poi.hssf.record.aggregates.RecordAggregate;
 import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
-import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.hssf.util.PaneInformation;
@@ -121,37 +106,33 @@ public final class Sheet implements Model {
 
     protected ArrayList                  records           =     null;
               int                        preoffset         =     0;            // offset of the sheet in a new file
-              int                        loc               =     0;
     protected int                        dimsloc           =     -1;  // TODO - is it legal for dims record to be missing?
-    protected DimensionsRecord           dims;
+    protected PrintGridlinesRecord       printGridlines    =     null;
+    protected GridsetRecord              gridset           =     null;
+    private   GutsRecord                 _gutsRecord;
     protected DefaultColWidthRecord      defaultcolwidth   =     null;
     protected DefaultRowHeightRecord     defaultrowheight  =     null;
-    protected GridsetRecord              gridset           =     null;
-       private   GutsRecord                 _gutsRecord;
-    protected PrintSetupRecord           printSetup        =     null;
-    protected HeaderRecord               header            =     null;
-    protected FooterRecord               footer            =     null;
-    protected PrintGridlinesRecord       printGridlines    =     null;
+    private PageSettingsBlock _psBlock;
+
+    // 'Worksheet Protection Block'
+    protected ProtectRecord              protect           =     null;
+    protected ObjectProtectRecord        objprotect        =     null;
+    protected ScenarioProtectRecord      scenprotect       =     null;
+    protected PasswordRecord             password          =     null;
+    
     protected WindowTwoRecord            windowTwo         =     null;
-    protected Margin[]                   margins           =     null;
-    private   MergedCellsTable           _mergedCellsTable;
     protected SelectionRecord            selection         =     null;
+    private   MergedCellsTable           _mergedCellsTable;
     /** always present in this POI object, not always written to Excel file */
     /*package*/ColumnInfoRecordsAggregate _columnInfos;
-    protected ValueRecordsAggregate      cells             =     null;
+    protected DimensionsRecord           dims;
     protected RowRecordsAggregate        _rowsAggregate              =     null;
-    private   Iterator                   valueRecIterator  =     null;
-    private   Iterator                   rowRecIterator    =     null;
-    protected int                        eofLoc            =     0;
-    protected ProtectRecord              protect           =     null;
-    protected PageBreakRecord            _rowBreaksRecord;
-    protected PageBreakRecord            _columnBreaksRecord;
     private   DataValidityTable          _dataValidityTable=     null;
-    protected ObjectProtectRecord        objprotect        =     null;
-    protected ScenarioProtectRecord      scenprotect       =     null;
-    protected PasswordRecord             password          =     null;
     private   ConditionalFormattingTable condFormatting;
 
+    protected int                        eofLoc            =     0;
+    private   Iterator                   rowRecIterator    =     null;
+
     /** Add an UncalcedRecord if not true indicating formulas have not been calculated */
     protected boolean _isUncalced = false;
     
@@ -196,17 +177,8 @@ public final class Sheet implements Model {
         boolean   isfirstcell        = true;
         int       bofEofNestingLevel = 0;
 
-        for (int k = offset; k < recs.size(); k++)
-        {
+        for (int k = offset; k < recs.size(); k++) {
             Record rec = ( Record ) recs.get(k);
-            if (rec.isValue() != (rec instanceof CellValueRecordInterface)) {
-               if (rec instanceof SharedFormulaRecord) {
-                       
-               } else {
-               "".length();
-               }
-            }
-
             if ( rec.getSid() == DBCellRecord.sid ) {
                 continue;
             }
@@ -239,23 +211,51 @@ public final class Sheet implements Model {
                 retval._dataValidityTable = new DataValidityTable(rs);
                 k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
                 records.add(retval._dataValidityTable);
-                continue; // TODO
+                continue;
             }
-            if ( rec.getSid() == RowRecord.sid )
-            {
+            // TODO construct RowRecordsAggregate from RecordStream
+            if ( rec.getSid() == RowRecord.sid ) {
                 RowRecord row = (RowRecord)rec;
                 if (retval._rowsAggregate == null) {
                     retval._rowsAggregate = new RowRecordsAggregate();
                     records.add(retval._rowsAggregate); //only add the aggregate once
-                               }
+                }
                 retval._rowsAggregate.insertRow(row);
                 continue;
             }
+            if ( rec.isValue() && bofEofNestingLevel == 1 ) {
+                if (isfirstcell) {
+                    isfirstcell = false;
+                    if (retval._rowsAggregate == null) {
+                        retval._rowsAggregate = new RowRecordsAggregate();
+                        records.add(retval._rowsAggregate); //only add the aggregate once
+                    }
+                    retval._rowsAggregate.constructCellValues( k, recs );
+                }
+               continue;
+            }
+             
+            if (PageSettingsBlock.isComponentRecord(rec.getSid())) {
+                RecordStream rs = new RecordStream(recs, k);
+                PageSettingsBlock psb = new PageSettingsBlock(rs);
+                if (bofEofNestingLevel == 1) {
+                    if (retval._psBlock == null) {
+                        retval._psBlock = psb;
+                    } else {
+                        // more than one 'Page Settings Block' at nesting level 1 ?
+                        // apparently this happens in about 15 test sample files
+                    }
+                }
+                records.add(psb);
+                k += rs.getCountRead()-1;
+                continue;
+            }
+            
             if (rec.getSid() == MergeCellsRecord.sid) {
                 RecordStream rs = new RecordStream(recs, k);
                 retval._mergedCellsTable = new MergedCellsTable(rs);
                 records.add(retval._mergedCellsTable);
-                continue; // TODO
+                continue;
             }
             
             if (rec.getSid() == BOFRecord.sid)
@@ -290,21 +290,7 @@ public final class Sheet implements Model {
                 retval.dims    = ( DimensionsRecord ) rec;
                 retval.dimsloc = records.size();
             }
-            else if ( rec.isValue() && bofEofNestingLevel == 1 )
-            {
-                if ( isfirstcell )
-                {
-                    retval.cells = new ValueRecordsAggregate();
-                    rec = retval.cells;
-                    retval.cells.construct( k, recs );
-                    isfirstcell = false;
-                }
-                else
-                {
-                    rec = null;
-                }
-            }
-            else  if (rec.getSid() == DefaultColWidthRecord.sid)
+            else if (rec.getSid() == DefaultColWidthRecord.sid)
             {
                 retval.defaultcolwidth = ( DefaultColWidthRecord ) rec;
             }
@@ -320,34 +306,6 @@ public final class Sheet implements Model {
             {
                 retval.gridset = (GridsetRecord) rec;
             }
-            else if ( rec.getSid() == HeaderRecord.sid && bofEofNestingLevel == 1)
-            {
-                retval.header = (HeaderRecord) rec;
-            }
-            else if ( rec.getSid() == FooterRecord.sid && bofEofNestingLevel == 1)
-            {
-                retval.footer = (FooterRecord) rec;
-            }
-            else if ( rec.getSid() == PrintSetupRecord.sid && bofEofNestingLevel == 1)
-            {
-                retval.printSetup = (PrintSetupRecord) rec;
-            }
-            else if ( rec.getSid() == LeftMarginRecord.sid)
-            {
-                retval.getMargins()[LeftMargin] = (LeftMarginRecord) rec;
-            }
-            else if ( rec.getSid() == RightMarginRecord.sid)
-            {
-                retval.getMargins()[RightMargin] = (RightMarginRecord) rec;
-            }
-            else if ( rec.getSid() == TopMarginRecord.sid)
-            {
-                retval.getMargins()[TopMargin] = (TopMarginRecord) rec;
-            }
-            else if ( rec.getSid() == BottomMarginRecord.sid)
-            {
-                retval.getMargins()[BottomMargin] = (BottomMarginRecord) rec;
-            }
             else if ( rec.getSid() == SelectionRecord.sid )
             {
                 retval.selection = (SelectionRecord) rec;
@@ -372,26 +330,14 @@ public final class Sheet implements Model {
             {
                 retval.password = (PasswordRecord) rec;
             }
-            else if (rec.getSid() == HorizontalPageBreakRecord.sid)
-            {
-                retval._rowBreaksRecord = (HorizontalPageBreakRecord)rec;
-            }
-            else if (rec.getSid() == VerticalPageBreakRecord.sid)
-            {
-                retval._columnBreaksRecord = (VerticalPageBreakRecord)rec;
-            }
 
-            if (rec != null)
-            {
-                records.add(rec);
-            }
+            records.add(rec);
         }
         if (retval.dimsloc < 0) {
-               throw new RuntimeException("DimensionsRecord was not found");
+            throw new RuntimeException("DimensionsRecord was not found");
         }
         retval.records = records;
         retval.checkRows();
-        retval.checkCells();
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
         return retval;
@@ -399,15 +345,16 @@ public final class Sheet implements Model {
 
     private static final class RecordCloner implements RecordVisitor {
 
-               private final List _destList;
+        private final List _destList;
 
-               public RecordCloner(List destList) {
-                       _destList = destList;
-               }
-               public void visitRecord(Record r) {
-                       _destList.add(r.clone());
-               }
+        public RecordCloner(List destList) {
+            _destList = destList;
+        }
+        public void visitRecord(Record r) {
+            _destList.add(r.clone());
+        }
     }
+
     /**
      * Clones the low level records of this sheet and returns the new sheet instance.
      * This method is implemented by adding methods for deep cloning to all records that
@@ -415,57 +362,18 @@ public final class Sheet implements Model {
      * When adding a new record, implement a public clone method if and only if the record
      * belongs to a sheet.
      */
-    public Sheet cloneSheet()
-    {
-      ArrayList clonedRecords = new ArrayList(this.records.size());
-      for (int i=0; i<this.records.size();i++) {
-        RecordBase rb = (RecordBase) this.records.get(i);
-        if (rb instanceof RecordAggregate) {
-               ((RecordAggregate)rb).visitContainedRecords(new RecordCloner(clonedRecords));
-               // TODO - make sure this logic works for the other RecordAggregates
-               continue;
-        }
-               Record rec = (Record)((Record)rb).clone();
-        //Need to pull out the Row record and the Value records from their
-        //Aggregates.
-        //This is probably the best way to do it since we probably dont want the createSheet
-        //To cater for these artificial Record types
-        if (rec instanceof RowRecordsAggregate) {
-          RowRecordsAggregate rrAgg = (RowRecordsAggregate)rec;
-          for (Iterator rowIter = rrAgg.getIterator();rowIter.hasNext();) {
-            Record rowRec = (Record)rowIter.next();
-            clonedRecords.add(rowRec);
-          }
-        } else if (rec instanceof ValueRecordsAggregate) {
-          ValueRecordsAggregate vrAgg = (ValueRecordsAggregate)rec;
-          for (Iterator cellIter = vrAgg.getIterator();cellIter.hasNext();) {
-            Record valRec = (Record)cellIter.next();
-
-            if (valRec instanceof FormulaRecordAggregate) {
-                FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec;
-                Record fmAggRec = fmAgg.getFormulaRecord();
-                if (fmAggRec != null)
-                  clonedRecords.add(fmAggRec);
-                fmAggRec =   fmAgg.getStringRecord();
-                if (fmAggRec != null)
-                  clonedRecords.add(fmAggRec);
-              } else {
-                clonedRecords.add(valRec);
-              }
-          }
-        } else if (rec instanceof FormulaRecordAggregate) {  //Is this required now??
-          FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)rec;
-          Record fmAggRec = fmAgg.getFormulaRecord();
-          if (fmAggRec != null)
-            clonedRecords.add(fmAggRec);
-          fmAggRec =   fmAgg.getStringRecord();
-          if (fmAggRec != null)
-            clonedRecords.add(fmAggRec);
-        } else {
-          clonedRecords.add(rec);
+    public Sheet cloneSheet() {
+        ArrayList clonedRecords = new ArrayList(this.records.size());
+        for (int i = 0; i < this.records.size(); i++) {
+            RecordBase rb = (RecordBase) this.records.get(i);
+            if (rb instanceof RecordAggregate) {
+                ((RecordAggregate) rb).visitContainedRecords(new RecordCloner(clonedRecords));
+                continue;
+            }
+            Record rec = (Record) ((Record) rb).clone();
+            clonedRecords.add(rec);
         }
-      }
-      return createSheet(clonedRecords, 0, 0);
+        return createSheet(clonedRecords, 0, 0);
     }
 
 
@@ -521,20 +429,9 @@ public final class Sheet implements Model {
         records.add( retval.createWSBool() );
         
         // 'Page Settings Block'
-        retval._rowBreaksRecord = new HorizontalPageBreakRecord();
-        records.add(retval._rowBreaksRecord);
-        retval._columnBreaksRecord = new VerticalPageBreakRecord();
-        records.add(retval._columnBreaksRecord);
-
-        retval.header = createHeader();
-        records.add( retval.header );
-        retval.footer = createFooter();
-        records.add( retval.footer );
-        records.add(createHCenter() );
-        records.add(createVCenter() );
-        retval.printSetup = createPrintSetup();
-        records.add( retval.printSetup );
-
+        retval._psBlock = new PageSettingsBlock();
+        records.add(retval._psBlock);
+        
         // 'Worksheet Protection Block' (after 'Page Settings Block' and before DEFCOLWIDTH)
         // PROTECT record normally goes here, don't add yet since the flag is initially false
         
@@ -547,7 +444,6 @@ public final class Sheet implements Model {
         records.add(retval.dims);
         retval.dimsloc = records.size()-1;
         records.add(retval.windowTwo = retval.createWindowTwo());
-        retval.setLoc(records.size() - 1);
         retval.selection = createSelection();
         records.add(retval.selection);
         records.add(EOFRecord.instance);
@@ -559,23 +455,6 @@ public final class Sheet implements Model {
         return retval;
     }
 
-    private void checkCells()
-    {
-        if (cells == null)
-        {
-            cells = new ValueRecordsAggregate();
-            // In the worksheet stream, the row records always occur before the cell (value) 
-            // records. Therefore POI's aggregates (RowRecordsAggregate, ValueRecordsAggregate) 
-            // should follow suit. Some methods in this class tolerate either order, while 
-            // others have been found to fail (see bug 45145).
-            int rraIndex = getDimsLoc() + 1;
-            if (records.get(rraIndex).getClass() != RowRecordsAggregate.class) {
-                throw new IllegalStateException("Cannot create value records before row records exist");
-            }
-            records.add(rraIndex+1, cells);
-        }
-    }
-
     private void checkRows()
     {
         if (_rowsAggregate == null)
@@ -585,16 +464,16 @@ public final class Sheet implements Model {
         }
     }
     private MergedCellsTable getMergedRecords() {
-       if (_mergedCellsTable == null) {
-               MergedCellsTable mct = new MergedCellsTable();
-               RecordOrderer.addNewSheetRecord(records, mct);
-               _mergedCellsTable = mct;
-       }
-       return _mergedCellsTable;
+        if (_mergedCellsTable == null) {
+            MergedCellsTable mct = new MergedCellsTable();
+            RecordOrderer.addNewSheetRecord(records, mct);
+            _mergedCellsTable = mct;
+        }
+        return _mergedCellsTable;
     }
 
 
-       public int addMergedRegion(int rowFrom, int colFrom, int rowTo, int colTo) {
+    public int addMergedRegion(int rowFrom, int colFrom, int rowTo, int colTo) {
         // Validate input
         if (rowTo < rowFrom) {
             throw new IllegalArgumentException("The 'to' row (" + rowTo
@@ -606,7 +485,7 @@ public final class Sheet implements Model {
         }
 
         MergedCellsTable mrt = getMergedRecords();
-               mrt.addArea(rowFrom, colFrom, rowTo, colTo);
+        mrt.addArea(rowFrom, colFrom, rowTo, colTo);
         return mrt.getNumberOfMergedRegions()-1;
     }
 
@@ -614,76 +493,50 @@ public final class Sheet implements Model {
     {
         //safety checks
         MergedCellsTable mrt = getMergedRecords();
-               if (index >= mrt.getNumberOfMergedRegions()) {
-                       return;
-               }
-               mrt.remove(index);
+        if (index >= mrt.getNumberOfMergedRegions()) {
+            return;
+        }
+        mrt.remove(index);
     }
 
     public CellRangeAddress getMergedRegionAt(int index) {
         //safety checks
         MergedCellsTable mrt = getMergedRecords();
-               if (index >=  mrt.getNumberOfMergedRegions()) {
-                       return null;
-               }
-               return mrt.get(index);
+        if (index >=  mrt.getNumberOfMergedRegions()) {
+            return null;
+        }
+        return mrt.get(index);
     }
 
     public int getNumMergedRegions() {
         return getMergedRecords().getNumberOfMergedRegions();
     }
     private ConditionalFormattingTable getConditionalFormattingTable() {
-       if (condFormatting == null) {
-               condFormatting = new ConditionalFormattingTable();
-               RecordOrderer.addNewSheetRecord(records, condFormatting);
-       }
-               return condFormatting;
+        if (condFormatting == null) {
+            condFormatting = new ConditionalFormattingTable();
+            RecordOrderer.addNewSheetRecord(records, condFormatting);
+        }
+        return condFormatting;
     }
 
 
-       public int addConditionalFormatting(CFRecordsAggregate cfAggregate) {
-               ConditionalFormattingTable cft = getConditionalFormattingTable();
+    public int addConditionalFormatting(CFRecordsAggregate cfAggregate) {
+        ConditionalFormattingTable cft = getConditionalFormattingTable();
         return cft.add(cfAggregate);
     }
 
     public void removeConditionalFormatting(int index) {
-       getConditionalFormattingTable().remove(index);
+        getConditionalFormattingTable().remove(index);
     }
 
     public CFRecordsAggregate getCFRecordsAggregateAt(int index) {
-       return getConditionalFormattingTable().get(index);
+        return getConditionalFormattingTable().get(index);
     }
 
     public int getNumConditionalFormattings() {
         return getConditionalFormattingTable().size();
     }
 
-    /**
-     * Returns the number of low level binary records in this sheet.  This adjusts things for the so called
-     * AgregateRecords.
-     *
-     * @see org.apache.poi.hssf.record.Record
-     */
-
-    public int getNumRecords()
-    {
-        checkCells();
-        checkRows();
-        if (log.check( POILogger.DEBUG ))
-        {
-            log.log(POILogger.DEBUG, "Sheet.getNumRecords");
-            log.logFormatted(POILogger.DEBUG, "returning % + % + % - 2 = %", new int[]
-            {
-                records.size(), cells.getPhysicalNumberOfCells(),
-                _rowsAggregate.getPhysicalNumberOfRows(),
-                records.size() + cells.getPhysicalNumberOfCells()
-                + _rowsAggregate.getPhysicalNumberOfRows() - 2
-            });
-        }
-        return records.size() + cells.getPhysicalNumberOfCells()
-               + _rowsAggregate.getPhysicalNumberOfRows() - 2;
-    }
-
     /**
      * Per an earlier reported bug in working with Andy Khan's excel read library.  This
      * sets the values in the sheet's DimensionsRecord object to be correct.  Excel doesn't
@@ -711,42 +564,6 @@ public final class Sheet implements Model {
             log.log(POILogger.DEBUG, "Sheet.setDimensions exiting");
     }
 
-    /**
-     * set the locator for where we should look for the next value record.  The
-     * algorithm will actually start here and find the correct location so you
-     * can set this to 0 and watch performance go down the tubes but it will work.
-     * After a value is set this is automatically advanced.  Its also set by the
-     * create method.  So you probably shouldn't mess with this unless you have
-     * a compelling reason why or the help for the method you're calling says so.
-     * Check the other methods for whether they care about
-     * the loc pointer.  Many of the "modify" and "remove" methods re-initialize this
-     * to "dimsloc" which is the location of the Dimensions Record and presumably the
-     * start of the value section (at or around 19 dec).
-     *
-     * @param loc the record number to start at
-     *
-     */
-
-    public void setLoc(int loc)
-    {
-        valueRecIterator = null;
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "sheet.setLoc(): " + loc);
-        this.loc = loc;
-    }
-
-    /**
-     * Returns the location pointer to the first record to look for when adding rows/values
-     *
-     */
-
-    public int getLoc()
-    {
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "sheet.getLoc():" + loc);
-        return loc;
-    }
-
     /**
      * Set the preoffset when using DBCELL records (currently unused) - this is
      * the position of this sheet within the whole file.
@@ -790,7 +607,7 @@ public final class Sheet implements Model {
 
         for (int k = 0; k < records.size(); k++)
         {
-               RecordBase record = (RecordBase) records.get(k);
+            RecordBase record = (RecordBase) records.get(k);
 
             // Don't write out UncalcedRecord entries, as
             //  we handle those specially just below
@@ -800,13 +617,7 @@ public final class Sheet implements Model {
 
             // Once the rows have been found in the list of records, start
             //  writing out the blocked row information. This includes the DBCell references
-            if (record instanceof RowRecordsAggregate) {
-              pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);
-            } else if (record instanceof ValueRecordsAggregate) {
-              //Do nothing here. The records were serialized during the RowRecordAggregate block serialization
-            } else {
-              pos += record.serialize(pos, data );
-            }
+            pos += record.serialize(pos, data);
 
             // If the BOF record was just serialized then add the IndexRecord
             if (record instanceof BOFRecord) {
@@ -838,13 +649,7 @@ public final class Sheet implements Model {
      * @param indexRecordOffset also happens to be the end of the BOF record
      * @return the size of the serialized INDEX record
      */
-    private int serializeIndexRecord(final int bofRecordIndex, final int indexRecordOffset,
-            byte[] data) {
-        IndexRecord index = new IndexRecord();
-        index.setFirstRow(_rowsAggregate.getFirstRowNum());
-        index.setLastRowAdd1(_rowsAggregate.getLastRowNum() + 1);
-        // Calculate the size of the records from the end of the BOF
-        // and up to the RowRecordsAggregate...
+    private int serializeIndexRecord(int bofRecordIndex, int indexRecordOffset, byte[] data) {
 
         // 'initial sheet records' are between INDEX and first ROW record.
         int sizeOfInitialSheetRecords = 0;
@@ -862,32 +667,7 @@ public final class Sheet implements Model {
         if (_isUncalced) {
             sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize();
         }
-
-        // Add the references to the DBCells in the IndexRecord (one for each block)
-        // Note: The offsets are relative to the Workbook BOF. Assume that this is
-        // 0 for now.....
-
-        int blockCount = _rowsAggregate.getRowBlockCount();
-        // Calculate the size of this IndexRecord
-        int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
-
-        int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
-
-        for (int block = 0; block < blockCount; block++) {
-            // each row-block has a DBCELL record.
-            // The offset of each DBCELL record needs to be updated in the INDEX record
-
-            // account for row records in this row-block
-            currentOffset += _rowsAggregate.getRowBlockSize(block);
-            // account for cell value records after those
-            currentOffset += null == cells ? 0 : cells.getRowCellBlockSize(_rowsAggregate
-                    .getStartRowNumberForBlock(block), _rowsAggregate.getEndRowNumberForBlock(block));
-
-            // currentOffset is now the location of the DBCELL record for this row-block
-            index.addDbcell(currentOffset);
-            // Add space required to write the DBCELL record (whose reference was just added).
-            currentOffset += (8 + (_rowsAggregate.getRowCountForBlock(block) * 2));
-        }
+        IndexRecord index = _rowsAggregate.createIndexRecord(indexRecordOffset, sizeOfInitialSheetRecords);
         return index.serialize(indexRecordOffset, data);
     }
 
@@ -911,15 +691,10 @@ public final class Sheet implements Model {
      * @param row the row to add the cell value to
      * @param col the cell value record itself.
      */
-    public void addValueRecord(int row, CellValueRecordInterface col)
-    {
-        checkCells();
-        if(log.check(POILogger.DEBUG))
-        {
-          log.logFormatted(POILogger.DEBUG, "add value record  row,loc %,%", new int[]
-          {
-              row, loc
-          });
+    public void addValueRecord(int row, CellValueRecordInterface col) {
+
+        if(log.check(POILogger.DEBUG)) {
+          log.log(POILogger.DEBUG, "add value record  row" + row);
         }
         DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc());
 
@@ -931,7 +706,7 @@ public final class Sheet implements Model {
         {
             d.setFirstCol(col.getColumn());
         }
-        cells.insertCell(col);
+        _rowsAggregate.insertCell(col);
     }
 
     /**
@@ -943,13 +718,11 @@ public final class Sheet implements Model {
      * @param col - a record supporting the CellValueRecordInterface.
      * @see org.apache.poi.hssf.record.CellValueRecordInterface
      */
-    public void removeValueRecord(int row, CellValueRecordInterface col)
-    {
-        checkCells();
+    public void removeValueRecord(int row, CellValueRecordInterface col) {
+
         log.logFormatted(POILogger.DEBUG, "remove value record row,dimsloc %,%",
                          new int[]{row, dimsloc} );
-        loc = dimsloc;
-        cells.removeCell(col);
+        _rowsAggregate.removeCell(col);
     }
 
     /**
@@ -962,10 +735,8 @@ public final class Sheet implements Model {
      *                be added.
      */
 
-    public void replaceValueRecord(CellValueRecordInterface newval)
-    {
-        checkCells();
-        setLoc(dimsloc);
+    public void replaceValueRecord(CellValueRecordInterface newval) {
+
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "replaceValueRecord ");
         //The ValueRecordsAggregate use a tree map underneath.
@@ -973,8 +744,8 @@ public final class Sheet implements Model {
         //key and the value, if we dont do a remove, then
         //the previous instance of the key is retained, effectively using
         //double the memory
-        cells.removeCell(newval);
-        cells.insertCell(newval);
+        _rowsAggregate.removeCell(newval);
+        _rowsAggregate.insertCell(newval);
     }
 
     /**
@@ -1005,11 +776,12 @@ public final class Sheet implements Model {
         {
             d.setFirstRow(row.getRowNumber());
         }
-        //IndexRecord index = null;
-         //If the row exists remove it, so that any cells attached to the row are removed
-         RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber());
-         if (existingRow != null)
-           _rowsAggregate.removeRow(existingRow);
+
+        //If the row exists remove it, so that any cells attached to the row are removed
+        RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber());
+        if (existingRow != null) {
+            _rowsAggregate.removeRow(existingRow);
+        }
 
         _rowsAggregate.insertRow(row);
 
@@ -1024,12 +796,8 @@ public final class Sheet implements Model {
      *
      * @param row  the row record to remove
      */
-
-    public void removeRow(RowRecord row)
-    {
+    public void removeRow(RowRecord row) {
         checkRows();
-
-        setLoc(getDimsLoc());
         _rowsAggregate.removeRow(row);
     }
 
@@ -1047,20 +815,8 @@ public final class Sheet implements Model {
      * @return CellValueRecordInterface representing the next value record or NULL if there are no more
      * @see #setLoc(int)
      */
-
-    public CellValueRecordInterface getNextValueRecord()
-    {
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "getNextValue loc= " + loc);
-        if (valueRecIterator == null)
-        {
-            valueRecIterator = cells.getIterator();
-        }
-        if (!valueRecIterator.hasNext())
-        {
-            return null;
-        }
-        return ( CellValueRecordInterface ) valueRecIterator.next();
+    public CellValueRecordInterface[] getValueRecords() {
+        return _rowsAggregate.getValueRecords();
     }
 
     /**
@@ -1077,11 +833,7 @@ public final class Sheet implements Model {
      * @see #setLoc(int)
      *
      */
-
-    public RowRecord getNextRow()
-    {
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
+    public RowRecord getNextRow() {
         if (rowRecIterator == null)
         {
             rowRecIterator = _rowsAggregate.getIterator();
@@ -1110,8 +862,6 @@ public final class Sheet implements Model {
      *
      */
     public RowRecord getRow(int rownum) {
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
         return _rowsAggregate.getRow(rownum);
     }
 
@@ -1235,13 +985,13 @@ public final class Sheet implements Model {
         return retval;
     }
     private GutsRecord getGutsRecord() {
-       if (_gutsRecord == null) {
-               GutsRecord result = createGuts();
-               RecordOrderer.addNewSheetRecord(records, result);
-                       _gutsRecord = result;
-               }
+        if (_gutsRecord == null) {
+            GutsRecord result = createGuts();
+            RecordOrderer.addNewSheetRecord(records, result);
+            _gutsRecord = result;
+        }
 
-               return _gutsRecord;
+        return _gutsRecord;
     }
 
     /**
@@ -1266,70 +1016,6 @@ public final class Sheet implements Model {
         return retval;
     }
 
-    /**
-     * creates the Header Record and sets it to nothing/0 length
-     */
-    private static HeaderRecord createHeader() {
-        HeaderRecord retval = new HeaderRecord();
-
-        retval.setHeaderLength(( byte ) 0);
-        retval.setHeader(null);
-        return retval;
-    }
-
-    /**
-     * creates the Footer Record and sets it to nothing/0 length
-     */
-    private static FooterRecord createFooter() {
-        FooterRecord retval = new FooterRecord();
-
-        retval.setFooterLength(( byte ) 0);
-        retval.setFooter(null);
-        return retval;
-    }
-
-    /**
-     * creates the HCenter Record and sets it to false (don't horizontally center)
-     */
-    private static HCenterRecord createHCenter() {
-        HCenterRecord retval = new HCenterRecord();
-
-        retval.setHCenter(false);
-        return retval;
-    }
-
-    /**
-     * creates the VCenter Record and sets it to false (don't horizontally center)
-    */
-    private static VCenterRecord createVCenter() {
-        VCenterRecord retval = new VCenterRecord();
-
-        retval.setVCenter(false);
-        return retval;
-    }
-
-    /**
-     * creates the PrintSetup Record and sets it to defaults and marks it invalid
-     * @see org.apache.poi.hssf.record.PrintSetupRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a PrintSetupRecord
-     */
-    private static PrintSetupRecord createPrintSetup() {
-        PrintSetupRecord retval = new PrintSetupRecord();
-
-        retval.setPaperSize(( short ) 1);
-        retval.setScale(( short ) 100);
-        retval.setPageStart(( short ) 1);
-        retval.setFitWidth(( short ) 1);
-        retval.setFitHeight(( short ) 1);
-        retval.setOptions(( short ) 2);
-        retval.setHResolution(( short ) 300);
-        retval.setVResolution(( short ) 300);
-        retval.setHeaderMargin( 0.5);
-        retval.setFooterMargin( 0.5);
-        retval.setCopies(( short ) 0);
-        return retval;
-    }
 
     /**
      * creates the DefaultColWidth Record and sets it to 8
@@ -1418,7 +1104,7 @@ public final class Sheet implements Model {
 
         ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex);
         if (ci != null) {
-               return ci.getColumnWidth();
+            return ci.getColumnWidth();
         }
         //default column width is measured in characters
         //multiply
@@ -1443,18 +1129,18 @@ public final class Sheet implements Model {
         ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex);
         if (ci != null) {
             return ci.getXFIndex();
-           }
-           return 0xF;
-       }
-
-    /**
-        * set the width for a given column in 1/256th of a character width units
-        
-        * @param column -
-        *            the column number
-        * @param width
-        *            (in units of 1/256th of a character width)
-        */
+         }
+        return 0xF;
+    }
+
+    /**
+     * set the width for a given column in 1/256th of a character width units
+     * 
+     * @param column -
+     *            the column number
+     * @param width
+     *            (in units of 1/256th of a character width)
+     */
     public void setColumnWidth(short column, short width) {
         setColumn( column, new Short(width), null, null, null);
     }
@@ -1468,11 +1154,11 @@ public final class Sheet implements Model {
      * @return whether the column is hidden or not.
      */
     public boolean isColumnHidden(short columnIndex) {
-       ColumnInfoRecord cir = _columnInfos.findColumnInfo(columnIndex);
-       if (cir == null) {
-               return false;
-       }
-       return cir.getHidden();
+        ColumnInfoRecord cir = _columnInfos.findColumnInfo(columnIndex);
+        if (cir == null) {
+            return false;
+        }
+        return cir.getHidden();
     }
 
     /**
@@ -1659,12 +1345,8 @@ public final class Sheet implements Model {
     /**
      * in the event the record is a dimensions record, resets both the loc index and dimsloc index
      */
-
-    public void checkDimsLoc(Record rec, int recloc)
-    {
-        if (rec.getSid() == DimensionsRecord.sid)
-        {
-            loc     = recloc;
+    public void checkDimsLoc(Record rec, int recloc) {
+        if (rec.getSid() == DimensionsRecord.sid) {
             dimsloc = recloc;
         }
     }
@@ -1672,32 +1354,21 @@ public final class Sheet implements Model {
     /**
      * @return the serialized size of this sheet
      */
-    public int getSize()
-    {
+    public int getSize() {
         int retval = 0;
 
         for ( int k = 0; k < records.size(); k++) {
-               RecordBase record = (RecordBase) records.get(k);
+            RecordBase record = (RecordBase) records.get(k);
             if (record instanceof UncalcedRecord) {
                 // skip the UncalcedRecord if present, it's only encoded if the isUncalced flag is set
                 continue;
             }
             retval += record.getRecordSize();
         }
+        // add space for IndexRecord if needed
         if (_rowsAggregate != null) {
-            // Add space for the IndexRecord and DBCell records
-            final int nBlocks = _rowsAggregate.getRowBlockCount();
-            int nRows = 0;
-            if (cells != null) {
-                for (Iterator itr = _rowsAggregate.getIterator(); itr.hasNext();) {
-                    RowRecord row = (RowRecord)itr.next();
-                    if (cells.rowHasCells(row.getRowNumber())) {
-                        nRows++;
-                    }
-                }
-            }
-            retval += IndexRecord.getRecordSizeForBlockCount(nBlocks);
-            retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows);
+            // rowsAggregate knows how to make the index record
+            retval += IndexRecord.getRecordSizeForBlockCount(_rowsAggregate.getRowBlockCount());
         }
         // Add space for UncalcedRecord
         if (_isUncalced) {
@@ -1726,11 +1397,11 @@ public final class Sheet implements Model {
 
     public Record findFirstRecordBySid(short sid)
     {
-       int ix = findFirstRecordLocBySid(sid);
-       if (ix < 0) {
-               return null;
-       }
-       return (Record) records.get(ix);
+        int ix = findFirstRecordLocBySid(sid);
+        if (ix < 0) {
+            return null;
+        }
+        return (Record) records.get(ix);
     }
 
     /**
@@ -1765,9 +1436,9 @@ public final class Sheet implements Model {
     public int findFirstRecordLocBySid( short sid ) { // TODO - remove this method
         int max = records.size();
         for (int i=0; i< max; i++) {
-               Object rb = records.get(i);
+            Object rb = records.get(i);
             if (!(rb instanceof Record)) {
-               continue;
+                continue;
             }
             Record record = (Record) rb;
             if (record.getSid() == sid) {
@@ -1777,63 +1448,10 @@ public final class Sheet implements Model {
         return -1;
     }
 
-    /**
-     * Returns the HeaderRecord.
-     * @return HeaderRecord for the sheet.
-     */
-    public HeaderRecord getHeader ()
-    {
-    return header;
-    }
-
     public WindowTwoRecord getWindowTwo() {
         return windowTwo;
     }
-    /**
-     * Sets the HeaderRecord.
-     * @param newHeader The new HeaderRecord for the sheet.
-     */
-    public void setHeader (HeaderRecord newHeader)
-    {
-        header = newHeader;
-    }
-
-    /**
-     * Returns the FooterRecord.
-     * @return FooterRecord for the sheet.
-     */
-    public FooterRecord getFooter ()
-    {
-        return footer;
-    }
-
-    /**
-     * Sets the FooterRecord.
-     * @param newFooter The new FooterRecord for the sheet.
-     */
-    public void setFooter (FooterRecord newFooter)
-    {
-        footer = newFooter;
-    }
-
-    /**
-     * Returns the PrintSetupRecord.
-     * @return PrintSetupRecord for the sheet.
-     */
-    public PrintSetupRecord getPrintSetup ()
-    {
-        return printSetup;
-    }
-
-    /**
-     * Sets the PrintSetupRecord.
-     * @param newPrintSetup The new PrintSetupRecord for the sheet.
-     */
-    public void setPrintSetup (PrintSetupRecord newPrintSetup)
-    {
-        printSetup = newPrintSetup;
-    }
-
     /**
      * Returns the PrintGridlinesRecord.
      * @return PrintGridlinesRecord for the sheet.
@@ -1860,65 +1478,6 @@ public final class Sheet implements Model {
         windowTwo.setSelected(sel);
     }
 
-     /**
-      * Gets the size of the margin in inches.
-      * @param margin which margin to get
-      * @return the size of the margin
-      */
-    public double getMargin(short margin) {
-    if (getMargins()[margin] != null)
-        return margins[margin].getMargin();
-    else {
-        switch ( margin )
-        {
-        case LeftMargin:
-            return .75;
-        case RightMargin:
-            return .75;
-        case TopMargin:
-            return 1.0;
-        case BottomMargin:
-            return 1.0;
-        default :
-            throw new RuntimeException( "Unknown margin constant:  " + margin );
-        }
-    }
-    }
-
-     /**
-      * Sets the size of the margin in inches.
-      * @param margin which margin to get
-      * @param size the size of the margin
-      */
-    public void setMargin(short margin, double size) {
-    Margin m = getMargins()[margin];
-    if (m  == null) {
-        switch ( margin )
-        {
-        case LeftMargin:
-            m = new LeftMarginRecord();
-            records.add( getDimsLoc() + 1, m );
-            break;
-        case RightMargin:
-            m = new RightMarginRecord();
-            records.add( getDimsLoc() + 1, m );
-            break;
-        case TopMargin:
-            m = new TopMarginRecord();
-            records.add( getDimsLoc() + 1, m );
-            break;
-        case BottomMargin:
-            m = new BottomMarginRecord();
-            records.add( getDimsLoc() + 1, m );
-            break;
-        default :
-            throw new RuntimeException( "Unknown margin constant:  " + margin );
-        }
-        margins[margin] = m;
-    }
-    m.setMargin( size );
-    }
-
     public int getEofLoc()
     {
         return eofLoc;
@@ -2095,8 +1654,8 @@ public final class Sheet implements Model {
      */
     private static PasswordRecord createPassword() {
         if (log.check( POILogger.DEBUG )) {
-                       log.log(POILogger.DEBUG, "create password record with 00 password");
-               }
+            log.log(POILogger.DEBUG, "create password record with 00 password");
+        }
         PasswordRecord retval = new PasswordRecord();
 
         retval.setPassword((short)00);
@@ -2167,17 +1726,6 @@ public final class Sheet implements Model {
         this._isUncalced = uncalced;
     }
 
-    /**
-     * Returns the array of margins.  If not created, will create.
-     *
-     * @return the array of marings.
-     */
-    protected Margin[] getMargins() {
-        if (margins == null)
-            margins = new Margin[4];
-        return margins;
-    }
-
     /**
      * Finds the DrawingRecord for our sheet, and
      *  attaches it to the DrawingManager (which knows about
@@ -2246,153 +1794,16 @@ public final class Sheet implements Model {
         }
     }
 
-    /**
-     * Shifts all the page breaks in the range "count" number of rows/columns
-     * @param breaks The page record to be shifted
-     * @param start Starting "main" value to shift breaks
-     * @param stop Ending "main" value to shift breaks
-     * @param count number of units (rows/columns) to shift by
-     */
-    private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {
-
-        Iterator iterator = breaks.getBreaksIterator();
-        List shiftedBreak = new ArrayList();
-        while(iterator.hasNext())
-        {
-            PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
-            int breakLocation = breakItem.main;
-            boolean inStart = (breakLocation >= start);
-            boolean inEnd = (breakLocation <= stop);
-            if(inStart && inEnd)
-                shiftedBreak.add(breakItem);
-        }
-
-        iterator = shiftedBreak.iterator();
-        while (iterator.hasNext()) {
-            PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
-            breaks.removeBreak(breakItem.main);
-            breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo);
-        }
-    }
-
-    private PageBreakRecord getRowBreaksRecord() {
-       if (_rowBreaksRecord == null) {
-                       _rowBreaksRecord = new HorizontalPageBreakRecord();
-                       RecordOrderer.addNewSheetRecord(records, _rowBreaksRecord);
-                       dimsloc++;
-               }
-               return _rowBreaksRecord;
-    }
-    
-    private PageBreakRecord getColumnBreaksRecord() {
-       if (_columnBreaksRecord == null) {
-               _columnBreaksRecord = new VerticalPageBreakRecord();
-                       RecordOrderer.addNewSheetRecord(records, _columnBreaksRecord);
-                       dimsloc++;
-               }
-               return _columnBreaksRecord;
-    }
-    
     
-    /**
-     * Sets a page break at the indicated row
-     * @param row
-     */
-    public void setRowBreak(int row, short fromCol, short toCol) {
-        getRowBreaksRecord().addBreak((short)row, fromCol, toCol);
-    }
-
-    /**
-     * Removes a page break at the indicated row
-     * @param row
-     */
-    public void removeRowBreak(int row) {
-        if (getRowBreaks() == null)
-            throw new IllegalArgumentException("Sheet does not define any row breaks");
-        getRowBreaksRecord().removeBreak((short)row);
-    }
-
-    /**
-     * Queries if the specified row has a page break
-     * @param row
-     * @return true if the specified row has a page break
-     */
-    public boolean isRowBroken(int row) {
-        return getRowBreaksRecord().getBreak(row) != null;
-    }
-
-    /**
-     * Sets a page break at the indicated column
-     *
-     */
-    public void setColumnBreak(short column, short fromRow, short toRow) {
-        getColumnBreaksRecord().addBreak(column, fromRow, toRow);
-    }
-
-    /**
-     * Removes a page break at the indicated column
-     *
-     */
-    public void removeColumnBreak(short column) {
-       getColumnBreaksRecord().removeBreak(column);
-    }
-
-    /**
-     * Queries if the specified column has a page break
-     *
-     * @return <code>true</code> if the specified column has a page break
-     */
-    public boolean isColumnBroken(short column) {
-        return getColumnBreaksRecord().getBreak(column) != null;
-    }
-
-    /**
-     * Shifts the horizontal page breaks for the indicated count
-     * @param startingRow
-     * @param endingRow
-     * @param count
-     */
-    public void shiftRowBreaks(int startingRow, int endingRow, int count) {
-        shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
-    }
-
-    /**
-     * Shifts the vertical page breaks for the indicated count
-     * @param startingCol
-     * @param endingCol
-     * @param count
-     */
-    public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
-        shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
-    }
-
-    /**
-     * @return all the horizontal page breaks, never <code>null</code>
-     */
-    public int[] getRowBreaks() {
-        return getRowBreaksRecord().getBreaks();
-    }
-
-    /**
-     * @return the number of row page breaks
-     */
-    public int getNumRowBreaks(){
-        return getRowBreaksRecord().getNumBreaks();
-    }
-
-    /**
-     * @return all the column page breaks, never <code>null</code>
-     */
-    public int[] getColumnBreaks(){
-        return getColumnBreaksRecord().getBreaks();
+    public PageSettingsBlock getPageSettings() {
+        if (_psBlock == null) {
+            _psBlock = new PageSettingsBlock();
+            RecordOrderer.addNewSheetRecord(records, _psBlock);
+            dimsloc++;
+        }
+        return _psBlock;
     }
 
-    /**
-     * @return the number of column page breaks
-     */
-    public int getNumColumnBreaks(){
-        return getColumnBreaksRecord().getNumBreaks();
-    }
 
     public void setColumnGroupCollapsed( short columnNumber, boolean collapsed )
     {
@@ -2520,8 +1931,8 @@ public final class Sheet implements Model {
     }
     public DataValidityTable getOrCreateDataValidityTable() {
         if (_dataValidityTable == null) {
-               DataValidityTable result = new DataValidityTable();
-               RecordOrderer.addNewSheetRecord(records, result);
+            DataValidityTable result = new DataValidityTable();
+            RecordOrderer.addNewSheetRecord(records, result);
             _dataValidityTable = result;
         }
         return _dataValidityTable;
index 1da6b82c73c41e8f91764ad9740ade55b07d82d6..d14e689ed533bbd27bdf3cb52af0b9f224e89a3a 100644 (file)
@@ -35,6 +35,7 @@ public final class DBCellRecord extends Record {
 
     public DBCellRecord()
     {
+        field_2_cell_offsets = new short[0];
     }
 
     /**
@@ -185,4 +186,9 @@ public final class DBCellRecord extends Record {
     {
         return true;
     }
+    public Object clone() {
+        // TODO - make immutable.
+        // this should be safe because only the instantiating code mutates these objects
+        return this;
+    }
 }
index 874f304abdefa600913099c948840ecbdb806a3f..a8518c7b316ba00530d3aaa528a3bbf603f0830d 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
@@ -15,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
@@ -24,18 +22,15 @@ import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 
 /**
- * Title:        Print Setup Record<P>
- * Description:  Stores print setup options -- bogus for HSSF (and marked as such)<P>
- * REFERENCE:  PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * Title:        PAGESETUP (0x00A1)<p/>
+ * Description:  Stores print setup options -- bogus for HSSF (and marked as such)<p/>
+ * REFERENCE:  PG 385 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)
  * @version 2.0-pre
  */
-
-public class PrintSetupRecord
-    extends Record
-{
-    public final static short     sid = 0xa1;
+public class PrintSetupRecord extends Record {
+    public final static short     sid = 0x00A1;
     private short                 field_1_paper_size;
     private short                 field_2_scale;
     private short                 field_3_page_start;
index 46d4a1efebfc084116a66dd553d1a0ae0db38771..2ef87639840dd4dacec559743c6fcff37053b049 100644 (file)
@@ -22,15 +22,17 @@ import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.LittleEndian;
 
 /**
- * Title:        Row Record<P>
- * Description:  stores the row information for the sheet. <P>
+ * Title:        Row Record (0x0208)<P/>
+ * Description:  stores the row information for the sheet. <P/>
  * REFERENCE:  PG 379 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)
  * @version 2.0-pre
  */
 public final class RowRecord extends Record implements Comparable {
-       public final static short sid = 0x208;
+    public final static short sid = 0x0208;
+
+    public static final int ENCODED_SIZE = 20;
     
     private static final int OPTION_BITS_ALWAYS_SET = 0x0100;
     private static final int DEFAULT_HEIGHT_BIT = 0x8000;
@@ -407,23 +409,23 @@ public final class RowRecord extends Record implements Comparable {
 
     public int serialize(int offset, byte [] data)
     {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, ( short ) 16);
-        LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber());
-        LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol());
-        LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol());
-        LittleEndian.putShort(data, 10 + offset, getHeight());
-        LittleEndian.putShort(data, 12 + offset, getOptimize());
-        LittleEndian.putShort(data, 14 + offset, field_6_reserved);
-        LittleEndian.putShort(data, 16 + offset, getOptionFlags());
+        LittleEndian.putUShort(data, 0 + offset, sid);
+        LittleEndian.putUShort(data, 2 + offset, ENCODED_SIZE - 4);
+        LittleEndian.putUShort(data, 4 + offset, getRowNumber());
+        LittleEndian.putUShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol());
+        LittleEndian.putUShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol());
+        LittleEndian.putUShort(data, 10 + offset, getHeight());
+        LittleEndian.putUShort(data, 12 + offset, getOptimize());
+        LittleEndian.putUShort(data, 14 + offset, field_6_reserved);
+        LittleEndian.putUShort(data, 16 + offset, getOptionFlags());
 
-        LittleEndian.putShort(data, 18 + offset, getXFIndex());
-        return getRecordSize();
+        LittleEndian.putUShort(data, 18 + offset, getXFIndex());
+        return ENCODED_SIZE;
     }
 
     public int getRecordSize()
     {
-        return 20;
+        return ENCODED_SIZE;
     }
 
     public short getSid()
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
new file mode 100644 (file)
index 0000000..cc8be41
--- /dev/null
@@ -0,0 +1,525 @@
+/* ====================================================================
+   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.aggregates;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.model.Sheet;
+import org.apache.poi.hssf.record.BottomMarginRecord;
+import org.apache.poi.hssf.record.FooterRecord;
+import org.apache.poi.hssf.record.HCenterRecord;
+import org.apache.poi.hssf.record.HeaderRecord;
+import org.apache.poi.hssf.record.HorizontalPageBreakRecord;
+import org.apache.poi.hssf.record.LeftMarginRecord;
+import org.apache.poi.hssf.record.Margin;
+import org.apache.poi.hssf.record.PageBreakRecord;
+import org.apache.poi.hssf.record.PrintSetupRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RightMarginRecord;
+import org.apache.poi.hssf.record.TopMarginRecord;
+import org.apache.poi.hssf.record.VCenterRecord;
+import org.apache.poi.hssf.record.VerticalPageBreakRecord;
+
+/**
+ * Groups the page settings records for a worksheet.<p/>
+ * 
+ * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block'
+ * 
+ * @author Josh Micich
+ */
+public final class PageSettingsBlock extends RecordAggregate {
+       // Every one of these component records is optional 
+       // (The whole PageSettingsBlock may not be present) 
+       private PageBreakRecord _rowBreaksRecord;
+       private PageBreakRecord _columnBreaksRecord;
+       private HeaderRecord header;
+       private FooterRecord footer;
+       private HCenterRecord _hCenter;
+       private VCenterRecord _vCenter;
+       private LeftMarginRecord _leftMargin;
+       private RightMarginRecord _rightMargin;
+       private TopMarginRecord _topMargin;
+       private BottomMarginRecord _bottomMargin;
+       private Record _pls;
+       private PrintSetupRecord printSetup;
+       private Record _bitmap;
+
+       public PageSettingsBlock(RecordStream rs) {
+               while(true) {
+                       if (!readARecord(rs)) {
+                               break;
+                       }
+               }
+       }
+
+       /**
+        * Creates a PageSettingsBlock with default settings
+        */
+       public PageSettingsBlock() {
+               _rowBreaksRecord = new HorizontalPageBreakRecord();
+               _columnBreaksRecord = new VerticalPageBreakRecord();
+               header = createHeader();
+               footer = createFooter();
+               _hCenter = createHCenter();
+               _vCenter = createVCenter();
+               printSetup = createPrintSetup();
+       }
+
+       /**
+        * @return <code>true</code> if the specified Record sid is one belonging to the 
+        * 'Page Settings Block'.
+        */
+       public static boolean isComponentRecord(int sid) {
+               switch (sid) {
+                       case HorizontalPageBreakRecord.sid:
+                       case VerticalPageBreakRecord.sid:
+                       case HeaderRecord.sid:
+                       case FooterRecord.sid:
+                       case HCenterRecord.sid:
+                       case VCenterRecord.sid:
+                       case LeftMarginRecord.sid:
+                       case RightMarginRecord.sid:
+                       case TopMarginRecord.sid:
+                       case BottomMarginRecord.sid:
+                       case 0x004D: // PLS
+                       case PrintSetupRecord.sid:
+                       case 0x00E9: // BITMAP
+                               return true;
+               }
+               return false;
+       }
+
+       private boolean readARecord(RecordStream rs) {
+               switch (rs.peekNextSid()) {
+                       case HorizontalPageBreakRecord.sid:
+                               _rowBreaksRecord = (PageBreakRecord) rs.getNext();
+                               break;
+                       case VerticalPageBreakRecord.sid:
+                               _columnBreaksRecord = (PageBreakRecord) rs.getNext();
+                               break;
+                       case HeaderRecord.sid:
+                               header = (HeaderRecord) rs.getNext();
+                               break;
+                       case FooterRecord.sid:
+                               footer = (FooterRecord) rs.getNext();
+                               break;
+                       case HCenterRecord.sid:
+                               _hCenter = (HCenterRecord) rs.getNext();
+                               break;
+                       case VCenterRecord.sid:
+                               _vCenter = (VCenterRecord) rs.getNext();
+                               break;
+                       case LeftMarginRecord.sid:
+                               _leftMargin = (LeftMarginRecord) rs.getNext();
+                               break;
+                       case RightMarginRecord.sid:
+                               _rightMargin = (RightMarginRecord) rs.getNext();
+                               break;
+                       case TopMarginRecord.sid:
+                               _topMargin = (TopMarginRecord) rs.getNext();
+                               break;
+                       case BottomMarginRecord.sid:
+                               _bottomMargin = (BottomMarginRecord) rs.getNext();
+                               break;
+                       case 0x004D: // PLS
+                               _pls = rs.getNext();
+                               break;
+                       case PrintSetupRecord.sid:
+                               printSetup = (PrintSetupRecord)rs.getNext();
+                               break;
+                       case 0x00E9: // BITMAP
+                               _bitmap = rs.getNext();
+                               break;
+                       default:
+                               // all other record types are not part of the PageSettingsBlock
+                               return false;
+               }
+               return true;
+       }
+
+       private PageBreakRecord getRowBreaksRecord() {
+               if (_rowBreaksRecord == null) {
+                       _rowBreaksRecord = new HorizontalPageBreakRecord();
+               }
+               return _rowBreaksRecord;
+       }
+
+       private PageBreakRecord getColumnBreaksRecord() {
+               if (_columnBreaksRecord == null) {
+                       _columnBreaksRecord = new VerticalPageBreakRecord();
+               }
+               return _columnBreaksRecord;
+       }
+
+
+       /**
+        * Sets a page break at the indicated column
+        *
+        */
+       public void setColumnBreak(short column, short fromRow, short toRow) {
+               getColumnBreaksRecord().addBreak(column, fromRow, toRow);
+       }
+
+       /**
+        * Removes a page break at the indicated column
+        *
+        */
+       public void removeColumnBreak(int column) {
+               getColumnBreaksRecord().removeBreak(column);
+       }
+
+
+
+
+       public void visitContainedRecords(RecordVisitor rv) {
+               visitIfPresent(_rowBreaksRecord, rv);
+               visitIfPresent(_columnBreaksRecord, rv);
+               visitIfPresent(header, rv);
+               visitIfPresent(footer, rv);
+               visitIfPresent(_hCenter, rv);
+               visitIfPresent(_vCenter, rv);
+               visitIfPresent(_leftMargin, rv);
+               visitIfPresent(_rightMargin, rv);
+               visitIfPresent(_topMargin, rv);
+               visitIfPresent(_bottomMargin, rv);
+               visitIfPresent(_pls, rv);
+               visitIfPresent(printSetup, rv);
+               visitIfPresent(_bitmap, rv);
+       }
+       private static void visitIfPresent(Record r, RecordVisitor rv) {
+               if (r != null) {
+                       rv.visitRecord(r);
+               }
+       }
+
+       /**
+        * creates the Header Record and sets it to nothing/0 length
+        */
+       private static HeaderRecord createHeader() {
+               HeaderRecord retval = new HeaderRecord();
+
+               retval.setHeaderLength(( byte ) 0);
+               retval.setHeader(null);
+               return retval;
+       }
+
+       /**
+        * creates the Footer Record and sets it to nothing/0 length
+        */
+       private static FooterRecord createFooter() {
+               FooterRecord retval = new FooterRecord();
+
+               retval.setFooterLength(( byte ) 0);
+               retval.setFooter(null);
+               return retval;
+       }
+
+       /**
+        * creates the HCenter Record and sets it to false (don't horizontally center)
+        */
+       private static HCenterRecord createHCenter() {
+               HCenterRecord retval = new HCenterRecord();
+
+               retval.setHCenter(false);
+               return retval;
+       }
+
+       /**
+        * creates the VCenter Record and sets it to false (don't horizontally center)
+       */
+       private static VCenterRecord createVCenter() {
+               VCenterRecord retval = new VCenterRecord();
+
+               retval.setVCenter(false);
+               return retval;
+       }
+
+       /**
+        * creates the PrintSetup Record and sets it to defaults and marks it invalid
+        * @see org.apache.poi.hssf.record.PrintSetupRecord
+        * @see org.apache.poi.hssf.record.Record
+        * @return record containing a PrintSetupRecord
+        */
+       private static PrintSetupRecord createPrintSetup() {
+               PrintSetupRecord retval = new PrintSetupRecord();
+
+               retval.setPaperSize(( short ) 1);
+               retval.setScale(( short ) 100);
+               retval.setPageStart(( short ) 1);
+               retval.setFitWidth(( short ) 1);
+               retval.setFitHeight(( short ) 1);
+               retval.setOptions(( short ) 2);
+               retval.setHResolution(( short ) 300);
+               retval.setVResolution(( short ) 300);
+               retval.setHeaderMargin( 0.5);
+               retval.setFooterMargin( 0.5);
+               retval.setCopies(( short ) 0);
+               return retval;
+       }
+
+
+       /**
+        * Returns the HeaderRecord.
+        * @return HeaderRecord for the sheet.
+        */
+       public HeaderRecord getHeader ()
+       {
+       return header;
+       }
+
+       /**
+        * Sets the HeaderRecord.
+        * @param newHeader The new HeaderRecord for the sheet.
+        */
+       public void setHeader (HeaderRecord newHeader)
+       {
+               header = newHeader;
+       }
+
+       /**
+        * Returns the FooterRecord.
+        * @return FooterRecord for the sheet.
+        */
+       public FooterRecord getFooter ()
+       {
+               return footer;
+       }
+
+       /**
+        * Sets the FooterRecord.
+        * @param newFooter The new FooterRecord for the sheet.
+        */
+       public void setFooter (FooterRecord newFooter)
+       {
+               footer = newFooter;
+       }
+
+       /**
+        * Returns the PrintSetupRecord.
+        * @return PrintSetupRecord for the sheet.
+        */
+       public PrintSetupRecord getPrintSetup ()
+       {
+               return printSetup;
+       }
+
+       /**
+        * Sets the PrintSetupRecord.
+        * @param newPrintSetup The new PrintSetupRecord for the sheet.
+        */
+       public void setPrintSetup (PrintSetupRecord newPrintSetup)
+       {
+               printSetup = newPrintSetup;
+       }
+
+
+       private Margin getMarginRec(int marginIndex) {
+               switch (marginIndex) {
+                       case Sheet.LeftMargin:   return _leftMargin;
+                       case Sheet.RightMargin:  return _rightMargin;
+                       case Sheet.TopMargin:    return _topMargin;
+                       case Sheet.BottomMargin: return _bottomMargin;
+               }
+               throw new RuntimeException( "Unknown margin constant:  " + marginIndex );
+       }
+
+
+       /**
+        * Gets the size of the margin in inches.
+        * @param margin which margin to get
+        * @return the size of the margin
+        */
+   public double getMargin(short margin) {
+          Margin m = getMarginRec(margin);
+          if (m != null) {
+               return m.getMargin();
+       } else {
+          switch ( margin )
+          {
+          case Sheet.LeftMargin:
+                  return .75;
+          case Sheet.RightMargin:
+                  return .75;
+          case Sheet.TopMargin:
+                  return 1.0;
+          case Sheet.BottomMargin:
+                  return 1.0;
+          }
+               throw new RuntimeException( "Unknown margin constant:  " + margin );
+   }
+   }
+
+       /**
+        * Sets the size of the margin in inches.
+        * @param margin which margin to get
+        * @param size the size of the margin
+        */
+   public void setMargin(short margin, double size) {
+   Margin m = getMarginRec(margin);
+   if (m  == null) {
+          switch ( margin )
+          {
+          case Sheet.LeftMargin:
+                  _leftMargin = new LeftMarginRecord();
+                  m = _leftMargin;
+                  break;
+          case Sheet.RightMargin:
+                  _rightMargin = new RightMarginRecord();
+                  m = _rightMargin;
+                  break;
+          case Sheet.TopMargin:
+                  _topMargin = new TopMarginRecord();
+                  m = _topMargin;
+                  break;
+          case Sheet.BottomMargin:
+                  _bottomMargin = new BottomMarginRecord();
+                  m = _bottomMargin;
+                  break;
+          default :
+                  throw new RuntimeException( "Unknown margin constant:  " + margin );
+          }
+   }
+   m.setMargin( size );
+   }
+
+       /**
+        * Shifts all the page breaks in the range "count" number of rows/columns
+        * @param breaks The page record to be shifted
+        * @param start Starting "main" value to shift breaks
+        * @param stop Ending "main" value to shift breaks
+        * @param count number of units (rows/columns) to shift by
+        */
+       private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {
+
+               Iterator iterator = breaks.getBreaksIterator();
+               List shiftedBreak = new ArrayList();
+               while(iterator.hasNext())
+               {
+                       PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
+                       int breakLocation = breakItem.main;
+                       boolean inStart = (breakLocation >= start);
+                       boolean inEnd = (breakLocation <= stop);
+                       if(inStart && inEnd)
+                               shiftedBreak.add(breakItem);
+               }
+
+               iterator = shiftedBreak.iterator();
+               while (iterator.hasNext()) {
+                       PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
+                       breaks.removeBreak(breakItem.main);
+                       breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo);
+               }
+       }
+
+
+       /**
+        * Sets a page break at the indicated row
+        * @param row
+        */
+       public void setRowBreak(int row, short fromCol, short toCol) {
+               getRowBreaksRecord().addBreak((short)row, fromCol, toCol);
+       }
+
+       /**
+        * Removes a page break at the indicated row
+        * @param row
+        */
+       public void removeRowBreak(int row) {
+               if (getRowBreaksRecord().getBreaks().length < 1)
+                       throw new IllegalArgumentException("Sheet does not define any row breaks");
+               getRowBreaksRecord().removeBreak((short)row);
+       }
+
+       /**
+        * Queries if the specified row has a page break
+        * @param row
+        * @return true if the specified row has a page break
+        */
+       public boolean isRowBroken(int row) {
+               return getRowBreaksRecord().getBreak(row) != null;
+       }
+
+
+       /**
+        * Queries if the specified column has a page break
+        *
+        * @return <code>true</code> if the specified column has a page break
+        */
+       public boolean isColumnBroken(int column) {
+               return getColumnBreaksRecord().getBreak(column) != null;
+       }
+
+       /**
+        * Shifts the horizontal page breaks for the indicated count
+        * @param startingRow
+        * @param endingRow
+        * @param count
+        */
+       public void shiftRowBreaks(int startingRow, int endingRow, int count) {
+               shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
+       }
+
+       /**
+        * Shifts the vertical page breaks for the indicated count
+        * @param startingCol
+        * @param endingCol
+        * @param count
+        */
+       public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
+               shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
+       }
+
+       /**
+        * @return all the horizontal page breaks, never <code>null</code>
+        */
+       public int[] getRowBreaks() {
+               return getRowBreaksRecord().getBreaks();
+       }
+
+       /**
+        * @return the number of row page breaks
+        */
+       public int getNumRowBreaks(){
+               return getRowBreaksRecord().getNumBreaks();
+       }
+
+       /**
+        * @return all the column page breaks, never <code>null</code>
+        */
+       public int[] getColumnBreaks(){
+               return getColumnBreaksRecord().getBreaks();
+       }
+
+       /**
+        * @return the number of column page breaks
+        */
+       public int getNumColumnBreaks(){
+               return getColumnBreaksRecord().getNumBreaks();
+       }
+
+       public VCenterRecord getVCenter() {
+               return _vCenter;
+       }
+
+       public HCenterRecord getHCenter() {
+               return _hCenter;
+       }
+}
index ce0bf894527205cb4683b40763de5851a05ff7d1..f9cbcd77700ad3562a0b599f899e4f3acb7c0d5f 100644 (file)
@@ -54,6 +54,10 @@ public abstract class RecordAggregate extends RecordBase {
        }\r
        \r
        public interface RecordVisitor {\r
+               /**\r
+                * Implementors may call non-mutating methods on Record r.\r
+                * @param r must not be <code>null</code>\r
+                */\r
                void visitRecord(Record r);\r
        }\r
        \r
index 65af632d3fbea30a8e1df7f96fa87e54662d214a..c9a302b614b3a851a97915d95e8c13ce12dcfaf2 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
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.aggregates;
 
-import org.apache.poi.hssf.record.DBCellRecord;
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.record.RowRecord;
-
-
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.DBCellRecord;
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RowRecord;
+
 /**
  *
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public final class RowRecordsAggregate extends Record {
-    private int     firstrow = -1;
-    private int     lastrow  = -1;
-    private Map records  = null; // TODO - use a proper key in this map
-    private int     size     = 0;
+public final class RowRecordsAggregate extends RecordAggregate {
+    private int _firstrow = -1;
+    private int _lastrow  = -1;
+    private final Map _rowRecords;
+    private final ValueRecordsAggregate _valuesAgg;
 
     /** Creates a new instance of ValueRecordsAggregate */
 
-    public RowRecordsAggregate()
-    {
-        records = new TreeMap();  
+    public RowRecordsAggregate() {
+        this(new TreeMap(), new ValueRecordsAggregate());
+    }
+    private RowRecordsAggregate(TreeMap rowRecords, ValueRecordsAggregate valuesAgg) {
+        _rowRecords = rowRecords;
+        _valuesAgg = valuesAgg;
     }
 
-    public void insertRow(RowRecord row)
-    {
-        size += row.getRecordSize();
-
+    public void insertRow(RowRecord row) {
         // Integer integer = new Integer(row.getRowNumber());
-        records.put(row, row);
-        if ((row.getRowNumber() < firstrow) || (firstrow == -1))
+        _rowRecords.put(new Integer(row.getRowNumber()), row);
+        if ((row.getRowNumber() < _firstrow) || (_firstrow == -1))
         {
-            firstrow = row.getRowNumber();
+            _firstrow = row.getRowNumber();
         }
-        if ((row.getRowNumber() > lastrow) || (lastrow == -1))
+        if ((row.getRowNumber() > _lastrow) || (_lastrow == -1))
         {
-            lastrow = row.getRowNumber();
+            _lastrow = row.getRowNumber();
         }
     }
 
-    public void removeRow(RowRecord row)
-    {
-        size -= row.getRecordSize();
-
-        // Integer integer = new Integer(row.getRowNumber());
-        records.remove(row);
+    public void removeRow(RowRecord row) {
+        int rowIndex = row.getRowNumber();
+        _valuesAgg.removeAllCellsValuesForRow(rowIndex);
+        Integer key = new Integer(rowIndex);
+        RowRecord rr = (RowRecord) _rowRecords.remove(key);
+        if (rr == null) {
+            throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
+        }
+        if (row != rr) {
+            _rowRecords.put(key, rr);
+            throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
+        }
     }
 
-    public RowRecord getRow(int rownum) {
-        // Row must be between 0 and 65535
-        if(rownum < 0 || rownum > 65535) {
+    public RowRecord getRow(int rowIndex) {
+        if (rowIndex < 0 || rowIndex > 65535) {
             throw new IllegalArgumentException("The row number must be between 0 and 65535");
         }
-
-        RowRecord row = new RowRecord(rownum);
-        return ( RowRecord ) records.get(row);
+        return (RowRecord) _rowRecords.get(new Integer(rowIndex));
     }
 
     public int getPhysicalNumberOfRows()
     {
-        return records.size();
+        return _rowRecords.size();
     }
 
     public int getFirstRowNum()
     {
-        return firstrow;
+        return _firstrow;
     }
 
     public int getLastRowNum()
     {
-        return lastrow;
+        return _lastrow;
     }
     
     /** Returns the number of row blocks.
@@ -102,184 +104,134 @@ public final class RowRecordsAggregate extends Record {
      * after them
      */
     public int getRowBlockCount() {
-      int size = records.size()/DBCellRecord.BLOCK_SIZE;
-      if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0)
+      int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
+      if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
           size++;
       return size;
     }
 
-    public int getRowBlockSize(int block) {
-      return 20 * getRowCountForBlock(block);
+    private int getRowBlockSize(int block) {
+      return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
     }
 
     /** Returns the number of physical rows within a block*/
     public int getRowCountForBlock(int block) {
       int startIndex = block * DBCellRecord.BLOCK_SIZE;
       int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
-      if (endIndex >= records.size())
-        endIndex = records.size()-1;
+      if (endIndex >= _rowRecords.size())
+        endIndex = _rowRecords.size()-1;
 
       return endIndex-startIndex+1;
     }
 
     /** Returns the physical row number of the first row in a block*/
-    public int getStartRowNumberForBlock(int block) {
+    private int getStartRowNumberForBlock(int block) {
       //Given that we basically iterate through the rows in order,
-      //For a performance improvement, it would be better to return an instance of
+      // TODO - For a performance improvement, it would be better to return an instance of
       //an iterator and use that instance throughout, rather than recreating one and
       //having to move it to the right position.
       int startIndex = block * DBCellRecord.BLOCK_SIZE;
-      Iterator rowIter = records.values().iterator();
+      Iterator rowIter = _rowRecords.values().iterator();
       RowRecord row = null;
       //Position the iterator at the start of the block
       for (int i=0; i<=startIndex;i++) {
         row = (RowRecord)rowIter.next();
       }
+      if (row == null) {
+          throw new RuntimeException("Did not find start row for block " + block);
+      }
 
       return row.getRowNumber();
     }
 
     /** Returns the physical row number of the end row in a block*/
-    public int getEndRowNumberForBlock(int block) {
+    private int getEndRowNumberForBlock(int block) {
       int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
-      if (endIndex >= records.size())
-        endIndex = records.size()-1;
+      if (endIndex >= _rowRecords.size())
+        endIndex = _rowRecords.size()-1;
 
-      Iterator rowIter = records.values().iterator();
+      Iterator rowIter = _rowRecords.values().iterator();
       RowRecord row = null;
       for (int i=0; i<=endIndex;i++) {
         row = (RowRecord)rowIter.next();
       }
+      if (row == null) {
+          throw new RuntimeException("Did not find start row for block " + block);
+      }
       return row.getRowNumber();
     }
-
-
-    /** Serializes a block of the rows */
-    private int serializeRowBlock(final int block, final int offset, byte[] data) {
-      final int startIndex = block*DBCellRecord.BLOCK_SIZE;
-      final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
-
-      Iterator rowIterator = records.values().iterator();
-      int pos = offset;
-
-      //Given that we basically iterate through the rows in order,
-      //For a performance improvement, it would be better to return an instance of
-      //an iterator and use that instance throughout, rather than recreating one and
-      //having to move it to the right position.
-      int i=0;
-      for (;i<startIndex;i++)
-        rowIterator.next();
-      while(rowIterator.hasNext() && (i++ < endIndex)) {
-        RowRecord row = (RowRecord)rowIterator.next();
-        pos += row.serialize(pos, data);
+    
+    private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) {
+        final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE;
+        final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
+
+        Iterator rowIterator = _rowRecords.values().iterator();
+
+        //Given that we basically iterate through the rows in order,
+        //For a performance improvement, it would be better to return an instance of
+        //an iterator and use that instance throughout, rather than recreating one and
+        //having to move it to the right position.
+        int i=0;
+        for (;i<startIndex;i++)
+          rowIterator.next();
+        int result = 0;
+        while(rowIterator.hasNext() && (i++ < endIndex)) {
+          Record rec = (Record)rowIterator.next();
+          result += rec.getRecordSize();
+          rv.visitRecord(rec);
+        }
+        return result;
       }
-      return pos - offset;
-    }
-
-    public int serialize(int offset, byte [] data) {
-      throw new RuntimeException("The serialize method that passes in cells should be used");
-    }
     
-
-    /**
-     * called by the class that is responsible for writing this sucker.
-     * Subclasses should implement this so that their data is passed back in a
-     * byte array.
-     *
-     * @param offset    offset to begin writing at
-     * @param data      byte array containing instance data
-     * @return number of bytes written
-     */
-
-    public int serialize(int offset, byte [] data, ValueRecordsAggregate cells)
-    {
-        int pos = offset;
-
+    public void visitContainedRecords(RecordVisitor rv) {
+        ValueRecordsAggregate cells = _valuesAgg;
+       
         //DBCells are serialized before row records.
         final int blockCount = getRowBlockCount();
-        for (int block=0;block<blockCount;block++) {
-          //Serialize a block of rows.
-          //Hold onto the position of the first row in the block
-          final int rowStartPos = pos;
-          //Hold onto the size of this block that was serialized
-          final int rowBlockSize = serializeRowBlock(block, pos, data);
-          pos += rowBlockSize;
-          //Serialize a block of cells for those rows
-          final int startRowNumber = getStartRowNumberForBlock(block);
-          final int endRowNumber = getEndRowNumberForBlock(block);
-          DBCellRecord cellRecord = new DBCellRecord();
-          //Note: Cell references start from the second row...
-          int cellRefOffset = (rowBlockSize-20);
-          for (int row=startRowNumber;row<=endRowNumber;row++) {
-            if (null != cells && cells.rowHasCells(row)) {
-              final int rowCellSize = cells.serializeCellRow(row, pos, data);
-              pos += rowCellSize;
-              //Add the offset to the first cell for the row into the DBCellRecord.
-              cellRecord.addCellOffset((short)cellRefOffset);
-              cellRefOffset = rowCellSize;
+        for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
+            // Serialize a block of rows.
+            // Hold onto the position of the first row in the block
+            int pos=0;
+            // Hold onto the size of this block that was serialized
+            final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv);
+            pos += rowBlockSize;
+            // Serialize a block of cells for those rows
+            final int startRowNumber = getStartRowNumberForBlock(blockIndex);
+            final int endRowNumber = getEndRowNumberForBlock(blockIndex);
+            DBCellRecord cellRecord = new DBCellRecord();
+            // Note: Cell references start from the second row...
+            int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE);
+            for (int row = startRowNumber; row <= endRowNumber; row++) {
+                if (cells.rowHasCells(row)) {
+                    final int rowCellSize = cells.visitCellsForRow(row, rv);
+                    pos += rowCellSize;
+                    // Add the offset to the first cell for the row into the
+                    // DBCellRecord.
+                    cellRecord.addCellOffset((short) cellRefOffset);
+                    cellRefOffset = rowCellSize;
+                }
             }
-          }
-          //Calculate Offset from the start of a DBCellRecord to the first Row
-          cellRecord.setRowOffset(pos - rowStartPos);
-          pos += cellRecord.serialize(pos, data);
-
+            // Calculate Offset from the start of a DBCellRecord to the first Row
+            cellRecord.setRowOffset(pos);
+            rv.visitRecord(cellRecord);
         }
-        return pos - offset;
-    }
-
-    /**
-     * You never fill an aggregate
-     */
-    protected void fillFields(RecordInputStream in)
-    {
-    }
-
-    /**
-     * called by constructor, should throw runtime exception in the event of a
-     * record passed with a differing ID.
-     *
-     * @param id alleged id for this record
-     */
-
-    protected void validateSid(short id)
-    {
     }
 
-    /**
-     * return the non static version of the id for this record.
-     */
-
-    public short getSid()
-    {
-        return -1000;
-    }
-
-    public int getRecordSize()
-    {
-        return size;
-    }
-
-    public Iterator getIterator()
-    {
-        return records.values().iterator();
+    public Iterator getIterator() {
+        return _rowRecords.values().iterator();
     }
     
-    /**
-     * Performs a deep clone of the record
-     */
-    public Object clone()
-    {
-        RowRecordsAggregate rec = new RowRecordsAggregate();
-        for ( Iterator rowIter = getIterator(); rowIter.hasNext(); )
-        {
-            //return the cloned Row Record & insert
-            RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone();
-            rec.insertRow( row );
+    
+    public Iterator getAllRecordsIterator() {
+        List result = new ArrayList(_rowRecords.size() * 2);
+        result.addAll(_rowRecords.values());
+        Iterator vi = _valuesAgg.getIterator();
+        while (vi.hasNext()) {
+            result.add(vi.next());
         }
-        return rec;
+        return result.iterator();
     }
 
-
     public int findStartOfRowOutlineGroup(int row)
     {
         // Find the start of the group.
@@ -449,5 +401,52 @@ public final class RowRecordsAggregate extends Record {
         }
     }
 
+    public CellValueRecordInterface[] getValueRecords() {
+        return _valuesAgg.getValueRecords();
+    }
+
+    public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) {
+        IndexRecord result = new IndexRecord();
+        result.setFirstRow(_firstrow);
+        result.setLastRowAdd1(_lastrow + 1);
+        // Calculate the size of the records from the end of the BOF
+        // and up to the RowRecordsAggregate...
+
+        // Add the references to the DBCells in the IndexRecord (one for each block)
+        // Note: The offsets are relative to the Workbook BOF. Assume that this is
+        // 0 for now.....
+
+        int blockCount = getRowBlockCount();
+        // Calculate the size of this IndexRecord
+        int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
+
+        int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
+
+        for (int block = 0; block < blockCount; block++) {
+            // each row-block has a DBCELL record.
+            // The offset of each DBCELL record needs to be updated in the INDEX record
+
+            // account for row records in this row-block
+            currentOffset += getRowBlockSize(block);
+            // account for cell value records after those
+            currentOffset += _valuesAgg.getRowCellBlockSize(
+                    getStartRowNumberForBlock(block), getEndRowNumberForBlock(block));
+
+            // currentOffset is now the location of the DBCELL record for this row-block
+            result.addDbcell(currentOffset);
+            // Add space required to write the DBCELL record (whose reference was just added).
+            currentOffset += (8 + (getRowCountForBlock(block) * 2));
+        }
+        return result;
+    }
+    public void constructCellValues(int offset, List records) {
+        _valuesAgg.construct(offset, records);
+    }
+    public void insertCell(CellValueRecordInterface cvRec) {
+        _valuesAgg.insertCell(cvRec);
+    }
+    public void removeCell(CellValueRecordInterface cvRec) {
+        _valuesAgg.removeCell(cvRec);
+    }
 }
 
index fb4bfd59a4bb2f87fe333487347845d77ae44dc2..8d5764187f7c44816cfdeef7bed6e7ef50ac2275 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
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.aggregates;
 
-import org.apache.poi.hssf.record.*;
-
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.StringRecord;
+import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
 
 /**
  *
@@ -33,20 +38,16 @@ import java.util.List;
  * @author  Glen Stampoultzis (glens at apache.org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public final class ValueRecordsAggregate
-    extends Record
-{
-    public final static short sid       = -1001; // 1000 clashes with RowRecordsAggregate
-    int                       firstcell = -1;
-    int                       lastcell  = -1;
-  CellValueRecordInterface[][] records;
+public final class ValueRecordsAggregate {
+    private int                       firstcell = -1;
+    private int                       lastcell  = -1;
+    private CellValueRecordInterface[][] records;
 
     /** Creates a new instance of ValueRecordsAggregate */
 
     public ValueRecordsAggregate()
     {
-    records = new CellValueRecordInterface[30][]; // We start with 30 Rows.
+        records = new CellValueRecordInterface[30][]; // We start with 30 Rows.
     }
 
   public void insertCell(CellValueRecordInterface cell) {
@@ -85,18 +86,33 @@ public final class ValueRecordsAggregate
     }
   }
 
-    public void removeCell(CellValueRecordInterface cell)
-    {
-       if (cell != null) {
-          short column = cell.getColumn();
-          int row = cell.getRow();
-          if(row>=records.length) return;
-          CellValueRecordInterface[] rowCells=records[row];
-          if(rowCells==null) return;
-          if(column>=rowCells.length) return;
-          rowCells[column]=null;
-       }
+    public void removeCell(CellValueRecordInterface cell) {
+        if (cell == null) {
+            throw new IllegalArgumentException("cell must not be null");
+        }
+        int row = cell.getRow();
+        if (row >= records.length) {
+            throw new RuntimeException("cell row is out of range");
+        }
+        CellValueRecordInterface[] rowCells = records[row];
+        if (rowCells == null) {
+            throw new RuntimeException("cell row is already empty");
+        }
+        short column = cell.getColumn();
+        if (column >= rowCells.length) {
+            throw new RuntimeException("cell column is out of range");
+        }
+        rowCells[column] = null;
+    }
+
+    public void removeAllCellsValuesForRow(int rowIndex) {
+        if (rowIndex >= records.length) {
+            throw new IllegalArgumentException("Specified rowIndex " + rowIndex 
+                    + " is outside the allowable range (0.." +records.length + ")");
+        }
+        records[rowIndex] = null;
     }
+    
 
     public int getPhysicalNumberOfCells()
     {
@@ -133,7 +149,7 @@ public final class ValueRecordsAggregate
         {
             Record rec = ( Record ) records.get(k);
             if (rec instanceof SharedFormulaRecord) {
-               sharedFormulas.add(rec);
+                sharedFormulas.add(rec);
             }
             if(rec instanceof EOFRecord) {
                 // End of current sheet. Ignore all subsequent shared formula records (Bugzilla 44449)
@@ -150,30 +166,30 @@ public final class ValueRecordsAggregate
             {
                 break;
             } else if (rec instanceof SharedFormulaRecord) {
-               // Already handled, not to worry
+                // Already handled, not to worry
             } else if (rec instanceof FormulaRecord)
             {
               FormulaRecord formula = (FormulaRecord)rec;
               if (formula.isSharedFormula()) {
                 // Traverse the list of shared formulas in
-               //  reverse order, and try to find the correct one
+                //  reverse order, and try to find the correct one
                 //  for us
                 boolean found = false;
                 for (int i=sharedFormulas.size()-1;i>=0;i--) {
                     // TODO - there is no junit test case to justify this reversed loop
                     // perhaps it could just run in the normal direction?
-                       SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i);
-                       if (shrd.isFormulaInShared(formula)) {
-                               shrd.convertSharedFormulaRecord(formula);
-                               found = true;
-                               break;
-                       }
+                    SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i);
+                    if (shrd.isFormulaInShared(formula)) {
+                        shrd.convertSharedFormulaRecord(formula);
+                        found = true;
+                        break;
+                    }
                 }
                 if (!found) {
                     handleMissingSharedFormulaRecord(formula);
                 }
               }
-               
+                
               lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null);
               insertCell( lastFormulaAggregate );
             }
@@ -206,21 +222,6 @@ public final class ValueRecordsAggregate
     private static void handleMissingSharedFormulaRecord(FormulaRecord formula) {
         // could log an info message here since this is a fairly unusual occurrence.
     }
-
-    /**
-     * called by the class that is responsible for writing this sucker.
-     * Subclasses should implement this so that their data is passed back in a
-     * byte array.
-     *
-     * @param offset to begin writing at
-     * @param data byte array containing instance data
-     * @return number of bytes written
-     */
-
-    public int serialize(int offset, byte [] data)
-    {
-      throw new RuntimeException("This method shouldnt be called. ValueRecordsAggregate.serializeCellRow() should be called from RowRecordsAggregate.");
-    }
     
     /** Tallies a count of the size of the cell records
      *  that are attached to the rows in the range specified.
@@ -241,8 +242,8 @@ public final class ValueRecordsAggregate
 
     /** Returns true if the row has cells attached to it */
     public boolean rowHasCells(int row) {
-       if (row > records.length-1) //previously this said row > records.length which means if 
-               return false;  // if records.length == 60 and I pass "60" here I get array out of bounds
+        if (row > records.length-1) //previously this said row > records.length which means if 
+            return false;  // if records.length == 60 and I pass "60" here I get array out of bounds
       CellValueRecordInterface[] rowCells=records[row]; //because a 60 length array has the last index = 59
       if(rowCells==null) return false;
       for(int col=0;col<rowCells.length;col++) {
@@ -266,47 +267,56 @@ public final class ValueRecordsAggregate
         }
         return pos - offset;
     }
-
     
-    /**
-     * You never fill an aggregate
-     */
-    protected void fillFields(RecordInputStream in)
-    {
-    }
-
-    /**
-     * called by constructor, should throw runtime exception in the event of a
-     * record passed with a differing ID.
-     *
-     * @param id alleged id for this record
-     */
-
-    protected void validateSid(short id)
-    {
-    }
-
-    /**
-     * return the non static version of the id for this record.
-     */
-
-    public short getSid()
-    {
-        return sid;
+    public int visitCellsForRow(int rowIndex, RecordVisitor rv) {
+        int result = 0;
+        CellValueRecordInterface[] cellRecs = records[rowIndex];
+        if (cellRecs != null) {
+            for (int i = 0; i < cellRecs.length; i++) {
+                CellValueRecordInterface cvr = cellRecs[i];
+                if (cvr == null) {
+                    continue;
+                }
+                if (cvr instanceof FormulaRecordAggregate) {
+                    FormulaRecordAggregate fmAgg = (FormulaRecordAggregate) cvr;
+                    Record fmAggRec = fmAgg.getFormulaRecord();
+                    rv.visitRecord(fmAggRec);
+                    result += fmAggRec.getRecordSize();
+                    fmAggRec = fmAgg.getStringRecord();
+                    if (fmAggRec != null) {
+                        rv.visitRecord(fmAggRec);
+                        result += fmAggRec.getRecordSize();
+                    }
+                } else {
+                    Record rec = (Record) cvr;
+                    rv.visitRecord(rec);
+                    result += rec.getRecordSize();
+                }
+            }
+        }
+        return result;
     }
 
-    public int getRecordSize() {
-    
-        int size = 0;
-    Iterator irecs = this.getIterator();
+    public CellValueRecordInterface[] getValueRecords() {
+        List temp = new ArrayList();
         
-        while (irecs.hasNext()) {
-                size += (( Record ) irecs.next()).getRecordSize();
+        for (int i = 0; i < records.length; i++) {
+            CellValueRecordInterface[] rowCells = records[i];
+            if (rowCells == null) {
+                continue;
+            }
+            for (int j = 0; j < rowCells.length; j++) {
+                CellValueRecordInterface cell = rowCells[j];
+                if (cell != null) {
+                    temp.add(cell);
+                }
+            }
         }
-
-        return size;
+        
+        CellValueRecordInterface[] result = new CellValueRecordInterface[temp.size()];
+        temp.toArray(result);
+        return result;
     }
-
     public Iterator getIterator()
     {
     return new MyIterator();
index 2c23a97b375b0e2e9610aeac846a51edce796b83..70930a9dcba331ab1477cbcbfc78df09f61d9e3e 100644 (file)
@@ -1,25 +1,40 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
+/* ====================================================================
+   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.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+
+/**
+ * Implementation of Excel NOW() Function
  *
+ * @author Frank Taffelt
  */
-package org.apache.poi.hssf.record.formula.functions;
+public final class Now implements Function {
 
-public class Now extends NotImplementedFunction {
+       public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
+               if (evals.length > 0) {
+                       return ErrorEval.VALUE_INVALID;
+               }
 
+               java.util.Date now = new java.util.Date(System.currentTimeMillis());
+               return new NumberEval(HSSFDateUtil.getExcelDate(now));
+       }
 }
index 6260d20a58e1ef32647221326721a7c75e3816c2..b70741213611bbd4f087145948f4c19d609da998 100644 (file)
@@ -1,25 +1,46 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
+/* ====================================================================
+   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.formula.functions;
 
-public class Today extends NotImplementedFunction {
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 
+/**
+ * Implementation of Excel TODAY() Function<br/>
+ * 
+ * @author Frank Taffelt
+ */
+public class Today implements Function {
+
+       public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
+               if (evals.length > 0) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+
+               Calendar now = new GregorianCalendar();
+               now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0);
+               now.set(Calendar.MILLISECOND, 0);
+               return new NumberEval(HSSFDateUtil.getExcelDate(now.getTime()));
+       }
 }
+
index 9abcebcd74edc686b5dabdf854c39a883d41cf8b..e46729d3d382feb1f914362eb0ca32896b1bcf7f 100644 (file)
    limitations under the License.
 ==================================================================== */
 
-
-
-/*
- * Cell.java
- *
- * Created on September 30, 2001, 3:46 PM
- */
 package org.apache.poi.hssf.usermodel;
 
 import java.text.DateFormat;
@@ -79,10 +72,7 @@ import org.apache.poi.ss.usermodel.RichTextString;
  * @author  Yegor Kozlov cell comments support
  * @version 1.0-pre
  */
-
-public class HSSFCell implements Cell
-{
-
+public class HSSFCell implements Cell {
     /**
      * Numeric Cell type (0)
      * @see #setCellType(int)
@@ -157,8 +147,6 @@ public class HSSFCell implements Cell
      *
      * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
      */
-
-    //protected HSSFCell(Workbook book, Sheet sheet, short row, short col)
     protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col)
     {
         checkBounds(col);
@@ -186,8 +174,6 @@ public class HSSFCell implements Cell
      *                Type of cell
      * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
      */
-
-    //protected HSSFCell(Workbook book, Sheet sheet, short row, short col,
     protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col,
                        int type)
     {
@@ -209,8 +195,6 @@ public class HSSFCell implements Cell
      * @param sheet - Sheet record of the sheet containing this cell
      * @param cval - the Cell Value Record we wish to represent
      */
-
-    //protected HSSFCell(Workbook book, Sheet sheet, short row,
     protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row,
                        CellValueRecordInterface cval)
     {
@@ -234,15 +218,9 @@ public class HSSFCell implements Cell
         }
         ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(cval.getXFIndex());
 
-        setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf, book));
+        setCellStyle(new HSSFCellStyle(cval.getXFIndex(), xf, book));
     }
 
-    /**
-     * private constructor to prevent blank construction
-     */
-    private HSSFCell()
-    {
-    }
 
     /**
      * used internally -- given a cell value record, figure out its type
@@ -351,11 +329,6 @@ public class HSSFCell implements Cell
     private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex)
     {
 
-        // if (cellType == CELL_TYPE_FORMULA)
-        // {
-        // throw new RuntimeException(
-        // "Formulas have not been implemented in this release");
-        // }
         if (cellType > CELL_TYPE_ERROR)
         {
             throw new RuntimeException("I have no idea what type that is!");
@@ -506,10 +479,7 @@ public class HSSFCell implements Cell
         if (cellType != this.cellType && 
             this.cellType!=-1 )  // Special Value to indicate an uninitialized Cell
         {
-            int loc = sheet.getLoc();
-
             sheet.replaceValueRecord(record);
-            sheet.setLoc(loc);
         }
         this.cellType = cellType;
     }
@@ -545,7 +515,7 @@ public class HSSFCell implements Cell
             setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
         }
         
-        // Save into the apropriate record
+        // Save into the appropriate record
         if(record instanceof FormulaRecordAggregate) {
                (( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
         } else {
@@ -679,9 +649,7 @@ public class HSSFCell implements Cell
             
             //only set to default if there is no extended format index already set
             if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
-            FormulaParser fp = new FormulaParser(formula, book);
-            fp.parse();
-            Ptg[] ptg  = fp.getRPNPtg();
+            Ptg[] ptgs = FormulaParser.parse(formula, book);
             int   size = 0;
 
             // clear the Ptg Stack
@@ -690,9 +658,9 @@ public class HSSFCell implements Cell
             }
 
             // fill the Ptg Stack with Ptgs of new formula
-            for (int k = 0; k < ptg.length; k++) {
-                size += ptg[ k ].getSize();
-                frec.pushExpressionToken(ptg[ k ]);
+            for (int k = 0; k < ptgs.length; k++) {
+                size += ptgs[ k ].getSize();
+                frec.pushExpressionToken(ptgs[ k ]);
             }
             rec.getFormulaRecord().setExpressionLength(( short ) size);
             //Workbook.currentBook = null;
@@ -967,38 +935,6 @@ public class HSSFCell implements Cell
       ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex);
       return new HSSFCellStyle(styleIndex, xf, book);
     }
-    
-    /**
-     * used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
-     *
-     * @see #ENCODING_UNCHANGED
-     * @see #ENCODING_COMPRESSED_UNICODE
-     * @see #ENCODING_UTF_16
-     *
-     * @return -1, 1 or 0 for unchanged, compressed or uncompressed (used only with String type)
-     * 
-     * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
-     */
-    public short getEncoding()
-    {
-        return encoding;
-    }
-
-    /**
-     * set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit)
-     *
-     * @see #ENCODING_UNCHANGED
-     * @see #ENCODING_COMPRESSED_UNICODE
-     * @see #ENCODING_UTF_16
-     *
-     * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1)
-     * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
-     */
-
-    public void setEncoding(short encoding)
-    {
-        this.encoding = encoding;
-    }
 
     /**
      * Should only be used by HSSFSheet and friends.  Returns the low level CellValueRecordInterface record
index 1d4100655a686f5b9a0147116cb76f2160a7f045..10d86015aa6f8dc4d2ebbf7040abf14de043f4e4 100644 (file)
@@ -26,17 +26,16 @@ import org.apache.poi.hssf.record.cf.PatternFormatting;
 import org.apache.poi.hssf.record.formula.Ptg;
 
 /**
- * 
+ *
  * High level representation of Conditional Formatting Rule.
  * It allows to specify formula based conditions for the Conditional Formatting
  * and the formatting settings such as font, border and pattern.
- * 
+ *
  * @author Dmitriy Kumshayev
  */
-
 public final class HSSFConditionalFormattingRule
 {
-    private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
+       private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
 
        private final CFRuleRecord cfRuleRecord;
        private final HSSFWorkbook workbook;
@@ -50,11 +49,11 @@ public final class HSSFConditionalFormattingRule
        {
                return cfRuleRecord;
        }
-       
+
        private HSSFFontFormatting getFontFormatting(boolean create)
        {
                FontFormatting fontFormatting = cfRuleRecord.getFontFormatting();
-               if ( fontFormatting != null) 
+               if ( fontFormatting != null)
                {
                        cfRuleRecord.setFontFormatting(fontFormatting);
                        return new HSSFFontFormatting(cfRuleRecord);
@@ -70,7 +69,7 @@ public final class HSSFConditionalFormattingRule
                        return null;
                }
        }
-       
+
        /**
         * @return - font formatting object  if defined,  <code>null</code> otherwise
         */
@@ -79,19 +78,19 @@ public final class HSSFConditionalFormattingRule
                return getFontFormatting(false);
        }
        /**
-        * create a new font formatting structure if it does not exist, 
+        * create a new font formatting structure if it does not exist,
         * otherwise just return existing object.
-        * @return - font formatting object, never returns <code>null</code>. 
+        * @return - font formatting object, never returns <code>null</code>.
         */
        public HSSFFontFormatting createFontFormatting()
        {
                return getFontFormatting(true);
        }
-       
+
        private HSSFBorderFormatting getBorderFormatting(boolean create)
        {
                BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
-               if ( borderFormatting != null) 
+               if ( borderFormatting != null)
                {
                        cfRuleRecord.setBorderFormatting(borderFormatting);
                        return new HSSFBorderFormatting(cfRuleRecord);
@@ -115,19 +114,19 @@ public final class HSSFConditionalFormattingRule
                return getBorderFormatting(false);
        }
        /**
-        * create a new border formatting structure if it does not exist, 
+        * create a new border formatting structure if it does not exist,
         * otherwise just return existing object.
-        * @return - border formatting object, never returns <code>null</code>. 
+        * @return - border formatting object, never returns <code>null</code>.
         */
        public HSSFBorderFormatting createBorderFormatting()
        {
                return getBorderFormatting(true);
        }
-       
+
        private HSSFPatternFormatting getPatternFormatting(boolean create)
        {
                PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
-               if ( patternFormatting != null) 
+               if ( patternFormatting != null)
                {
                        cfRuleRecord.setPatternFormatting(patternFormatting);
                        return new HSSFPatternFormatting(cfRuleRecord);
@@ -143,7 +142,7 @@ public final class HSSFConditionalFormattingRule
                        return null;
                }
        }
-       
+
        /**
         * @return - pattern formatting object  if defined, <code>null</code> otherwise
         */
@@ -152,15 +151,29 @@ public final class HSSFConditionalFormattingRule
                return getPatternFormatting(false);
        }
        /**
-        * create a new pattern formatting structure if it does not exist, 
+        * create a new pattern formatting structure if it does not exist,
         * otherwise just return existing object.
-        * @return - pattern formatting object, never returns <code>null</code>. 
+        * @return - pattern formatting object, never returns <code>null</code>.
         */
        public HSSFPatternFormatting createPatternFormatting()
        {
                return getPatternFormatting(true);
        }
-       
+
+       /**
+        * @return -  the conditiontype for the cfrule
+        */
+       public byte getConditionType() {
+               return cfRuleRecord.getConditionType();
+       }
+
+       /**
+        * @return - the comparisionoperatation for the cfrule
+        */
+       public byte getComparisonOperation() {
+               return cfRuleRecord.getComparisonOperation();
+       }
+
        public String getFormula1()
        {
                return toFormulaString(cfRuleRecord.getParsedExpression1());
index 9ad89c34a57fc2c83a92bba09441d97e74c245b8..1a2b98f4302e81a909ea78eb0ca605a5398e504f 100644 (file)
@@ -102,20 +102,17 @@ public final class HSSFRow implements Comparable, Row {
     }
 
     /**
-     * Use this to create new cells within the row and return it.
-     * <p>
-     * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
-     * either through calling <code>setCellValue</code> or <code>setCellType</code>.
-     *
-     * @param column - the column number this cell represents
-     *
-     * @return HSSFCell a high level representation of the created cell.
+     * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int) }
      */
-    public HSSFCell createCell(short column)
-    {
-        return this.createCell(column,HSSFCell.CELL_TYPE_BLANK);
+    public HSSFCell createCell(short columnIndex) {
+        return createCell((int)columnIndex);
+    }
+    /**
+     * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int, int) }
+     */
+    public HSSFCell createCell(short columnIndex, int type) {
+        return createCell((int)columnIndex, type);
     }
-
     /**
      * Use this to create new cells within the row and return it.
      * <p>
@@ -128,11 +125,7 @@ public final class HSSFRow implements Comparable, Row {
      */
     public HSSFCell createCell(int column)
     {
-       short shortCellNum = (short)column;
-       if(column > 0x7FFF) {
-               shortCellNum = (short)(0xffff - column);
-       }
-        return this.createCell(shortCellNum,HSSFCell.CELL_TYPE_BLANK);
+        return this.createCell(column,HSSFCell.CELL_TYPE_BLANK);
     }
 
     /**
@@ -141,14 +134,18 @@ public final class HSSFRow implements Comparable, Row {
      * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
      * either through calling setCellValue or setCellType.
      *
-     * @param column - the column number this cell represents
+     * @param columnIndex - the column number this cell represents
      *
      * @return HSSFCell a high level representation of the created cell.
      */
-    public HSSFCell createCell(short column, int type)
+    public HSSFCell createCell(int columnIndex, int type)
     {
-        HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column, type);
+       short shortCellNum = (short)columnIndex;
+       if(columnIndex > 0x7FFF) {
+               shortCellNum = (short)(0xffff - columnIndex);
+       }
 
+        HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), shortCellNum, type);
         addCell(cell);
         sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
         return cell;
@@ -193,12 +190,12 @@ public final class HSSFRow implements Comparable, Row {
      *  records too.
      */
     protected void removeAllCells() {
-       for(int i=0; i<cells.length; i++) {
-               if(cells[i] != null) {
-                       removeCell(cells[i], true);
-               }
-       }
-       cells=new HSSFCell[INITIAL_CAPACITY];
+        for(int i=0; i<cells.length; i++) {
+            if(cells[i] != null) {
+                removeCell(cells[i], true);
+            }
+        }
+        cells=new HSSFCell[INITIAL_CAPACITY];
     }
 
     /**
@@ -346,7 +343,7 @@ public final class HSSFRow implements Comparable, Row {
      * @return HSSFCell representing that column or null if undefined.
      */
     public HSSFCell getCell(int cellnum) {
-       return getCell(cellnum, book.getMissingCellPolicy());
+        return getCell(cellnum, book.getMissingCellPolicy());
     }
     
     /**
@@ -359,24 +356,24 @@ public final class HSSFRow implements Comparable, Row {
      * @return representing that column or null if undefined + policy allows.
      */
     public HSSFCell getCell(int cellnum, MissingCellPolicy policy) {
-       HSSFCell cell = retrieveCell(cellnum);
-       if(policy == RETURN_NULL_AND_BLANK) {
-               return cell;
-       }
-       if(policy == RETURN_BLANK_AS_NULL) {
-               if(cell == null) return cell;
-               if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
-                       return null;
-               }
-               return cell;
-       }
-       if(policy == CREATE_NULL_AS_BLANK) {
-               if(cell == null) {
-                       return createCell((short)cellnum, HSSFCell.CELL_TYPE_BLANK);
-               }
-               return cell;
-       }
-       throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")");
+        HSSFCell cell = retrieveCell(cellnum);
+        if(policy == RETURN_NULL_AND_BLANK) {
+            return cell;
+        }
+        if(policy == RETURN_BLANK_AS_NULL) {
+            if(cell == null) return cell;
+            if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
+                return null;
+            }
+            return cell;
+        }
+        if(policy == CREATE_NULL_AS_BLANK) {
+            if(cell == null) {
+                return createCell((short)cellnum, HSSFCell.CELL_TYPE_BLANK);
+            }
+            return cell;
+        }
+        throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")");
     }
 
     /**
@@ -550,7 +547,6 @@ public final class HSSFRow implements Comparable, Row {
         return cellnum;
     }
 
-
     /**
      * @return cell iterator of the physically defined cells. 
      * Note that the 4th element might well not be cell 4, as the iterator
index 7dd85e364a91487fc7a1b56029fb91c1c788ae3a..1fb38f4c6546da7a6964db10223c766b792171f5 100644 (file)
@@ -98,7 +98,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
 
     private Sheet sheet;
-    private TreeMap rows;
+    private TreeMap rows; // TODO - use simple key into this map
     protected Workbook book;
     protected HSSFWorkbook workbook;
     private int firstrow;
@@ -147,21 +147,18 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
     /**
      * used internally to set the properties given a Sheet object
      */
+    private void setPropertiesFromSheet(Sheet sheet) {
 
-    private void setPropertiesFromSheet(Sheet sheet)
-    {
-        int sloc = sheet.getLoc();
         RowRecord row = sheet.getNextRow();
         boolean rowRecordsAlreadyPresent = row!=null;
 
-        while (row != null)
-        {
+        while (row != null) {
             createRowFromRecord(row);
 
             row = sheet.getNextRow();
         }
-        sheet.setLoc(sloc);
-        CellValueRecordInterface cval = sheet.getNextValueRecord();
+
+        CellValueRecordInterface[] cvals = sheet.getValueRecords();
         long timestart = System.currentTimeMillis();
 
         if (log.check( POILogger.DEBUG ))
@@ -169,14 +166,16 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
                 new Long(timestart));
         HSSFRow lastrow = null;
 
-        while (cval != null)
-        {
+        // Add every cell to its row
+        for (int i = 0; i < cvals.length; i++) {
+            CellValueRecordInterface cval = cvals[i];
+
             long cellstart = System.currentTimeMillis();
             HSSFRow hrow = lastrow;
 
-            if ( ( lastrow == null ) || ( lastrow.getRowNum() != cval.getRow() ) )
-            {
+            if (hrow == null || hrow.getRowNum() != cval.getRow()) {
                 hrow = getRow( cval.getRow() );
+                lastrow = hrow;
                 if (hrow == null) {
                     // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords 
                     // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too.
@@ -190,21 +189,13 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
                     hrow = createRowFromRecord(rowRec);
                 }
             }
-            if ( hrow != null )
-            {
-                lastrow = hrow;
-                if (log.check( POILogger.DEBUG ))
-                    log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
-                hrow.createCellFromRecord( cval );
-                cval = sheet.getNextValueRecord();
-                if (log.check( POILogger.DEBUG ))
-                    log.log( DEBUG, "record took ",
-                        new Long( System.currentTimeMillis() - cellstart ) );
-            }
-            else
-            {
-                cval = null;
-            }
+            if (log.check( POILogger.DEBUG ))
+                log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
+            hrow.createCellFromRecord( cval );
+            if (log.check( POILogger.DEBUG ))
+                log.log( DEBUG, "record took ",
+                    new Long( System.currentTimeMillis() - cellstart ) );
+            
         }
         if (log.check( POILogger.DEBUG ))
             log.log(DEBUG, "total sheet cell creation took ",
@@ -247,11 +238,9 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      *
      * @param row   representing a row to remove.
      */
-
     public void removeRow(Row row)
     {
         HSSFRow hrow = (HSSFRow) row;
-        sheet.setLoc(sheet.getDimsLoc());
         if (rows.size() > 0)
         {
             rows.remove(row);
@@ -263,15 +252,6 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
             {
                 firstrow = findFirstRow(firstrow);
             }
-            Iterator iter = hrow.cellIterator();
-
-            while (iter.hasNext())
-            {
-                HSSFCell cell = (HSSFCell) iter.next();
-
-                sheet.removeValueRecord(hrow.getRowNum(),
-                        cell.getCellValueRecord());
-            }
             sheet.removeRow(hrow.getRowRecord());
         }
     }
@@ -586,10 +566,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
 
     public void setVerticallyCenter(boolean value)
     {
-        VCenterRecord record =
-                (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
-
-        record.setVCenter(value);
+        sheet.getPageSettings().getVCenter().setVCenter(value);
     }
 
     /**
@@ -605,10 +582,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public boolean getVerticallyCenter()
     {
-        VCenterRecord record =
-                (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
-
-        return record.getVCenter();
+        return sheet.getPageSettings().getVCenter().getVCenter();
     }
 
     /**
@@ -618,10 +592,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
 
     public void setHorizontallyCenter(boolean value)
     {
-        HCenterRecord record =
-                (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
-
-        record.setHCenter(value);
+       sheet.getPageSettings().getHCenter().setHCenter(value);
     }
 
     /**
@@ -630,10 +601,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
 
     public boolean getHorizontallyCenter()
     {
-        HCenterRecord record =
-                (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
 
-        return record.getHCenter();
+        return sheet.getPageSettings().getHCenter().getHCenter();
     }
 
 
@@ -664,8 +633,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
     public Region getMergedRegionAt(int index) {
         CellRangeAddress cra = getMergedRegion(index);
         
-               return new Region(cra.getFirstRow(), (short)cra.getFirstColumn(), 
-                               cra.getLastRow(), (short)cra.getLastColumn());
+        return new Region(cra.getFirstRow(), (short)cra.getFirstColumn(), 
+                cra.getLastRow(), (short)cra.getLastColumn());
     }
     /**
      * @return the merged region at the specified index
@@ -921,7 +890,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public HSSFPrintSetup getPrintSetup()
     {
-        return new HSSFPrintSetup( getSheet().getPrintSetup() );
+        return new HSSFPrintSetup( sheet.getPageSettings().getPrintSetup() );
     }
 
     /**
@@ -930,7 +899,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public HSSFHeader getHeader()
     {
-        return new HSSFHeader( getSheet().getHeader() );
+        return new HSSFHeader( sheet.getPageSettings().getHeader() );
     }
 
     /**
@@ -939,7 +908,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public HSSFFooter getFooter()
     {
-        return new HSSFFooter( getSheet().getFooter() );
+        return new HSSFFooter( sheet.getPageSettings().getFooter() );
     }
 
     /**
@@ -979,7 +948,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public double getMargin( short margin )
     {
-        return getSheet().getMargin( margin );
+        return sheet.getPageSettings().getMargin( margin );
     }
 
     /**
@@ -989,7 +958,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public void setMargin( short margin, double size )
     {
-        getSheet().setMargin( margin, size );
+        sheet.getPageSettings().setMargin( margin, size );
     }
 
     /**
@@ -1112,8 +1081,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
 
              //don't check if it's not within the shifted area
              if (!inStart || !inEnd) {
-                               continue;
-                        }
+                continue;
+             }
 
              //only shift if the region outside the shifted rows is not merged too
              if (!containsCell(merged, startRow-1, 0) && !containsCell(merged, endRow+1, 0)){
@@ -1129,7 +1098,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
         //read so it doesn't get shifted again
         Iterator iterator = shiftedRegions.iterator();
         while (iterator.hasNext()) {
-               CellRangeAddress region = (CellRangeAddress)iterator.next();
+            CellRangeAddress region = (CellRangeAddress)iterator.next();
 
             this.addMergedRegion(region);
         }
@@ -1179,7 +1148,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public void shiftRows( int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight)
     {
-       shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true);
+        shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true);
     }
     
     /**
@@ -1216,7 +1185,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
         }
 
         shiftMerged(startRow, endRow, n, true);
-        sheet.shiftRowBreaks(startRow, endRow, n);
+        sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n);
 
         for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc )
         {
@@ -1241,8 +1210,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
             // Fetch the first and last columns of the
             //  row now, so we still have them to hand
             //  once we start removing cells
-               short firstCol = row.getFirstCellNum();
-               short lastCol = row.getLastCellNum();
+            short firstCol = row.getFirstCellNum();
+            short lastCol = row.getLastCellNum();
 
             // Fix up row heights if required
             if (copyRowHeight) {
@@ -1255,7 +1224,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
             // Copy each cell from the source row to
             //  the destination row
             for(Iterator cells = row.cellIterator(); cells.hasNext(); ) {
-               cell = (HSSFCell)cells.next();
+                cell = (HSSFCell)cells.next();
                 row.removeCell( cell );
                 CellValueRecordInterface cellRecord = cell.getCellValueRecord();
                 cellRecord.setRow( rowNum + n );
@@ -1269,12 +1238,12 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
             //  destination row. Note that comments can
             //  exist for cells which are null
             if(moveComments) {
-                   for( short col = firstCol; col <= lastCol; col++ ) {
-                       HSSFComment comment = getCellComment(rowNum, col);
-                       if (comment != null) {
-                          comment.setRow(rowNum + n);
-                       }
-                   }
+                for( short col = firstCol; col <= lastCol; col++ ) {
+                    HSSFComment comment = getCellComment(rowNum, col);
+                    if (comment != null) {
+                       comment.setRow(rowNum + n);
+                    }
+                }
             }
         }
         if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 );
@@ -1443,24 +1412,21 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public void setRowBreak(int row) {
         validateRow(row);
-        sheet.setRowBreak(row, (short)0, (short)255);
+        sheet.getPageSettings().setRowBreak(row, (short)0, (short)255);
     }
 
     /**
-     * Determines if there is a page break at the indicated row
-     * @param row FIXME: Document this!
-     * @return FIXME: Document this!
+     * @return <code>true</code> if there is a page break at the indicated row
      */
     public boolean isRowBroken(int row) {
-        return sheet.isRowBroken(row);
+        return sheet.getPageSettings().isRowBroken(row);
     }
 
     /**
      * Removes the page break at the indicated row
-     * @param row
      */
     public void removeRowBreak(int row) {
-        sheet.removeRowBreak(row);
+        sheet.getPageSettings().removeRowBreak(row);
     }
 
     /**
@@ -1468,7 +1434,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public int[] getRowBreaks(){
         //we can probably cache this information, but this should be a sparsely used function
-        return sheet.getRowBreaks();
+        return sheet.getPageSettings().getRowBreaks();
     }
 
     /**
@@ -1476,7 +1442,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public int[] getColumnBreaks(){
         //we can probably cache this information, but this should be a sparsely used function
-        return sheet.getColumnBreaks();
+        return sheet.getPageSettings().getColumnBreaks();
     }
 
 
@@ -1486,7 +1452,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      */
     public void setColumnBreak(short column) {
         validateColumn(column);
-        sheet.setColumnBreak(column, (short)0, (short)65535);
+        sheet.getPageSettings().setColumnBreak(column, (short)0, (short)65535);
     }
 
     /**
@@ -1495,7 +1461,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      * @return FIXME: Document this!
      */
     public boolean isColumnBroken(short column) {
-        return sheet.isColumnBroken(column);
+        return sheet.getPageSettings().isColumnBroken(column);
     }
 
     /**
@@ -1503,7 +1469,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      * @param column
      */
     public void removeColumnBreak(short column) {
-        sheet.removeColumnBreak(column);
+        sheet.getPageSettings().removeColumnBreak(column);
     }
 
     /**
@@ -1610,9 +1576,9 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      *  start from scratch!
      */
     public HSSFPatriarch getDrawingPatriarch() {
-       EscherAggregate agg = getDrawingEscherAggregate();
-       if(agg == null) return null;
-       
+        EscherAggregate agg = getDrawingEscherAggregate();
+        if(agg == null) return null;
+        
         HSSFPatriarch patriarch = new HSSFPatriarch(this, agg);
         agg.setPatriarch(patriarch);
 
@@ -1687,7 +1653,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
      * @param column the column index
      */
     public void autoSizeColumn(short column) {
-       autoSizeColumn(column, false);
+        autoSizeColumn(column, false);
     }
     
     /**
@@ -1736,19 +1702,19 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
             HSSFCell cell = row.getCell(column);
 
             if (cell == null) {
-                               continue;
-                       }
+                continue;
+            }
 
             int colspan = 1;
             for (int i = 0 ; i < getNumMergedRegions(); i++) {
                 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(region.getFirstColumn());
-                       colspan = 1 + region.getLastColumn() - region.getFirstColumn();
+                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(region.getFirstColumn());
+                    colspan = 1 + region.getLastColumn() - region.getFirstColumn();
                 }
             }
 
@@ -1839,7 +1805,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
         }
         if (width != -1) {
             if (width > Short.MAX_VALUE) { //width can be bigger that Short.MAX_VALUE!
-               width = Short.MAX_VALUE;
+                width = Short.MAX_VALUE;
             }
             sheet.setColumnWidth(column, (short) (width * 256));
         }
index 5422776fc1a2a5a1f1bcf91222e3fd188e51ec5c..e663f38f2a94827d6660beb3ca8785987d3404b2 100644 (file)
@@ -272,21 +272,11 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
 
         // convert all LabelRecord records to LabelSSTRecord
         convertLabelRecords(records, recOffset);
-        while (recOffset < records.size())
-        {
+        while (recOffset < records.size()) {
             Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
 
-            recOffset = sheet.getEofLoc()+1;
-            if (recOffset == 1)
-            {
-                break;
-            }
-
-            HSSFSheet hsheet = new HSSFSheet(this, sheet);
-
-            _sheets.add(hsheet);
-
-            // workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
+            recOffset = sheet.getEofLoc()+1; // TODO - use better technique to keep track of the used records
+            _sheets.add(new HSSFSheet(this, sheet));
         }
 
         for (int i = 0 ; i < workbook.getNumNames() ; ++i){
index 0c46c5863d56dc7ff613c22af6dd71a4b829052c..bbed1cfdbbc5620c2173af77d08a28f7b022c292 100644 (file)
@@ -59,8 +59,7 @@ public interface Row extends Iterable<Cell> {
      *
      * @return HSSFCell a high level representation of the created cell.
      */
-
-    Cell createCell(short column, int type);
+    Cell createCell(int column, int type);
 
     /**
      * remove the HSSFCell from this row.
index 40b349a54e870498696f4a1538bbd5df7efc96dd..0b245c0a783a99f18d7fb1a08587a9b85eb7c600 100644 (file)
@@ -39,8 +39,8 @@ import org.apache.poi.hssf.record.RowRecord;
 import org.apache.poi.hssf.record.StringRecord;
 import org.apache.poi.hssf.record.UncalcedRecord;
 import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
 import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
-import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
 import org.apache.poi.hssf.util.CellRangeAddress;
 
 /**
@@ -62,7 +62,6 @@ public final class TestSheet extends TestCase {
         assertTrue( sheet.records.get(pos++) instanceof ColumnInfoRecordsAggregate );
         assertTrue( sheet.records.get(pos++) instanceof DimensionsRecord );
         assertTrue( sheet.records.get(pos++) instanceof RowRecordsAggregate );
-        assertTrue( sheet.records.get(pos++) instanceof ValueRecordsAggregate );
         assertTrue( sheet.records.get(pos++) instanceof EOFRecord );
     }
 
@@ -209,7 +208,8 @@ public final class TestSheet extends TestCase {
         short colFrom = 0;
         short colTo = 255;
 
-        Sheet sheet = Sheet.createSheet();
+        Sheet worksheet = Sheet.createSheet();
+        PageSettingsBlock sheet = worksheet.getPageSettings();
         sheet.setRowBreak(0, colFrom, colTo);
 
         assertTrue("no row break at 0", sheet.isRowBroken(0));
@@ -264,24 +264,25 @@ public final class TestSheet extends TestCase {
         short rowFrom = 0;
         short rowTo = (short)65535;
 
-        Sheet sheet = Sheet.createSheet();
+        Sheet worksheet = Sheet.createSheet();
+        PageSettingsBlock sheet = worksheet.getPageSettings();
         sheet.setColumnBreak((short)0, rowFrom, rowTo);
 
-        assertTrue("no col break at 0", sheet.isColumnBroken((short)0));
+        assertTrue("no col break at 0", sheet.isColumnBroken(0));
         assertEquals("1 col break available", 1, sheet.getNumColumnBreaks());
 
         sheet.setColumnBreak((short)0, rowFrom, rowTo);
 
-        assertTrue("no col break at 0", sheet.isColumnBroken((short)0));
+        assertTrue("no col break at 0", sheet.isColumnBroken(0));
         assertEquals("1 col break available", 1, sheet.getNumColumnBreaks());
 
         sheet.setColumnBreak((short)1, rowFrom, rowTo);
         sheet.setColumnBreak((short)10, rowFrom, rowTo);
         sheet.setColumnBreak((short)15, rowFrom, rowTo);
 
-        assertTrue("no col break at 1", sheet.isColumnBroken((short)1));
-        assertTrue("no col break at 10", sheet.isColumnBroken((short)10));
-        assertTrue("no col break at 15", sheet.isColumnBroken((short)15));
+        assertTrue("no col break at 1", sheet.isColumnBroken(1));
+        assertTrue("no col break at 10", sheet.isColumnBroken(10));
+        assertTrue("no col break at 15", sheet.isColumnBroken(15));
         assertEquals("4 col break available", 4, sheet.getNumColumnBreaks());
 
         boolean is10 = false;
@@ -301,17 +302,17 @@ public final class TestSheet extends TestCase {
 
         assertTrue("one of the breaks didnt make it", is0 && is1 && is10 && is15);
 
-        sheet.removeColumnBreak((short)15);
-        assertFalse("column break should not be there", sheet.isColumnBroken((short)15));
+        sheet.removeColumnBreak(15);
+        assertFalse("column break should not be there", sheet.isColumnBroken(15));
 
-        sheet.removeColumnBreak((short)0);
-        assertFalse("column break should not be there", sheet.isColumnBroken((short)0));
+        sheet.removeColumnBreak(0);
+        assertFalse("column break should not be there", sheet.isColumnBroken(0));
 
-        sheet.removeColumnBreak((short)1);
-        assertFalse("column break should not be there", sheet.isColumnBroken((short)1));
+        sheet.removeColumnBreak(1);
+        assertFalse("column break should not be there", sheet.isColumnBroken(1));
 
-        sheet.removeColumnBreak((short)10);
-        assertFalse("column break should not be there", sheet.isColumnBroken((short)10));
+        sheet.removeColumnBreak(10);
+        assertFalse("column break should not be there", sheet.isColumnBroken(10));
 
         assertEquals("no more breaks", 0, sheet.getNumColumnBreaks());
     }
@@ -434,12 +435,12 @@ public final class TestSheet extends TestCase {
             throw new AssertionFailedError("Identified  bug 45145");
         }
 
-        // make sure that RRA and VRA are in the right place
-        int rraIx = sheet.getDimsLoc()+1;
-        List recs = sheet.getRecords();
-        assertEquals(RowRecordsAggregate.class, recs.get(rraIx).getClass());
-        assertEquals(ValueRecordsAggregate.class, recs.get(rraIx+1).getClass());
-
+        if (false) {
+            // make sure that RRA and VRA are in the right place
+            // (Aug 2008) since the VRA is now part of the RRA, there is much less chance that
+               // they could get out of order. Still, one could write serialize the sheet here, 
+               // and read back with EventRecordFactory to make sure...
+        }
         assertEquals(242, dbCellRecordPos);
     }
 
index 5c14b70e155d390fbc7a59b851c1118fd63b940d..2ae2eebc429da3725889f9c7a70ccaab7265892f 100755 (executable)
@@ -106,9 +106,7 @@ public class TestValueRecordsAggregate extends TestCase
         assertTrue( iterator.hasNext() );
     }
 
-    public void testRemoveCell()
-            throws Exception
-    {
+    public void testRemoveCell() {
         BlankRecord blankRecord1 = newBlankRecord();
         valueRecord.insertCell( blankRecord1 );
         BlankRecord blankRecord2 = newBlankRecord();
@@ -118,10 +116,6 @@ public class TestValueRecordsAggregate extends TestCase
 
         // removing an already empty cell just falls through
         valueRecord.removeCell( blankRecord2 );
-
-        // even trying to remove null just falls through silently.
-        valueRecord.removeCell( null );
-
     }
 
     public void testGetPhysicalNumberOfCells() throws Exception
@@ -204,22 +198,6 @@ public class TestValueRecordsAggregate extends TestCase
         return blankRecord;
     }
 
-    public void testGetRecordSize() throws Exception
-    {
-        List records = testData();
-        valueRecord.construct( 0, records );
-        assertEquals( 36, valueRecord.getRecordSize() );
-    }
-
-    public void testClone() throws Exception
-    {
-        List records = testData();
-        valueRecord.construct( 0, records );
-        valueRecord = (ValueRecordsAggregate) valueRecord.clone();
-        assertEquals( 36, valueRecord.getRecordSize() );
-    }
-
-    
     /**
      * Sometimes the 'shared formula' flag (<tt>FormulaRecord.isSharedFormula()</tt>) is set when 
      * there is no corresponding SharedFormulaRecord available. SharedFormulaRecord definitions do
index 0235564b35e7857472458a17f3a8b710e5c89d2c..0d5fbdc9bf78493f567448032eedc6785eb39fb1 100644 (file)
@@ -23,6 +23,7 @@ import junit.framework.Assert;
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
 
 import java.util.List;
 
@@ -106,7 +107,6 @@ public class SanityChecker
             }
 
             return matchOneOrMany( records, firstRecord );
-//            return matchOneOrMany( records, recordIdx );
         }
 
         private int matchRequired( int firstRecord, List records, int recordIdx )
@@ -117,7 +117,6 @@ public class SanityChecker
             }
 
             return matchOneOrMany( records, firstRecord );
-//            return matchOneOrMany( records, recordIdx );
         }
 
         private int matchOneOrMany( List records, int recordIdx )
@@ -204,11 +203,7 @@ public class SanityChecker
         new CheckRecord(GutsRecord.class, '1'),
         new CheckRecord(DefaultRowHeightRecord.class, '1'),
         new CheckRecord(WSBoolRecord.class, '1'),
-        new CheckRecord(HeaderRecord.class, '1'),
-        new CheckRecord(FooterRecord.class, '1'),
-        new CheckRecord(HCenterRecord.class, '1'),
-        new CheckRecord(VCenterRecord.class, '1'),
-        new CheckRecord(PrintSetupRecord.class, '1'),
+        new CheckRecord(PageSettingsBlock.class, '1'),
         new CheckRecord(DefaultColWidthRecord.class, '1'),
         new CheckRecord(DimensionsRecord.class, '1'),
         new CheckRecord(WindowTwoRecord.class, '1'),
@@ -275,7 +270,7 @@ public class SanityChecker
         }
     } */
 
-    private static int findFirstRecord( List records, Class record, int startIndex )
+    /* package */ static int findFirstRecord( List records, Class record, int startIndex )
     {
         for (int i = startIndex; i < records.size(); i++)
         {
@@ -285,11 +280,6 @@ public class SanityChecker
         return -1;
     }
 
-//    private static int findFirstRecord( List records, Class record )
-//    {
-//        return findFirstRecord ( records, record, 0 );
-//    }
-
     void checkRecordOrder(List records, CheckRecord[] check)
     {
         int recordIdx = 0;
index 646321d3d2eb638c9e457aaa83db0904aca652a9..3343757ad7758f972427909f917c8f2d0f858497 100644 (file)
@@ -34,7 +34,6 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.CellValueRecordInterface;
 import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
-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;
@@ -992,8 +991,8 @@ public final class TestBugs extends TestCase {
         assertEquals("Forms.CheckBox.1", obj.getOLE2ClassName());
         
         try {
-               obj.getDirectory();
-               fail();
+            obj.getDirectory();
+            fail();
         } catch(FileNotFoundException e) {}
     }
     
@@ -1012,12 +1011,12 @@ public final class TestBugs extends TestCase {
         //  DeletedArea3DPtg
         Workbook w = wb.getWorkbook();
         for(int i=0; i<w.getNumNames(); i++) {
-               NameRecord r = w.getNameRecord(i);
-               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
-               
-               List nd = r.getNameDefinition();
-               assertEquals(1, nd.size());
-               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+            NameRecord r = w.getNameRecord(i);
+            assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+            
+            List nd = r.getNameDefinition();
+            assertEquals(1, nd.size());
+            assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
         }
         
         
@@ -1030,12 +1029,12 @@ public final class TestBugs extends TestCase {
         assertEquals(2, wb.getNumberOfSheets());
         
         for(int i=0; i<w.getNumNames(); i++) {
-               NameRecord r = w.getNameRecord(i);
-               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
-               
-               List nd = r.getNameDefinition();
-               assertEquals(1, nd.size());
-               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+            NameRecord r = w.getNameRecord(i);
+            assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+            
+            List nd = r.getNameDefinition();
+            assertEquals(1, nd.size());
+            assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
         }
         
         
@@ -1047,12 +1046,12 @@ public final class TestBugs extends TestCase {
         assertEquals(2, wb.getNumberOfSheets());
         
         for(int i=0; i<w.getNumNames(); i++) {
-               NameRecord r = w.getNameRecord(i);
-               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
-               
-               List nd = r.getNameDefinition();
-               assertEquals(1, nd.size());
-               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+            NameRecord r = w.getNameRecord(i);
+            assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+            
+            List nd = r.getNameDefinition();
+            assertEquals(1, nd.size());
+            assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
         }
     }
     
@@ -1060,84 +1059,84 @@ public final class TestBugs extends TestCase {
      * Test that fonts get added properly
      */
     public void test45338() throws Exception {
-       HSSFWorkbook wb = new HSSFWorkbook();
-       assertEquals(4, wb.getNumberOfFonts());
-       
-       HSSFSheet s = wb.createSheet();
-       s.createRow(0);
-       s.createRow(1);
-       HSSFCell c1 = s.getRow(0).createCell((short)0);
-       HSSFCell c2 = s.getRow(1).createCell((short)0);
-       
-       assertEquals(4, wb.getNumberOfFonts());
-       
-       HSSFFont f1 = wb.getFontAt((short)0);
-       assertEquals(400, f1.getBoldweight());
-       
-       // Check that asking for the same font
-       //  multiple times gives you the same thing.
-       // Otherwise, our tests wouldn't work!
-       assertEquals(
-                       wb.getFontAt((short)0),
-                       wb.getFontAt((short)0)
-       );
-       assertEquals(
-                       wb.getFontAt((short)2),
-                       wb.getFontAt((short)2)
-       );
-       assertTrue(
-                       wb.getFontAt((short)0)
-                       !=
-                       wb.getFontAt((short)2)
-       );
-       
-       // Look for a new font we have
-       //  yet to add
-       assertNull(
-               wb.findFont(
-                       (short)11, (short)123, (short)22, 
-                       "Thingy", false, true, (short)2, (byte)2
-               )
-       );
-       
-       HSSFFont nf = wb.createFont();
-       assertEquals(5, wb.getNumberOfFonts());
-       
-       assertEquals(5, nf.getIndex());
-       assertEquals(nf, wb.getFontAt((short)5));
-       
-       nf.setBoldweight((short)11);
-       nf.setColor((short)123);
-       nf.setFontHeight((short)22);
-       nf.setFontName("Thingy");
-       nf.setItalic(false);
-       nf.setStrikeout(true);
-       nf.setTypeOffset((short)2);
-       nf.setUnderline((byte)2);
-       
-       assertEquals(5, wb.getNumberOfFonts());
-       assertEquals(nf, wb.getFontAt((short)5));
-       
-       // Find it now
-       assertNotNull(
-               wb.findFont(
-                       (short)11, (short)123, (short)22, 
-                       "Thingy", false, true, (short)2, (byte)2
-               )
-       );
-       assertEquals(
-               5,
-               wb.findFont(
-                               (short)11, (short)123, (short)22, 
-                               "Thingy", false, true, (short)2, (byte)2
-                       ).getIndex()
-       );
-       assertEquals(nf,
-                       wb.findFont(
-                               (short)11, (short)123, (short)22, 
-                               "Thingy", false, true, (short)2, (byte)2
-                       )
-       );
+        HSSFWorkbook wb = new HSSFWorkbook();
+        assertEquals(4, wb.getNumberOfFonts());
+        
+        HSSFSheet s = wb.createSheet();
+        s.createRow(0);
+        s.createRow(1);
+        HSSFCell c1 = s.getRow(0).createCell((short)0);
+        HSSFCell c2 = s.getRow(1).createCell((short)0);
+        
+        assertEquals(4, wb.getNumberOfFonts());
+        
+        HSSFFont f1 = wb.getFontAt((short)0);
+        assertEquals(400, f1.getBoldweight());
+        
+        // Check that asking for the same font
+        //  multiple times gives you the same thing.
+        // Otherwise, our tests wouldn't work!
+        assertEquals(
+                wb.getFontAt((short)0),
+                wb.getFontAt((short)0)
+        );
+        assertEquals(
+                wb.getFontAt((short)2),
+                wb.getFontAt((short)2)
+        );
+        assertTrue(
+                wb.getFontAt((short)0)
+                !=
+                wb.getFontAt((short)2)
+        );
+        
+        // Look for a new font we have
+        //  yet to add
+        assertNull(
+            wb.findFont(
+                (short)11, (short)123, (short)22, 
+                "Thingy", false, true, (short)2, (byte)2
+            )
+        );
+        
+        HSSFFont nf = wb.createFont();
+        assertEquals(5, wb.getNumberOfFonts());
+        
+        assertEquals(5, nf.getIndex());
+        assertEquals(nf, wb.getFontAt((short)5));
+        
+        nf.setBoldweight((short)11);
+        nf.setColor((short)123);
+        nf.setFontHeight((short)22);
+        nf.setFontName("Thingy");
+        nf.setItalic(false);
+        nf.setStrikeout(true);
+        nf.setTypeOffset((short)2);
+        nf.setUnderline((byte)2);
+        
+        assertEquals(5, wb.getNumberOfFonts());
+        assertEquals(nf, wb.getFontAt((short)5));
+        
+        // Find it now
+        assertNotNull(
+            wb.findFont(
+                (short)11, (short)123, (short)22, 
+                "Thingy", false, true, (short)2, (byte)2
+            )
+        );
+        assertEquals(
+            5,
+            wb.findFont(
+                   (short)11, (short)123, (short)22, 
+                   "Thingy", false, true, (short)2, (byte)2
+               ).getIndex()
+        );
+        assertEquals(nf,
+               wb.findFont(
+                   (short)11, (short)123, (short)22, 
+                   "Thingy", false, true, (short)2, (byte)2
+               )
+        );
     }
     
     /**
@@ -1146,94 +1145,90 @@ public final class TestBugs extends TestCase {
      * @throws Exception
      */
     public void testZipCodeFormulas() throws Exception {
-       HSSFWorkbook wb = new HSSFWorkbook();
-       HSSFSheet s = wb.createSheet();
-       s.createRow(0);
-       HSSFCell c1 = s.getRow(0).createCell((short)0);
-       HSSFCell c2 = s.getRow(0).createCell((short)1);
-       HSSFCell c3 = s.getRow(0).createCell((short)2);
-
-       // As number and string
-       c1.setCellFormula("70164");
-       c2.setCellFormula("\"70164\"");
-       c3.setCellFormula("\"90210\"");
-       
-       // Check the formulas
-       assertEquals("70164.0", c1.getCellFormula());
-       assertEquals("\"70164\"", c2.getCellFormula());
-       
-       // And check the values - blank
-       assertEquals(0.0, c1.getNumericCellValue(), 0.00001);
-       assertEquals("", c1.getRichStringCellValue().getString());
-       assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
-       assertEquals("", c2.getRichStringCellValue().getString());
-       assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
-       assertEquals("", c3.getRichStringCellValue().getString());
-       
-       // Try changing the cached value on one of the string
-       //  formula cells, so we can see it updates properly
-       c3.setCellValue(new HSSFRichTextString("test"));
-       assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
-       assertEquals("test", c3.getRichStringCellValue().getString());
-       
-       
-       // Now evaluate, they should all be changed
-       HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
-       eval.setCurrentRow(s.getRow(0));
-       eval.evaluateFormulaCell(c1);
-       eval.evaluateFormulaCell(c2);
-       eval.evaluateFormulaCell(c3);
-       
-       // Check that the cells now contain
-       //  the correct values
-       assertEquals(70164.0, c1.getNumericCellValue(), 0.00001);
-       assertEquals("", c1.getRichStringCellValue().getString());
-       assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
-       assertEquals("70164", c2.getRichStringCellValue().getString());
-       assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
-       assertEquals("90210", c3.getRichStringCellValue().getString());
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet s = wb.createSheet();
+        s.createRow(0);
+        HSSFCell c1 = s.getRow(0).createCell((short)0);
+        HSSFCell c2 = s.getRow(0).createCell((short)1);
+        HSSFCell c3 = s.getRow(0).createCell((short)2);
+
+        // As number and string
+        c1.setCellFormula("70164");
+        c2.setCellFormula("\"70164\"");
+        c3.setCellFormula("\"90210\"");
+        
+        // Check the formulas
+        assertEquals("70164.0", c1.getCellFormula());
+        assertEquals("\"70164\"", c2.getCellFormula());
+        
+        // And check the values - blank
+        assertEquals(0.0, c1.getNumericCellValue(), 0.00001);
+        assertEquals("", c1.getRichStringCellValue().getString());
+        assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
+        assertEquals("", c2.getRichStringCellValue().getString());
+        assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+        assertEquals("", c3.getRichStringCellValue().getString());
+        
+        // Try changing the cached value on one of the string
+        //  formula cells, so we can see it updates properly
+        c3.setCellValue(new HSSFRichTextString("test"));
+        assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+        assertEquals("test", c3.getRichStringCellValue().getString());
+        
+        
+        // Now evaluate, they should all be changed
+        HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
+        eval.setCurrentRow(s.getRow(0));
+        eval.evaluateFormulaCell(c1);
+        eval.evaluateFormulaCell(c2);
+        eval.evaluateFormulaCell(c3);
+        
+        // Check that the cells now contain
+        //  the correct values
+        assertEquals(70164.0, c1.getNumericCellValue(), 0.00001);
+        assertEquals("", c1.getRichStringCellValue().getString());
+        assertEquals(0.0, c2.getNumericCellValue(), 0.00001);
+        assertEquals("70164", c2.getRichStringCellValue().getString());
+        assertEquals(0.0, c3.getNumericCellValue(), 0.00001);
+        assertEquals("90210", c3.getRichStringCellValue().getString());
   
-       
-       // Write and read
-       HSSFWorkbook nwb = writeOutAndReadBack(wb);
-       HSSFSheet ns = nwb.getSheetAt(0);
-       HSSFCell nc1 = ns.getRow(0).getCell((short)0);
-       HSSFCell nc2 = ns.getRow(0).getCell((short)1);
-       HSSFCell nc3 = ns.getRow(0).getCell((short)2);
-       
-       // Re-check
-       assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001);
-       assertEquals("", nc1.getRichStringCellValue().getString());
-       assertEquals(0.0, nc2.getNumericCellValue(), 0.00001);
-       assertEquals("70164", nc2.getRichStringCellValue().getString());
-       assertEquals(0.0, nc3.getNumericCellValue(), 0.00001);
-       assertEquals("90210", nc3.getRichStringCellValue().getString());
-       
-       // Now check record level stuff too
-       ns.getSheet().setLoc(0);
-       int fn = 0;
-       CellValueRecordInterface cvr;
-       while((cvr = ns.getSheet().getNextValueRecord()) != null) {
-               if(cvr instanceof FormulaRecordAggregate) {
-                       FormulaRecordAggregate fr = (FormulaRecordAggregate)cvr;
-                       
-                       if(fn == 0) {
-                               assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001);
-                               assertNull(fr.getStringRecord());
-                       } else if (fn == 1) {
-                               assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
-                               assertNotNull(fr.getStringRecord());
-                               assertEquals("70164", fr.getStringRecord().getString());
-                       } else {
-                               assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
-                               assertNotNull(fr.getStringRecord());
-                               assertEquals("90210", fr.getStringRecord().getString());
-                       }
-                       
-                       fn++;
-               }
-       }
-       assertEquals(3, fn);
+        
+        // Write and read
+        HSSFWorkbook nwb = writeOutAndReadBack(wb);
+        HSSFSheet ns = nwb.getSheetAt(0);
+        HSSFCell nc1 = ns.getRow(0).getCell((short)0);
+        HSSFCell nc2 = ns.getRow(0).getCell((short)1);
+        HSSFCell nc3 = ns.getRow(0).getCell((short)2);
+        
+        // Re-check
+        assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001);
+        assertEquals("", nc1.getRichStringCellValue().getString());
+        assertEquals(0.0, nc2.getNumericCellValue(), 0.00001);
+        assertEquals("70164", nc2.getRichStringCellValue().getString());
+        assertEquals(0.0, nc3.getNumericCellValue(), 0.00001);
+        assertEquals("90210", nc3.getRichStringCellValue().getString());
+        
+        CellValueRecordInterface[] cvrs = ns.getSheet().getValueRecords();
+        for (int i = 0; i < cvrs.length; i++) {
+            CellValueRecordInterface cvr = cvrs[i];
+            if(cvr instanceof FormulaRecordAggregate) {
+                FormulaRecordAggregate fr = (FormulaRecordAggregate)cvr;
+                
+                if(i == 0) {
+                    assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001);
+                    assertNull(fr.getStringRecord());
+                } else if (i == 1) {
+                    assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
+                    assertNotNull(fr.getStringRecord());
+                    assertEquals("70164", fr.getStringRecord().getString());
+                } else {
+                    assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
+                    assertNotNull(fr.getStringRecord());
+                    assertEquals("90210", fr.getStringRecord().getString());
+                }
+            }
+        }
+        assertEquals(3, cvrs.length);
     }
     
     /**
@@ -1264,8 +1259,8 @@ public final class TestBugs extends TestCase {
         assertEquals("{=sin(B1:B9){9,1)[2][0]", c3.getCellFormula());
         
         // Save and re-open, ensure it still works
-       HSSFWorkbook nwb = writeOutAndReadBack(wb);
-       HSSFSheet ns1 = nwb.getSheetAt(0);
+        HSSFWorkbook nwb = writeOutAndReadBack(wb);
+        HSSFSheet ns1 = nwb.getSheetAt(0);
         HSSFCell nc1 = ns1.getRow(0).getCell(2);
         HSSFCell nc2 = ns1.getRow(1).getCell(2);
         HSSFCell nc3 = ns1.getRow(2).getCell(2);
@@ -1280,48 +1275,48 @@ public final class TestBugs extends TestCase {
      *  row and cell number
      */
     public void test30635() throws Exception {
-       HSSFWorkbook wb = new HSSFWorkbook();
-       HSSFSheet s = wb.createSheet();
-       
-       // No rows, everything is 0
-       assertEquals(0, s.getFirstRowNum());
-       assertEquals(0, s.getLastRowNum());
-       assertEquals(0, s.getPhysicalNumberOfRows());
-       
-       // One row, most things are 0, physical is 1
-       s.createRow(0);
-       assertEquals(0, s.getFirstRowNum());
-       assertEquals(0, s.getLastRowNum());
-       assertEquals(1, s.getPhysicalNumberOfRows());
-       
-       // And another, things change
-       s.createRow(4);
-       assertEquals(0, s.getFirstRowNum());
-       assertEquals(4, s.getLastRowNum());
-       assertEquals(2, s.getPhysicalNumberOfRows());
-       
-       
-       // Now start on cells
-       HSSFRow r = s.getRow(0);
-       assertEquals(-1, r.getFirstCellNum());
-       assertEquals(-1, r.getLastCellNum());
-       assertEquals(0, r.getPhysicalNumberOfCells());
-       
-       // Add a cell, things move off -1
-       r.createCell((short)0);
-       assertEquals(0, r.getFirstCellNum());
-       assertEquals(1, r.getLastCellNum()); // last cell # + 1
-       assertEquals(1, r.getPhysicalNumberOfCells());
-       
-       r.createCell((short)1);
-       assertEquals(0, r.getFirstCellNum());
-       assertEquals(2, r.getLastCellNum()); // last cell # + 1
-       assertEquals(2, r.getPhysicalNumberOfCells());
-       
-       r.createCell((short)4);
-       assertEquals(0, r.getFirstCellNum());
-       assertEquals(5, r.getLastCellNum()); // last cell # + 1
-       assertEquals(3, r.getPhysicalNumberOfCells());
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet s = wb.createSheet();
+        
+        // No rows, everything is 0
+        assertEquals(0, s.getFirstRowNum());
+        assertEquals(0, s.getLastRowNum());
+        assertEquals(0, s.getPhysicalNumberOfRows());
+        
+        // One row, most things are 0, physical is 1
+        s.createRow(0);
+        assertEquals(0, s.getFirstRowNum());
+        assertEquals(0, s.getLastRowNum());
+        assertEquals(1, s.getPhysicalNumberOfRows());
+        
+        // And another, things change
+        s.createRow(4);
+        assertEquals(0, s.getFirstRowNum());
+        assertEquals(4, s.getLastRowNum());
+        assertEquals(2, s.getPhysicalNumberOfRows());
+        
+        
+        // Now start on cells
+        HSSFRow r = s.getRow(0);
+        assertEquals(-1, r.getFirstCellNum());
+        assertEquals(-1, r.getLastCellNum());
+        assertEquals(0, r.getPhysicalNumberOfCells());
+        
+        // Add a cell, things move off -1
+        r.createCell((short)0);
+        assertEquals(0, r.getFirstCellNum());
+        assertEquals(1, r.getLastCellNum()); // last cell # + 1
+        assertEquals(1, r.getPhysicalNumberOfCells());
+        
+        r.createCell((short)1);
+        assertEquals(0, r.getFirstCellNum());
+        assertEquals(2, r.getLastCellNum()); // last cell # + 1
+        assertEquals(2, r.getPhysicalNumberOfCells());
+        
+        r.createCell((short)4);
+        assertEquals(0, r.getFirstCellNum());
+        assertEquals(5, r.getLastCellNum()); // last cell # + 1
+        assertEquals(3, r.getPhysicalNumberOfCells());
     }
     
     /**
@@ -1332,7 +1327,7 @@ public final class TestBugs extends TestCase {
         HSSFSheet s;
         HSSFRow r;
         HSSFCell c;
-       
+        
         // Check the contents of the formulas
         
         // E4 to G9 of sheet 4 make up the table
@@ -1369,18 +1364,18 @@ public final class TestBugs extends TestCase {
      *  with diagrams on. Don't any more
      */
     public void test45414() throws Exception {
-       HSSFWorkbook wb = openSample("WithThreeCharts.xls");
-       wb.getSheetAt(0).setForceFormulaRecalculation(true);
-       wb.getSheetAt(1).setForceFormulaRecalculation(false);
-       wb.getSheetAt(2).setForceFormulaRecalculation(true);
-       
-       // Write out and back in again
-       // This used to break
-       HSSFWorkbook nwb = writeOutAndReadBack(wb);
-       
-       // Check now set as it should be
-       assertTrue(nwb.getSheetAt(0).getForceFormulaRecalculation());
-       assertFalse(nwb.getSheetAt(1).getForceFormulaRecalculation());
-       assertTrue(nwb.getSheetAt(2).getForceFormulaRecalculation());
+        HSSFWorkbook wb = openSample("WithThreeCharts.xls");
+        wb.getSheetAt(0).setForceFormulaRecalculation(true);
+        wb.getSheetAt(1).setForceFormulaRecalculation(false);
+        wb.getSheetAt(2).setForceFormulaRecalculation(true);
+        
+        // Write out and back in again
+        // This used to break
+        HSSFWorkbook nwb = writeOutAndReadBack(wb);
+        
+        // Check now set as it should be
+        assertTrue(nwb.getSheetAt(0).getForceFormulaRecalculation());
+        assertFalse(nwb.getSheetAt(1).getForceFormulaRecalculation());
+        assertTrue(nwb.getSheetAt(2).getForceFormulaRecalculation());
     }
 }
index 80bab8a44518128fe77e79598026dbbcc31ea1ed..3fdc1a9dbac6e3b27006306819d219a7f8e4fc99 100644 (file)
@@ -265,14 +265,14 @@ public final class TestFormulas extends TestCase {
         HSSFCell         c      = null;
 
         //get our minimum values
-        r = s.createRow((short)0);
-        c = r.createCell((short)1);
+        r = s.createRow(0);
+        c = r.createCell(1);
         c.setCellFormula("A2" + operator + "A3");
 
-        for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
-            r = s.createRow((short) x);
+        for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
+            r = s.createRow(x);
 
-            for (short y = 1; y < 256 && y > 0; y++) {
+            for (int y = 1; y < 256 && y > 0; y++) {
 
                 String ref=null;
                 String ref2=null;
@@ -296,13 +296,13 @@ public final class TestFormulas extends TestCase {
                     refy2=(short)(y-3);
                 }
 
-                c = r.getCell((short) y);
+                c = r.getCell(y);
                 CellReference cr= new CellReference(refx1,refy1, false, false);
                 ref=cr.formatAsString();
                 cr=new CellReference(refx2,refy2, false, false);
                 ref2=cr.formatAsString();
 
-                c = r.createCell((short) y);
+                c = r.createCell(y);
                 c.setCellFormula("" + ref + operator + ref2);
 
 
@@ -312,8 +312,8 @@ public final class TestFormulas extends TestCase {
 
         //make sure we do the maximum value of the Int operator
         if (s.getLastRowNum() < Short.MAX_VALUE) {
-            r = s.createRow((short)0);
-            c = r.createCell((short)0);
+            r = s.getRow(0);
+            c = r.createCell(0);
             c.setCellFormula("" + "B1" + operator + "IV255");
         }
 
@@ -453,16 +453,16 @@ public final class TestFormulas extends TestCase {
         HSSFCell         c      = null;
 
         //get our minimum values
-        r = s.createRow((short)0);
-        c = r.createCell((short)1);
+        r = s.createRow(0);
+        c = r.createCell(1);
         c.setCellFormula(1 + operator + 1);
 
-        for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
-            r = s.createRow((short) x);
+        for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
+            r = s.createRow(x);
 
-            for (short y = 1; y < 256 && y > 0; y++) {
+            for (int y = 1; y < 256 && y > 0; y++) {
 
-                c = r.createCell((short) y);
+                c = r.createCell(y);
                 c.setCellFormula("" + x + operator + y);
 
             }
@@ -470,8 +470,8 @@ public final class TestFormulas extends TestCase {
 
         //make sure we do the maximum value of the Int operator
         if (s.getLastRowNum() < Short.MAX_VALUE) {
-            r = s.createRow((short)0);
-            c = r.createCell((short)0);
+            r = s.getRow(0);
+            c = r.createCell(0);
             c.setCellFormula("" + Short.MAX_VALUE + operator + Short.MAX_VALUE);
         }
 
index 2c8287f4bc9154a2d2fe1cd0a707c5b57039be2d..a24e5e7970bcfd02eb8c5e0ee4958e2d1c94d15a 100644 (file)
@@ -71,8 +71,7 @@ public final class TestHSSFSheet extends TestCase {
                HSSFWorkbook wb = new HSSFWorkbook();
                HSSFSheet s = wb.createSheet();
                Sheet sheet = s.getSheet();
-               VCenterRecord record =
-                               (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
+               VCenterRecord record = sheet.getPageSettings().getVCenter();
 
                assertEquals(false, record.getVCenter());
                s.setVerticallyCenter(true);
@@ -88,8 +87,7 @@ public final class TestHSSFSheet extends TestCase {
                HSSFWorkbook wb = new HSSFWorkbook();
                HSSFSheet s = wb.createSheet();
                Sheet sheet = s.getSheet();
-               HCenterRecord record =
-                               (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
+               HCenterRecord record = sheet.getPageSettings().getHCenter();
 
                assertEquals(false, record.getHCenter());
                s.setHorizontallyCenter(true);
index 916f6f4f0faa28b3af71d42b6b4e16d95e3cab32..c0231cdfea61c24074fce60e2b33fad095ff8d8e 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hssf.usermodel;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -26,11 +27,13 @@ import java.util.Iterator;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.eventmodel.ERFListener;
+import org.apache.poi.hssf.eventmodel.EventRecordFactory;
 import org.apache.poi.hssf.model.Workbook;
 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.record.aggregates.RowRecordsAggregate;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.Region;
@@ -94,7 +97,7 @@ public final class TestWorkbook extends TestCase {
                                + ((( double ) rownum / 1000)
                                   + (( double ) cellnum / 10000)));
                 c = r.createCell(( short ) (cellnum + 1));
-                c.setCellValue("TEST");
+                c.setCellValue(new HSSFRichTextString("TEST"));
             }
         }
         wb.write(out);
@@ -140,7 +143,7 @@ public final class TestWorkbook extends TestCase {
                                + ((( double ) rownum / 1000)
                                   + (( double ) cellnum / 10000)));
                 c = r.createCell(( short ) (cellnum + 1));
-                c.setCellValue("TEST");
+                c.setCellValue(new HSSFRichTextString("TEST"));
             }
         }
         for (short rownum = ( short ) 0; rownum < 25; rownum++)
@@ -311,9 +314,9 @@ public final class TestWorkbook extends TestCase {
         HSSFSheet sheet = workbook.getSheetAt(0);
         HSSFCell cell = sheet.getRow(0).getCell(1);
 
-        cell.setCellValue(REPLACED);
+        cell.setCellValue(new HSSFRichTextString(REPLACED));
         cell = sheet.getRow(1).getCell(0);
-        cell.setCellValue(REPLACED);
+        cell.setCellValue(new HSSFRichTextString(REPLACED));
 
         workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
 
@@ -381,11 +384,11 @@ public final class TestWorkbook extends TestCase {
         HSSFSheet       sheet    = workbook.getSheetAt(0);
         HSSFCell        cell     = sheet.getRow(3).getCell(2);
 
-        cell.setCellValue(LAST_NAME_VALUE);
+        cell.setCellValue(new HSSFRichTextString(LAST_NAME_VALUE));
         cell = sheet.getRow(4).getCell(2);
-        cell.setCellValue(FIRST_NAME_VALUE);
+        cell.setCellValue(new HSSFRichTextString(FIRST_NAME_VALUE));
         cell = sheet.getRow(5).getCell(2);
-        cell.setCellValue(SSN_VALUE);
+        cell.setCellValue(new HSSFRichTextString(SSN_VALUE));
 
         workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
         sheet    = workbook.getSheetAt(0);
@@ -454,13 +457,13 @@ public final class TestWorkbook extends TestCase {
     }
 
     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());
-       }
+        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.
      */
 
@@ -477,51 +480,52 @@ public final class TestWorkbook extends TestCase {
         assertEquals(1, record.getBackup());
     }
 
+    private static final class RecordCounter implements ERFListener {
+        private int _count;
+
+        public RecordCounter() {
+            _count=0;
+        }
+        public int getCount() {
+            return _count;
+        }
+        public boolean processRecord(Record rec) {
+            _count++;
+            return true;
+        }
+    }
+    
     /**
      * This tests is for bug [ #506658 ] Repeating output.
      *
      * We need to make sure only one LabelSSTRecord is produced.
      */
-
     public void testRepeatingBug()
         throws Exception
     {
         HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet    sheet    = workbook.createSheet("Design Variants");
-        HSSFRow      row      = sheet.createRow(( short ) 2);
-        HSSFCell     cell     = row.createCell(( short ) 1);
+        HSSFRow      row      = sheet.createRow(2);
+        HSSFCell     cell     = row.createCell(1);
 
         cell.setCellValue(new HSSFRichTextString("Class"));
-        cell = row.createCell(( short ) 2);
-
-        // workbook.write(new FileOutputStream("/a2.xls"));
-        ValueRecordsAggregate valueAggregate =
-            ( ValueRecordsAggregate ) sheet.getSheet()
-                .findFirstRecordBySid(ValueRecordsAggregate.sid);
-        int                   sstRecords     = 0;
-        Iterator              iterator       = valueAggregate.getIterator();
+        cell = row.createCell(2);
 
-        while (iterator.hasNext())
-        {
-            if ((( Record ) iterator.next()).getSid() == LabelSSTRecord.sid)
-            {
-                sstRecords++;
-            }
-        }
-        assertEquals(1, sstRecords);
+        byte[] data = new byte[sheet.getSheet().getSize()];
+        sheet.getSheet().serialize(0, data);
+        RecordCounter rc = new RecordCounter();
+        EventRecordFactory erf = new EventRecordFactory(rc, new short[] { LabelSSTRecord.sid, });
+        erf.processRecords(new ByteArrayInputStream(data));
+        
+        assertEquals(1, rc.getCount());
     }
 
 
-    public void testManyRows()
-        throws Exception
-    {
-        String testName = "TestManyRows";
-        File file = TempFile.createTempFile(testName, ".xls");
-        FileOutputStream out  = new FileOutputStream(file);
+    public void testManyRows() {
         HSSFWorkbook workbook = new HSSFWorkbook();
         HSSFSheet sheet = workbook.createSheet();
-        HSSFRow row = null;
-        HSSFCell cell = null;
+        HSSFRow row;
+        HSSFCell cell;
         int i, j;
         for ( i = 0, j = 32771; j > 0; i++, j-- )
         {
@@ -529,22 +533,17 @@ public final class TestWorkbook extends TestCase {
             cell = row.createCell((short) 0);
             cell.setCellValue(i);
         }
-        workbook.write(out);
-        out.close();
         sanityChecker.checkHSSFWorkbook(workbook);
         assertEquals("LAST ROW == 32770", 32770, sheet.getLastRowNum());
+        cell = sheet.getRow(32770).getCell(0);
         double lastVal = cell.getNumericCellValue();
 
-        FileInputStream in      = new FileInputStream(file);
-        POIFSFileSystem fs       = new POIFSFileSystem(in);
-        HSSFWorkbook    wb = new HSSFWorkbook(fs);
+        HSSFWorkbook    wb = HSSFTestDataSamples.writeOutAndReadBack(workbook);
         HSSFSheet       s    = wb.getSheetAt(0);
         row = s.getRow(32770);
-        cell = row.getCell(( short ) 0);
+        cell = row.getCell(0);
         assertEquals("Value from last row == 32770", lastVal, cell.getNumericCellValue(), 0);
         assertEquals("LAST ROW == 32770", 32770, s.getLastRowNum());
-        in.close();
-        file.deleteOnExit();
     }
 
     /**
@@ -571,10 +570,4 @@ public final class TestWorkbook extends TestCase {
 
         assertTrue("file exists",file.exists());
     }
-
-
-    public static void main(String [] ignored_args)
-    {
-        junit.textui.TestRunner.run(TestWorkbook.class);
-    }
 }