Fix for bug 45519 - keep data validation records together

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@681530 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-07-31 22:44:48 +00:00
parent d5020af75e
commit 9ec8702c99
13 changed files with 570 additions and 497 deletions

View File

@ -37,6 +37,7 @@
<!-- 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>

View File

@ -34,6 +34,7 @@
<!-- 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>

View File

@ -25,7 +25,7 @@ import org.apache.poi.hssf.record.Record;
*
* @author Josh Micich
*/
final class RecordStream {
public final class RecordStream {
private final List _list;
private int _nextIndex;

View File

@ -17,13 +17,13 @@
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;
@ -31,7 +31,7 @@ import org.apache.poi.util.POILogger;
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)
@ -90,6 +90,7 @@ public final class Sheet implements Model {
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;
@ -299,7 +300,12 @@ public final class Sheet implements Model {
// 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;
@ -425,56 +431,56 @@ public final class Sheet implements Model {
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;
@ -522,7 +528,7 @@ public final class Sheet implements Model {
if (merged == null || merged.getNumAreas() == 1027)
{
merged = ( MergeCellsRecord ) createMergedCells();
merged = createMergedCells();
mergedRecords.add(merged);
records.add(records.size() - 1, merged);
}
@ -911,124 +917,11 @@ public final class Sheet implements Model {
/**
* 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).
@ -1247,13 +1140,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1266,31 +1154,10 @@ public final class Sheet implements Model {
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);
@ -1298,29 +1165,19 @@ public final class Sheet implements Model {
}
/**
* 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);
@ -1329,13 +1186,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1344,13 +1196,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1359,13 +1206,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1374,13 +1216,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1390,14 +1227,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1406,13 +1237,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1421,13 +1247,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1439,13 +1260,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1455,13 +1271,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1471,13 +1282,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1487,13 +1293,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1503,13 +1304,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1518,13 +1314,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1537,9 +1328,7 @@ public final class Sheet implements Model {
* @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);
@ -1558,30 +1347,13 @@ public final class Sheet implements Model {
/**
* 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
@ -1600,7 +1372,7 @@ public final class Sheet implements Model {
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);
@ -1816,22 +1588,18 @@ public final class Sheet implements Model {
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);
@ -1849,13 +1617,8 @@ public final class Sheet implements Model {
* 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);
@ -1869,14 +1632,8 @@ public final class Sheet implements Model {
/**
* 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);
@ -1903,19 +1660,15 @@ public final class Sheet implements Model {
* 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
@ -1977,25 +1730,12 @@ public final class Sheet implements Model {
}
}
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
@ -2383,28 +2123,20 @@ public final class Sheet implements Model {
/**
* 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();
@ -2415,12 +2147,8 @@ public final class Sheet implements Model {
/**
* 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();
@ -2435,9 +2163,9 @@ public final class Sheet implements Model {
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;
@ -2459,14 +2187,11 @@ public final class Sheet implements Model {
/**
* 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);
@ -2892,4 +2617,10 @@ public final class Sheet implements Model {
rows.expandRow( row );
}
}
public DataValidityTable getOrCreateDataValidityTable() {
if (_dataValidityTable == null) {
_dataValidityTable = DataValidityTable.createForSheet(records);
}
return _dataValidityTable;
}
}

View File

@ -23,6 +23,7 @@ import java.util.Stack;
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;
@ -114,7 +115,7 @@ public final class DVRecord extends Record
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);
@ -283,25 +284,37 @@ public final class DVRecord extends Record
{
return (this.opt_empty_cell_allowed.isSet(this.field_option_flags));
}
/**
* 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
* @see org.apache.poi.hssf.util.HSSFDataValidation utility class
*/
public void setSurppresDropdownArrow(boolean surppress)
{
this.field_option_flags = this.opt_surppres_dropdown_arrow.setBoolean(this.field_option_flags, surppress);
* @deprecated - (Jul-2008) use setSuppressDropDownArrow
*/
public void setSurppresDropdownArrow(boolean suppress) {
setSuppressDropdownArrow(suppress);
}
/**
* @deprecated - (Jul-2008) use getSuppressDropDownArrow
*/
public boolean getSurppresDropdownArrow() {
return getSuppressDropdownArrow();
}
/**
* 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
* 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 boolean getSurppresDropdownArrow()
public void setSuppressDropdownArrow(boolean suppress)
{
return (this.opt_surppres_dropdown_arrow.isSet(this.field_option_flags));
this.field_option_flags = this.opt_suppress_dropdown_arrow.setBoolean(this.field_option_flags, suppress);
}
/**
* 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 getSuppressDropdownArrow()
{
return (this.opt_suppress_dropdown_arrow.isSet(this.field_option_flags));
}
/**
@ -433,9 +446,40 @@ public final class DVRecord extends Record
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)
@ -506,7 +550,7 @@ public final class DVRecord extends Record
* contents are somewhat complex
*/
public Object clone() {
return cloneViaReserialise();
return cloneViaReserialise();
}
/**@todo DVRecord = Serializare */
@ -535,7 +579,7 @@ public final class DVRecord extends Record
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
{

View File

@ -0,0 +1,240 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record.aggregates;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.CFHeaderRecord;
import org.apache.poi.hssf.record.CFRuleRecord;
import org.apache.poi.hssf.record.DVALRecord;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.HyperlinkRecord;
import org.apache.poi.hssf.record.MergeCellsRecord;
import org.apache.poi.hssf.record.PaneRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SelectionRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFCellRangeAddress;
import org.apache.poi.hssf.util.HSSFDataValidation;
/**
* Manages the DVALRecord and DVRecords for a single sheet<br/>
* See OOO excelfileformat.pdf section 4.14
* @author Josh Micich
*/
public final class DataValidityTable extends RecordAggregate {
private static final short sid = -0x01B2; // not a real record
private final DVALRecord _headerRec;
/**
* The list of data validations for the current sheet.
* Note - this may be empty (contrary to OOO documentation)
*/
private final List _validationList;
public DataValidityTable(RecordStream rs) {
_headerRec = (DVALRecord) rs.getNext();
List temp = new ArrayList();
while (rs.peekNextClass() == DVRecord.class) {
temp.add(rs.getNext());
}
_validationList = temp;
}
private DataValidityTable() {
_headerRec = new DVALRecord();
_validationList = new ArrayList();
}
public short getSid() {
return sid;
}
public int serialize(int offset, byte[] data) {
int result = _headerRec.serialize(offset, data);
for (int i = 0; i < _validationList.size(); i++) {
result += ((Record) _validationList.get(i)).serialize(offset + result, data);
}
return result;
}
public int getRecordSize() {
int result = _headerRec.getRecordSize();
for (int i = _validationList.size() - 1; i >= 0; i--) {
result += ((Record) _validationList.get(i)).getRecordSize();
}
return result;
}
/**
* Creates a new <tt>DataValidityTable</tt> and inserts it in the right
* place in the sheetRecords list.
*/
public static DataValidityTable createForSheet(List sheetRecords) {
int index = findDVTableInsertPos(sheetRecords);
DataValidityTable result = new DataValidityTable();
sheetRecords.add(index, result);
return result;
}
/**
* Finds the index where the sheet validations header record should be inserted
* @param records the records for this sheet
*
* + WINDOW2
* o SCL
* o PANE
* oo SELECTION
* o STANDARDWIDTH
* oo MERGEDCELLS
* o LABELRANGES
* o PHONETICPR
* o Conditional Formatting Table
* o Hyperlink Table
* o Data Validity Table
* o SHEETLAYOUT
* o SHEETPROTECTION
* o RANGEPROTECTION
* + EOF
*/
private static int findDVTableInsertPos(List records) {
int i = records.size() - 1;
if (!(records.get(i) instanceof EOFRecord)) {
throw new IllegalStateException("Last sheet record should be EOFRecord");
}
while (i > 0) {
i--;
Record rec = (Record) records.get(i);
if (isPriorRecord(rec.getSid())) {
Record nextRec = (Record) records.get(i + 1);
if (!isSubsequentRecord(nextRec.getSid())) {
throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName()
+ ") found after (" + rec.getClass().getName() + ")");
}
return i;
}
if (!isSubsequentRecord(rec.getSid())) {
throw new IllegalStateException("Unexpected (" + rec.getClass().getName()
+ ") while looking for DV Table insert pos");
}
}
return 0;
}
// TODO - add UninterpretedRecord as base class for many of these
// unimplemented sids
private static boolean isPriorRecord(short sid) {
switch(sid) {
case WindowTwoRecord.sid:
case 0x00A0: // SCL
case PaneRecord.sid:
case SelectionRecord.sid:
case 0x0099: // STANDARDWIDTH
case MergeCellsRecord.sid:
case 0x015F: // LABELRANGES
case 0x00EF: // PHONETICPR
case CFHeaderRecord.sid:
case CFRuleRecord.sid:
case HyperlinkRecord.sid:
case 0x0800: // QUICKTIP
return true;
}
return false;
}
private static boolean isSubsequentRecord(short sid) {
switch(sid) {
case 0x0862: // SHEETLAYOUT
case 0x0867: // SHEETPROTECTION
case 0x0868: // RANGEPROTECTION
case EOFRecord.sid:
return true;
}
return false;
}
public void addDataValidation(HSSFDataValidation dataValidation, HSSFWorkbook workbook) {
DVRecord dvRecord = new DVRecord();
// dv record's option flags
dvRecord.setDataType(dataValidation.getDataValidationType());
dvRecord.setErrorStyle(dataValidation.getErrorStyle());
dvRecord.setEmptyCellAllowed(dataValidation.getEmptyCellAllowed());
dvRecord.setSuppressDropdownArrow(dataValidation.getSuppressDropDownArrow());
dvRecord.setShowPromptOnCellSelected(dataValidation.getShowPromptBox());
dvRecord.setShowErrorOnInvalidValue(dataValidation.getShowErrorBox());
dvRecord.setConditionOperator(dataValidation.getOperator());
// string fields
dvRecord.setStringField(DVRecord.STRING_PROMPT_TITLE, dataValidation.getPromptBoxTitle());
dvRecord.setStringField(DVRecord.STRING_PROMPT_TEXT, dataValidation.getPromptBoxText());
dvRecord.setStringField(DVRecord.STRING_ERROR_TITLE, dataValidation.getErrorBoxTitle());
dvRecord.setStringField(DVRecord.STRING_ERROR_TEXT, dataValidation.getErrorBoxText());
// formula fields ( size and data )
Stack ptg_arr = new Stack();
Ptg[] ptg = FormulaParser.parse(dataValidation.getFirstFormula(), workbook);
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]);
}
dvRecord.setFirstFormulaRPN(ptg_arr);
dvRecord.setFirstFormulaSize((short) size);
dvRecord.setListExplicitFormula(dataValidation.getExplicitListFormula());
if (dataValidation.getSecondFormula() != null) {
ptg_arr = new Stack();
ptg = FormulaParser.parse(dataValidation.getSecondFormula(), workbook);
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(dataValidation.getFirstRow(), dataValidation.getFirstColumn(),
dataValidation.getLastRow(), dataValidation.getLastColumn());
dvRecord.setCellRangeAddress(cell_range);
_validationList.add(dvRecord);
_headerRec.setDVRecNo(_validationList.size());
}
}

View File

@ -0,0 +1,41 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordInputStream;
/**
* <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored
* together and/or updated together. Workbook / Sheet records are typically stored in a sequential
* list, which does not provide much structure to coordinate updates.
*
* @author Josh Micich
*/
public abstract class RecordAggregate extends Record {
// TODO - convert existing aggregate classes to proper subclasses of this one
protected final void validateSid(short id) {
// TODO - break class hierarchy and make separate from Record
throw new RuntimeException("Should not be called");
}
protected final void fillFields(RecordInputStream in) {
throw new RuntimeException("Should not be called");
}
// force subclassses to provide better implementation than default
public abstract int getRecordSize();
}

View File

@ -28,7 +28,6 @@ import java.text.NumberFormat;
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;
@ -36,9 +35,9 @@ 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.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;
@ -375,92 +374,18 @@ public final class HSSFSheet {
/**
* 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;
public void addValidationData(HSSFDataValidation dataValidation) {
if (dataValidation == null) {
throw new IllegalArgumentException("objValidation must not be null");
}
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);
DataValidityTable dvt = sheet.getOrCreateDataValidityTable();
//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]);
}
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);
//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)

View File

@ -218,13 +218,25 @@ public class HSSFDataValidation
{
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;
}
@ -235,7 +247,7 @@ public class HSSFDataValidation
* @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 )
{

Binary file not shown.

View File

@ -297,7 +297,8 @@ public final class TestSheet extends TestCase {
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

View File

@ -17,13 +17,10 @@
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
@ -32,7 +29,8 @@ public final class TestSheetAdditional extends TestCase {
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);

View File

@ -16,13 +16,25 @@
package org.apache.poi.hssf.usermodel;
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 junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.util.*;
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>
@ -34,19 +46,6 @@ import java.text.SimpleDateFormat;
*/
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
{
@ -903,8 +902,88 @@ public class TestDataValidation extends TestCase
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;
}
}