Start on importing validation patches from bug #27511 (DVRecord still needs more work before it can go in)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@600513 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2007-12-03 13:00:02 +00:00
parent b895dae8fc
commit efac971e79
3 changed files with 882 additions and 0 deletions

View File

@ -0,0 +1,157 @@
/* ====================================================================
Copyright 2002-2004 Apache Software Foundation
Licensed 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;
import org.apache.poi.util.LittleEndian;
/**
* Title: DVAL Record<P>
* Description: used in data validation ;
* This record is the list header of all data validation records in the current sheet.
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
* @version 2.0-pre
*/
public class DVALRecord extends Record
{
public final static short sid = 0x01B2;
//unknown field ; it's size should be 10
private short field_unknown = 0x0000;
//Object ID of the drop down arrow object for list boxes ;
//in our case this will be always FFFF , until
//MSODrawingGroup and MSODrawing records are implemented
private int field_cbo_id = 0xFFFFFFFF;
//Number of following DV records
//Default value is 1
private int field_3_dv_no = 0x00000000;
public DVALRecord()
{
}
/**
* Constructs a DVAL record and sets its fields appropriately.
*
* @param in the RecordInputstream to read the record from
*/
public DVALRecord(RecordInputStream in)
{
super(in);
}
protected void validateSid(short id)
{
if (id != sid)
{
throw new RecordFormatException("NOT A valid DVAL RECORD");
}
}
protected void fillFields(RecordInputStream in)
{
for ( int i=0; i<5; i++)
{
this.field_unknown = in.readShort();
}
this.field_cbo_id = in.readInt();
this.field_3_dv_no = in.readInt();
}
/**
* set the object ID of the drop down arrow object for list boxes
* @param cboID - Object ID
*/
public void setObjectID(int cboID)
{
this.field_cbo_id = cboID;
}
/**
* Set the number of following DV records
* @param dvNo - the DV records number
*/
public void setDVRecNo(int dvNo)
{
this.field_3_dv_no = dvNo;
}
/**
* get Object ID of the drop down arrow object for list boxes
*/
public int getObjectID( )
{
return this.field_cbo_id;
}
/**
* Get number of following DV records
*/
public int getDVRecNo( )
{
return this.field_3_dv_no;
}
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append("[DVAL]\n");
buffer.append(" .comboObjectID = ").append(Integer.toHexString(this.getObjectID())).append("\n");
buffer.append(" .DVRecordsNumber = ").append(Integer.toHexString(this.getDVRecNo())).append("\n");
buffer.append("[/DVAL]\n");
return buffer.toString();
}
public int serialize(int offset, byte [] data)
{
LittleEndian.putShort(data, 0 + offset, this.sid);
LittleEndian.putShort(data, 2 + offset, ( short)(this.getRecordSize()-4));
for ( int i=0; i<5; i++)
{
LittleEndian.putShort(data, 4 + i*2 + offset, (short)this.field_unknown);
}
LittleEndian.putInt(data, 14 + offset, this.getObjectID());
LittleEndian.putInt(data, 18 + offset, this.getDVRecNo());
return getRecordSize();
}
//with 4 bytes header
public int getRecordSize()
{
return 22;
}
public short getSid()
{
return this.sid;
}
public Object clone()
{
DVALRecord rec = new DVALRecord();
rec.field_unknown = this.field_unknown;
rec.field_cbo_id = this.field_cbo_id;
rec.field_3_dv_no = this.field_3_dv_no;
return rec;
}
}

View File

@ -0,0 +1,254 @@
/* ====================================================================
Copyright 2002-2004 Apache Software Foundation
Licensed 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.util;
import org.apache.poi.util.LittleEndian;
import java.util.ArrayList;
/**
* <p>Title: HSSFCellRangeAddress</p>
* <p>Description:
* Implementation of the cell range address lists,like is described in
* OpenOffice.org's Excel Documentation .
* In BIFF8 there is a common way to store absolute cell range address
* lists in several records (not formulas). A cell range address list
* consists of a field with the number of ranges and the list of the range
* addresses. Each cell range address (called an ADDR structure) contains
* 4 16-bit-values.</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
* @version 2.0-pre
*/
public class HSSFCellRangeAddress
{
/**
* Number of following ADDR structures
*/
private short field_addr_number;
/**
* List of ADDR structures. Each structure represents a cell range
*/
private ArrayList field_regions_list;
public HSSFCellRangeAddress()
{
}
/**
* Construct a new HSSFCellRangeAddress object and sets its fields appropriately .
* Even this isn't an Excel record , I kept the same behavior for reading/writing
* the object's data as for a regular record .
* @param data Excel's file stream data
* @param offset the offset in Excel's file data
*/
public HSSFCellRangeAddress( byte [] data, int offset )
{
this.fillFields(data, offset);
}
public void fillFields(byte [] data, int offset)
{
this.field_addr_number = LittleEndian.getShort(data, 0 + offset);
this.field_regions_list = new ArrayList(this.field_addr_number);
int pos = 2;
for (int k = 0; k < this.field_addr_number; k++)
{
short first_row = LittleEndian.getShort(data, pos + offset);
short first_col = LittleEndian.getShort(data, pos + 2 + offset);
short last_row = LittleEndian.getShort(data, pos + 4 + offset);
short last_col = LittleEndian.getShort(data, pos + 6 + offset);
AddrStructure region = new AddrStructure(first_row, first_col, last_row, last_col);
pos += 8;
this.field_regions_list.add(region);
}
}
/**
* Get the number of following ADDR structures.
* The number of this structures is automatically set when reading an Excel file
* and/or increased when you manually add a new ADDR structure .
* This is the reason there isn't a set method for this field .
* @return number of ADDR structures
*/
public short getADDRStructureNumber()
{
return this.field_addr_number;
}
/**
* Add an ADDR structure .
* @param first_row - the upper left hand corner's row
* @param first_col - the upper left hand corner's col
* @param last_row - the lower right hand corner's row
* @param last_col - the lower right hand corner's col
* @return the index of this ADDR structure
*/
public int addADDRStructure(short first_row, short first_col, short last_row, short last_col)
{
if (this.field_regions_list == null)
{
//just to be sure :-)
this.field_addr_number= 0;
this.field_regions_list = new ArrayList(10);
}
AddrStructure region = new AddrStructure(first_row, last_row, first_col, last_col);
this.field_regions_list.add(region);
this.field_addr_number++;
return this.field_addr_number;
}
/**
* Remove the ADDR structure stored at the passed in index
* @param index The ADDR structure's index
*/
public void removeADDRStructureAt(int index)
{
this.field_regions_list.remove(index);
this.field_addr_number--;
}
/**
* return the ADDR structure at the given index.
* @return AddrStructure representing
*/
public AddrStructure getADDRStructureAt(int index)
{
return ( AddrStructure ) this.field_regions_list.get(index);
}
public int serialize(int offset, byte [] data)
{
int pos = 2;
LittleEndian.putShort(data, offset, this.getADDRStructureNumber());
for (int k = 0; k < this.getADDRStructureNumber(); k++)
{
AddrStructure region = this.getADDRStructureAt(k);
LittleEndian.putShort(data, offset + pos, region.getFirstRow());
pos += 2;
LittleEndian.putShort(data, offset + pos, region.getLastRow());
pos += 2;
LittleEndian.putShort(data, offset + pos, region.getFirstColumn());
pos += 2;
LittleEndian.putShort(data, offset + pos, region.getLastColumn());
pos += 2;
}
return this.getSize();
}
public int getSize()
{
return 2 + this.field_addr_number*8;
}
public class AddrStructure
{
private short _first_row;
private short _first_col;
private short _last_row;
private short _last_col;
public AddrStructure(short first_row, short last_row, short first_col, short last_col)
{
this._first_row = first_row;
this._last_row = last_row;
this._first_col = first_col;
this._last_col = last_col;
}
/**
* get the upper left hand corner column number
* @return column number for the upper left hand corner
*/
public short getFirstColumn()
{
return this._first_col;
}
/**
* get the upper left hand corner row number
* @return row number for the upper left hand corner
*/
public short getFirstRow()
{
return this._first_row;
}
/**
* get the lower right hand corner column number
* @return column number for the lower right hand corner
*/
public short getLastColumn()
{
return this._last_col;
}
/**
* get the lower right hand corner row number
* @return row number for the lower right hand corner
*/
public short getLastRow()
{
return this._last_row;
}
/**
* set the upper left hand corner column number
* @param this._first_col column number for the upper left hand corner
*/
public void setFirstColumn(short first_col)
{
this._first_col = first_col;
}
/**
* set the upper left hand corner row number
* @param rowFrom row number for the upper left hand corner
*/
public void setFirstRow(short first_row)
{
this._first_row = first_row;
}
/**
* set the lower right hand corner column number
* @param colTo column number for the lower right hand corner
*/
public void setLastColumn(short last_col)
{
this._last_col = last_col;
}
/**
* get the lower right hand corner row number
* @param rowTo row number for the lower right hand corner
*/
public void setLastRow(short last_row)
{
this._last_row = last_row;
}
}
}

View File

@ -0,0 +1,471 @@
/* ====================================================================
Copyright 2002-2004 Apache Software Foundation
Licensed 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.util;
/**
* <p>Title: HSSFDataValidation</p>
* <p>Description: Utilty class for creating data validation cells</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
* @version 2.0-pre
*/
public class HSSFDataValidation
{
/**
* Validation data type constants
*/
/**
* Any type
*/
public static final int DATA_TYPE_ANY = 0x00;
/**
* Integer type
*/
public static final int DATA_TYPE_INTEGER = 0x01;
/**
* Decimal type
*/
public static final int DATA_TYPE_DECIMAL = 0x02;
/**
* List type ( combo box type )
*/
public static final int DATA_TYPE_LIST = 0x03;
/**
* Date type
*/
public static final int DATA_TYPE_DATE = 0x04;
/**
* Time type
*/
public static final int DATA_TYPE_TIME = 0x05;
/**
* String length type
*/
public static final int DATA_TYPE_TEXT_LENGTH = 0x06;
/**
* Formula ( custom ) type
*/
public static final int DATA_TYPE_FORMULA = 0x07;
/**
* Error style constants for error box
*/
/**
* STOP style like
*/
public static final int ERROR_STYLE_STOP = 0x00;
/**
* WARNING style like
*/
public static final int ERROR_STYLE_WARNING = 0x01;
/**
* INFO style like
*/
public static final int ERROR_STYLE_INFO = 0x02;
/**
* Condition operator
*/
public static final int OPERATOR_BETWEEN = 0x00;
public static final int OPERATOR_NOT_BETWEEN = 0x01;
public static final int OPERATOR_EQUAL = 0x02;
public static final int OPERATOR_NOT_EQUAL = 0x03;
public static final int OPERATOR_GREATER_THAN = 0x04;
public static final int OPERATOR_LESS_THAN = 0x05;
public static final int OPERATOR_GREATER_OR_EQUAL = 0x06;
public static final int OPERATOR_LESS_OR_EQUAL = 0x07;
private short _first_row = 0;
private short _first_col = 0;
private short _last_row = 0;
private short _last_col = 0;
private String _prompt_title = null;
private String _prompt_text = null;
private String _error_title = null;
private String _error_text = null;
private String _string_first_formula = null;
private String _string_sec_formula = null;
private int _data_type = HSSFDataValidation.DATA_TYPE_ANY;
private int _error_style = HSSFDataValidation.ERROR_STYLE_STOP;
private boolean _list_explicit_formula = true;
private boolean _empty_cell_allowed = true;
private boolean _surpress_dropdown_arrow = false;
private boolean _show_prompt_box = true;
private boolean _show_error_box = true;
private int _operator = HSSFDataValidation.OPERATOR_BETWEEN;
/**
* Empty constructor
*/
public HSSFDataValidation( )
{
}
/**
* Constructor wich initializes the cell range on wich this object will be applied
* @param first_row First row
* @param first_col First column
* @param last_row Last row
* @param last_col Last column
*/
public HSSFDataValidation( short first_row, short first_col, short last_row, short last_col )
{
this._first_row = first_row;
this._first_col = first_col;
this._last_row = last_row;
this._last_col = last_col;
}
/**
* Set the type of this object
* @param data_type The type
* @see DATA_TYPE_ANY, DATA_TYPE_INTEGER, DATA_TYPE_DECIMNAL, DATA_TYPE_LIST, DATA_TYPE_DATE,
* DATA_TYPE_TIME, DATA_TYPE_TEXT_LENTGH, DATA_TYPE_FORMULA
*/
public void setDataValidationType( int data_type )
{
this._data_type = data_type;
}
/**
* The data type of this object
* @return The type
* @see DATA_TYPE_ANY, DATA_TYPE_INTEGER, DATA_TYPE_DECIMNAL, DATA_TYPE_LIST, DATA_TYPE_DATE,
* DATA_TYPE_TIME, DATA_TYPE_TEXT_LENTGH, DATA_TYPE_FORMULA
*/
public int getDataValidationType()
{
return this._data_type;
}
/**
* Sets the error style for error box
* @param error_style Error style constant
* @see ERROR_STYLE_STOP, ERROR_STYLE_WARNING, ERROR_STYLE_INFO
*/
public void setErrorStyle( int error_style )
{
this._error_style = error_style;
}
/**
* returns the error style of errror box
* @return the style constant
* @see ERROR_STYLE_STOP, ERROR_STYLE_WARNING, ERROR_STYLE_INFO
*/
public int getErrorStyle( )
{
return this._error_style;
}
/**
* If this object has an explicit formula . This is useful only for list data validation object
* @param explicit True if use an explicit formula
*/
public void setExplicitListFormula( boolean explicit )
{
this._list_explicit_formula = explicit;
}
/**
* Returns the settings for explicit formula . This is useful only for list data validation objects.
* This method always returns false if the object isn't a list validation object
* @see setDataValidationType( int data_type )
* @return
*/
public boolean getExplicitListFormula( )
{
if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
{
return false;
}
return this._list_explicit_formula ;
}
/**
* Sets if this object allows empty as a valid value
* @param allowed True if this object should treats empty as valid value , false otherwise
*/
public void setEmptyCellAllowed( boolean allowed )
{
this._empty_cell_allowed = allowed;
}
/**
* Retrieve the settings for empty cells allowed
* @return True if this object should treats empty as valid value , false otherwise
*/
public boolean getEmptyCellAllowed( )
{
return this._empty_cell_allowed ;
}
/**
* 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 )
{
this._surpress_dropdown_arrow = surppres;
}
/**
* Useful only list validation objects .
* This method always returns false if the object isn't a list validation object
* @return True if a list should display the values into a drop down list , false otherwise .
* @see setDataValidationType( int data_type )
*/
public boolean getSurppressDropDownArrow( )
{
if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
{
return false;
}
return this._surpress_dropdown_arrow ;
}
/**
* Sets the behaviour when a cell which belongs to this object is selected
* @param show True if an prompt box should be displayed , false otherwise
*/
public void setShowPromptBox( boolean show )
{
this._show_prompt_box = show;
}
/**
* @param show True if an prompt box should be displayed , false otherwise
*/
public boolean getShowPromptBox( )
{
if ( (this.getPromptBoxText() == null) && (this.getPromptBoxTitle() == null) )
{
return false;
}
return this._show_prompt_box ;
}
/**
* Sets the behaviour when an invalid value is entered
* @param show True if an error box should be displayed , false otherwise
*/
public void setShowErrorBox( boolean show )
{
this._show_error_box = show;
}
/**
* @return True if an error box should be displayed , false otherwise
*/
public boolean getShowErrorBox( )
{
if ( (this.getErrorBoxText() == null) && (this.getErrorBoxTitle() == null) )
{
return false;
}
return this._show_error_box ;
}
/**
* Sets the operator involved in the formula whic governs this object
* Example : if you wants that a cell to accept only values between 1 and 5 , which
* mathematically means 1 <= value <= 5 , then the operator should be OPERATOR_BETWEEN
* @param operator A constant for operator
* @see OPERATOR_BETWEEN, OPERATOR_NOT_BETWEEN, OPERATOR_EQUAL, OPERATOR_NOT_EQUAL
* OPERATOR_GREATER_THAN, OPERATOR_LESS_THAN, OPERATOR_GREATER_OR_EQUAL,
* OPERATOR_LESS_OR_EQUAL
*/
public void setOperator( int operator )
{
this._operator = operator;
}
/**
* Retrieves the operator used for this object's formula
* @return
* @see OPERATOR_BETWEEN, OPERATOR_NOT_BETWEEN, OPERATOR_EQUAL, OPERATOR_NOT_EQUAL
* OPERATOR_GREATER_THAN, OPERATOR_LESS_THAN, OPERATOR_GREATER_OR_EQUAL,
* OPERATOR_LESS_OR_EQUAL
*/
public int getOperator()
{
return this._operator;
}
/**
* Sets the title and text for the prompt box . Prompt box is displayed when the user
* selects a cell which belongs to this validation object . In order for a prompt box
* to be displayed you should also use method setShowPromptBox( boolean show )
* @param title The prompt box's title
* @param text The prompt box's text
* @see setShowPromptBox( boolean show )
*/
public void createPromptBox( String title, String text )
{
this._prompt_title = title;
this._prompt_text = text;
this.setShowPromptBox(true);
}
/**
* Returns the prompt box's title
* @return Prompt box's title or null
*/
public String getPromptBoxTitle( )
{
return this._prompt_title;
}
/**
* Returns the prompt box's text
* @return Prompt box's text or null
*/
public String getPromptBoxText( )
{
return this._prompt_text;
}
/**
* Sets the title and text for the error box . Error box is displayed when the user
* enters an invalid value int o a cell which belongs to this validation object .
* In order for an error box to be displayed you should also use method
* setShowErrorBox( boolean show )
* @param title The error box's title
* @param text The error box's text
* @see setShowErrorBox( boolean show )
*/
public void createErrorBox( String title, String text )
{
this._error_title = title;
this._error_text = text;
this.setShowErrorBox(true);
}
/**
* Returns the error box's title
* @return Error box's title or null
*/
public String getErrorBoxTitle( )
{
return this._error_title;
}
/**
* Returns the error box's text
* @return Error box's text or null
*/
public String getErrorBoxText( )
{
return this._error_text;
}
/**
* Sets the first formula for this object .
* A formula is divided into three parts : first formula , operator and second formula .
* In other words , a formula contains a left oprand , an operator and a right operand.
* This is the general rule . An example is 1<= value <= 5 . In this case ,
* the left operand ( or the first formula ) is the number 1 . The operator is
* OPERATOR_BETWEEN and the right operand ( or the second formula ) is 5 .
* @param formula
*/
public void setFirstFormula( String formula )
{
this._string_first_formula = formula;
}
/**
* Returns the first formula
* @return
*/
public String getFirstFormula( )
{
return this._string_first_formula;
}
/**
* Sets the first formula for this object .
* A formula is divided into three parts : first formula , operator and second formula .
* In other words , a formula contains a left oprand , an operator and a right operand.
* This is the general rule . An example is 1<= value <=5 . In this case ,
* the left operand ( or the first formula ) is the number 1 . The operator is
* OPERATOR_BETWEEN and the right operand ( or the second formula ) is 5 .
* But there are cases when a second formula isn't needed :
* You want somethink like : all values less than 5 . In this case , there's only a first
* formula ( in our case 5 ) and the operator OPERATOR_LESS_THAN
* @param formula
*/
public void setSecondFormula( String formula )
{
this._string_sec_formula = formula;
}
/**
* Returns the second formula
* @return
*/
public String getSecondFormula( )
{
return this._string_sec_formula;
}
public void setFirstRow( short first_row )
{
this._first_row = first_row;
}
public void setFirstColumn( short first_column )
{
this._first_col = first_column;
}
public void setLastRow( short last_row )
{
this._last_row = last_row;
}
public void setLastColumn( short last_column )
{
this._last_col = last_column;
}
public short getFirstRow()
{
return this._first_row;
}
public short getFirstColumn()
{
return this._first_col;
}
public short getLastRow()
{
return this._last_row;
}
public short getLastColumn()
{
return this._last_col;
}
}