<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
<action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
<action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
<action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
<action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>
*
* @author Josh Micich
*/
-final class RecordStream {
+public final class RecordStream {
private final List _list;
private int _nextIndex;
package org.apache.poi.hssf.model;
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.*; // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
+import org.apache.poi.hssf.record.aggregates.DataValidityTable;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
-import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.util.POILogFactory;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List; // normally I don't do this, buy we literally mean ALL
+import java.util.List;
/**
* Low level model implementation of a Sheet (one workbook contains many sheets)
protected ProtectRecord protect = null;
protected PageBreakRecord rowBreaks = null;
protected PageBreakRecord colBreaks = null;
+ private DataValidityTable _dataValidityTable= null;
protected ObjectProtectRecord objprotect = null;
protected ScenarioProtectRecord scenprotect = null;
protected PasswordRecord password = null;
// and POI always re-calculates its contents
rec = null;
}
-
+ else if ( rec.getSid() == DVALRecord.sid) {
+ RecordStream rs = new RecordStream(recs, k);
+ retval._dataValidityTable = new DataValidityTable(rs);
+ k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
+ rec = retval._dataValidityTable;
+ }
else if ( rec.getSid() == ProtectRecord.sid )
{
retval.protect = (ProtectRecord) rec;
Sheet retval = new Sheet();
ArrayList records = new ArrayList(30);
- records.add(retval.createBOF());
+ records.add(createBOF());
// records.add(retval.createIndex());
- records.add(retval.createCalcMode());
- records.add(retval.createCalcCount() );
- records.add( retval.createRefMode() );
- records.add( retval.createIteration() );
- records.add( retval.createDelta() );
- records.add( retval.createSaveRecalc() );
- records.add( retval.createPrintHeaders() );
- retval.printGridlines = (PrintGridlinesRecord) retval.createPrintGridlines();
+ records.add(createCalcMode());
+ records.add(createCalcCount() );
+ records.add(createRefMode() );
+ records.add(createIteration() );
+ records.add(createDelta() );
+ records.add(createSaveRecalc() );
+ records.add(createPrintHeaders() );
+ retval.printGridlines = createPrintGridlines();
records.add( retval.printGridlines );
- retval.gridset = (GridsetRecord) retval.createGridset();
+ retval.gridset = createGridset();
records.add( retval.gridset );
records.add( retval.createGuts() );
- retval.defaultrowheight =
- (DefaultRowHeightRecord) retval.createDefaultRowHeight();
+ retval.defaultrowheight = createDefaultRowHeight();
records.add( retval.defaultrowheight );
records.add( retval.createWSBool() );
-
+
+ // 'Page Settings Block'
retval.rowBreaks = new PageBreakRecord(PageBreakRecord.HORIZONTAL_SID);
records.add(retval.rowBreaks);
retval.colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID);
records.add(retval.colBreaks);
- retval.header = (HeaderRecord) retval.createHeader();
+ retval.header = createHeader();
records.add( retval.header );
- retval.footer = (FooterRecord) retval.createFooter();
+ retval.footer = createFooter();
records.add( retval.footer );
- records.add( retval.createHCenter() );
- records.add( retval.createVCenter() );
- retval.printSetup = (PrintSetupRecord) retval.createPrintSetup();
+ records.add(createHCenter() );
+ records.add(createVCenter() );
+ retval.printSetup = createPrintSetup();
records.add( retval.printSetup );
- retval.defaultcolwidth =
- (DefaultColWidthRecord) retval.createDefaultColWidth();
+
+ // '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
+
+ retval.defaultcolwidth = createDefaultColWidth();
records.add( retval.defaultcolwidth);
ColumnInfoRecordsAggregate columns = new ColumnInfoRecordsAggregate();
records.add( columns );
retval.columns = columns;
- retval.dims = ( DimensionsRecord ) retval.createDimensions();
+ retval.dims = createDimensions();
records.add(retval.dims);
retval.dimsloc = records.size()-1;
records.add(retval.windowTwo = retval.createWindowTwo());
retval.setLoc(records.size() - 1);
- retval.selection =
- (SelectionRecord) retval.createSelection();
+ retval.selection = createSelection();
records.add(retval.selection);
- retval.protect = (ProtectRecord) retval.createProtect();
- records.add(retval.protect);
- records.add(retval.createEOF());
+ records.add(new EOFRecord());
retval.records = records;
if (merged == null || merged.getNumAreas() == 1027)
{
- merged = ( MergeCellsRecord ) createMergedCells();
+ merged = createMergedCells();
mergedRecords.add(merged);
records.add(records.size() - 1, merged);
}
/**
* Create a row record. (does not add it to the records contained in this sheet)
- *
- * @param row number
- * @return RowRecord created for the passed in row number
- * @see org.apache.poi.hssf.record.RowRecord
*/
-
- public RowRecord createRow(int row)
- {
+ private static RowRecord createRow(int row) {
return RowRecordsAggregate.createRow( row );
}
- /**
- * Create a LABELSST Record (does not add it to the records contained in this sheet)
- *
- * @param row the row the LabelSST is a member of
- * @param col the column the LabelSST defines
- * @param index the index of the string within the SST (use workbook addSSTString method)
- * @return LabelSSTRecord newly created containing your SST Index, row,col.
- * @see org.apache.poi.hssf.record.SSTRecord
- */
- public LabelSSTRecord createLabelSST(int row, short col, int index)
- {
- log.logFormatted(POILogger.DEBUG, "create labelsst row,col,index %,%,%",
- new int[]
- {
- row, col, index
- });
- LabelSSTRecord rec = new LabelSSTRecord();
-
- rec.setRow(row);
- rec.setColumn(col);
- rec.setSSTIndex(index);
- rec.setXFIndex(( short ) 0x0f);
- return rec;
- }
-
- /**
- * Create a NUMBER Record (does not add it to the records contained in this sheet)
- *
- * @param row the row the NumberRecord is a member of
- * @param col the column the NumberRecord defines
- * @param value for the number record
- *
- * @return NumberRecord for that row, col containing that value as added to the sheet
- */
- public NumberRecord createNumber(int row, short col, double value)
- {
- log.logFormatted(POILogger.DEBUG, "create number row,col,value %,%,%",
- new double[]
- {
- row, col, value
- });
- NumberRecord rec = new NumberRecord();
-
- rec.setRow(row);
- rec.setColumn(col);
- rec.setValue(value);
- rec.setXFIndex(( short ) 0x0f);
- return rec;
- }
-
- /**
- * create a BLANK record (does not add it to the records contained in this sheet)
- *
- * @param row - the row the BlankRecord is a member of
- * @param col - the column the BlankRecord is a member of
- */
- public BlankRecord createBlank(int row, short col)
- {
- log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new int[]
- {
- row, col
- });
- BlankRecord rec = new BlankRecord();
-
- rec.setRow(row);
- rec.setColumn(col);
- rec.setXFIndex(( short ) 0x0f);
- return rec;
- }
-
- /**
- * Attempts to parse the formula into PTGs and create a formula record
- * DOES NOT WORK YET
- *
- * @param row - the row for the formula record
- * @param col - the column of the formula record
- * @param formula - a String representing the formula. To be parsed to PTGs
- * @return bogus/useless formula record
- */
- public FormulaRecord createFormula(int row, short col, String formula)
- {
- log.logFormatted(POILogger.DEBUG, "create formula row,col,formula %,%,%",
- new int[]
- {
- row, col
- }, formula);
- FormulaRecord rec = new FormulaRecord();
-
- rec.setRow(row);
- rec.setColumn(col);
- rec.setOptions(( short ) 2);
- rec.setValue(0);
- rec.setXFIndex(( short ) 0x0f);
- FormulaParser fp = new FormulaParser(formula,null); //fix - do we need this method?
- fp.parse();
- Ptg[] ptg = fp.getRPNPtg();
- int size = 0;
-
- for (int k = 0; k < ptg.length; k++)
- {
- size += ptg[ k ].getSize();
- rec.pushExpressionToken(ptg[ k ]);
- }
- rec.setExpressionLength(( short ) size);
- return rec;
- }
-
/**
* Adds a value record to the sheet's contained binary records
* (i.e. LabelSSTRecord or NumberRecord).
/**
* creates the BOF record
- * @see org.apache.poi.hssf.record.BOFRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a BOFRecord
*/
-
- protected Record createBOF()
- {
+ private static BOFRecord createBOF() {
BOFRecord retval = new BOFRecord();
retval.setVersion(( short ) 0x600);
return retval;
}
- /**
- * creates the Index record - not currently used
- * @see org.apache.poi.hssf.record.IndexRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a IndexRecord
- */
-
- protected Record createIndex()
- {
- IndexRecord retval = new IndexRecord();
-
- retval.setFirstRow(0); // must be set explicitly
- retval.setLastRowAdd1(0);
- return retval;
- }
-
/**
* creates the CalcMode record and sets it to 1 (automatic formula caculation)
- * @see org.apache.poi.hssf.record.CalcModeRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a CalcModeRecord
*/
-
- protected Record createCalcMode()
- {
+ private static CalcModeRecord createCalcMode() {
CalcModeRecord retval = new CalcModeRecord();
retval.setCalcMode(( short ) 1);
}
/**
- * creates the CalcCount record and sets it to 0x64 (default number of iterations)
- * @see org.apache.poi.hssf.record.CalcCountRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a CalcCountRecord
+ * creates the CalcCount record and sets it to 100 (default number of iterations)
*/
-
- protected Record createCalcCount()
- {
+ private static CalcCountRecord createCalcCount() {
CalcCountRecord retval = new CalcCountRecord();
- retval.setIterations(( short ) 0x64); // default 64 iterations
+ retval.setIterations(( short ) 100); // default 100 iterations
return retval;
}
/**
* creates the RefMode record and sets it to A1 Mode (default reference mode)
- * @see org.apache.poi.hssf.record.RefModeRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a RefModeRecord
*/
-
- protected Record createRefMode()
- {
+ private static RefModeRecord createRefMode() {
RefModeRecord retval = new RefModeRecord();
retval.setMode(RefModeRecord.USE_A1_MODE);
/**
* creates the Iteration record and sets it to false (don't iteratively calculate formulas)
- * @see org.apache.poi.hssf.record.IterationRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a IterationRecord
*/
-
- protected Record createIteration()
- {
+ private static IterationRecord createIteration() {
IterationRecord retval = new IterationRecord();
retval.setIteration(false);
/**
* creates the Delta record and sets it to 0.0010 (default accuracy)
- * @see org.apache.poi.hssf.record.DeltaRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a DeltaRecord
*/
-
- protected Record createDelta()
- {
+ private static DeltaRecord createDelta() {
DeltaRecord retval = new DeltaRecord();
retval.setMaxChange(0.0010);
/**
* creates the SaveRecalc record and sets it to true (recalculate before saving)
- * @see org.apache.poi.hssf.record.SaveRecalcRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a SaveRecalcRecord
*/
-
- protected Record createSaveRecalc()
- {
+ private static SaveRecalcRecord createSaveRecalc() {
SaveRecalcRecord retval = new SaveRecalcRecord();
retval.setRecalc(true);
/**
* creates the PrintHeaders record and sets it to false (we don't create headers yet so why print them)
- * @see org.apache.poi.hssf.record.PrintHeadersRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a PrintHeadersRecord
*/
-
- protected Record createPrintHeaders()
- {
+ private static PrintHeadersRecord createPrintHeaders() {
PrintHeadersRecord retval = new PrintHeadersRecord();
retval.setPrintHeaders(false);
/**
* creates the PrintGridlines record and sets it to false (that makes for ugly sheets). As far as I can
* tell this does the same thing as the GridsetRecord
- *
- * @see org.apache.poi.hssf.record.PrintGridlinesRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a PrintGridlinesRecord
*/
-
- protected Record createPrintGridlines()
- {
+ private static PrintGridlinesRecord createPrintGridlines() {
PrintGridlinesRecord retval = new PrintGridlinesRecord();
retval.setPrintGridlines(false);
/**
* creates the Gridset record and sets it to true (user has mucked with the gridlines)
- * @see org.apache.poi.hssf.record.GridsetRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a GridsetRecord
*/
-
- protected Record createGridset()
- {
+ private static GridsetRecord createGridset() {
GridsetRecord retval = new GridsetRecord();
retval.setGridset(true);
/**
* creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0
- * @see org.apache.poi.hssf.record.GutsRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a GutsRecordRecord
- */
-
- protected Record createGuts()
- {
+ */
+ private static GutsRecord createGuts() {
GutsRecord retval = new GutsRecord();
retval.setLeftRowGutter(( short ) 0);
/**
* creates the DefaultRowHeight Record and sets its options to 0 and rowheight to 0xff
- * @see org.apache.poi.hssf.record.DefaultRowHeightRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a DefaultRowHeightRecord
*/
-
- protected Record createDefaultRowHeight()
- {
+ private static DefaultRowHeightRecord createDefaultRowHeight() {
DefaultRowHeightRecord retval = new DefaultRowHeightRecord();
retval.setOptionFlags(( short ) 0);
/**
* creates the WSBoolRecord and sets its values to defaults
- * @see org.apache.poi.hssf.record.WSBoolRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a WSBoolRecord
*/
-
- protected Record createWSBool()
- {
+ private static WSBoolRecord createWSBool() {
WSBoolRecord retval = new WSBoolRecord();
retval.setWSBool1(( byte ) 0x4);
/**
* creates the Header Record and sets it to nothing/0 length
- * @see org.apache.poi.hssf.record.HeaderRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a HeaderRecord
*/
-
- protected Record createHeader()
- {
+ private static HeaderRecord createHeader() {
HeaderRecord retval = new HeaderRecord();
retval.setHeaderLength(( byte ) 0);
/**
* creates the Footer Record and sets it to nothing/0 length
- * @see org.apache.poi.hssf.record.FooterRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a FooterRecord
*/
-
- protected Record createFooter()
- {
+ private static FooterRecord createFooter() {
FooterRecord retval = new FooterRecord();
retval.setFooterLength(( byte ) 0);
/**
* creates the HCenter Record and sets it to false (don't horizontally center)
- * @see org.apache.poi.hssf.record.HCenterRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a HCenterRecord
*/
-
- protected Record createHCenter()
- {
+ private static HCenterRecord createHCenter() {
HCenterRecord retval = new HCenterRecord();
retval.setHCenter(false);
/**
* creates the VCenter Record and sets it to false (don't horizontally center)
- * @see org.apache.poi.hssf.record.VCenterRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a VCenterRecord
- */
-
- protected Record createVCenter()
- {
+ */
+ private static VCenterRecord createVCenter() {
VCenterRecord retval = new VCenterRecord();
retval.setVCenter(false);
* @see org.apache.poi.hssf.record.Record
* @return record containing a PrintSetupRecord
*/
-
- protected Record createPrintSetup()
- {
+ private static PrintSetupRecord createPrintSetup() {
PrintSetupRecord retval = new PrintSetupRecord();
retval.setPaperSize(( short ) 1);
/**
* creates the DefaultColWidth Record and sets it to 8
- * @see org.apache.poi.hssf.record.DefaultColWidthRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a DefaultColWidthRecord
- */
-
- protected Record createDefaultColWidth()
- {
+ */
+ private static DefaultColWidthRecord createDefaultColWidth() {
DefaultColWidthRecord retval = new DefaultColWidthRecord();
-
retval.setColWidth(( short ) 8);
return retval;
}
- /**
- * creates the ColumnInfo Record and sets it to a default column/width
- * @see org.apache.poi.hssf.record.ColumnInfoRecord
- * @return record containing a ColumnInfoRecord
- */
- // TODO change return type to ColumnInfoRecord
- protected Record createColInfo()
- {
- return ColumnInfoRecordsAggregate.createColInfo();
- }
-
/**
* get the default column width for the sheet (if the columns do not define their own width)
* @return default column width
public boolean isGridsPrinted()
{
if (gridset == null) {
- gridset = (GridsetRecord)createGridset();
+ gridset = createGridset();
//Insert the newlycreated Gridset record at the end of the record (just before the EOF)
int loc = findFirstRecordLocBySid(EOFRecord.sid);
records.add(loc, gridset);
GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid );
guts.setColLevelMax( (short) ( maxLevel+1 ) );
- if (maxLevel == 0)
+ if (maxLevel == 0) {
guts.setTopColGutter( (short)0 );
- else
+ } else {
guts.setTopColGutter( (short) ( 29 + (12 * (maxLevel-1)) ) );
+ }
}
/**
* creates the Dimensions Record and sets it to bogus values (you should set this yourself
* or let the high level API do it for you)
- * @see org.apache.poi.hssf.record.DimensionsRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a DimensionsRecord
*/
-
- protected Record createDimensions()
- {
+ private static DimensionsRecord createDimensions() {
DimensionsRecord retval = new DimensionsRecord();
retval.setFirstCol(( short ) 0);
* headercolor = 0x40 <P>
* pagebreakzoom = 0x0 <P>
* normalzoom = 0x0 <p>
- * @see org.apache.poi.hssf.record.WindowTwoRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a WindowTwoRecord
*/
-
- protected WindowTwoRecord createWindowTwo()
- {
+ private static WindowTwoRecord createWindowTwo() {
WindowTwoRecord retval = new WindowTwoRecord();
retval.setOptions(( short ) 0x6b6);
/**
* Creates the Selection record and sets it to nothing selected
- *
- * @see org.apache.poi.hssf.record.SelectionRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a SelectionRecord
- */
-
- protected Record createSelection()
- {
+ */
+ private static SelectionRecord createSelection() {
SelectionRecord retval = new SelectionRecord();
retval.setPane(( byte ) 0x3);
* Sets the left column to show in desktop window pane.
* @param leftCol the left column to show in desktop window pane
*/
- public void setLeftCol(short leftCol){
- if (windowTwo!=null)
- {
+ public void setLeftCol(short leftCol){
+ if (windowTwo!=null) {
windowTwo.setLeftCol(leftCol);
- }
}
+ }
- public short getLeftCol()
- {
- return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
- }
-
-
+ public short getLeftCol() {
+ return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
+ }
/**
* Returns the active row
}
}
- protected Record createMergedCells()
- {
+ private static MergeCellsRecord createMergedCells() {
MergeCellsRecord retval = new MergeCellsRecord();
retval.setNumAreas(( short ) 0);
return retval;
}
- /**
- * creates the EOF record
- * @see org.apache.poi.hssf.record.EOFRecord
- * @see org.apache.poi.hssf.record.Record
- * @return record containing a EOFRecord
- */
-
- protected Record createEOF()
- {
- return new EOFRecord();
- }
-
/**
* get the location of the DimensionsRecord (which is the last record before the value section)
* @return location in the array of records of the DimensionsRecord
/**
* creates a Protect record with protect set to false.
- * @see org.apache.poi.hssf.record.ProtectRecord
- * @see org.apache.poi.hssf.record.Record
- * @return a ProtectRecord
*/
- protected Record createProtect()
- {
- if (log.check( POILogger.DEBUG ))
+ private static ProtectRecord createProtect() {
+ if (log.check( POILogger.DEBUG )) {
log.log(POILogger.DEBUG, "create protect record with protection disabled");
- ProtectRecord retval = new ProtectRecord();
-
- retval.setProtect(false);
+ }
+ ProtectRecord retval = new ProtectRecord();
+ retval.setProtect(false); // TODO - supply param to constructor
return retval;
}
/**
* creates an ObjectProtect record with protect set to false.
- * @see org.apache.poi.hssf.record.ObjectProtectRecord
- * @see org.apache.poi.hssf.record.Record
- * @return an ObjectProtectRecord
*/
- protected ObjectProtectRecord createObjectProtect()
- {
+ private static ObjectProtectRecord createObjectProtect() {
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "create protect record with protection disabled");
ObjectProtectRecord retval = new ObjectProtectRecord();
/**
* creates a ScenarioProtect record with protect set to false.
- * @see org.apache.poi.hssf.record.ScenarioProtectRecord
- * @see org.apache.poi.hssf.record.Record
- * @return a ScenarioProtectRecord
*/
- protected ScenarioProtectRecord createScenarioProtect()
- {
+ private static ScenarioProtectRecord createScenarioProtect() {
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "create protect record with protection disabled");
ScenarioProtectRecord retval = new ScenarioProtectRecord();
public ProtectRecord getProtect()
{
if (protect == null) {
- protect = (ProtectRecord)createProtect();
- //Insert the newlycreated protect record at the end of the record (just before the EOF)
- int loc = findFirstRecordLocBySid(EOFRecord.sid);
+ protect = createProtect();
+ // Insert the newly created protect record just before DefaultColWidthRecord
+ int loc = findFirstRecordLocBySid(DefaultColWidthRecord.sid);
records.add(loc, protect);
}
return protect;
/**
* creates a Password record with password set to 00.
- * @see org.apache.poi.hssf.record.PasswordRecord
- * @see org.apache.poi.hssf.record.Record
- * @return a PasswordRecord
*/
- protected PasswordRecord createPassword()
- {
- if (log.check( POILogger.DEBUG ))
- log.log(POILogger.DEBUG, "create password record with 00 password");
+ private static PasswordRecord createPassword() {
+ if (log.check( POILogger.DEBUG )) {
+ log.log(POILogger.DEBUG, "create password record with 00 password");
+ }
PasswordRecord retval = new PasswordRecord();
retval.setPassword((short)00);
rows.expandRow( row );
}
}
+ public DataValidityTable getOrCreateDataValidityTable() {
+ if (_dataValidityTable == null) {
+ _dataValidityTable = DataValidityTable.createForSheet(records);
+ }
+ return _dataValidityTable;
+ }
}
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
+import org.apache.poi.hssf.util.HSSFCellRangeAddress.AddrStructure;
import org.apache.poi.util.BitField;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
private BitField opt_error_style = new BitField(0x00000070);
private BitField opt_string_list_formula = new BitField(0x00000080);
private BitField opt_empty_cell_allowed = new BitField(0x00000100);
- private BitField opt_surppres_dropdown_arrow = new BitField(0x00000200);
+ private BitField opt_suppress_dropdown_arrow = new BitField(0x00000200);
private BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000);
private BitField opt_show_error_on_invalid_value = new BitField(0x00080000);
private BitField opt_condition_operator = new BitField(0x00F00000);
{
return (this.opt_empty_cell_allowed.isSet(this.field_option_flags));
}
+ /**
+ * @deprecated - (Jul-2008) use setSuppressDropDownArrow
+ */
+ public void setSurppresDropdownArrow(boolean suppress) {
+ setSuppressDropdownArrow(suppress);
+ }
+ /**
+ * @deprecated - (Jul-2008) use getSuppressDropDownArrow
+ */
+ public boolean getSurppresDropdownArrow() {
+ return getSuppressDropdownArrow();
+ }
/**
- * set if drop down arrow should be surppressed when list validation is used
- * @param type - true if drop down arrow should be surppressed when list validation is used, false otherwise
+ * set if drop down arrow should be suppressed when list validation is used
+ * @param type - true if drop down arrow should be suppressed when list validation is used, false otherwise
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
*/
- public void setSurppresDropdownArrow(boolean surppress)
+ public void setSuppressDropdownArrow(boolean suppress)
{
- this.field_option_flags = this.opt_surppres_dropdown_arrow.setBoolean(this.field_option_flags, surppress);
+ this.field_option_flags = this.opt_suppress_dropdown_arrow.setBoolean(this.field_option_flags, suppress);
}
/**
- * return true if drop down arrow should be surppressed when list validation is used, false otherwise
- * @return if drop down arrow should be surppressed when list validation is used, false otherwise
+ * return true if drop down arrow should be suppressed when list validation is used, false otherwise
+ * @return if drop down arrow should be suppressed when list validation is used, false otherwise
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
*/
- public boolean getSurppresDropdownArrow()
+ public boolean getSuppressDropdownArrow()
{
- return (this.opt_surppres_dropdown_arrow.isSet(this.field_option_flags));
+ return (this.opt_suppress_dropdown_arrow.isSet(this.field_option_flags));
}
/**
public String toString()
{
/** @todo DVRecord string representation */
- StringBuffer buffer = new StringBuffer();
+ StringBuffer sb = new StringBuffer();
+ sb.append("[DV]\n");
+ sb.append(" options=").append(Integer.toHexString(field_option_flags));
+ sb.append(" title-prompt=").append(field_title_prompt);
+ sb.append(" title-error=").append(field_title_error);
+ sb.append(" text-prompt=").append(field_text_prompt);
+ sb.append(" text-error=").append(field_text_error);
+ sb.append("\n");
+ appendFormula(sb, "Formula 1:", field_rpn_token_1);
+ appendFormula(sb, "Formula 2:", field_rpn_token_2);
+ int nRegions = field_regions.getADDRStructureNumber();
+ for(int i=0; i<nRegions; i++) {
+ AddrStructure addr = field_regions.getADDRStructureAt(i);
+ sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow());
+ sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')');
+ }
+ sb.append("\n");
+ sb.append("[/DV]");
- return buffer.toString();
+ return sb.toString();
+ }
+
+ private void appendFormula(StringBuffer sb, String label, Stack stack) {
+ sb.append(label);
+ if (stack.isEmpty()) {
+ sb.append("<empty>\n");
+ return;
+ }
+ sb.append("\n");
+ Ptg[] ptgs = new Ptg[stack.size()];
+ stack.toArray(ptgs);
+ for (int i = 0; i < ptgs.length; i++) {
+ sb.append('\t').append(ptgs[i].toString()).append('\n');
+ }
}
public int serialize(int offset, byte [] data)
* contents are somewhat complex
*/
public Object clone() {
- return cloneViaReserialise();
+ return cloneViaReserialise();
}
/**@todo DVRecord = Serializare */
this._string_unicode_flag = in.readByte();
if (this._string_unicode_flag == 1)
{
- this._string_data = in.readUnicodeLEString(this._string_length);
+ this._string_data = in.readUnicodeLEString(this._string_length);
}
else
{
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record.aggregates;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.apache.poi.hssf.model.FormulaParser;\r
+import org.apache.poi.hssf.model.RecordStream;\r
+import org.apache.poi.hssf.record.CFHeaderRecord;\r
+import org.apache.poi.hssf.record.CFRuleRecord;\r
+import org.apache.poi.hssf.record.DVALRecord;\r
+import org.apache.poi.hssf.record.DVRecord;\r
+import org.apache.poi.hssf.record.EOFRecord;\r
+import org.apache.poi.hssf.record.HyperlinkRecord;\r
+import org.apache.poi.hssf.record.MergeCellsRecord;\r
+import org.apache.poi.hssf.record.PaneRecord;\r
+import org.apache.poi.hssf.record.Record;\r
+import org.apache.poi.hssf.record.SelectionRecord;\r
+import org.apache.poi.hssf.record.WindowTwoRecord;\r
+import org.apache.poi.hssf.record.formula.Ptg;\r
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
+import org.apache.poi.hssf.util.HSSFCellRangeAddress;\r
+import org.apache.poi.hssf.util.HSSFDataValidation;\r
+\r
+/**\r
+ * Manages the DVALRecord and DVRecords for a single sheet<br/>\r
+ * See OOO excelfileformat.pdf section 4.14\r
+ * @author Josh Micich\r
+ */\r
+public final class DataValidityTable extends RecordAggregate {\r
+\r
+ private static final short sid = -0x01B2; // not a real record\r
+ private final DVALRecord _headerRec;\r
+ /**\r
+ * The list of data validations for the current sheet.\r
+ * Note - this may be empty (contrary to OOO documentation)\r
+ */\r
+ private final List _validationList;\r
+\r
+ public DataValidityTable(RecordStream rs) {\r
+ _headerRec = (DVALRecord) rs.getNext();\r
+ List temp = new ArrayList();\r
+ while (rs.peekNextClass() == DVRecord.class) {\r
+ temp.add(rs.getNext());\r
+ }\r
+ _validationList = temp;\r
+ }\r
+\r
+ private DataValidityTable() {\r
+ _headerRec = new DVALRecord();\r
+ _validationList = new ArrayList();\r
+ }\r
+\r
+ public short getSid() {\r
+ return sid;\r
+ }\r
+\r
+ public int serialize(int offset, byte[] data) {\r
+ int result = _headerRec.serialize(offset, data);\r
+ for (int i = 0; i < _validationList.size(); i++) {\r
+ result += ((Record) _validationList.get(i)).serialize(offset + result, data);\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public int getRecordSize() {\r
+ int result = _headerRec.getRecordSize();\r
+ for (int i = _validationList.size() - 1; i >= 0; i--) {\r
+ result += ((Record) _validationList.get(i)).getRecordSize();\r
+ }\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Creates a new <tt>DataValidityTable</tt> and inserts it in the right\r
+ * place in the sheetRecords list.\r
+ */\r
+ public static DataValidityTable createForSheet(List sheetRecords) {\r
+ int index = findDVTableInsertPos(sheetRecords);\r
+\r
+ DataValidityTable result = new DataValidityTable();\r
+ sheetRecords.add(index, result);\r
+ return result;\r
+ }\r
+ \r
+ /**\r
+ * Finds the index where the sheet validations header record should be inserted\r
+ * @param records the records for this sheet\r
+ * \r
+ * + WINDOW2\r
+ * o SCL\r
+ * o PANE\r
+ * oo SELECTION\r
+ * o STANDARDWIDTH\r
+ * oo MERGEDCELLS\r
+ * o LABELRANGES\r
+ * o PHONETICPR\r
+ * o Conditional Formatting Table\r
+ * o Hyperlink Table\r
+ * o Data Validity Table\r
+ * o SHEETLAYOUT\r
+ * o SHEETPROTECTION\r
+ * o RANGEPROTECTION\r
+ * + EOF\r
+ */\r
+ private static int findDVTableInsertPos(List records) {\r
+ int i = records.size() - 1;\r
+ if (!(records.get(i) instanceof EOFRecord)) {\r
+ throw new IllegalStateException("Last sheet record should be EOFRecord");\r
+ }\r
+ while (i > 0) {\r
+ i--;\r
+ Record rec = (Record) records.get(i);\r
+ if (isPriorRecord(rec.getSid())) {\r
+ Record nextRec = (Record) records.get(i + 1);\r
+ if (!isSubsequentRecord(nextRec.getSid())) {\r
+ throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName()\r
+ + ") found after (" + rec.getClass().getName() + ")");\r
+ }\r
+ return i;\r
+ }\r
+ if (!isSubsequentRecord(rec.getSid())) {\r
+ throw new IllegalStateException("Unexpected (" + rec.getClass().getName()\r
+ + ") while looking for DV Table insert pos");\r
+ }\r
+ }\r
+ return 0;\r
+ }\r
+\r
+ // TODO - add UninterpretedRecord as base class for many of these\r
+ // unimplemented sids\r
+\r
+ private static boolean isPriorRecord(short sid) {\r
+ switch(sid) {\r
+ case WindowTwoRecord.sid:\r
+ case 0x00A0: // SCL\r
+ case PaneRecord.sid:\r
+ case SelectionRecord.sid:\r
+ case 0x0099: // STANDARDWIDTH\r
+ case MergeCellsRecord.sid:\r
+ case 0x015F: // LABELRANGES\r
+ case 0x00EF: // PHONETICPR\r
+ case CFHeaderRecord.sid:\r
+ case CFRuleRecord.sid:\r
+ case HyperlinkRecord.sid:\r
+ case 0x0800: // QUICKTIP\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ private static boolean isSubsequentRecord(short sid) {\r
+ switch(sid) {\r
+ case 0x0862: // SHEETLAYOUT\r
+ case 0x0867: // SHEETPROTECTION\r
+ case 0x0868: // RANGEPROTECTION\r
+ case EOFRecord.sid:\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ public void addDataValidation(HSSFDataValidation dataValidation, HSSFWorkbook workbook) {\r
+\r
+ DVRecord dvRecord = new DVRecord();\r
+\r
+ // dv record's option flags\r
+ dvRecord.setDataType(dataValidation.getDataValidationType());\r
+ dvRecord.setErrorStyle(dataValidation.getErrorStyle());\r
+ dvRecord.setEmptyCellAllowed(dataValidation.getEmptyCellAllowed());\r
+ dvRecord.setSuppressDropdownArrow(dataValidation.getSuppressDropDownArrow());\r
+ dvRecord.setShowPromptOnCellSelected(dataValidation.getShowPromptBox());\r
+ dvRecord.setShowErrorOnInvalidValue(dataValidation.getShowErrorBox());\r
+ dvRecord.setConditionOperator(dataValidation.getOperator());\r
+\r
+ // string fields\r
+ dvRecord.setStringField(DVRecord.STRING_PROMPT_TITLE, dataValidation.getPromptBoxTitle());\r
+ dvRecord.setStringField(DVRecord.STRING_PROMPT_TEXT, dataValidation.getPromptBoxText());\r
+ dvRecord.setStringField(DVRecord.STRING_ERROR_TITLE, dataValidation.getErrorBoxTitle());\r
+ dvRecord.setStringField(DVRecord.STRING_ERROR_TEXT, dataValidation.getErrorBoxText());\r
+\r
+ // formula fields ( size and data )\r
+ Stack ptg_arr = new Stack();\r
+ Ptg[] ptg = FormulaParser.parse(dataValidation.getFirstFormula(), workbook);\r
+ int size = 0;\r
+ for (int k = 0; k < ptg.length; k++) {\r
+ if (ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg) {\r
+ // we should set ptgClass to Ptg.CLASS_REF and explicit formula\r
+ // string to false\r
+ // ptg[k].setClass(Ptg.CLASS_REF);\r
+ // obj_validation.setExplicitListFormula(false);\r
+ }\r
+ size += ptg[k].getSize();\r
+ ptg_arr.push(ptg[k]);\r
+ }\r
+ dvRecord.setFirstFormulaRPN(ptg_arr);\r
+ dvRecord.setFirstFormulaSize((short) size);\r
+\r
+ dvRecord.setListExplicitFormula(dataValidation.getExplicitListFormula());\r
+\r
+ if (dataValidation.getSecondFormula() != null) {\r
+\r
+ ptg_arr = new Stack();\r
+ ptg = FormulaParser.parse(dataValidation.getSecondFormula(), workbook);\r
+ size = 0;\r
+ for (int k = 0; k < ptg.length; k++) {\r
+ size += ptg[k].getSize();\r
+ ptg_arr.push(ptg[k]);\r
+ }\r
+ dvRecord.setSecFormulaRPN(ptg_arr);\r
+ dvRecord.setSecFormulaSize((short) size);\r
+ }\r
+\r
+ // dv records cell range field\r
+ HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();\r
+ cell_range.addADDRStructure(dataValidation.getFirstRow(), dataValidation.getFirstColumn(),\r
+ dataValidation.getLastRow(), dataValidation.getLastColumn());\r
+ dvRecord.setCellRangeAddress(cell_range);\r
+\r
+ _validationList.add(dvRecord);\r
+ _headerRec.setDVRecNo(_validationList.size());\r
+ }\r
+}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record.aggregates;\r
+\r
+import org.apache.poi.hssf.record.Record;\r
+import org.apache.poi.hssf.record.RecordInputStream;\r
+\r
+/**\r
+ * <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored \r
+ * together and/or updated together. Workbook / Sheet records are typically stored in a sequential\r
+ * list, which does not provide much structure to coordinate updates.\r
+ * \r
+ * @author Josh Micich\r
+ */\r
+public abstract class RecordAggregate extends Record {\r
+ // TODO - convert existing aggregate classes to proper subclasses of this one\r
+ protected final void validateSid(short id) {\r
+ // TODO - break class hierarchy and make separate from Record\r
+ throw new RuntimeException("Should not be called");\r
+ }\r
+ protected final void fillFields(RecordInputStream in) {\r
+ throw new RuntimeException("Should not be called");\r
+ }\r
+ // force subclassses to provide better implementation than default\r
+ public abstract int getRecordSize();\r
+}\r
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Stack;
import java.util.TreeMap;
import org.apache.poi.ddf.EscherRecord;
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.DataValidityTable;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.util.HSSFCellRangeAddress;
import org.apache.poi.hssf.util.HSSFDataValidation;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.hssf.util.Region;
/**
* Creates a data validation object
- * @param obj_validation The Data validation object settings
+ * @param dataValidation The Data validation object settings
*/
- public void addValidationData(HSSFDataValidation obj_validation)
- {
- if ( obj_validation == null )
- {
- return;
- }
- DVALRecord dvalRec = (DVALRecord)sheet.findFirstRecordBySid( DVALRecord.sid );
- int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
- if ( dvalRec == null )
- {
- dvalRec = new DVALRecord();
- sheet.getRecords().add( eofLoc, dvalRec );
- }
- int curr_dvRecNo = dvalRec.getDVRecNo();
- dvalRec.setDVRecNo(curr_dvRecNo+1);
-
- //create dv record
- DVRecord dvRecord = new DVRecord();
-
- //dv record's option flags
- dvRecord.setDataType( obj_validation.getDataValidationType() );
- dvRecord.setErrorStyle(obj_validation.getErrorStyle());
- dvRecord.setEmptyCellAllowed(obj_validation.getEmptyCellAllowed());
- dvRecord.setSurppresDropdownArrow(obj_validation.getSurppressDropDownArrow());
- dvRecord.setShowPromptOnCellSelected(obj_validation.getShowPromptBox());
- dvRecord.setShowErrorOnInvalidValue(obj_validation.getShowErrorBox());
- dvRecord.setConditionOperator(obj_validation.getOperator());
-
- //string fields
- dvRecord.setStringField( DVRecord.STRING_PROMPT_TITLE,obj_validation.getPromptBoxTitle());
- dvRecord.setStringField( DVRecord.STRING_PROMPT_TEXT, obj_validation.getPromptBoxText());
- dvRecord.setStringField( DVRecord.STRING_ERROR_TITLE, obj_validation.getErrorBoxTitle());
- dvRecord.setStringField( DVRecord.STRING_ERROR_TEXT, obj_validation.getErrorBoxText());
-
- //formula fields ( size and data )
- String str_formula = obj_validation.getFirstFormula();
- FormulaParser fp = new FormulaParser(str_formula, workbook);
- fp.parse();
- Stack ptg_arr = new Stack();
- Ptg[] ptg = fp.getRPNPtg();
- int size = 0;
- for (int k = 0; k < ptg.length; k++)
- {
- if ( ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg )
- {
- //we should set ptgClass to Ptg.CLASS_REF and explicit formula string to false
- ptg[k].setClass(Ptg.CLASS_REF);
- obj_validation.setExplicitListFormula(false);
- }
- size += ptg[k].getSize();
- ptg_arr.push(ptg[k]);
+ public void addValidationData(HSSFDataValidation dataValidation) {
+ if (dataValidation == null) {
+ throw new IllegalArgumentException("objValidation must not be null");
}
- dvRecord.setFirstFormulaRPN(ptg_arr);
- dvRecord.setFirstFormulaSize((short)size);
-
- dvRecord.setListExplicitFormula(obj_validation.getExplicitListFormula());
-
- if ( obj_validation.getSecondFormula() != null )
- {
- str_formula = obj_validation.getSecondFormula();
- fp = new FormulaParser(str_formula, workbook);
- fp.parse();
- ptg_arr = new Stack();
- ptg = fp.getRPNPtg();
- size = 0;
- for (int k = 0; k < ptg.length; k++)
- {
- size += ptg[k].getSize();
- ptg_arr.push(ptg[k]);
- }
- dvRecord.setSecFormulaRPN(ptg_arr);
- dvRecord.setSecFormulaSize((short)size);
- }
-
- //dv records cell range field
- HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
- cell_range.addADDRStructure(obj_validation.getFirstRow(), obj_validation.getFirstColumn(), obj_validation.getLastRow(), obj_validation.getLastColumn());
- dvRecord.setCellRangeAddress(cell_range);
+ DataValidityTable dvt = sheet.getOrCreateDataValidityTable();
- //add dv record
- eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
- sheet.getRecords().add( eofLoc, dvRecord );
+ dvt.addDataValidation(dataValidation, workbook);
}
+
/**
* Get the visibility state for a given column.
* @param column - the column to get (0-based)
{
return this._empty_cell_allowed ;
}
+ /**
+ * @deprecated - (Jul-2008) use setSuppressDropDownArrow
+ */
+ public void setSurppressDropDownArrow( boolean suppress ) {
+ setSuppressDropDownArrow(suppress);
+ }
+ /**
+ * @deprecated - (Jul-2008) use getSuppressDropDownArrow
+ */
+ public boolean getSurppressDropDownArrow( ) {
+ return getSuppressDropDownArrow();
+ }
/**
* Useful for list validation objects .
* @param surppres True if a list should display the values into a drop down list , false otherwise .
* In other words , if a list should display the arrow sign on its right side
*/
- public void setSurppressDropDownArrow( boolean surppres )
+ public void setSuppressDropDownArrow( boolean surppres )
{
this._surpress_dropdown_arrow = surppres;
}
* @return True if a list should display the values into a drop down list , false otherwise .
* @see setDataValidationType( int data_type )
*/
- public boolean getSurppressDropDownArrow( )
+ public boolean getSuppressDropDownArrow( )
{
if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
{
xfindex = sheet.getXFIndexForColAt((short) 1);
assertEquals(DEFAULT_IDX, xfindex);
- ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
+ // TODO change return type to ColumnInfoRecord
+ ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
sheet.columns.insertColumn(nci);
// single column ColumnInfoRecord
package org.apache.poi.hssf.model;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-
import junit.framework.TestCase;
import org.apache.poi.hssf.record.ColumnInfoRecord;
+import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
/**
* @author Tony Poppleton
public void testGetCellWidth() {
Sheet sheet = Sheet.createSheet();
- ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
+ // TODO change return type to ColumnInfoRecord
+ ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
// Prepare test model
nci.setFirstColumn((short)5);
package org.apache.poi.hssf.usermodel;
-import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
-import org.apache.poi.hssf.util.*;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
-import java.io.*;
-import java.util.*;
-import java.text.SimpleDateFormat;
+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.record.DVRecord;
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.hssf.util.HSSFDataValidation;
+import org.apache.poi.hssf.util.Region;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/**
* <p>Title: TestDataValidation</p>
*/
public class TestDataValidation extends TestCase
{
- public TestDataValidation(String name)
- {
- super(name);
- }
-
- protected void setUp()
- {
- String filename = System.getProperty("HSSF.testdata.path");
- if (filename == null)
- {
- System.setProperty("HSSF.testdata.path", "src/testcases/org/apache/poi/hssf/data");
- }
- }
public void testDataValidation() throws Exception
{
cell.setCellValue(strStettings);
}
- public static void main(String[] args)
- {
- junit.textui.TestRunner.run(TestDataValidation.class);
- }
+
+ public void testAddToExistingSheet() {
+
+ // dvEmpty.xls is a simple one sheet workbook. With a DataValidations header record but no
+ // DataValidations. It's important that the example has one SHEETPROTECTION record.
+ // Such a workbook can be created in Excel (2007) by adding datavalidation for one cell
+ // and then deleting the row that contains the cell.
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls");
+ int dvRow = 0;
+ HSSFSheet sheet = wb.getSheetAt(0);
+ sheet.createRow(dvRow).createCell((short)0);
+ HSSFDataValidation dv = new HSSFDataValidation((short)dvRow, (short)0, (short)dvRow, (short)0);
+
+ dv.setDataValidationType(HSSFDataValidation.DATA_TYPE_INTEGER);
+ dv.setEmptyCellAllowed(false);
+ dv.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+ dv.setFirstFormula("42");
+ dv.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+ dv.setShowPromptBox(true);
+ dv.createErrorBox("Error", "The value is wrong");
+ dv.setSurppressDropDownArrow(true);
+
+ sheet.addValidationData(dv);
+ wb.toString();
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ wb.write(baos);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ byte[] wbData = baos.toByteArray();
+
+ if (false) { // TODO (Jul 2008) fix EventRecordFactory to process unknown records, (and DV records for that matter)
+ EventRecordFactory erf = new EventRecordFactory();
+ ERFListener erfListener = null; // new MyERFListener();
+ erf.registerListener(erfListener, null);
+ try {
+ POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
+ erf.processRecords(fs.createDocumentInputStream("Workbook"));
+ } catch (RecordFormatException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ // else verify record ordering by navigating the raw bytes
+
+ byte[] dvHeaderRecStart= { (byte)0xB2, 0x01, 0x12, 0x00, };
+ int dvHeaderOffset = findIndex(wbData, dvHeaderRecStart);
+ assertTrue(dvHeaderOffset > 0);
+ int nextRecIndex = dvHeaderOffset + 22;
+ int nextSid
+ = ((wbData[nextRecIndex + 0] << 0) & 0x00FF)
+ + ((wbData[nextRecIndex + 1] << 8) & 0xFF00)
+ ;
+ // nextSid should be for a DVRecord. If anything comes between the DV header record
+ // and the DV records, Excel will not be able to open the workbook without error.
+
+ if (nextSid == 0x0867) {
+ throw new AssertionFailedError("Identified bug XXXX");
+ }
+ assertEquals(DVRecord.sid, nextSid);
+ }
+ private int findIndex(byte[] largeData, byte[] searchPattern) {
+ byte firstByte = searchPattern[0];
+ for (int i = 0; i < largeData.length; i++) {
+ if(largeData[i] != firstByte) {
+ continue;
+ }
+ boolean match = true;
+ for (int j = 1; j < searchPattern.length; j++) {
+ if(searchPattern[j] != largeData[i+j]) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ return i;
+ }
+ }
+ return -1;
+ }
}