You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2008/01/25 16:48:23 UTC

svn commit: r615249 [2/3] - in /poi/tags/REL_3_0_2_BETA3: ./ src/documentation/content/xdocs/ src/documentation/content/xdocs/hssf/ src/java/org/apache/poi/ddf/ src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/ src/java/org/apach...

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java Fri Jan 25 07:48:14 2008
@@ -20,10 +20,8 @@
 package org.apache.poi.hssf.record;
 
 import java.util.Stack;
-import java.util.List;
 
 import org.apache.poi.hssf.record.formula.*;
-import org.apache.poi.util.LittleEndian;
 
 /**
  * Title:        SharedFormulaRecord
@@ -156,15 +154,12 @@
         return sid;
     }
 
-	 /**
-	  * Shared formulas are to treated like unknown records, and as a result d
-	  */
     protected void fillFields(RecordInputStream in)
     {
-      field_1_first_row       = in.readShort();
-      field_2_last_row        = in.readShort();
-      field_3_first_column    = in.readByte();
-      field_4_last_column     = in.readByte();
+      field_1_first_row       = in.readUShort();
+      field_2_last_row        = in.readUShort();
+      field_3_first_column    = in.readUByte();
+      field_4_last_column     = in.readUByte();
       field_5_reserved        = in.readShort();
       field_6_expression_len = in.readShort();
       field_7_parsed_expr    = getParsedExpressionTokens(in);
@@ -181,6 +176,9 @@
         return stack;
     }
 
+    /**
+     * Are we shared by the supplied formula record?
+     */
     public boolean isFormulaInShared(FormulaRecord formula) {
       final int formulaRow = formula.getRow();
       final int formulaColumn = formula.getColumn();
@@ -202,48 +200,48 @@
             Ptg ptg = (Ptg) field_7_parsed_expr.get(k);
             if (ptg instanceof RefNPtg) {
               RefNPtg refNPtg = (RefNPtg)ptg;
-              ptg = new ReferencePtg( (short)(formulaRow + refNPtg.getRow()),
-                                      (byte)(formulaColumn + refNPtg.getColumn()),
+              ptg = new ReferencePtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+                                     fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
                                      refNPtg.isRowRelative(),
                                      refNPtg.isColRelative());
             } else if (ptg instanceof RefNVPtg) {
               RefNVPtg refNVPtg = (RefNVPtg)ptg;
-              ptg = new RefVPtg( (short)(formulaRow + refNVPtg.getRow()),
-                                 (byte)(formulaColumn + refNVPtg.getColumn()),
-                                 refNVPtg.isRowRelative(),
-                                 refNVPtg.isColRelative());
+              ptg = new RefVPtg(fixupRelativeRow(formulaRow,refNVPtg.getRow(),refNVPtg.isRowRelative()),
+                                fixupRelativeColumn(formulaColumn,refNVPtg.getColumn(),refNVPtg.isColRelative()),
+                                refNVPtg.isRowRelative(),
+                                refNVPtg.isColRelative());
             } else if (ptg instanceof RefNAPtg) {
               RefNAPtg refNAPtg = (RefNAPtg)ptg;
-              ptg = new RefAPtg( (short)(formulaRow + refNAPtg.getRow()),
-                                 (byte)(formulaColumn + refNAPtg.getColumn()),
+              ptg = new RefAPtg( fixupRelativeRow(formulaRow,refNAPtg.getRow(),refNAPtg.isRowRelative()),
+                                 fixupRelativeColumn(formulaColumn,refNAPtg.getColumn(),refNAPtg.isColRelative()),
                                  refNAPtg.isRowRelative(),
                                  refNAPtg.isColRelative());
             } else if (ptg instanceof AreaNPtg) {
               AreaNPtg areaNPtg = (AreaNPtg)ptg;
-              ptg = new AreaPtg((short)(formulaRow + areaNPtg.getFirstRow()),
-                                (short)(formulaRow + areaNPtg.getLastRow()),
-                                (short)(formulaColumn + areaNPtg.getFirstColumn()),
-                                (short)(formulaColumn + areaNPtg.getLastColumn()),
+              ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
+                                fixupRelativeRow(formulaRow,areaNPtg.getLastRow(),areaNPtg.isLastRowRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNPtg.getFirstColumn(),areaNPtg.isFirstColRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNPtg.getLastColumn(),areaNPtg.isLastColRelative()),
                                 areaNPtg.isFirstRowRelative(),
                                 areaNPtg.isLastRowRelative(),
                                 areaNPtg.isFirstColRelative(),
                                 areaNPtg.isLastColRelative());
             } else if (ptg instanceof AreaNVPtg) {
               AreaNVPtg areaNVPtg = (AreaNVPtg)ptg;
-              ptg = new AreaVPtg((short)(formulaRow + areaNVPtg.getFirstRow()),
-                                (short)(formulaRow + areaNVPtg.getLastRow()),
-                                (short)(formulaColumn + areaNVPtg.getFirstColumn()),
-                                (short)(formulaColumn + areaNVPtg.getLastColumn()),
+              ptg = new AreaVPtg(fixupRelativeRow(formulaRow,areaNVPtg.getFirstRow(),areaNVPtg.isFirstRowRelative()),
+                                fixupRelativeRow(formulaRow,areaNVPtg.getLastRow(),areaNVPtg.isLastRowRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNVPtg.getFirstColumn(),areaNVPtg.isFirstColRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNVPtg.getLastColumn(),areaNVPtg.isLastColRelative()),
                                 areaNVPtg.isFirstRowRelative(),
                                 areaNVPtg.isLastRowRelative(),
                                 areaNVPtg.isFirstColRelative(),
                                 areaNVPtg.isLastColRelative());
             } else if (ptg instanceof AreaNAPtg) {
               AreaNAPtg areaNAPtg = (AreaNAPtg)ptg;
-              ptg = new AreaAPtg((short)(formulaRow + areaNAPtg.getFirstRow()),
-                                (short)(formulaRow + areaNAPtg.getLastRow()),
-                                (short)(formulaColumn + areaNAPtg.getFirstColumn()),
-                                (short)(formulaColumn + areaNAPtg.getLastColumn()),
+              ptg = new AreaAPtg(fixupRelativeRow(formulaRow,areaNAPtg.getFirstRow(),areaNAPtg.isFirstRowRelative()),
+                                fixupRelativeRow(formulaRow,areaNAPtg.getLastRow(),areaNAPtg.isLastRowRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNAPtg.getFirstColumn(),areaNAPtg.isFirstColRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNAPtg.getLastColumn(),areaNAPtg.isLastColRelative()),
                                 areaNAPtg.isFirstRowRelative(),
                                 areaNAPtg.isLastRowRelative(),
                                 areaNAPtg.isFirstColRelative(),
@@ -258,6 +256,21 @@
         throw new RuntimeException("Shared Formula Conversion: Coding Error");
       }
     }
+    
+    private short fixupRelativeColumn(int currentcolumn, short column, boolean relative) {
+    	if(relative) {
+    		if((column&128)!=0) column=(short)(column-256);
+    		column+=currentcolumn;
+    	}
+    	return column;
+	}
+
+	private short fixupRelativeRow(int currentrow, short row, boolean relative) {
+		if(relative) {
+			row+=currentrow;
+		}
+		return row;
+	}
 
 	/**
 	 * Mirroring formula records so it is registered in the ValueRecordsAggregate

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/TextObjectRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/TextObjectRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/TextObjectRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/TextObjectRecord.java Fri Jan 25 07:48:14 2008
@@ -251,4 +251,21 @@
         buffer.append( "[/TXO]\n" );
         return buffer.toString();
     }
+
+    public Object clone() {
+
+        TextObjectRecord rec = new TextObjectRecord();
+        rec.str = str;
+
+        rec.setOptions(getOptions());
+        rec.setTextOrientation(getTextOrientation());
+        rec.setReserved4(getReserved4());
+        rec.setReserved5(getReserved5());
+        rec.setReserved6(getReserved6());
+        rec.setTextLength(getTextLength());
+        rec.setFormattingRunLength(getFormattingRunLength());
+        rec.setReserved7(getReserved7());
+        return rec;
+    }
+
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java Fri Jan 25 07:48:14 2008
@@ -99,7 +99,7 @@
     {
         this.formulaRecord = formulaRecord;
     }
-
+    
     public FormulaRecord getFormulaRecord()
     {
         return formulaRecord;
@@ -109,7 +109,7 @@
     {
         return stringRecord;
     }
-
+    
     public boolean isEqual(CellValueRecordInterface i)
     {
         return formulaRecord.isEqual( i );

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java Fri Jan 25 07:48:14 2008
@@ -127,8 +127,17 @@
 
         FormulaRecordAggregate lastFormulaAggregate = null;
         
+        // First up, locate all the shared formulas
         List sharedFormulas = new java.util.ArrayList();
+        for (k = offset; k < records.size(); k++)
+        {
+            Record rec = ( Record ) records.get(k);
+            if (rec instanceof SharedFormulaRecord) {
+            	sharedFormulas.add(rec);
+            }
+        }
 
+        // Now do the main processing sweep
         for (k = offset; k < records.size(); k++)
         {
             Record rec = ( Record ) records.get(k);
@@ -137,18 +146,14 @@
             {
                 break;
             } else if (rec instanceof SharedFormulaRecord) {
-            	sharedFormulas.add(rec);
+            	// Already handled, not to worry
             } else if (rec instanceof FormulaRecord)
             {
               FormulaRecord formula = (FormulaRecord)rec;
               if (formula.isSharedFormula()) {
-                Record nextRecord = (Record) records.get(k + 1);
-                if (nextRecord instanceof SharedFormulaRecord) {
-                	sharedFormulas.add(nextRecord);
-                	k++;
-                }
-                //traverse the list of shared formulas in reverse order, and try to find the correct one
-                //for us
+                // Traverse the list of shared formulas in
+            	//  reverse order, and try to find the correct one
+                //  for us
                 boolean found = false;
                 for (int i=sharedFormulas.size()-1;i>=0;i--) {
                 	SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i);

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java Fri Jan 25 07:48:14 2008
@@ -243,16 +243,22 @@
 	public void setArea( String ref )
 	{
 		AreaReference ar = new AreaReference( ref );
+		CellReference[] crs = ar.getCells();
+		
+		CellReference firstCell = crs[0];
+		CellReference lastCell = firstCell;
+		if(crs.length > 1) {
+			lastCell = crs[1];
+		}
 
-		setFirstRow( (short) ar.getCells()[0].getRow() );
-		setFirstColumn( (short) ar.getCells()[0].getCol() );
-		setLastRow( (short) ar.getCells()[1].getRow() );
-		setLastColumn( (short) ar.getCells()[1].getCol() );
-		setFirstColRelative( !ar.getCells()[0].isColAbsolute() );
-		setLastColRelative( !ar.getCells()[1].isColAbsolute() );
-		setFirstRowRelative( !ar.getCells()[0].isRowAbsolute() );
-		setLastRowRelative( !ar.getCells()[1].isRowAbsolute() );
-
+		setFirstRow(    (short) firstCell.getRow() );
+		setFirstColumn( (short) firstCell.getCol() );
+		setLastRow(     (short) lastCell.getRow() );
+		setLastColumn(  (short) lastCell.getCol() );
+		setFirstColRelative( !firstCell.isColAbsolute() );
+		setLastColRelative(  !lastCell.isColAbsolute() );
+		setFirstRowRelative( !firstCell.isRowAbsolute() );
+		setLastRowRelative(  !lastCell.isRowAbsolute() );
 	}
 
 	public String toFormulaString(Workbook book)

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java Fri Jan 25 07:48:14 2008
@@ -29,7 +29,7 @@
 public class ErrPtg extends Ptg
 {
     public static final short sid  = 0x1c;
-    private static final int  SIZE = 7;
+    private static final int  SIZE = 2;
     private byte              field_1_error_code;
 
     /** Creates new ErrPtg */

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java Fri Jan 25 07:48:14 2008
@@ -75,7 +75,7 @@
 
     public String toFormulaString(Workbook book)
     {
-        throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula");
+        throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
     }
     
     public String toString()

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java Fri Jan 25 07:48:14 2008
@@ -24,17 +24,33 @@
  */
 package org.apache.poi.hssf.usermodel;
 
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+
 import org.apache.poi.hssf.model.FormulaParser;
 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.BlankRecord;
+import org.apache.poi.hssf.record.BoolErrRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
+import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NoteRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SubRecord;
+import org.apache.poi.hssf.record.TextObjectRecord;
+import org.apache.poi.hssf.record.UnicodeString;
 import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.formula.Ptg;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
 /**
  * High level representation of a cell in a row of a spreadsheet.
  * Cells can be numeric, formula-based or string-based (text).  The cell type
@@ -266,14 +282,24 @@
     }
 
     /**
-     * set the cell's number within the row (0 based)
+     * Set the cell's number within the row (0 based).
      * @param num  short the cell number
+     * @deprecated Doesn't update the row's idea of what cell this is, use {@link HSSFRow#moveCell(HSSFCell, short)} instead
      */
-
     public void setCellNum(short num)
     {
         record.setColumn(num);
     }
+    
+    /**
+     * Updates the cell record's idea of what
+     *  column it belongs in (0 based)
+     * @param num the new cell number
+     */
+    protected void updateCellNum(short num)
+    {
+    	record.setColumn(num);
+    }
 
     /**
      *  get the cell's number within the row
@@ -508,7 +534,13 @@
         {
             setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
         }
-        (( NumberRecord ) record).setValue(value);
+        
+        // Save into the apropriate record
+        if(record instanceof FormulaRecordAggregate) {
+        	(( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
+        } else {
+        	(( NumberRecord ) record).setValue(value);
+        }
     }
 
     /**

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java Fri Jan 25 07:48:14 2008
@@ -21,6 +21,13 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.poi.ddf.EscherComplexProperty;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperty;
+import org.apache.poi.hssf.record.EscherAggregate;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.StringUtil;
+
 /**
  * The patriarch is the toplevel container for shapes in a sheet.  It does
  * little other than act as a container for other shapes and groups.
@@ -38,12 +45,20 @@
     int y2 = 255;
 
     /**
+     * The EscherAggregate we have been bound to.
+     * (This will handle writing us out into records,
+     *  and building up our shapes from the records)
+     */
+    private EscherAggregate boundAggregate;
+
+    /**
      * Creates the patriarch.
      *
-     * @param sheet     the sheet this patriarch is stored in.
+     * @param sheet the sheet this patriarch is stored in.
      */
-    HSSFPatriarch(HSSFSheet sheet)
+    HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate)
     {
+    	this.boundAggregate = boundAggregate;
         this.sheet = sheet;
     }
 
@@ -173,6 +188,39 @@
         this.x2 = x2;
         this.y2 = y2;
     }
+    
+    /**
+     * Does this HSSFPatriarch contain a chart?
+     * (Technically a reference to a chart, since they
+     *  get stored in a different block of records)
+     * FIXME - detect chart in all cases (only seems
+     *  to work on some charts so far)
+     */
+    public boolean containsChart() {
+    	// TODO - support charts properly in usermodel
+    	
+    	// We're looking for a EscherOptRecord
+    	EscherOptRecord optRecord = (EscherOptRecord)
+    		boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
+    	if(optRecord == null) {
+    		// No opt record, can't have chart
+    		return false;
+    	}
+    	
+    	for(Iterator it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
+    		EscherProperty prop = (EscherProperty)it.next();
+    		if(prop.getPropertyNumber() == 896 && prop.isComplex()) {
+    			EscherComplexProperty cp = (EscherComplexProperty)prop;
+    			String str = StringUtil.getFromUnicodeLE(cp.getComplexData());
+    			System.err.println(str);
+    			if(str.equals("Chart 1\0")) {
+    				return true;
+    			}
+    		}
+    	}
+
+    	return false;
+    }
 
     /**
      * The top left x coordinate of this group.
@@ -206,4 +254,10 @@
         return y2;
     }
 
+    /**
+     * Returns the aggregate escher record we're bound to 
+     */
+    protected EscherAggregate _getBoundAggregate() {
+    	return boundAggregate;
+    }
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java Fri Jan 25 07:48:14 2008
@@ -22,15 +22,14 @@
  */
 package org.apache.poi.hssf.usermodel;
 
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.CellValueRecordInterface;
 import org.apache.poi.hssf.record.RowRecord;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
 /**
  * High level representation of a row of a spreadsheet.
  *
@@ -157,11 +156,15 @@
      * remove the HSSFCell from this row.
      * @param cell to remove
      */
-    public void removeCell(HSSFCell cell)
-    {
-        CellValueRecordInterface cval = cell.getCellValueRecord();
-
-        sheet.removeValueRecord(getRowNum(), cval);
+    public void removeCell(HSSFCell cell) {
+    	removeCell(cell, true);
+    }
+    private void removeCell(HSSFCell cell, boolean alsoRemoveRecords) {
+    	if(alsoRemoveRecords) {
+	        CellValueRecordInterface cval = cell.getCellValueRecord();
+	        sheet.removeValueRecord(getRowNum(), cval);
+    	}
+    	
         short column=cell.getCellNum();
         if(cell!=null && column<cells.length)
         {
@@ -223,11 +226,44 @@
     {
         return rowNum;
     }
+    
+    /**
+     * Returns the rows outline level. Increased as you
+     *  put it into more groups (outlines), reduced as
+     *  you take it out of them.
+     * TODO - Should this really be public?
+     */
+    protected int getOutlineLevel() {
+    	return row.getOutlineLevel();
+    }
+    
+    /**
+     * Moves the supplied cell to a new column, which
+     *  must not already have a cell there!
+     * @param cell The cell to move
+     * @param newColumn The new column number (0 based)
+     */
+    public void moveCell(HSSFCell cell, short newColumn) {
+    	// Ensure the destination is free
+    	if(cells.length > newColumn && cells[newColumn] != null) {
+    		throw new IllegalArgumentException("Asked to move cell to column " + newColumn + " but there's already a cell there");
+    	}
+    	
+    	// Check it's one of ours
+    	if(! cells[cell.getCellNum()].equals(cell)) {
+    		throw new IllegalArgumentException("Asked to move a cell, but it didn't belong to our row");
+    	}
+    	
+    	// Move the cell to the new position
+    	// (Don't remove the records though)
+    	removeCell(cell, false);
+    	cell.updateCellNum(newColumn);
+    	addCell(cell);
+    }
 
     /**
      * used internally to add a cell.
      */
-
     private void addCell(HSSFCell cell)
     {
         short column=cell.getCellNum();

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java Fri Jan 25 07:48:14 2008
@@ -121,7 +121,7 @@
     }
 
     /**
-     * Sets the coordinate space of this group.  All children are contrained
+     * Sets the coordinate space of this group.  All children are constrained
      * to these coordinates.
      */
     public void setCoordinates( int x1, int y1, int x2, int y2 )
@@ -177,5 +177,4 @@
         }
         return count;
     }
-
-}
+}
\ No newline at end of file

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Fri Jan 25 07:48:14 2008
@@ -28,6 +28,7 @@
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.*;
 import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.ReferencePtg;
 import org.apache.poi.hssf.util.HSSFCellRangeAddress;
 import org.apache.poi.hssf.util.HSSFDataValidation;
 import org.apache.poi.hssf.util.Region;
@@ -594,6 +595,26 @@
     }
 
     /**
+     * Whether a record must be inserted or not at generation to indicate that 
+     * formula must be recalculated when workbook is opened.
+     * @param value true if an uncalced record must be inserted or not at generation
+     */
+    public void setForceFormulaRecalculation(boolean value)
+    {
+    	sheet.setUncalced(value);
+    }
+    /**
+     * Whether a record must be inserted or not at generation to indicate that 
+     * formula must be recalculated when workbook is opened.
+     * @return true if an uncalced record must be inserted or not at generation
+     */
+    public boolean getForceFormulaRecalculation()
+    {
+    	return sheet.getUncalced();
+    }
+
+    
+    /**
      * determines whether the output is vertically centered on the page.
      * @param value true to vertically center, false otherwise.
      */
@@ -1202,10 +1223,66 @@
                     row2Replace.createCellFromRecord( cellRecord );
                     sheet.addValueRecord( rowNum + n, cellRecord );
                 }
+
+                // move comments if exist (can exist even if cell is null)
+                HSSFComment comment = getCellComment(rowNum, col);
+                if (comment != null) {
+                   comment.setRow(rowNum + n);
+                }
             }
         }
         if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 );
         if ( startRow == firstrow || startRow + n < firstrow ) firstrow = Math.max( startRow + n, 0 );
+        
+        // Update any formulas on this sheet that point to
+        //  rows which have been moved
+        updateFormulasAfterShift(startRow, endRow, n);
+    }
+    
+    /**
+     * Called by shiftRows to update formulas on this sheet
+     *  to point to the new location of moved rows
+     */
+    private void updateFormulasAfterShift(int startRow, int endRow, int n) {
+    	// Need to look at every cell on the sheet
+    	// Not just those that were moved
+        Iterator ri = rowIterator();
+        while(ri.hasNext()) {
+        	HSSFRow r = (HSSFRow)ri.next();
+        	Iterator ci = r.cellIterator();
+        	while(ci.hasNext()) {
+        		HSSFCell c = (HSSFCell)ci.next();
+        		if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+        			// Since it's a formula cell, process the
+        			//  formula string, and look to see if
+        			//  it contains any references
+        			FormulaParser fp = new FormulaParser(c.getCellFormula(), workbook.getWorkbook());
+        			fp.parse();
+        			
+        			// Look for references, and update if needed
+        			Ptg[] ptgs = fp.getRPNPtg();
+        			boolean changed = false;
+        			for(int i=0; i<ptgs.length; i++) {
+        				if(ptgs[i] instanceof ReferencePtg) {
+        					ReferencePtg rptg = (ReferencePtg)ptgs[i];
+        					if(startRow <= rptg.getRowAsInt() &&
+        							rptg.getRowAsInt() <= endRow) {
+        						// References a row that moved
+        						rptg.setRow(rptg.getRowAsInt() + n);
+        						changed = true;
+        					}
+        				}
+        			}
+        			// If any references were changed, then
+        			//  re-create the formula string
+        			if(changed) {
+        				c.setCellFormula(
+        						fp.toFormulaString(ptgs)
+        				);
+        			}
+        		}
+        	}
+        }
     }
 
     protected void insertChartRecords( List records )
@@ -1431,7 +1508,7 @@
      */
     public void dumpDrawingRecords(boolean fat)
     {
-        sheet.aggregateDrawingRecords(book.getDrawingManager());
+        sheet.aggregateDrawingRecords(book.getDrawingManager(), false);
 
         EscherAggregate r = (EscherAggregate) getSheet().findFirstRecordBySid(EscherAggregate.sid);
         List escherRecords = r.getEscherRecords();
@@ -1448,9 +1525,10 @@
     }
 
     /**
-     * Creates the toplevel drawing patriarch.  This will have the effect of
-     * removing any existing drawings on this sheet.
-     *
+     * Creates the top-level drawing patriarch.  This will have
+     *  the effect of removing any existing drawings on this
+     *  sheet.
+     * This may then be used to add graphics or charts
      * @return  The new patriarch.
      */
     public HSSFPatriarch createDrawingPatriarch()
@@ -1458,14 +1536,57 @@
         // Create the drawing group if it doesn't already exist.
         book.createDrawingGroup();
 
-        sheet.aggregateDrawingRecords(book.getDrawingManager());
+        sheet.aggregateDrawingRecords(book.getDrawingManager(), true);
         EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid);
-        HSSFPatriarch patriarch = new HSSFPatriarch(this);
+        HSSFPatriarch patriarch = new HSSFPatriarch(this, agg);
         agg.clear();     // Initially the behaviour will be to clear out any existing shapes in the sheet when
                          // creating a new patriarch.
         agg.setPatriarch(patriarch);
         return patriarch;
     }
+    
+    /**
+     * Returns the top-level drawing patriach, if there is
+     *  one.
+     * This will hold any graphics or charts for the sheet.
+     * WARNING - calling this will trigger a parsing of the
+     *  associated escher records. Any that aren't supported
+     *  (such as charts and complex drawing types) will almost
+     *  certainly be lost or corrupted when written out. Only
+     *  use this with simple drawings, otherwise call
+     *  {@link HSSFSheet#createDrawingPatriarch()} and
+     *  start from scratch!
+     */
+    public HSSFPatriarch getDrawingPatriarch() {
+    	book.findDrawingGroup();
+    	
+    	// If there's now no drawing manager, then there's
+    	//  no drawing escher records on the workbook
+    	if(book.getDrawingManager() == null) {
+    		return null;
+    	}
+    	
+    	int found = sheet.aggregateDrawingRecords(
+    			book.getDrawingManager(), false
+    	);
+    	if(found == -1) {
+    		// Workbook has drawing stuff, but this sheet doesn't
+    		return null;
+    	}
+    	
+    	// Grab our aggregate record, and wire it up
+        EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid);
+        HSSFPatriarch patriarch = new HSSFPatriarch(this, agg);
+        agg.setPatriarch(patriarch);
+        
+        // Have it process the records into high level objects
+        //  as best it can do (this step may eat anything
+        //  that isn't supported, you were warned...)
+        agg.convertRecordsToUserModel();
+        
+        // Return what we could cope with
+        return patriarch;
+    }
 
     /**
      * Expands or collapses a column group.
@@ -1558,7 +1679,13 @@
         for (Iterator it = rowIterator(); it.hasNext();) {
             HSSFRow row = (HSSFRow) it.next();
             HSSFCell cell = row.getCell(column);
-            if (cell == null) continue;
+
+            boolean isCellInMergedRegion = false;
+            for (int i = 0 ; i < getNumMergedRegions() && ! isCellInMergedRegion; i++) {
+                isCellInMergedRegion = getMergedRegionAt(i).contains(row.getRowNum(), column);
+            }
+
+            if (cell == null | isCellInMergedRegion) continue;
 
             HSSFCellStyle style = cell.getCellStyle();
             HSSFFont font = wb.getFontAt(style.getFontIndex());
@@ -1621,27 +1748,28 @@
                 } else if (cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
                     sval = String.valueOf(cell.getBooleanCellValue());
                 }
+                if(sval != null) {
+                    String txt = sval + defaultChar;
+                    str = new AttributedString(txt);
+                    copyAttributes(font, str, 0, txt.length());
 
-                String txt = sval + defaultChar;
-                str = new AttributedString(txt);
-                copyAttributes(font, str, 0, txt.length());
-
-                layout = new TextLayout(str.getIterator(), frc);
-                if(style.getRotation() != 0){
-                    /*
-                     * Transform the text using a scale so that it's height is increased by a multiple of the leading,
-                     * and then rotate the text before computing the bounds. The scale results in some whitespace around
-                     * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
-                     * is added by the standard Excel autosize.
-                     */
-                    AffineTransform trans = new AffineTransform();
-                    trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
-                    trans.concatenate(
-                    AffineTransform.getScaleInstance(1, fontHeightMultiple)
-                    );
-                    width = Math.max(width, layout.getOutline(trans).getBounds().getWidth() / defaultCharWidth);
-                } else {
-                    width = Math.max(width, layout.getBounds().getWidth() / defaultCharWidth);
+                    layout = new TextLayout(str.getIterator(), frc);
+                    if(style.getRotation() != 0){
+                        /*
+                         * Transform the text using a scale so that it's height is increased by a multiple of the leading,
+                         * and then rotate the text before computing the bounds. The scale results in some whitespace around
+                         * the unrotated top and bottom of the text that normally wouldn't be present if unscaled, but
+                         * is added by the standard Excel autosize.
+                         */
+                        AffineTransform trans = new AffineTransform();
+                        trans.concatenate(AffineTransform.getRotateInstance(style.getRotation()*2.0*Math.PI/360.0));
+                        trans.concatenate(
+                        AffineTransform.getScaleInstance(1, fontHeightMultiple)
+                        );
+                        width = Math.max(width, layout.getOutline(trans).getBounds().getWidth() / defaultCharWidth);
+                    } else {
+                        width = Math.max(width, layout.getBounds().getWidth() / defaultCharWidth);
+                    }
                 }
             }
 
@@ -1671,7 +1799,21 @@
      * @return cell comment or <code>null</code> if not found
      */
      public HSSFComment getCellComment(int row, int column){
-        return HSSFCell.findCellComment(sheet, row, column);
+        // Don't call findCellComment directly, otherwise
+        //  two calls to this method will result in two
+        //  new HSSFComment instances, which is bad
+        HSSFRow r = getRow(row);
+        if(r != null) {
+            HSSFCell c = r.getCell((short)column);
+            if(c != null) {
+                return c.getCellComment();
+            } else {
+                // No cell, so you will get new
+                //  objects every time, sorry...
+                return HSSFCell.findCellComment(sheet, row, column);
+            }
+        }
+        return null;
     }
 
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Fri Jan 25 07:48:14 2008
@@ -445,6 +445,35 @@
         return workbook.getSheetName(sheet);
     }
 
+    /**
+     * check whether a sheet is hidden
+     * @param sheet Number
+     * @return True if sheet is hidden
+     */
+
+    public boolean isSheetHidden(int sheet) {
+        if (sheet > (sheets.size() - 1))
+        {
+            throw new RuntimeException("Sheet out of bounds");
+        }
+        return workbook.isSheetHidden(sheet);
+    }
+
+    /**
+     * Hide or unhide a sheet
+     * 
+     * @param sheetnum The sheet number
+     * @param hidden True to mark the sheet as hidden, false otherwise
+     */
+
+    public void setSheetHidden(int sheet, boolean hidden) {
+        if (sheet > (sheets.size() - 1))
+        {
+            throw new RuntimeException("Sheet out of bounds");
+        }
+        workbook.setSheetHidden(sheet,hidden);
+    }
+    
     /*
      * get the sheet's index
      * @param name  sheet name

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/AreaReference.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/AreaReference.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/AreaReference.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/AreaReference.java Fri Jan 25 07:48:14 2008
@@ -18,15 +18,24 @@
 
 package org.apache.poi.hssf.util;
 
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
 public class AreaReference {
 
 
 private CellReference [] cells;
 private int dim;
 
-    /** Create an area ref from a string representation
+    /**
+     * Create an area ref from a string representation.
+     * The area reference must be contiguous
      */
     public AreaReference(String reference) {
+        if(! isContiguous(reference)) {
+            throw new IllegalArgumentException("References passed to the AreaReference must be contiguous, use generateContiguous(ref) if you have non-contiguous references");
+        }
+
         String[] refs = seperateAreaRefs(reference);
         dim = refs.length;
         cells = new CellReference[dim];
@@ -34,15 +43,72 @@
             cells[i]=new CellReference(refs[i]);
         }
     }
+
+    /**
+     * Is the reference for a contiguous (i.e.
+     *  unbroken) area, or is it made up of
+     *  several different parts?
+     * (If it is, you will need to call
+     *  ....
+     */
+    public static boolean isContiguous(String reference) {
+        if(reference.indexOf(',') == -1) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Takes a non-contiguous area reference, and
+     *  returns an array of contiguous area references.
+     */
+    public static AreaReference[] generateContiguous(String reference) {
+        ArrayList refs = new ArrayList();
+        StringTokenizer st = new StringTokenizer(reference, ",");
+        while(st.hasMoreTokens()) {
+            refs.add(
+                    new AreaReference(st.nextToken())
+            );
+        }
+        return (AreaReference[])refs.toArray(new AreaReference[refs.size()]);
+    }
+
     //not sure if we need to be flexible here!
     /** return the dimensions of this area
      **/
     public int getDim() {
         return dim;
     }
-    /** return the cell references that define this area */
+    /** 
+     * Return the cell references that define this area
+     * (i.e. the two corners) 
+     */
     public CellReference[] getCells() {
         return cells;
+    }
+    /**
+     * Returns a reference to every cell covered by this area
+     */
+    public CellReference[] getAllReferencedCells() {
+    	// Special case for single cell reference
+    	if(cells.length == 1) {
+    		return cells;
+    	}
+    	// Interpolate between the two
+    	int minRow = Math.min(cells[0].getRow(), cells[1].getRow());
+    	int maxRow = Math.max(cells[0].getRow(), cells[1].getRow());
+    	int minCol = Math.min(cells[0].getCol(), cells[1].getCol());
+    	int maxCol = Math.max(cells[0].getCol(), cells[1].getCol());
+    	
+    	ArrayList refs = new ArrayList();
+    	for(int row=minRow; row<=maxRow; row++) {
+    		for(int col=minCol; col<=maxCol; col++) {
+    			CellReference ref = new CellReference(row, col, cells[0].isRowAbsolute(), cells[0].isColAbsolute());
+    			ref.setSheetName(cells[0].getSheetName());
+    			refs.add(ref);
+    		}
+    	}
+    	return (CellReference[])refs.toArray(new CellReference[refs.size()]);
     }
 
     public String toString() {

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/CellReference.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/CellReference.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/CellReference.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/hssf/util/CellReference.java Fri Jan 25 07:48:14 2008
@@ -69,6 +69,10 @@
     public boolean isRowAbsolute(){return rowAbs;}
     public boolean isColAbsolute(){return colAbs;}
     public String getSheetName(){return sheetName;}
+    
+    protected void setSheetName(String sheetName) {
+    	this.sheetName = sheetName;
+    }
 
     /**
      * takes in a column reference portion of a CellRef and converts it from

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/common/POIFSConstants.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/common/POIFSConstants.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/common/POIFSConstants.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/common/POIFSConstants.java Fri Jan 25 07:48:14 2008
@@ -31,4 +31,7 @@
     public static final int END_OF_CHAIN   = -2;
     public static final int PROPERTY_SIZE  = 0x0080;
     public static final int UNUSED_BLOCK   = -1;
+    
+    public static final byte[] OOXML_FILE_HEADER = 
+    	new byte[] { 0x50, 0x4b, 0x03, 0x04 };
 }   // end public interface POIFSConstants;

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java Fri Jan 25 07:48:14 2008
@@ -19,14 +19,19 @@
 
 package org.apache.poi.poifs.filesystem;
 
-import java.io.*;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
-import java.util.*;
-
-import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
 import org.apache.poi.poifs.property.DirectoryProperty;
-import org.apache.poi.poifs.property.DocumentProperty;
 import org.apache.poi.poifs.property.Property;
 import org.apache.poi.poifs.property.PropertyTable;
 import org.apache.poi.poifs.storage.BATBlock;
@@ -34,13 +39,14 @@
 import org.apache.poi.poifs.storage.BlockAllocationTableWriter;
 import org.apache.poi.poifs.storage.BlockList;
 import org.apache.poi.poifs.storage.BlockWritable;
+import org.apache.poi.poifs.storage.HeaderBlockConstants;
 import org.apache.poi.poifs.storage.HeaderBlockReader;
 import org.apache.poi.poifs.storage.HeaderBlockWriter;
-import org.apache.poi.poifs.storage.RawDataBlock;
 import org.apache.poi.poifs.storage.RawDataBlockList;
 import org.apache.poi.poifs.storage.SmallBlockTableReader;
 import org.apache.poi.poifs.storage.SmallBlockTableWriter;
-import org.apache.poi.poifs.storage.SmallDocumentBlock;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LongField;
 
 /**
  * This is the main class of the POIFS system; it manages the entire
@@ -105,6 +111,35 @@
                 .getRoot(), header_block_reader
                     .getSBATStart()), data_blocks, properties.getRoot()
                         .getChildren(), null);
+    }
+    
+    /**
+     * Checks that the supplied InputStream (which MUST
+     *  support mark and reset, or be a PushbackInputStream) 
+     *  has a POIFS (OLE2) header at the start of it.
+     * If your InputStream does not support mark / reset,
+     *  then wrap it in a PushBackInputStream, then be
+     *  sure to always use that, and not the original!
+     * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream 
+     */
+    public static boolean hasPOIFSHeader(InputStream inp) throws IOException {
+    	// We want to peek at the first 8 bytes 
+    	inp.mark(8);
+
+    	byte[] header = new byte[8];
+    	IOUtils.readFully(inp, header);
+        LongField signature = new LongField(HeaderBlockConstants._signature_offset, header);
+
+        // Wind back those 8 bytes
+        if(inp instanceof PushbackInputStream) {
+        	PushbackInputStream pin = (PushbackInputStream)inp;
+        	pin.unread(header);
+        } else {
+        	inp.reset();
+        }
+    	
+    	// Did it match the signature?
+    	return (signature.get() == HeaderBlockConstants._signature);
     }
 
     /**

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java Fri Jan 25 07:48:14 2008
@@ -91,8 +91,11 @@
         if (signature.get() != _signature)
         {
 			// Is it one of the usual suspects?
-			if(_data[0] == 0x50 && _data[1] == 0x4b && _data[2] == 0x03 &&
-					_data[3] == 0x04) {
+        	byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER;
+			if(_data[0] == OOXML_FILE_HEADER[0] && 
+					_data[1] == OOXML_FILE_HEADER[1] && 
+					_data[2] == OOXML_FILE_HEADER[2] &&
+					_data[3] == OOXML_FILE_HEADER[3]) {
 				throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. POI only supports OLE2 Office documents");
 			}
 

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/RawDataBlock.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/RawDataBlock.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/RawDataBlock.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/poifs/storage/RawDataBlock.java Fri Jan 25 07:48:14 2008
@@ -42,34 +42,44 @@
      * @param stream the InputStream from which the data will be read
      *
      * @exception IOException on I/O errors, and if an insufficient
-     *            amount of data is read
+     *            amount of data is read (the InputStream must
+     *            be an exact multiple of the block size)
      */
-
     public RawDataBlock(final InputStream stream)
-        throws IOException
-    {
-        _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ];
+    		throws IOException {
+    	this(stream, POIFSConstants.BIG_BLOCK_SIZE);
+    }
+    /**
+     * Constructor RawDataBlock
+     *
+     * @param stream the InputStream from which the data will be read
+     * @param blockSize the size of the POIFS blocks, normally 512 bytes {@link POIFSConstants#BIG_BLOCK_SIZE}
+     *
+     * @exception IOException on I/O errors, and if an insufficient
+     *            amount of data is read (the InputStream must
+     *            be an exact multiple of the block size)
+     */
+    public RawDataBlock(final InputStream stream, int blockSize)
+    		throws IOException {
+        _data = new byte[ blockSize ];
         int count = IOUtils.readFully(stream, _data);
 
-        if (count == -1)
-        {
+        if (count == -1) {
             _eof = true;
         }
-        else if (count != POIFSConstants.BIG_BLOCK_SIZE)
-        {
-        	if (count == -1)
-        		//Cant have -1 bytes read in the error message!
-        		count = 0;
-        	
+        else if (count != blockSize) {
+        	// IOUtils.readFully will always read the
+        	//  requested number of bytes, unless it hits
+        	//  an EOF
+            _eof = true;
             String type = " byte" + ((count == 1) ? ("")
                                                   : ("s"));
 
             throw new IOException("Unable to read entire block; " + count
-                                  + type + " read; expected "
-                                  + POIFSConstants.BIG_BLOCK_SIZE + " bytes");
+                                  + type + " read before EOF; expected "
+                                  + blockSize + " bytes");
         }
-        else
-        {
+        else {
             _eof = false;
         }
     }
@@ -82,7 +92,6 @@
      *
      * @exception IOException
      */
-
     public boolean eof()
         throws IOException
     {
@@ -98,7 +107,6 @@
      *
      * @exception IOException if there is no data
      */
-
     public byte [] getData()
         throws IOException
     {

Modified: poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/util/IOUtils.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/util/IOUtils.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/util/IOUtils.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/java/org/apache/poi/util/IOUtils.java Fri Jan 25 07:48:14 2008
@@ -58,11 +58,16 @@
     }
 
     /**
-     * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure that
-     * the entire len number of bytes is read.
+     * Same as the normal <tt>in.read(b, off, len)</tt>, but
+     *  tries to ensure that the entire len number of bytes
+     *  is read.
      * <p>
-     * If the end of file is reached before any bytes are read, returns -1.
-     * Otherwise, returns the number of bytes read.
+     * If the end of file is reached before any bytes
+     *  are read, returns -1.
+     * If the end of the file is reached after some bytes are
+     *  read, returns the number of bytes read.
+     * If the end of the file isn't reached before len
+     *  bytes have been read, will return len bytes.
      */
     public static int readFully(InputStream in, byte[] b, int off, int len)
     throws IOException
@@ -79,5 +84,4 @@
             }
         }
     }
-}
-
+}
\ No newline at end of file

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java Fri Jan 25 07:48:14 2008
@@ -41,7 +41,9 @@
 	private HSLFSlideShow _hslfshow;
 	private SlideShow _show;
 	private Slide[] _slides;
-	private Notes[] _notes;
+	
+	private boolean slidesByDefault = true;
+	private boolean notesByDefault = false;
 
   /**
    * Basic extractor. Returns all the text, and optionally all the notes
@@ -99,7 +101,6 @@
 		_hslfshow = ss;
 		_show = new SlideShow(_hslfshow);
 		_slides = _show.getSlides();
-		_notes = _show.getNotes();
 	}
 
 	/**
@@ -110,23 +111,39 @@
 		_hslfshow = null;
 		_show = null;
 		_slides = null;
-		_notes = null;
 	}
 
+	/**
+	 * Should a call to getText() return slide text?
+	 * Default is yes
+	 */
+	public void setSlidesByDefault(boolean slidesByDefault) {
+		this.slidesByDefault = slidesByDefault;
+	}
+	/**
+	 * Should a call to getText() return notes text?
+	 * Default is no
+	 */
+	public void setNotesByDefault(boolean notesByDefault) {
+		this.notesByDefault = notesByDefault;
+	}
 
-  /**
-   * Fetches all the slide text from the slideshow, but not the notes
-   */
-  public String getText() {
-	return getText(true,false);
-  }
+	/**
+	 * Fetches all the slide text from the slideshow, 
+	 *  but not the notes, unless you've called
+	 *  setSlidesByDefault() and setNotesByDefault()
+	 *  to change this
+	 */
+	public String getText() {
+		return getText(slidesByDefault,notesByDefault);
+	}
 
-  /**
-   * Fetches all the notes text from the slideshow, but not the slide text
-   */
-  public String getNotes() {
-	return getText(false,true);
-  }
+	/**
+	 * Fetches all the notes text from the slideshow, but not the slide text
+	 */
+	public String getNotes() {
+		return getText(false,true);
+	}
 
   /**
    * Fetches text from the slideshow, be it slide text or note text.
@@ -154,7 +171,7 @@
 			}
 		}
 		if(getNoteText) {
-			ret.append(" ");
+			ret.append("\n");
 		}
 	}
 

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java Fri Jan 25 07:48:14 2008
@@ -24,7 +24,12 @@
 import java.util.Vector;
 
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
-import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.record.Record;
+import org.apache.poi.hslf.record.RecordContainer;
+import org.apache.poi.hslf.record.StyleTextPropAtom;
+import org.apache.poi.hslf.record.TextBytesAtom;
+import org.apache.poi.hslf.record.TextCharsAtom;
+import org.apache.poi.hslf.record.TextHeaderAtom;
 import org.apache.poi.hslf.usermodel.RichTextRun;
 import org.apache.poi.hslf.usermodel.SlideShow;
 import org.apache.poi.util.StringUtil;
@@ -252,9 +257,70 @@
 	
 	
 	// Update methods follow
+	
+	/**
+	 * Adds the supplied text onto the end of the TextRun, 
+	 *  creating a new RichTextRun (returned) for it to
+	 *  sit in. 
+	 * In many cases, before calling this, you'll want to add
+	 *  a newline onto the end of your last RichTextRun
+	 */
+	public RichTextRun appendText(String s) {
+		// We will need a StyleTextProp atom
+		ensureStyleAtomPresent();
+		
+		// First up, append the text to the 
+		//  underlying text atom
+		int oldSize = getRawText().length();
+		storeText(
+				getRawText() + s
+		);
+		
+		// If either of the previous styles overran
+		//  the text by one, we need to shuffle that
+		//  extra character onto the new ones
+		int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize;
+		int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize;
+		if(pOverRun > 0) {
+			TextPropCollection tpc = (TextPropCollection)
+				_styleAtom.getParagraphStyles().getLast();
+			tpc.updateTextSize(
+					tpc.getCharactersCovered() - pOverRun
+			);
+		}
+		if(cOverRun > 0) {
+			TextPropCollection tpc = (TextPropCollection)
+				_styleAtom.getCharacterStyles().getLast();
+			tpc.updateTextSize(
+					tpc.getCharactersCovered() - cOverRun
+			);
+		}
+		
+		// Next, add the styles for its paragraph and characters
+		TextPropCollection newPTP =
+			_styleAtom.addParagraphTextPropCollection(s.length()+pOverRun);
+		TextPropCollection newCTP =
+			_styleAtom.addCharacterTextPropCollection(s.length()+cOverRun);
+		
+		// Now, create the new RichTextRun
+		RichTextRun nr = new RichTextRun(
+				this, oldSize, s.length(), 
+				newPTP, newCTP, false, false
+		);
+		
+		// Add the new RichTextRun onto our list
+		RichTextRun[] newRuns = new RichTextRun[_rtRuns.length+1];
+		System.arraycopy(_rtRuns, 0, newRuns, 0, _rtRuns.length);
+		newRuns[newRuns.length-1] = nr;
+		_rtRuns = newRuns;
+		
+		// And return the new run to the caller
+		return nr;
+	}
 
 	/**
-	 * Saves the given string to the records. Doesn't touch the stylings. 
+	 * Saves the given string to the records. Doesn't 
+	 *  touch the stylings. 
 	 */
 	private void storeText(String s) {
 		// Remove a single trailing \n, as there is an implicit one at the

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java Fri Jan 25 07:48:14 2008
@@ -19,17 +19,19 @@
 
 package org.apache.poi.hslf.record;
 
-import org.apache.poi.hslf.model.textproperties.*;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
-
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.LinkedList;
-import java.util.Vector;
-import java.util.List;
 import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.poi.hslf.model.textproperties.AlignmentTextProp;
+import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
 
 /**
  * A StyleTextPropAtom (type 4001). Holds basic character properties 
@@ -88,6 +90,37 @@
 	 *  character stylings
 	 */
 	public void setCharacterStyles(LinkedList cs) { charStyles = cs; }
+	
+	/**
+	 * Returns how many characters the paragraph's
+	 *  TextPropCollections cover.
+	 * (May be one or two more than the underlying text does,
+	 *  due to having extra characters meaning something
+	 *  special to powerpoint)
+	 */
+	public int getParagraphTextLengthCovered() {
+		return getCharactersCovered(paragraphStyles);
+	}
+	/**
+	 * Returns how many characters the character's
+	 *  TextPropCollections cover.
+	 * (May be one or two more than the underlying text does,
+	 *  due to having extra characters meaning something
+	 *  special to powerpoint)
+	 */
+	public int getCharacterTextLengthCovered() {
+		return getCharactersCovered(charStyles);
+	}
+	private int getCharactersCovered(LinkedList styles) {
+		int length = 0;
+		Iterator it = styles.iterator();
+		while(it.hasNext()) {
+			TextPropCollection tpc =
+				(TextPropCollection)it.next();
+			length += tpc.getCharactersCovered();
+		}
+		return length;
+	}
 
 	/** All the different kinds of paragraph properties we might handle */
 	public static TextProp[] paragraphTextPropTypes = new TextProp[] {
@@ -355,8 +388,7 @@
 		charStyles.add(tpc);
 		return tpc;
 	}
-
-
+	
 /* ************************************************************************ */
 
 

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java Fri Jan 25 07:48:14 2008
@@ -20,25 +20,28 @@
 
 package org.apache.poi.hslf.usermodel;
 
-import org.apache.poi.hslf.model.*;
+import java.awt.Color;
+
+import org.apache.poi.hslf.model.MasterSheet;
 import org.apache.poi.hslf.model.Shape;
-import org.apache.poi.hslf.model.textproperties.*;
+import org.apache.poi.hslf.model.Sheet;
+import org.apache.poi.hslf.model.TextRun;
+import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
+import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.hslf.exceptions.HSLFException;
-
-import java.awt.*;
 
 
 /**
  * Represents a run of text, all with the same style
  * 
- * TODO: get access to the font/character properties
- *
- * @author Nick Burch
+ * TODO: finish all the getters and setters to the
+ *  font/character/paragraph properties (currently only
+ *  has some of them) 
  */
-
-public class RichTextRun
-{
+public class RichTextRun {
 	/** The TextRun we belong to */
 	private TextRun parentRun;
 	/** The SlideShow we belong to */

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Fri Jan 25 07:48:14 2008
@@ -217,14 +217,66 @@
     
     
     /**
-     * If cell contains formula, it evaluates the formula, and puts the 
-     * formula result back into the cell.
-     * Else if cell does not contain formula, this method leaves the cell 
-     * unchanged. Note that the same instance of HSSFCell is returned to 
+     * If cell contains formula, it evaluates the formula,
+     *  and saves the result of the formula. The cell
+     *  remains as a formula cell.
+     * Else if cell does not contain formula, this method leaves
+     *  the cell unchanged. 
+     * Note that the type of the formula result is returned,
+     *  so you know what kind of value is also stored with
+     *  the formula. 
+     * <pre>
+     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
+     * </pre>
+     * Be aware that your cell will hold both the formula,
+     *  and the result. If you want the cell replaced with
+     *  the result of the formula, use {@link #evaluateInCell(HSSFCell)}
+     * @param cell The cell to evaluate
+     * @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however)
+     */
+    public int evaluateFormulaCell(HSSFCell cell) {
+        if (cell != null) {
+            switch (cell.getCellType()) {
+            case HSSFCell.CELL_TYPE_FORMULA:
+                CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook));
+                switch (cv.getCellType()) {
+                case HSSFCell.CELL_TYPE_BOOLEAN:
+                    cell.setCellValue(cv.getBooleanValue());
+                    break;
+                case HSSFCell.CELL_TYPE_ERROR:
+                    cell.setCellValue(cv.getErrorValue());
+                    break;
+                case HSSFCell.CELL_TYPE_NUMERIC:
+                    cell.setCellValue(cv.getNumberValue());
+                    break;
+                case HSSFCell.CELL_TYPE_STRING:
+                    cell.setCellValue(cv.getRichTextStringValue());
+                    break;
+                case HSSFCell.CELL_TYPE_BLANK:
+                    break;
+                case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
+                    break;
+                }
+                return cv.getCellType();
+            }
+        }
+        return -1;
+    }
+        
+    /**
+     * If cell contains formula, it evaluates the formula, and
+     *  puts the formula result back into the cell, in place
+     *  of the old formula.
+     * Else if cell does not contain formula, this method leaves
+     *  the cell unchanged. 
+     * Note that the same instance of HSSFCell is returned to 
      * allow chained calls like:
      * <pre>
      * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
      * </pre>
+     * Be aware that your cell value will be changed to hold the
+     *  result of the formula. If you simply want the formula
+     *  value computed for you, use {@link #evaluateFormulaCell(HSSFCell)}
      * @param cell
      */
     public HSSFCell evaluateInCell(HSSFCell cell) {

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableRow.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableRow.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableRow.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/src/org/apache/poi/hwpf/usermodel/TableRow.java Fri Jan 25 07:48:14 2008
@@ -58,7 +58,7 @@
         p = getParagraph(end);
         s = p.text();
       }
-      _cells[cellIndex] = new TableCell(start, end, this, levelNum,
+      _cells[cellIndex] = new TableCell(start, end+1, this, levelNum,
                                         _tprops.getRgtc()[cellIndex],
                                         _tprops.getRgdxaCenter()[cellIndex],
                                         _tprops.getRgdxaCenter()[cellIndex+1]-_tprops.getRgdxaCenter()[cellIndex]);

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TextExtractor.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TextExtractor.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TextExtractor.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TextExtractor.java Fri Jan 25 07:48:14 2008
@@ -72,6 +72,29 @@
 		
 		ensureTwoStringsTheSame(expectText, notesText);
 	}
+	
+	public void testReadBoth() throws Exception {
+		String[] slText = new String[] {
+				"This is a test title\nThis is a test subtitle\nThis is on page 1\n",
+				"This is the title on page 2\nThis is page two\nIt has several blocks of text\nNone of them have formatting\n"
+		};
+		String[] ntText = new String[] {
+				"These are the notes for page 1\n",
+				"These are the notes on page two, again lacking formatting\n"
+		};
+		
+		ppe.setSlidesByDefault(true);
+		ppe.setNotesByDefault(false);
+		assertEquals(slText[0]+slText[1], ppe.getText());
+		
+		ppe.setSlidesByDefault(false);
+		ppe.setNotesByDefault(true);
+		assertEquals(ntText[0]+ntText[1], ppe.getText());
+		
+		ppe.setSlidesByDefault(true);
+		ppe.setNotesByDefault(true);
+		assertEquals(slText[0]+slText[1]+"\n"+ntText[0]+ntText[1], ppe.getText());
+	}
 
 	/**
 	 * Test that when presented with a PPT file missing the odd

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java Fri Jan 25 07:48:14 2008
@@ -16,16 +16,22 @@
 */
 package org.apache.poi.hslf.usermodel;
 
-import java.io.*;
-import java.awt.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import junit.framework.TestCase;
 
 import org.apache.poi.hslf.HSLFSlideShow;
-import org.apache.poi.hslf.model.*;
+import org.apache.poi.hslf.model.Slide;
+import org.apache.poi.hslf.model.SlideMaster;
+import org.apache.poi.hslf.model.TextBox;
+import org.apache.poi.hslf.model.TextRun;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.SlideListWithText;
 
-import junit.framework.TestCase;
-
 /**
  * Test that the friendly getters and setters on RichTextRun
  *  behave as expected.
@@ -548,5 +554,76 @@
         assertEquals(50, rt.getTextOffset());
         assertEquals(0, rt.getBulletOffset());
         assertEquals('\u263A', rt.getBulletChar());
+    }
+    
+    public void testAddText() throws Exception {
+        FileInputStream is = new FileInputStream(new File(System.getProperty("HSLF.testdata.path"), "bullets.ppt"));
+        SlideShow ppt = new SlideShow(is);
+        is.close();
+        assertTrue("No Exceptions while reading file", true);
+
+        RichTextRun rt;
+        TextRun[] txt;
+        Slide[] slides = ppt.getSlides();
+        
+        assertEquals(2, slides.length);
+        txt = slides[0].getTextRuns();
+        assertEquals(2, txt.length);
+
+        assertEquals("Title text", txt[0].getRawText());
+        assertEquals(1, txt[0].getRichTextRuns().length);
+        rt = txt[0].getRichTextRuns()[0];
+        assertFalse(rt.isBullet());
+        
+        // Add some new text
+        txt[0].appendText("Foo! I'm new!");
+        assertEquals(2, txt[0].getRichTextRuns().length);
+        
+        rt = txt[0].getRichTextRuns()[0];
+        assertFalse(rt.isBold());
+        assertEquals("Title text", rt.getText());
+        rt = txt[0].getRichTextRuns()[1];
+        assertFalse(rt.isBold());
+        assertEquals("Foo! I'm new!", rt.getText());
+        rt.setBold(true);
+        
+        // And some more
+        txt[0].appendText("Me too!");
+        assertEquals(3, txt[0].getRichTextRuns().length);
+        rt = txt[0].getRichTextRuns()[0];
+        assertFalse(rt.isBold());
+        assertEquals("Title text", rt.getText());
+        rt = txt[0].getRichTextRuns()[1];
+        assertTrue(rt.isBold());
+        assertEquals("Foo! I'm new!", rt.getText());
+        rt = txt[0].getRichTextRuns()[2];
+        assertFalse(rt.isBold());
+        assertEquals("Me too!", rt.getText());
+        
+        // Save and re-open
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        out.close();
+
+        ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
+        slides = ppt.getSlides();
+        
+        assertEquals(2, slides.length);
+        
+        txt = slides[0].getTextRuns();
+        assertEquals(2, txt.length);
+        assertEquals(3, txt[0].getRichTextRuns().length);
+        rt = txt[0].getRichTextRuns()[0];
+        assertFalse(rt.isBold());
+        assertEquals("Title text", rt.getText());
+        rt = txt[0].getRichTextRuns()[1];
+        assertTrue(rt.isBold());
+        assertEquals("Foo! I'm new!", rt.getText());
+        rt = txt[0].getRichTextRuns()[2];
+        assertFalse(rt.isBold());
+        assertEquals("Me too!", rt.getText());
+        
+//        FileOutputStream fout = new FileOutputStream("/tmp/foo.ppt");
+//        ppt.write(fout);
     }
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java Fri Jan 25 07:48:14 2008
@@ -74,4 +74,34 @@
     		}
     	}
 	}
+
+	/**
+	 * Test for TableCell not skipping the last paragraph
+	 */
+	public void testTableCellLastParagraph() throws Exception {
+    	HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/Bug44292.doc"));
+		Range r = doc.getRange();
+			
+		//get the table
+		Paragraph p = r.getParagraph(0);
+		Table t = r.getTable(p);
+		
+		//get the only row
+		TableRow row = t.getRow(0);
+		
+		//get the first cell
+		TableCell cell = row.getCell(0);
+		// First cell should have one paragraph
+		assertEquals(1, cell.numParagraphs());
+		
+		//get the second
+		cell = row.getCell(1);
+		// Second cell should be detected as having two paragraphs
+		assertEquals(2, cell.numParagraphs());
+				
+		//get the last cell
+		cell = row.getCell(2);
+		// Last cell should have one paragraph
+		assertEquals(1, cell.numParagraphs());
+	}
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java Fri Jan 25 07:48:14 2008
@@ -82,21 +82,45 @@
         r2.setOptions( (short) 0x9876 );
         r2.setRecordId( EscherOptRecord.RECORD_ID );
 
+        String expected;
         r.addChildRecord( r2 );
-        String expected = "org.apache.poi.ddf.EscherContainerRecord (SpContainer):" + nl +
-                        "  isContainer: true" + nl +
-                        "  options: 0x000F" + nl +
-                        "  recordId: 0xF004" + nl +
-                        "  numchildren: 1" + nl +
-                        "  children: " + nl +
-                        "org.apache.poi.ddf.EscherOptRecord:" + nl +
-                        "  isContainer: false" + nl +
-                        "  options: 0x0003" + nl +
-                        "  recordId: 0xF00B" + nl +
-                        "  numchildren: 0" + nl +
-                        "  properties:" + nl;
+        expected = "org.apache.poi.ddf.EscherContainerRecord (SpContainer):" + nl +
+                   "  isContainer: true" + nl +
+                   "  options: 0x000F" + nl +
+                   "  recordId: 0xF004" + nl +
+                   "  numchildren: 1" + nl +
+                   "  children: " + nl +
+                   "   Child 0:" + nl +
+                   "org.apache.poi.ddf.EscherOptRecord:" + nl +
+                   "  isContainer: false" + nl +
+                   "  options: 0x0003" + nl +
+                   "  recordId: 0xF00B" + nl +
+                   "  numchildren: 0" + nl +
+                   "  properties:" + nl;
         assertEquals( expected, r.toString() );
 
+        r.addChildRecord( r2 );
+        expected = "org.apache.poi.ddf.EscherContainerRecord (SpContainer):" + nl +
+                   "  isContainer: true" + nl +
+                   "  options: 0x000F" + nl +
+                   "  recordId: 0xF004" + nl +
+                   "  numchildren: 2" + nl +
+                   "  children: " + nl +
+                   "   Child 0:" + nl +
+                   "org.apache.poi.ddf.EscherOptRecord:" + nl +
+                   "  isContainer: false" + nl +
+                   "  options: 0x0003" + nl +
+                   "  recordId: 0xF00B" + nl +
+                   "  numchildren: 0" + nl +
+                   "  properties:" + nl +
+                   "   Child 1:" + nl +
+                   "org.apache.poi.ddf.EscherOptRecord:" + nl +
+                   "  isContainer: false" + nl +
+                   "  options: 0x0003" + nl +
+                   "  recordId: 0xF00B" + nl +
+                   "  numchildren: 0" + nl +
+                   "  properties:" + nl;
+        assertEquals( expected, r.toString() );
     }
 
     public void testGetRecordSize() throws Exception

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/HSSFTests.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/HSSFTests.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/HSSFTests.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/HSSFTests.java Fri Jan 25 07:48:14 2008
@@ -23,8 +23,8 @@
 
 import org.apache.poi.hssf.eventmodel.TestEventRecordFactory;
 import org.apache.poi.hssf.eventmodel.TestModelFactory;
-import org.apache.poi.hssf.model.TestFormulaParser;
 import org.apache.poi.hssf.model.TestDrawingManager;
+import org.apache.poi.hssf.model.TestFormulaParser;
 import org.apache.poi.hssf.model.TestSheet;
 import org.apache.poi.hssf.record.TestAreaFormatRecord;
 import org.apache.poi.hssf.record.TestAreaRecord;
@@ -91,6 +91,7 @@
 import org.apache.poi.hssf.usermodel.TestFormulas;
 import org.apache.poi.hssf.usermodel.TestHSSFCell;
 import org.apache.poi.hssf.usermodel.TestHSSFClientAnchor;
+import org.apache.poi.hssf.usermodel.TestHSSFComment;
 import org.apache.poi.hssf.usermodel.TestHSSFDateUtil;
 import org.apache.poi.hssf.usermodel.TestHSSFHeaderFooter;
 import org.apache.poi.hssf.usermodel.TestHSSFPalette;
@@ -110,7 +111,6 @@
 import org.apache.poi.hssf.util.TestRKUtil;
 import org.apache.poi.hssf.util.TestRangeAddress;
 import org.apache.poi.hssf.util.TestSheetReferences;
-import org.apache.poi.hssf.usermodel.TestHSSFComment;
 
 /**
  * Test Suite for running just HSSF tests.  Mostly

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java Fri Jan 25 07:48:14 2008
@@ -45,7 +45,9 @@
 
 /**
  * Test the low level formula parser functionality. High level tests are to 
- * be done via usermodel/HSSFCell.setFormulaValue() . 
+ *  be done via usermodel/HSSFCell.setFormulaValue() .
+ * Some tests are also done in scratchpad, if they need
+ *  HSSFFormulaEvaluator, which is there
  */
 public class TestFormulaParser extends TestCase {
 
@@ -349,7 +351,7 @@
 		assertTrue("ptg0 is a StringPtg", ptg[0] instanceof StringPtg);
 		assertTrue("ptg0 contains exact value", ((StringPtg)ptg[0]).getValue().equals(value));
 	}
-
+	
 	public void testLookupAndMatchFunctionArgs()
 	{
 		FormulaParser fp = new FormulaParser("lookup(A1, A3:A52, B3:B52)", null);

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteRecord.java Fri Jan 25 07:48:14 2008
@@ -79,4 +79,27 @@
         System.arraycopy(ser, 4, recdata, 0, recdata.length);
         assertTrue(Arrays.equals(data, recdata));
     }
+
+    public void testClone()
+    {
+        NoteRecord record = new NoteRecord();
+
+        record.setRow((short)1);
+        record.setColumn((short)2);
+        record.setFlags(NoteRecord.NOTE_VISIBLE);
+        record.setShapeId((short)1026);
+        record.setAuthor("Apache Software Foundation");
+
+        NoteRecord cloned = (NoteRecord)record.clone();
+        assertEquals(record.getRow(), cloned.getRow());
+        assertEquals(record.getColumn(), cloned.getColumn());
+        assertEquals(record.getFlags(), cloned.getFlags());
+        assertEquals(record.getShapeId(), cloned.getShapeId());
+        assertEquals(record.getAuthor(), cloned.getAuthor());
+
+        //finally check that the serialized data is the same
+        byte[] src = record.serialize();
+        byte[] cln = cloned.serialize();
+        assertTrue(Arrays.equals(src, cln));
+    }
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java Fri Jan 25 07:48:14 2008
@@ -65,4 +65,16 @@
         assertEquals(ser.length - 4, data.length);
 
     }
+
+    public void testClone()
+    {
+        NoteStructureSubRecord record = new NoteStructureSubRecord();
+        byte[] src = record.serialize();
+
+        NoteStructureSubRecord cloned = (NoteStructureSubRecord)record.clone();
+        byte[] cln = cloned.serialize();
+
+        assertEquals(record.getRecordSize(), cloned.getRecordSize());
+        assertTrue(Arrays.equals(src, cln));
+    }
 }

Modified: poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestTextObjectRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestTextObjectRecord.java?rev=615249&r1=615248&r2=615249&view=diff
==============================================================================
--- poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestTextObjectRecord.java (original)
+++ poi/tags/REL_3_0_2_BETA3/src/testcases/org/apache/poi/hssf/record/TestTextObjectRecord.java Fri Jan 25 07:48:14 2008
@@ -117,4 +117,44 @@
         }
 
     }
+
+    /**
+     * Test cloning
+     */
+    public void testClone() {
+        String text = "Hello, World";
+        HSSFRichTextString str = new HSSFRichTextString(text);
+
+        TextObjectRecord obj = new TextObjectRecord();
+        int frLength = ( str.numFormattingRuns() + 1 ) * 8;
+        obj.setFormattingRunLength( (short) frLength );
+        obj.setTextLength( (short) str.length() );
+        obj.setReserved1(true);
+        obj.setReserved2((short)2);
+        obj.setReserved3((short)3);
+        obj.setReserved4((short)4);
+        obj.setReserved5((short)5);
+        obj.setReserved6((short)6);
+        obj.setReserved7((short)7);
+        obj.setStr( str );
+
+
+        TextObjectRecord cloned = (TextObjectRecord)obj.clone();
+        assertEquals(obj.getReserved2(), cloned.getReserved2());
+        assertEquals(obj.getReserved3(), cloned.getReserved3());
+        assertEquals(obj.getReserved4(), cloned.getReserved4());
+        assertEquals(obj.getReserved5(), cloned.getReserved5());
+        assertEquals(obj.getReserved6(), cloned.getReserved6());
+        assertEquals(obj.getReserved7(), cloned.getReserved7());
+        assertEquals(obj.getRecordSize(), cloned.getRecordSize());
+        assertEquals(obj.getOptions(), cloned.getOptions());
+        assertEquals(obj.getHorizontalTextAlignment(), cloned.getHorizontalTextAlignment());
+        assertEquals(obj.getFormattingRunLength(), cloned.getFormattingRunLength());
+        assertEquals(obj.getStr().getString(), cloned.getStr().getString());
+
+        //finally check that the serialized data is the same
+        byte[] src = obj.serialize();
+        byte[] cln = cloned.serialize();
+        assertTrue(Arrays.equals(src, cln));
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org