Initial work on bug 45720 - copy 'FilterDatabase' named record when cloning sheets. Some clean-up in NameRecord.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@691740 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-09-03 19:22:53 +00:00
parent a1a888f7f7
commit df610f03ef
8 changed files with 400 additions and 527 deletions

View File

@ -17,9 +17,8 @@
package org.apache.poi.hssf.record; package org.apache.poi.hssf.record;
import java.util.Iterator; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.model.FormulaParser; import org.apache.poi.hssf.model.FormulaParser;
import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.Area3DPtg;
@ -44,50 +43,32 @@ import org.apache.poi.util.StringUtil;
*/ */
public final class NameRecord extends Record { public final class NameRecord extends Record {
public final static short sid = 0x0018; public final static short sid = 0x0018;
/**Included for completeness sake, not implemented /**Included for completeness sake, not implemented */
*/ public final static byte BUILTIN_CONSOLIDATE_AREA = 1;
public final static byte BUILTIN_CONSOLIDATE_AREA = (byte)1; /**Included for completeness sake, not implemented */
public final static byte BUILTIN_AUTO_OPEN = 2;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_AUTO_CLOSE = 3;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_DATABASE = 4;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_CRITERIA = 5;
/**Included for completeness sake, not implemented public final static byte BUILTIN_PRINT_AREA = 6;
*/ public final static byte BUILTIN_PRINT_TITLE = 7;
public final static byte BUILTIN_AUTO_OPEN = (byte)2;
/**Included for completeness sake, not implemented /**Included for completeness sake, not implemented */
*/ public final static byte BUILTIN_RECORDER = 8;
public final static byte BUILTIN_AUTO_CLOSE = (byte)3; /**Included for completeness sake, not implemented */
public final static byte BUILTIN_DATA_FORM = 9;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_AUTO_ACTIVATE = 10;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_AUTO_DEACTIVATE = 11;
/**Included for completeness sake, not implemented */
public final static byte BUILTIN_SHEET_TITLE = 12;
/**Included for completeness sake, not implemented public final static byte BUILTIN_FILTER_DB = 13;
*/
public final static byte BUILTIN_DATABASE = (byte)4;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_CRITERIA = (byte)5;
public final static byte BUILTIN_PRINT_AREA = (byte)6;
public final static byte BUILTIN_PRINT_TITLE = (byte)7;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_RECORDER = (byte)8;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_DATA_FORM = (byte)9;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_AUTO_ACTIVATE = (byte)10;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_AUTO_DEACTIVATE = (byte)11;
/**Included for completeness sake, not implemented
*/
public final static byte BUILTIN_SHEET_TITLE = (byte)12;
private static final class Option { private static final class Option {
public static final int OPT_HIDDEN_NAME = 0x0001; public static final int OPT_HIDDEN_NAME = 0x0001;
@ -101,19 +82,13 @@ public final class NameRecord extends Record {
private short field_1_option_flag; private short field_1_option_flag;
private byte field_2_keyboard_shortcut; private byte field_2_keyboard_shortcut;
private byte field_3_length_name_text;
private short field_4_length_name_definition;
private short field_5_index_to_sheet; // unused: see field_6 private short field_5_index_to_sheet; // unused: see field_6
/** the one based sheet number. Zero if this is a global name */ /** the one based sheet number. Zero if this is a global name */
private int field_6_sheetNumber; private int field_6_sheetNumber;
private byte field_7_length_custom_menu; private boolean field_11_nameIsMultibyte;
private byte field_8_length_description_text; private byte field_12_built_in_code;
private byte field_9_length_help_topic_text;
private byte field_10_length_status_bar_text;
private byte field_11_compressed_unicode_flag; // not documented
private byte field_12_builtIn_name;
private String field_12_name_text; private String field_12_name_text;
private Stack field_13_name_definition; private Ptg[] field_13_name_definition;
private String field_14_custom_menu_text; private String field_14_custom_menu_text;
private String field_15_description_text; private String field_15_description_text;
private String field_16_help_topic_text; private String field_16_help_topic_text;
@ -122,13 +97,13 @@ public final class NameRecord extends Record {
/** Creates new NameRecord */ /** Creates new NameRecord */
public NameRecord() { public NameRecord() {
field_13_name_definition = new Stack(); field_13_name_definition = Ptg.EMPTY_PTG_ARRAY;
field_12_name_text = new String(); field_12_name_text = "";
field_14_custom_menu_text = new String(); field_14_custom_menu_text = "";
field_15_description_text = new String(); field_15_description_text = "";
field_16_help_topic_text = new String(); field_16_help_topic_text = "";
field_17_status_bar_text = new String(); field_17_status_bar_text = "";
} }
/** /**
@ -147,18 +122,9 @@ public final class NameRecord extends Record {
public NameRecord(byte builtin, int sheetNumber) public NameRecord(byte builtin, int sheetNumber)
{ {
this(); this();
this.field_12_builtIn_name = builtin; field_12_built_in_code = builtin;
this.setOptionFlag((short)(this.field_1_option_flag | Option.OPT_BUILTIN)); setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
this.setNameTextLength((byte)1);
field_6_sheetNumber = sheetNumber; //the extern sheets are set through references field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
//clearing these because they are not used with builtin records
this.setCustomMenuLength((byte)0);
this.setDescriptionTextLength((byte)0);
this.setHelpTopicLength((byte)0);
this.setStatusBarLength((byte)0);
} }
/** sets the option flag for the named range /** sets the option flag for the named range
@ -176,31 +142,6 @@ public final class NameRecord extends Record {
field_2_keyboard_shortcut = shortcut; field_2_keyboard_shortcut = shortcut;
} }
/** sets the name of the named range length
* @param length name length
*/
public void setNameTextLength(byte length){
field_3_length_name_text = length;
}
/** sets the definition (reference - formula) length
* @param length defenition length
*/
public void setDefinitionTextLength(short length){
field_4_length_name_definition = length;
}
/** sets the index number to the extern sheet (thats is what writen in documentation
* but as i saw , it works differently)
* @param index extern sheet index
*/
public void setUnused(short index){
field_5_index_to_sheet = index;
// field_6_equals_to_index_to_sheet is equal to field_5_index_to_sheet
// field_6_equals_to_index_to_sheet = index;
}
/** /**
* For named ranges, and built-in names * For named ranges, and built-in names
* @return the 1-based sheet number. Zero if this is a global name * @return the 1-based sheet number. Zero if this is a global name
@ -226,49 +167,12 @@ public final class NameRecord extends Record {
} }
/** sets the custom menu length
* @param length custom menu length
*/
public void setCustomMenuLength(byte length){
field_7_length_custom_menu = length;
}
/** sets the length of named range description
* @param length description length
*/
public void setDescriptionTextLength(byte length){
field_8_length_description_text = length;
}
/** sets the help topic length
* @param length help topic length
*/
public void setHelpTopicLength(byte length){
field_9_length_help_topic_text = length;
}
/** sets the length of the status bar text
* @param length status bar text length
*/
public void setStatusBarLength(byte length){
field_10_length_status_bar_text = length;
}
/** sets the compressed unicode flag
* @param flag unicode flag
*/
public void setCompressedUnicodeFlag(byte flag) {
field_11_compressed_unicode_flag = flag;
}
/** sets the name of the named range /** sets the name of the named range
* @param name named range name * @param name named range name
*/ */
public void setNameText(String name){ public void setNameText(String name){
field_12_name_text = name; field_12_name_text = name;
setCompressedUnicodeFlag( field_11_nameIsMultibyte = StringUtil.hasMultibyte(name);
StringUtil.hasMultibyte(name) ? (byte)1 : (byte)0
);
} }
/** sets the custom menu text /** sets the custom menu text
@ -317,68 +221,11 @@ public final class NameRecord extends Record {
* gets the name length, in characters * gets the name length, in characters
* @return name length * @return name length
*/ */
public byte getNameTextLength(){ private int getNameTextLength(){
return field_3_length_name_text; if (isBuiltInName()) {
return 1;
} }
return field_12_name_text.length();
/**
* gets the name length, in bytes
* @return raw name length
*/
public byte getRawNameTextLength(){
if( (field_11_compressed_unicode_flag & 0x01) == 1 ) {
return (byte)(2 * field_3_length_name_text);
}
return field_3_length_name_text;
}
/** get the definition length
* @return definition length
*/
public short getDefinitionLength(){
return field_4_length_name_definition;
}
/** gets the index to extern sheet
* @return index to extern sheet
*/
public short getUnused(){
return field_5_index_to_sheet;
}
/** gets the custom menu length
* @return custom menu length
*/
public byte getCustomMenuLength(){
return field_7_length_custom_menu;
}
/** gets the description text length
* @return description text length
*/
public byte getDescriptionTextLength(){
return field_8_length_description_text;
}
/** gets the help topic length
* @return help topic length
*/
public byte getHelpTopicLength(){
return field_9_length_help_topic_text;
}
/** get the status bar text length
* @return satus bar length
*/
public byte getStatusBarLength(){
return field_10_length_status_bar_text;
}
/** gets the name compressed Unicode flag
* @return compressed unicode flag
*/
public byte getCompressedUnicodeFlag() {
return field_11_compressed_unicode_flag;
} }
@ -388,6 +235,13 @@ public final class NameRecord extends Record {
public boolean isHiddenName() { public boolean isHiddenName() {
return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0; return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
} }
public void setHidden(boolean b) {
if (b) {
field_1_option_flag |= Option.OPT_HIDDEN_NAME;
} else {
field_1_option_flag &= (~Option.OPT_HIDDEN_NAME);
}
}
/** /**
* @return true if name is a function * @return true if name is a function
*/ */
@ -419,7 +273,7 @@ public final class NameRecord extends Record {
*/ */
public boolean isBuiltInName() public boolean isBuiltInName()
{ {
return ((this.field_1_option_flag & Option.OPT_BUILTIN) != 0); return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
} }
@ -428,7 +282,7 @@ public final class NameRecord extends Record {
*/ */
public String getNameText(){ public String getNameText(){
return this.isBuiltInName() ? this.translateBuiltInName(this.getBuiltInName()) : field_12_name_text; return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
} }
/** Gets the Built In Name /** Gets the Built In Name
@ -436,19 +290,19 @@ public final class NameRecord extends Record {
*/ */
public byte getBuiltInName() public byte getBuiltInName()
{ {
return this.field_12_builtIn_name; return field_12_built_in_code;
} }
/** gets the definition, reference (Formula) /** gets the definition, reference (Formula)
* @return definition -- can be null if we cant parse ptgs * @return the name formula. never <code>null</code>
*/ */
public List getNameDefinition() { public Ptg[] getNameDefinition() {
return field_13_name_definition; return (Ptg[]) field_13_name_definition.clone();
} }
public void setNameDefinition(Stack nameDefinition) { public void setNameDefinition(Ptg[] ptgs) {
field_13_name_definition = nameDefinition; field_13_name_definition = (Ptg[]) ptgs.clone();
} }
/** get the custom menu text /** get the custom menu text
@ -491,6 +345,7 @@ public final class NameRecord extends Record {
} }
} }
/** /**
* called by the class that is responsible for writing this sucker. * called by the class that is responsible for writing this sucker.
* Subclasses should implement this so that their data is passed back in a * Subclasses should implement this so that their data is passed back in a
@ -498,109 +353,107 @@ public final class NameRecord extends Record {
* @param data byte array containing instance data * @param data byte array containing instance data
* @return number of bytes written * @return number of bytes written
*/ */
public int serialize( int offset, byte[] data ) public int serialize( int offset, byte[] data ) {
{
int field_7_length_custom_menu = field_14_custom_menu_text.length();
int field_8_length_description_text = field_15_description_text.length();
int field_9_length_help_topic_text = field_16_help_topic_text.length();
int field_10_length_status_bar_text = field_17_status_bar_text.length();
int rawNameSize = getNameRawSize();
int formulaTotalSize = Ptg.getEncodedSize(field_13_name_definition);
int dataSize = 15 // 4 shorts + 7 bytes
+ rawNameSize
+ field_7_length_custom_menu
+ field_8_length_description_text
+ field_9_length_help_topic_text
+ field_10_length_status_bar_text
+ formulaTotalSize;
LittleEndian.putShort(data, 0 + offset, sid); LittleEndian.putShort(data, 0 + offset, sid);
short size = (short)( 15 + getTextsLength() + getNameDefinitionSize()); LittleEndian.putUShort(data, 2 + offset, dataSize);
LittleEndian.putShort( data, 2 + offset, size );
// size defined below // size defined below
LittleEndian.putShort(data, 4 + offset, getOptionFlag()); LittleEndian.putShort(data, 4 + offset, getOptionFlag());
data[6 + offset] = getKeyboardShortcut(); LittleEndian.putByte(data, 6 + offset, getKeyboardShortcut());
data[7 + offset] = getNameTextLength(); LittleEndian.putByte(data, 7 + offset, getNameTextLength());
LittleEndian.putShort( data, 8 + offset, getDefinitionLength() ); // Note -
LittleEndian.putShort( data, 10 + offset, getUnused() ); LittleEndian.putUShort(data, 8 + offset, Ptg.getEncodedSizeWithoutArrayData(field_13_name_definition));
LittleEndian.putUShort(data, 10 + offset, field_5_index_to_sheet);
LittleEndian.putUShort(data, 12 + offset, field_6_sheetNumber); LittleEndian.putUShort(data, 12 + offset, field_6_sheetNumber);
data[14 + offset] = getCustomMenuLength(); LittleEndian.putByte(data, 14 + offset, field_7_length_custom_menu);
data[15 + offset] = getDescriptionTextLength(); LittleEndian.putByte(data, 15 + offset, field_8_length_description_text);
data[16 + offset] = getHelpTopicLength(); LittleEndian.putByte(data, 16 + offset, field_9_length_help_topic_text);
data[17 + offset] = getStatusBarLength(); LittleEndian.putByte(data, 17 + offset, field_10_length_status_bar_text);
data[18 + offset] = getCompressedUnicodeFlag(); LittleEndian.putByte(data, 18 + offset, field_11_nameIsMultibyte ? 1 : 0);
int pos = 19 + offset;
int start_of_name_definition = 19 + field_3_length_name_text; if (isBuiltInName()) {
if (this.isBuiltInName()) {
//can send the builtin name directly in //can send the builtin name directly in
data [19 + offset] = this.getBuiltInName(); LittleEndian.putByte(data, pos, field_12_built_in_code);
} else if ((this.getCompressedUnicodeFlag() & 0x01) == 1) {
StringUtil.putUnicodeLE( getNameText(), data, 19 + offset );
start_of_name_definition = 19 + (2 * field_3_length_name_text);
} else { } else {
StringUtil.putCompressedUnicode( getNameText(), data, 19 + offset ); String nameText = field_12_name_text;
if (field_11_nameIsMultibyte) {
StringUtil.putUnicodeLE(nameText, data, pos);
} else {
StringUtil.putCompressedUnicode(nameText, data, pos);
} }
Ptg.serializePtgStack(field_13_name_definition, data, start_of_name_definition + offset );
int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition;
StringUtil.putCompressedUnicode( getCustomMenuText(), data, start_of_custom_menu_text + offset );
int start_of_description_text = start_of_custom_menu_text + field_7_length_custom_menu;
StringUtil.putCompressedUnicode( getDescriptionText(), data, start_of_description_text + offset );
int start_of_help_topic_text = start_of_description_text + field_8_length_description_text;
StringUtil.putCompressedUnicode( getHelpTopicText(), data, start_of_help_topic_text + offset );
int start_of_status_bar_text = start_of_help_topic_text + field_9_length_help_topic_text;
StringUtil.putCompressedUnicode( getStatusBarText(), data, start_of_status_bar_text + offset );
return getRecordSize();
/* } */
} }
pos += rawNameSize;
/** Ptg.serializePtgs(field_13_name_definition, data, pos);
* Gets the length of all texts, in bytes pos += formulaTotalSize;
* @return total length
*/
public int getTextsLength(){
int result;
result = getRawNameTextLength() + getDescriptionTextLength() + StringUtil.putCompressedUnicode( getCustomMenuText(), data, pos);
getHelpTopicLength() + getStatusBarLength(); pos += field_7_length_custom_menu;
StringUtil.putCompressedUnicode( getDescriptionText(), data, pos);
pos += field_8_length_description_text;
StringUtil.putCompressedUnicode( getHelpTopicText(), data, pos);
pos += field_9_length_help_topic_text;
StringUtil.putCompressedUnicode( getStatusBarText(), data, pos);
return result; return 4 + dataSize;
} }
private int getNameRawSize() {
private int getNameDefinitionSize() { if (isBuiltInName()) {
int result = 0; return 1;
List list = field_13_name_definition;
for (int k = 0; k < list.size(); k++)
{
Ptg ptg = ( Ptg ) list.get(k);
result += ptg.getSize();
} }
return result; int nChars = field_12_name_text.length();
if(field_11_nameIsMultibyte) {
return 2 * nChars;
}
return nChars;
} }
/** returns the record size /** returns the record size
*/ */
public int getRecordSize(){ public int getRecordSize(){
int result; return 4 // sid + size
+ 15 // 4 shorts + 7 bytes
result = 19 + getTextsLength() + getNameDefinitionSize(); + getNameRawSize()
+ field_14_custom_menu_text.length()
+ field_15_description_text.length()
return result; + field_16_help_topic_text.length()
+ field_17_status_bar_text.length()
+ Ptg.getEncodedSize(field_13_name_definition);
} }
/** gets the extern sheet number /** gets the extern sheet number
* @return extern sheet index * @return extern sheet index
*/ */
public short getExternSheetNumber(){ public short getExternSheetNumber(){
if (field_13_name_definition == null || field_13_name_definition.isEmpty()) return 0; if (field_13_name_definition.length < 1) {
Ptg ptg = (Ptg) field_13_name_definition.peek(); return 0;
short result = 0; }
Ptg ptg = field_13_name_definition[0];
if (ptg.getClass() == Area3DPtg.class){ if (ptg.getClass() == Area3DPtg.class){
result = ((Area3DPtg) ptg).getExternSheetIndex(); return ((Area3DPtg) ptg).getExternSheetIndex();
} else if (ptg.getClass() == Ref3DPtg.class){
result = ((Ref3DPtg) ptg).getExternSheetIndex();
} }
if (ptg.getClass() == Ref3DPtg.class){
return result; return ((Ref3DPtg) ptg).getExternSheetIndex();
}
return 0;
} }
/** sets the extern sheet number /** sets the extern sheet number
@ -609,11 +462,13 @@ public final class NameRecord extends Record {
public void setExternSheetNumber(short externSheetNumber){ public void setExternSheetNumber(short externSheetNumber){
Ptg ptg; Ptg ptg;
if (field_13_name_definition == null || field_13_name_definition.isEmpty()){ if (field_13_name_definition.length < 1){
field_13_name_definition = new Stack();
ptg = createNewPtg(); ptg = createNewPtg();
field_13_name_definition = new Ptg[] {
ptg,
};
} else { } else {
ptg = (Ptg) field_13_name_definition.peek(); ptg = field_13_name_definition[0];
} }
if (ptg.getClass() == Area3DPtg.class){ if (ptg.getClass() == Area3DPtg.class){
@ -625,11 +480,8 @@ public final class NameRecord extends Record {
} }
private Ptg createNewPtg(){ private static Ptg createNewPtg(){
Ptg ptg = new Area3DPtg("A1", 0); // TODO - change to not be partially initialised return new Area3DPtg("A1", 0); // TODO - change to not be partially initialised
field_13_name_definition.push(ptg);
return ptg;
} }
/** gets the reference , the area only (range) /** gets the reference , the area only (range)
@ -646,16 +498,14 @@ public final class NameRecord extends Record {
//Trying to find if what ptg do we need //Trying to find if what ptg do we need
RangeAddress ra = new RangeAddress(ref); RangeAddress ra = new RangeAddress(ref);
Ptg oldPtg; Ptg oldPtg;
Ptg ptg;
if (field_13_name_definition==null ||field_13_name_definition.isEmpty()){ if (field_13_name_definition.length < 1){
field_13_name_definition = new Stack();
oldPtg = createNewPtg(); oldPtg = createNewPtg();
} else { } else {
//Trying to find extern sheet index //Trying to find extern sheet index
oldPtg = (Ptg) field_13_name_definition.pop(); oldPtg = field_13_name_definition[0];
} }
List temp = new ArrayList();
short externSheetIndex = 0; short externSheetIndex = 0;
if (oldPtg.getClass() == Area3DPtg.class){ if (oldPtg.getClass() == Area3DPtg.class){
@ -667,29 +517,27 @@ public final class NameRecord extends Record {
if (ra.hasRange()) { if (ra.hasRange()) {
// Is it contiguous or not? // Is it contiguous or not?
AreaReference[] refs = AreaReference[] refs = AreaReference.generateContiguous(ref);
AreaReference.generateContiguous(ref);
this.setDefinitionTextLength((short)0);
// Add the area reference(s) // Add the area reference(s)
for(int i=0; i<refs.length; i++) { for(int i=0; i<refs.length; i++) {
ptg = new Area3DPtg(refs[i].formatAsString(), externSheetIndex); Ptg ptg = new Area3DPtg(refs[i].formatAsString(), externSheetIndex);
field_13_name_definition.push(ptg); temp.add(ptg);
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
} }
// And then a union if we had more than one area // And then a union if we had more than one area
if(refs.length > 1) { if(refs.length > 1) {
ptg = UnionPtg.instance; Ptg ptg = UnionPtg.instance;
field_13_name_definition.push(ptg); temp.add(ptg);
this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
} }
} else { } else {
ptg = new Ref3DPtg(); Ptg ptg = new Ref3DPtg();
((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex); ((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex);
((Ref3DPtg) ptg).setArea(ref); ((Ref3DPtg) ptg).setArea(ref);
field_13_name_definition.push(ptg); temp.add(ptg);
this.setDefinitionTextLength((short)ptg.getSize());
} }
Ptg[] ptgs = new Ptg[temp.size()];
temp.toArray(ptgs);
field_13_name_definition = ptgs;
} }
/** /**
@ -701,38 +549,34 @@ public final class NameRecord extends Record {
protected void fillFields(RecordInputStream in) { protected void fillFields(RecordInputStream in) {
field_1_option_flag = in.readShort(); field_1_option_flag = in.readShort();
field_2_keyboard_shortcut = in.readByte(); field_2_keyboard_shortcut = in.readByte();
field_3_length_name_text = in.readByte(); int field_3_length_name_text = in.readByte();
field_4_length_name_definition = in.readShort(); int field_4_length_name_definition = in.readShort();
field_5_index_to_sheet = in.readShort(); field_5_index_to_sheet = in.readShort();
field_6_sheetNumber = in.readUShort(); field_6_sheetNumber = in.readUShort();
field_7_length_custom_menu = in.readByte(); int field_7_length_custom_menu = in.readUByte();
field_8_length_description_text = in.readByte(); int field_8_length_description_text = in.readUByte();
field_9_length_help_topic_text = in.readByte(); int field_9_length_help_topic_text = in.readUByte();
field_10_length_status_bar_text = in.readByte(); int field_10_length_status_bar_text = in.readUByte();
//store the name in byte form if it's a builtin name //store the name in byte form if it's a built-in name
field_11_compressed_unicode_flag= in.readByte(); field_11_nameIsMultibyte = (in.readByte() != 0);
if (this.isBuiltInName()) { if (isBuiltInName()) {
field_12_builtIn_name = in.readByte(); field_12_built_in_code = in.readByte();
} else { } else {
if (field_11_compressed_unicode_flag == 1) { if (field_11_nameIsMultibyte) {
field_12_name_text = in.readUnicodeLEString(field_3_length_name_text); field_12_name_text = in.readUnicodeLEString(field_3_length_name_text);
} else { } else {
field_12_name_text = in.readCompressedUnicode(field_3_length_name_text); field_12_name_text = in.readCompressedUnicode(field_3_length_name_text);
} }
} }
field_13_name_definition = Ptg.createParsedExpressionTokens(field_4_length_name_definition, in); field_13_name_definition = Ptg.readTokens(field_4_length_name_definition, in);
//Who says that this can only ever be compressed unicode??? //Who says that this can only ever be compressed unicode???
field_14_custom_menu_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_7_length_custom_menu)); field_14_custom_menu_text = in.readCompressedUnicode(field_7_length_custom_menu);
field_15_description_text = in.readCompressedUnicode(field_8_length_description_text);
field_15_description_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_8_length_description_text)); field_16_help_topic_text = in.readCompressedUnicode(field_9_length_help_topic_text);
field_17_status_bar_text = in.readCompressedUnicode(field_10_length_status_bar_text);
field_16_help_topic_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_9_length_help_topic_text));
field_17_status_bar_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_10_length_status_bar_text));
/*} */
} }
/** /**
@ -792,63 +636,40 @@ public final class NameRecord extends Record {
3B 00 00 07 00 07 00 00 00 FF 00 ] 3B 00 00 07 00 07 00 00 00 FF 00 ]
*/ */
/**
* @see Object#toString()
*/
public String toString() { public String toString() {
StringBuffer buffer = new StringBuffer(); StringBuffer sb = new StringBuffer();
buffer.append("[NAME]\n"); sb.append("[NAME]\n");
buffer.append(" .option flags = ").append( HexDump.toHex( field_1_option_flag ) ) sb.append(" .option flags = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
.append("\n"); sb.append(" .keyboard shortcut = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
buffer.append(" .keyboard shortcut = ").append( HexDump.toHex( field_2_keyboard_shortcut ) ) sb.append(" .length of the name = ").append(getNameTextLength()).append("\n");
.append("\n"); sb.append(" .unused = ").append( field_5_index_to_sheet ).append("\n");
buffer.append(" .length of the name = ").append( field_3_length_name_text ) sb.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber ).append("\n");
.append("\n"); sb.append(" .Menu text length = ").append(field_14_custom_menu_text.length()).append("\n");
buffer.append(" .size of the formula data = ").append( field_4_length_name_definition ) sb.append(" .Description text length= ").append(field_15_description_text.length()).append("\n");
.append("\n"); sb.append(" .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n");
buffer.append(" .unused = ").append( field_5_index_to_sheet ) sb.append(" .Status bar text length = ").append(field_17_status_bar_text.length()).append("\n");
.append("\n"); sb.append(" .NameIsMultibyte = ").append(field_11_nameIsMultibyte).append("\n");
buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber ) sb.append(" .Name (Unicode text) = ").append( getNameText() ).append("\n");
.append("\n"); sb.append(" .Formula (nTokens=").append(field_13_name_definition.length).append("):") .append("\n");
buffer.append(" .Length of menu text (character count) = ").append( field_7_length_custom_menu ) for (int i = 0; i < field_13_name_definition.length; i++) {
.append("\n"); Ptg ptg = field_13_name_definition[i];
buffer.append(" .Length of description text (character count) = ").append( field_8_length_description_text ) sb.append(" " + ptg.toString()).append(ptg.getRVAType()).append("\n");
.append("\n");
buffer.append(" .Length of help topic text (character count) = ").append( field_9_length_help_topic_text )
.append("\n");
buffer.append(" .Length of status bar text (character count) = ").append( field_10_length_status_bar_text )
.append("\n");
buffer.append(" .Name (Unicode flag) = ").append( field_11_compressed_unicode_flag )
.append("\n");
buffer.append(" .Name (Unicode text) = ").append( getNameText() )
.append("\n");
buffer.append(" .Parts (" + field_13_name_definition.size() +"):")
.append("\n");
Iterator it = field_13_name_definition.iterator();
while(it.hasNext()) {
Ptg ptg = (Ptg)it.next();
buffer.append(" " + ptg.toString()).append("\n");
} }
buffer.append(" .Menu text (Unicode string without length field) = ").append( field_14_custom_menu_text ) sb.append(" .Menu text = ").append(field_14_custom_menu_text).append("\n");
.append("\n"); sb.append(" .Description text= ").append(field_15_description_text).append("\n");
buffer.append(" .Description text (Unicode string without length field) = ").append( field_15_description_text ) sb.append(" .Help topic text = ").append(field_16_help_topic_text).append("\n");
.append("\n"); sb.append(" .Status bar text = ").append(field_17_status_bar_text).append("\n");
buffer.append(" .Help topic text (Unicode string without length field) = ").append( field_16_help_topic_text ) sb.append("[/NAME]\n");
.append("\n");
buffer.append(" .Status bar text (Unicode string without length field) = ").append( field_17_status_bar_text )
.append("\n");
buffer.append("[/NAME]\n");
return buffer.toString(); return sb.toString();
} }
/**Creates a human readable name for built in types /**Creates a human readable name for built in types
* @return Unknown if the built-in name cannot be translated * @return Unknown if the built-in name cannot be translated
*/ */
protected String translateBuiltInName(byte name) private static String translateBuiltInName(byte name)
{ {
switch (name) switch (name)
{ {
@ -864,6 +685,7 @@ public final class NameRecord extends Record {
case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles"; case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
case NameRecord.BUILTIN_RECORDER : return "Recorder"; case NameRecord.BUILTIN_RECORDER : return "Recorder";
case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title"; case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
case NameRecord.BUILTIN_FILTER_DB : return "_FilterDatabase";
} }

View File

@ -41,7 +41,7 @@ public final class Ref3DPtg extends OperandPtg {
private static final BitField colRelative = BitFieldFactory.getInstance(0x4000); private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
private final static int SIZE = 7; // 6 + 1 for Ptg private final static int SIZE = 7; // 6 + 1 for Ptg
private short field_1_index_extern_sheet; private int field_1_index_extern_sheet;
/** The row index - zero based unsigned 16 bit value */ /** The row index - zero based unsigned 16 bit value */
private int field_2_row; private int field_2_row;
/** Field 2 /** Field 2
@ -93,10 +93,10 @@ public final class Ref3DPtg extends OperandPtg {
} }
public short getExternSheetIndex(){ public short getExternSheetIndex(){
return field_1_index_extern_sheet; return (short)field_1_index_extern_sheet;
} }
public void setExternSheetIndex(short index){ public void setExternSheetIndex(int index){
field_1_index_extern_sheet = index; field_1_index_extern_sheet = index;
} }

View File

@ -65,7 +65,6 @@ public final class HSSFName {
*/ */
public void setNameName(String nameName){ public void setNameName(String nameName){
_definedNameRec.setNameText(nameName); _definedNameRec.setNameText(nameName);
_definedNameRec.setNameTextLength((byte)nameName.length());
Workbook wb = _book.getWorkbook(); Workbook wb = _book.getWorkbook();
//Check to ensure no other names have the same case-insensitive name //Check to ensure no other names have the same case-insensitive name

View File

@ -27,7 +27,6 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Stack;
import org.apache.poi.POIDocument; import org.apache.poi.POIDocument;
import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBSERecord;
@ -55,6 +54,8 @@ import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg; import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.NameXPtg; import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.UnionPtg; import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy; import org.apache.poi.hssf.usermodel.HSSFRow.MissingCellPolicy;
import org.apache.poi.hssf.util.CellReference; import org.apache.poi.hssf.util.CellReference;
@ -666,33 +667,81 @@ public class HSSFWorkbook extends POIDocument
* @return HSSFSheet representing the cloned sheet. * @return HSSFSheet representing the cloned sheet.
*/ */
public HSSFSheet cloneSheet(int sheetNum) { public HSSFSheet cloneSheet(int sheetIndex) {
validateSheetIndex(sheetNum); validateSheetIndex(sheetIndex);
HSSFSheet srcSheet = (HSSFSheet) _sheets.get(sheetNum); HSSFSheet srcSheet = (HSSFSheet) _sheets.get(sheetIndex);
String srcName = workbook.getSheetName(sheetNum); String srcName = workbook.getSheetName(sheetIndex);
HSSFSheet clonedSheet = srcSheet.cloneSheet(this); HSSFSheet clonedSheet = srcSheet.cloneSheet(this);
clonedSheet.setSelected(false); clonedSheet.setSelected(false);
clonedSheet.setActive(false); clonedSheet.setActive(false);
String name = getUniqueSheetName(srcName);
int newSheetIndex = _sheets.size();
_sheets.add(clonedSheet); _sheets.add(clonedSheet);
int i = 1; workbook.setSheetName(newSheetIndex, name);
// Check this sheet has an autofilter, (which has a built-in NameRecord at workbook level)
int filterDbNameIndex = findExistingBuiltinNameRecordIdx(sheetIndex, NameRecord.BUILTIN_FILTER_DB);
if (filterDbNameIndex >=0) {
NameRecord origNameRecord = workbook.getNameRecord(filterDbNameIndex);
// copy original formula but adjust 3D refs to the new external sheet index
int newExtSheetIx = getExternalSheetIndex(newSheetIndex);
Ptg[] ptgs = origNameRecord.getNameDefinition();
for (int i=0; i< ptgs.length; i++) {
Ptg ptg = ptgs[i];
ptg = ptg.copy();
if (ptg instanceof Area3DPtg) {
Area3DPtg a3p = (Area3DPtg) ptg;
a3p.setExternSheetIndex(newExtSheetIx);
} else if (ptg instanceof Ref3DPtg) {
Ref3DPtg r3p = (Ref3DPtg) ptg;
r3p.setExternSheetIndex(newExtSheetIx);
}
ptgs[i] = ptg;
}
NameRecord newNameRecord = workbook.createBuiltInName(NameRecord.BUILTIN_FILTER_DB, newSheetIndex+1);
newNameRecord.setNameDefinition(ptgs);
newNameRecord.setHidden(true);
HSSFName newName = new HSSFName(this, newNameRecord);
names.add(newName);
// TODO - when an Autofilter is present, there are some DrawingRecords which also need adjusting
// In particular, some IDs of some EscherSpRecords need changing. See bug 45720
}
// TODO - maybe same logic required for other/all built-in name records
return clonedSheet;
}
private String getUniqueSheetName(String srcName) {
int uniqueIndex = 2;
String baseName = srcName;
int bracketPos = srcName.lastIndexOf('(');
if (bracketPos > 0 && srcName.endsWith(")")) {
String suffix = srcName.substring(bracketPos + 1, srcName.length() - ")".length());
try {
uniqueIndex = Integer.parseInt(suffix.trim());
uniqueIndex++;
baseName=srcName.substring(0, bracketPos).trim();
} catch (NumberFormatException e) {
// contents of brackets not numeric
}
}
while (true) { while (true) {
// Try and find the next sheet name that is unique // Try and find the next sheet name that is unique
String name = srcName; String index = Integer.toString(uniqueIndex++);
String index = Integer.toString(i++); String name;
if (name.length() + index.length() + 2 < 31) { if (baseName.length() + index.length() + 2 < 31) {
name = name + "(" + index + ")"; name = baseName + " (" + index + ")";
} else { } else {
name = name.substring(0, 31 - index.length() - 2) + "(" + index + ")"; name = baseName.substring(0, 31 - index.length() - 2) + "(" + index + ")";
} }
//If the sheet name is unique, then set it otherwise move on to the next number. //If the sheet name is unique, then set it otherwise move on to the next number.
if (workbook.getSheetIndex(name) == -1) { if (workbook.getSheetIndex(name) == -1) {
workbook.setSheetName(_sheets.size()-1, name); return name;
break;
} }
} }
return clonedSheet;
} }
/** /**
@ -901,7 +950,7 @@ public class HSSFWorkbook extends POIDocument
boolean removingRange = boolean removingRange =
startColumn == -1 && endColumn == -1 && startRow == -1 && endRow == -1; startColumn == -1 && endColumn == -1 && startRow == -1 && endRow == -1;
int rowColHeaderNameIndex = findExistingRowColHeaderNameRecordIdx(sheetIndex); int rowColHeaderNameIndex = findExistingBuiltinNameRecordIdx(sheetIndex, NameRecord.BUILTIN_PRINT_TITLE);
if (removingRange) { if (removingRange) {
if (rowColHeaderNameIndex >= 0) { if (rowColHeaderNameIndex >= 0) {
workbook.removeName(rowColHeaderNameIndex); workbook.removeName(rowColHeaderNameIndex);
@ -919,29 +968,27 @@ public class HSSFWorkbook extends POIDocument
isNewRecord = false; isNewRecord = false;
} }
short definitionTextLength = settingRowAndColumn ? (short)0x001a : (short)0x000b; List temp = new ArrayList();
nameRecord.setDefinitionTextLength(definitionTextLength); // TODO - remove
Stack ptgs = new Stack();
if (settingRowAndColumn) { if (settingRowAndColumn) {
final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE
ptgs.add(new MemFuncPtg(exprsSize)); temp.add(new MemFuncPtg(exprsSize));
} }
if (startColumn >= 0) { if (startColumn >= 0) {
Area3DPtg colArea = new Area3DPtg(0, MAX_ROW, startColumn, endColumn, Area3DPtg colArea = new Area3DPtg(0, MAX_ROW, startColumn, endColumn,
false, false, false, false, externSheetIndex); false, false, false, false, externSheetIndex);
ptgs.add(colArea); temp.add(colArea);
} }
if (startRow >= 0) { if (startRow >= 0) {
Area3DPtg rowArea = new Area3DPtg(startRow, endRow, 0, MAX_COLUMN, Area3DPtg rowArea = new Area3DPtg(startRow, endRow, 0, MAX_COLUMN,
false, false, false, false, externSheetIndex); false, false, false, false, externSheetIndex);
ptgs.add(rowArea); temp.add(rowArea);
} }
if (settingRowAndColumn) if (settingRowAndColumn) {
{ temp.add(UnionPtg.instance);
ptgs.add(UnionPtg.instance);
} }
Ptg[] ptgs = new Ptg[temp.size()];
temp.toArray(ptgs);
nameRecord.setNameDefinition(ptgs); nameRecord.setNameDefinition(ptgs);
if (isNewRecord) if (isNewRecord)
@ -957,13 +1004,13 @@ public class HSSFWorkbook extends POIDocument
} }
private int findExistingRowColHeaderNameRecordIdx(int sheetIndex) { private int findExistingBuiltinNameRecordIdx(int sheetIndex, byte builtinCode) {
for(int defNameIndex =0; defNameIndex<names.size(); defNameIndex++) { for(int defNameIndex =0; defNameIndex<names.size(); defNameIndex++) {
NameRecord r = workbook.getNameRecord(defNameIndex); NameRecord r = workbook.getNameRecord(defNameIndex);
if (r == null) { if (r == null) {
throw new RuntimeException("Unable to find all defined names to iterate over"); throw new RuntimeException("Unable to find all defined names to iterate over");
} }
if (!isRowColHeaderRecord( r )) { if (!r.isBuiltInName() || r.getBuiltInName() != builtinCode) {
continue; continue;
} }
if(r.getSheetNumber() == 0) { if(r.getSheetNumber() == 0) {
@ -979,10 +1026,6 @@ public class HSSFWorkbook extends POIDocument
return -1; return -1;
} }
private static boolean isRowColHeaderRecord(NameRecord r) {
return r.isBuiltInName() && r.getBuiltInName() == NameRecord.BUILTIN_PRINT_TITLE;
}
/** /**
* create a new Font and add it to the workbook's font table * create a new Font and add it to the workbook's font table
* @return new font object * @return new font object

View File

@ -34,6 +34,7 @@ import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg; import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.util.CellRangeAddress; import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.util.TempFile; import org.apache.poi.util.TempFile;
@ -1018,9 +1019,9 @@ public final class TestBugs extends TestCase {
NameRecord r = w.getNameRecord(i); NameRecord r = w.getNameRecord(i);
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets()); assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition(); Ptg[] nd = r.getNameDefinition();
assertEquals(1, nd.size()); assertEquals(1, nd.length);
assertTrue(nd.get(0) instanceof DeletedArea3DPtg); assertTrue(nd[0] instanceof DeletedArea3DPtg);
} }
@ -1036,9 +1037,9 @@ public final class TestBugs extends TestCase {
NameRecord r = w.getNameRecord(i); NameRecord r = w.getNameRecord(i);
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets()); assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition(); Ptg[] nd = r.getNameDefinition();
assertEquals(1, nd.size()); assertEquals(1, nd.length);
assertTrue(nd.get(0) instanceof DeletedArea3DPtg); assertTrue(nd[0] instanceof DeletedArea3DPtg);
} }
@ -1053,9 +1054,9 @@ public final class TestBugs extends TestCase {
NameRecord r = w.getNameRecord(i); NameRecord r = w.getNameRecord(i);
assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets()); assertTrue(r.getSheetNumber() <= wb.getNumberOfSheets());
List nd = r.getNameDefinition(); Ptg[] nd = r.getNameDefinition();
assertEquals(1, nd.size()); assertEquals(1, nd.length);
assertTrue(nd.get(0) instanceof DeletedArea3DPtg); assertTrue(nd[0] instanceof DeletedArea3DPtg);
} }
} }

View File

@ -223,8 +223,16 @@ public final class TestHSSFSheet extends TestCase {
workbook.cloneSheet(0); workbook.cloneSheet(0);
assertNotNull(workbook.getSheet("Test Clone")); assertNotNull(workbook.getSheet("Test Clone"));
assertNotNull(workbook.getSheet("Test Clone(1)"));
assertNotNull(workbook.getSheet("Test Clone (2)")); assertNotNull(workbook.getSheet("Test Clone (2)"));
assertEquals("Test Clone (3)", workbook.getSheetName(2));
assertNotNull(workbook.getSheet("Test Clone (3)"));
workbook.removeSheetAt(0);
workbook.removeSheetAt(0);
workbook.removeSheetAt(0);
workbook.createSheet("abc ( 123)");
workbook.cloneSheet(0);
assertEquals("abc (124)", workbook.getSheetName(1));
} }
/** /**

View File

@ -429,9 +429,9 @@ public final class TestHSSFWorkbook extends TestCase {
assertEquals("On2", nr.getNameText()); assertEquals("On2", nr.getNameText());
assertEquals(0, nr.getSheetNumber()); assertEquals(0, nr.getSheetNumber());
assertEquals(1, nr.getExternSheetNumber()); assertEquals(1, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size()); assertEquals(1, nr.getNameDefinition().length);
ptg = (Area3DPtg)nr.getNameDefinition().get(0); ptg = (Area3DPtg)nr.getNameDefinition()[0];
assertEquals(1, ptg.getExternSheetIndex()); assertEquals(1, ptg.getExternSheetIndex());
assertEquals(0, ptg.getFirstColumn()); assertEquals(0, ptg.getFirstColumn());
assertEquals(0, ptg.getFirstRow()); assertEquals(0, ptg.getFirstRow());
@ -452,9 +452,9 @@ public final class TestHSSFWorkbook extends TestCase {
assertEquals("OnOne", nr.getNameText()); assertEquals("OnOne", nr.getNameText());
assertEquals(0, nr.getSheetNumber()); assertEquals(0, nr.getSheetNumber());
assertEquals(0, nr.getExternSheetNumber()); assertEquals(0, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size()); assertEquals(1, nr.getNameDefinition().length);
ptg = (Area3DPtg)nr.getNameDefinition().get(0); ptg = (Area3DPtg)nr.getNameDefinition()[0];
assertEquals(0, ptg.getExternSheetIndex()); assertEquals(0, ptg.getExternSheetIndex());
assertEquals(0, ptg.getFirstColumn()); assertEquals(0, ptg.getFirstColumn());
assertEquals(2, ptg.getFirstRow()); assertEquals(2, ptg.getFirstRow());
@ -475,9 +475,9 @@ public final class TestHSSFWorkbook extends TestCase {
assertEquals("OnSheet3", nr.getNameText()); assertEquals("OnSheet3", nr.getNameText());
assertEquals(0, nr.getSheetNumber()); assertEquals(0, nr.getSheetNumber());
assertEquals(2, nr.getExternSheetNumber()); assertEquals(2, nr.getExternSheetNumber());
assertEquals(1, nr.getNameDefinition().size()); assertEquals(1, nr.getNameDefinition().length);
ptg = (Area3DPtg)nr.getNameDefinition().get(0); ptg = (Area3DPtg)nr.getNameDefinition()[0];
assertEquals(2, ptg.getExternSheetIndex()); assertEquals(2, ptg.getExternSheetIndex());
assertEquals(0, ptg.getFirstColumn()); assertEquals(0, ptg.getFirstColumn());
assertEquals(0, ptg.getFirstRow()); assertEquals(0, ptg.getFirstRow());

View File

@ -19,7 +19,6 @@ package org.apache.poi.hssf.util;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -28,6 +27,7 @@ import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg; import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.UnionPtg; import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFName; import org.apache.poi.hssf.usermodel.HSSFName;
@ -204,13 +204,13 @@ public final class TestAreaReference extends TestCase {
assertNotNull(nr); assertNotNull(nr);
assertEquals("test", nr.getNameText()); assertEquals("test", nr.getNameText());
List def =nr.getNameDefinition(); Ptg[] def =nr.getNameDefinition();
assertEquals(4, def.size()); assertEquals(4, def.length);
MemFuncPtg ptgA = (MemFuncPtg)def.get(0); MemFuncPtg ptgA = (MemFuncPtg)def[0];
Area3DPtg ptgB = (Area3DPtg)def.get(1); Area3DPtg ptgB = (Area3DPtg)def[1];
Area3DPtg ptgC = (Area3DPtg)def.get(2); Area3DPtg ptgC = (Area3DPtg)def[2];
UnionPtg ptgD = (UnionPtg)def.get(3); UnionPtg ptgD = (UnionPtg)def[3];
assertEquals("", ptgA.toFormulaString(wb)); assertEquals("", ptgA.toFormulaString(wb));
assertEquals(refA, ptgB.toFormulaString(wb)); assertEquals(refA, ptgB.toFormulaString(wb));
assertEquals(refB, ptgC.toFormulaString(wb)); assertEquals(refB, ptgC.toFormulaString(wb));