2002-04-23 18:28:58 -04:00
|
|
|
/* ====================================================================
|
2006-12-22 14:18:16 -05:00
|
|
|
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
|
2004-04-09 09:05:39 -04:00
|
|
|
|
|
|
|
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.
|
|
|
|
==================================================================== */
|
2002-04-23 18:28:58 -04:00
|
|
|
|
|
|
|
package org.apache.poi.hssf.record;
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
import java.util.ArrayList;
|
2003-05-17 14:32:42 -04:00
|
|
|
import java.util.List;
|
|
|
|
|
2008-09-18 22:19:58 -04:00
|
|
|
import org.apache.poi.hssf.model.HSSFFormulaParser;
|
2008-04-15 12:00:50 -04:00
|
|
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
|
|
|
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.usermodel.HSSFWorkbook;
|
2008-01-08 10:47:00 -05:00
|
|
|
import org.apache.poi.hssf.util.AreaReference;
|
2002-04-23 18:28:58 -04:00
|
|
|
import org.apache.poi.hssf.util.RangeAddress;
|
2003-05-17 14:32:42 -04:00
|
|
|
import org.apache.poi.util.HexDump;
|
|
|
|
import org.apache.poi.util.LittleEndian;
|
|
|
|
import org.apache.poi.util.StringUtil;
|
2002-04-23 18:28:58 -04:00
|
|
|
|
|
|
|
/**
|
2008-08-11 18:55:38 -04:00
|
|
|
* Title: DEFINEDNAME Record (0x0018) <p/>
|
2002-04-23 18:28:58 -04:00
|
|
|
* Description: Defines a named range within a workbook. <P>
|
|
|
|
* REFERENCE: <P>
|
|
|
|
* @author Libin Roman (Vista Portal LDT. Developer)
|
2002-09-01 22:11:16 -04:00
|
|
|
* @author Sergei Kozello (sergeikozello at mail.ru)
|
2003-02-06 05:29:45 -05:00
|
|
|
* @author Glen Stampoultzis (glens at apache.org)
|
2002-04-23 18:28:58 -04:00
|
|
|
* @version 1.0-pre
|
|
|
|
*/
|
2008-06-20 03:10:03 -04:00
|
|
|
public final class NameRecord extends Record {
|
2008-08-11 18:55:38 -04:00
|
|
|
public final static short sid = 0x0018;
|
2008-09-03 15:22:53 -04:00
|
|
|
/**Included for completeness sake, not implemented */
|
|
|
|
public final static byte BUILTIN_CONSOLIDATE_AREA = 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;
|
|
|
|
|
|
|
|
public final static byte BUILTIN_PRINT_AREA = 6;
|
|
|
|
public final static byte BUILTIN_PRINT_TITLE = 7;
|
|
|
|
|
|
|
|
/**Included for completeness sake, not implemented */
|
|
|
|
public final static byte BUILTIN_RECORDER = 8;
|
|
|
|
/**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;
|
|
|
|
|
|
|
|
public final static byte BUILTIN_FILTER_DB = 13;
|
2003-03-06 15:41:17 -05:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
private static final class Option {
|
|
|
|
public static final int OPT_HIDDEN_NAME = 0x0001;
|
|
|
|
public static final int OPT_FUNCTION_NAME = 0x0002;
|
|
|
|
public static final int OPT_COMMAND_NAME = 0x0004;
|
|
|
|
public static final int OPT_MACRO = 0x0008;
|
|
|
|
public static final int OPT_COMPLEX = 0x0010;
|
|
|
|
public static final int OPT_BUILTIN = 0x0020;
|
|
|
|
public static final int OPT_BINDATA = 0x1000;
|
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
private short field_1_option_flag;
|
|
|
|
private byte field_2_keyboard_shortcut;
|
2008-09-08 15:49:03 -04:00
|
|
|
/** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name */
|
|
|
|
private short field_5_externSheetIndex_plus1;
|
|
|
|
/** the one based sheet number. */
|
2008-08-11 17:24:19 -04:00
|
|
|
private int field_6_sheetNumber;
|
2008-09-03 15:22:53 -04:00
|
|
|
private boolean field_11_nameIsMultibyte;
|
|
|
|
private byte field_12_built_in_code;
|
2008-08-11 17:24:19 -04:00
|
|
|
private String field_12_name_text;
|
2008-09-03 15:22:53 -04:00
|
|
|
private Ptg[] field_13_name_definition;
|
2008-08-11 17:24:19 -04:00
|
|
|
private String field_14_custom_menu_text;
|
|
|
|
private String field_15_description_text;
|
|
|
|
private String field_16_help_topic_text;
|
|
|
|
private String field_17_status_bar_text;
|
|
|
|
|
|
|
|
|
|
|
|
/** Creates new NameRecord */
|
|
|
|
public NameRecord() {
|
2008-09-03 15:22:53 -04:00
|
|
|
field_13_name_definition = Ptg.EMPTY_PTG_ARRAY;
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
field_12_name_text = "";
|
|
|
|
field_14_custom_menu_text = "";
|
|
|
|
field_15_description_text = "";
|
|
|
|
field_16_help_topic_text = "";
|
|
|
|
field_17_status_bar_text = "";
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a Name record and sets its fields appropriately.
|
|
|
|
*
|
|
|
|
* @param in the RecordInputstream to read the record from
|
|
|
|
*/
|
|
|
|
public NameRecord(RecordInputStream in) {
|
2008-08-11 18:55:38 -04:00
|
|
|
super(in);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2002-06-17 13:20:16 -04:00
|
|
|
|
2003-03-06 15:41:17 -05:00
|
|
|
/**
|
|
|
|
* Constructor to create a built-in named region
|
|
|
|
* @param builtin Built-in byte representation for the name record, use the public constants
|
|
|
|
*/
|
2008-08-11 17:24:19 -04:00
|
|
|
public NameRecord(byte builtin, int sheetNumber)
|
2003-03-06 15:41:17 -05:00
|
|
|
{
|
2008-09-03 15:22:53 -04:00
|
|
|
this();
|
|
|
|
field_12_built_in_code = builtin;
|
|
|
|
setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
|
2008-08-11 18:55:38 -04:00
|
|
|
field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
|
2003-03-06 15:41:17 -05:00
|
|
|
}
|
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/** sets the option flag for the named range
|
|
|
|
* @param flag option flag
|
|
|
|
*/
|
|
|
|
public void setOptionFlag(short flag){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_1_option_flag = flag;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** sets the keyboard shortcut
|
|
|
|
* @param shortcut keyboard shortcut
|
|
|
|
*/
|
|
|
|
public void setKeyboardShortcut(byte shortcut){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_2_keyboard_shortcut = shortcut;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For named ranges, and built-in names
|
2008-09-08 15:49:03 -04:00
|
|
|
* @return the 1-based sheet number.
|
2008-08-11 17:24:19 -04:00
|
|
|
*/
|
|
|
|
public int getSheetNumber()
|
|
|
|
{
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_6_sheetNumber;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2003-02-06 05:29:45 -05:00
|
|
|
|
2003-03-06 15:41:17 -05:00
|
|
|
/**
|
2008-08-11 17:24:19 -04:00
|
|
|
* @return function group
|
|
|
|
* @see FnGroupCountRecord
|
|
|
|
*/
|
|
|
|
public byte getFnGroup() {
|
2008-08-11 18:55:38 -04:00
|
|
|
int masked = field_1_option_flag & 0x0fc0;
|
|
|
|
return (byte) (masked >> 4);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setSheetNumber(int value)
|
|
|
|
{
|
2008-08-11 18:55:38 -04:00
|
|
|
field_6_sheetNumber = value;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** sets the name of the named range
|
|
|
|
* @param name named range name
|
|
|
|
*/
|
|
|
|
public void setNameText(String name){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_12_name_text = name;
|
2008-09-03 15:22:53 -04:00
|
|
|
field_11_nameIsMultibyte = StringUtil.hasMultibyte(name);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** sets the custom menu text
|
|
|
|
* @param text custom menu text
|
|
|
|
*/
|
|
|
|
public void setCustomMenuText(String text){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_14_custom_menu_text = text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** sets the description text
|
|
|
|
* @param text the description text
|
|
|
|
*/
|
|
|
|
public void setDescriptionText(String text){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_15_description_text = text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** sets the help topic text
|
|
|
|
* @param text help topix text
|
|
|
|
*/
|
|
|
|
public void setHelpTopicText(String text){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_16_help_topic_text = text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** sets the status bar text
|
|
|
|
* @param text status bar text
|
|
|
|
*/
|
|
|
|
public void setStatusBarText(String text){
|
2008-08-11 18:55:38 -04:00
|
|
|
field_17_status_bar_text = text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** gets the option flag
|
|
|
|
* @return option flag
|
|
|
|
*/
|
|
|
|
public short getOptionFlag(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_1_option_flag;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** returns the keyboard shortcut
|
|
|
|
* @return keyboard shortcut
|
|
|
|
*/
|
|
|
|
public byte getKeyboardShortcut(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_2_keyboard_shortcut ;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
/**
|
2008-08-11 17:24:19 -04:00
|
|
|
* gets the name length, in characters
|
|
|
|
* @return name length
|
|
|
|
*/
|
2008-09-03 15:22:53 -04:00
|
|
|
private int getNameTextLength(){
|
|
|
|
if (isBuiltInName()) {
|
|
|
|
return 1;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
return field_12_name_text.length();
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/**
|
|
|
|
* @return true if name is hidden
|
|
|
|
*/
|
|
|
|
public boolean isHiddenName() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
public void setHidden(boolean b) {
|
|
|
|
if (b) {
|
|
|
|
field_1_option_flag |= Option.OPT_HIDDEN_NAME;
|
|
|
|
} else {
|
|
|
|
field_1_option_flag &= (~Option.OPT_HIDDEN_NAME);
|
|
|
|
}
|
|
|
|
}
|
2008-08-11 17:24:19 -04:00
|
|
|
/**
|
2008-09-04 17:32:17 -04:00
|
|
|
* @return <code>true</code> if name is a function
|
2008-08-11 17:24:19 -04:00
|
|
|
*/
|
|
|
|
public boolean isFunctionName() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
2008-09-04 17:32:17 -04:00
|
|
|
/**
|
|
|
|
* @return <code>true</code> if name has a formula (named range or defined value)
|
|
|
|
*/
|
|
|
|
public boolean hasFormula() {
|
|
|
|
return field_1_option_flag == 0 && field_13_name_definition.length > 0;
|
|
|
|
}
|
2008-08-11 18:55:38 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/**
|
|
|
|
* @return true if name is a command
|
|
|
|
*/
|
|
|
|
public boolean isCommandName() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @return true if function macro or command macro
|
|
|
|
*/
|
|
|
|
public boolean isMacro() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return (field_1_option_flag & Option.OPT_MACRO) != 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @return true if array formula or user defined
|
|
|
|
*/
|
|
|
|
public boolean isComplexFunction() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return (field_1_option_flag & Option.OPT_COMPLEX) != 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2003-08-31 02:16:57 -04:00
|
|
|
|
2003-03-06 15:41:17 -05:00
|
|
|
/**Convenience Function to determine if the name is a built-in name
|
|
|
|
*/
|
|
|
|
public boolean isBuiltInName()
|
|
|
|
{
|
2008-09-03 15:22:53 -04:00
|
|
|
return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
|
2003-03-06 15:41:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** gets the name
|
|
|
|
* @return name
|
|
|
|
*/
|
|
|
|
public String getNameText(){
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
|
2003-03-06 15:41:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Gets the Built In Name
|
|
|
|
* @return the built in Name
|
|
|
|
*/
|
|
|
|
public byte getBuiltInName()
|
|
|
|
{
|
2008-09-03 15:22:53 -04:00
|
|
|
return field_12_built_in_code;
|
2003-03-06 15:41:17 -05:00
|
|
|
}
|
|
|
|
|
2002-06-17 13:20:16 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/** gets the definition, reference (Formula)
|
2008-09-03 15:22:53 -04:00
|
|
|
* @return the name formula. never <code>null</code>
|
2008-08-11 17:24:19 -04:00
|
|
|
*/
|
2008-09-03 15:22:53 -04:00
|
|
|
public Ptg[] getNameDefinition() {
|
|
|
|
return (Ptg[]) field_13_name_definition.clone();
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
public void setNameDefinition(Ptg[] ptgs) {
|
|
|
|
field_13_name_definition = (Ptg[]) ptgs.clone();
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** get the custom menu text
|
|
|
|
* @return custom menu text
|
|
|
|
*/
|
|
|
|
public String getCustomMenuText(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_14_custom_menu_text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** gets the description text
|
|
|
|
* @return description text
|
|
|
|
*/
|
|
|
|
public String getDescriptionText(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_15_description_text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** get the help topic text
|
|
|
|
* @return gelp topic text
|
|
|
|
*/
|
|
|
|
public String getHelpTopicText(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_16_help_topic_text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** gets the status bar text
|
|
|
|
* @return status bar text
|
|
|
|
*/
|
|
|
|
public String getStatusBarText(){
|
2008-08-11 18:55:38 -04:00
|
|
|
return field_17_status_bar_text;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* called by constructor, should throw runtime exception in the event of a
|
|
|
|
* record passed with a differing ID.
|
|
|
|
*
|
|
|
|
* @param id alleged id for this record
|
|
|
|
*/
|
|
|
|
protected void validateSid(short id) {
|
2008-08-11 18:55:38 -04:00
|
|
|
if (id != sid) {
|
|
|
|
throw new RecordFormatException("NOT A valid Name RECORD");
|
|
|
|
}
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
|
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/**
|
|
|
|
* called by the class that is responsible for writing this sucker.
|
|
|
|
* Subclasses should implement this so that their data is passed back in a
|
2007-06-29 11:01:01 -04:00
|
|
|
* @param offset to begin writing at
|
|
|
|
* @param data byte array containing instance data
|
2008-08-11 17:24:19 -04:00
|
|
|
* @return number of bytes written
|
|
|
|
*/
|
2008-09-03 15:22:53 -04:00
|
|
|
public int serialize( int offset, byte[] data ) {
|
2003-02-06 05:29:45 -05:00
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
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();
|
2008-08-11 18:55:38 -04:00
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
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.putUShort(data, 2 + offset, dataSize);
|
|
|
|
// size defined below
|
|
|
|
LittleEndian.putShort(data, 4 + offset, getOptionFlag());
|
|
|
|
LittleEndian.putByte(data, 6 + offset, getKeyboardShortcut());
|
|
|
|
LittleEndian.putByte(data, 7 + offset, getNameTextLength());
|
|
|
|
// Note -
|
|
|
|
LittleEndian.putUShort(data, 8 + offset, Ptg.getEncodedSizeWithoutArrayData(field_13_name_definition));
|
2008-09-08 15:49:03 -04:00
|
|
|
LittleEndian.putUShort(data, 10 + offset, field_5_externSheetIndex_plus1);
|
2008-09-03 15:22:53 -04:00
|
|
|
LittleEndian.putUShort(data, 12 + offset, field_6_sheetNumber);
|
|
|
|
LittleEndian.putByte(data, 14 + offset, field_7_length_custom_menu);
|
|
|
|
LittleEndian.putByte(data, 15 + offset, field_8_length_description_text);
|
|
|
|
LittleEndian.putByte(data, 16 + offset, field_9_length_help_topic_text);
|
|
|
|
LittleEndian.putByte(data, 17 + offset, field_10_length_status_bar_text);
|
|
|
|
LittleEndian.putByte(data, 18 + offset, field_11_nameIsMultibyte ? 1 : 0);
|
|
|
|
int pos = 19 + offset;
|
|
|
|
|
|
|
|
if (isBuiltInName()) {
|
|
|
|
//can send the builtin name directly in
|
|
|
|
LittleEndian.putByte(data, pos, field_12_built_in_code);
|
|
|
|
} else {
|
|
|
|
String nameText = field_12_name_text;
|
|
|
|
if (field_11_nameIsMultibyte) {
|
|
|
|
StringUtil.putUnicodeLE(nameText, data, pos);
|
|
|
|
} else {
|
|
|
|
StringUtil.putCompressedUnicode(nameText, data, pos);
|
|
|
|
}
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
pos += rawNameSize;
|
|
|
|
|
|
|
|
Ptg.serializePtgs(field_13_name_definition, data, pos);
|
|
|
|
pos += formulaTotalSize;
|
|
|
|
|
|
|
|
StringUtil.putCompressedUnicode( getCustomMenuText(), data, pos);
|
|
|
|
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 4 + dataSize;
|
|
|
|
}
|
|
|
|
private int getNameRawSize() {
|
|
|
|
if (isBuiltInName()) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int nChars = field_12_name_text.length();
|
|
|
|
if(field_11_nameIsMultibyte) {
|
|
|
|
return 2 * nChars;
|
|
|
|
}
|
|
|
|
return nChars;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** returns the record size
|
|
|
|
*/
|
|
|
|
public int getRecordSize(){
|
2008-09-03 15:22:53 -04:00
|
|
|
return 4 // sid + size
|
|
|
|
+ 15 // 4 shorts + 7 bytes
|
|
|
|
+ getNameRawSize()
|
|
|
|
+ field_14_custom_menu_text.length()
|
|
|
|
+ field_15_description_text.length()
|
|
|
|
+ field_16_help_topic_text.length()
|
|
|
|
+ field_17_status_bar_text.length()
|
|
|
|
+ Ptg.getEncodedSize(field_13_name_definition);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** gets the extern sheet number
|
|
|
|
* @return extern sheet index
|
|
|
|
*/
|
2008-09-17 18:35:09 -04:00
|
|
|
public int getExternSheetNumber(){
|
2008-09-03 15:22:53 -04:00
|
|
|
if (field_13_name_definition.length < 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
Ptg ptg = field_13_name_definition[0];
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
if (ptg.getClass() == Area3DPtg.class){
|
2008-09-03 15:22:53 -04:00
|
|
|
return ((Area3DPtg) ptg).getExternSheetIndex();
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
if (ptg.getClass() == Ref3DPtg.class){
|
|
|
|
return ((Ref3DPtg) ptg).getExternSheetIndex();
|
|
|
|
}
|
|
|
|
return 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** sets the extern sheet number
|
|
|
|
* @param externSheetNumber extern sheet number
|
|
|
|
*/
|
|
|
|
public void setExternSheetNumber(short externSheetNumber){
|
2008-08-11 18:55:38 -04:00
|
|
|
Ptg ptg;
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
if (field_13_name_definition.length < 1){
|
2008-08-11 18:55:38 -04:00
|
|
|
ptg = createNewPtg();
|
2008-09-03 15:22:53 -04:00
|
|
|
field_13_name_definition = new Ptg[] {
|
|
|
|
ptg,
|
|
|
|
};
|
2008-08-11 18:55:38 -04:00
|
|
|
} else {
|
2008-09-03 15:22:53 -04:00
|
|
|
ptg = field_13_name_definition[0];
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
if (ptg.getClass() == Area3DPtg.class){
|
|
|
|
((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
} else if (ptg.getClass() == Ref3DPtg.class){
|
|
|
|
((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber);
|
|
|
|
}
|
2008-08-11 17:24:19 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
private static Ptg createNewPtg(){
|
2008-09-05 16:38:51 -04:00
|
|
|
return new Area3DPtg("A1:A1", 0); // TODO - change to not be partially initialised
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** gets the reference , the area only (range)
|
|
|
|
* @return area reference
|
|
|
|
*/
|
2008-06-20 03:10:03 -04:00
|
|
|
public String getAreaReference(HSSFWorkbook book){
|
2008-09-18 22:19:58 -04:00
|
|
|
return HSSFFormulaParser.toFormulaString(book, field_13_name_definition);
|
2008-06-20 03:10:03 -04:00
|
|
|
}
|
2002-06-17 13:20:16 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
/** sets the reference , the area only (range)
|
|
|
|
* @param ref area reference
|
|
|
|
*/
|
|
|
|
public void setAreaReference(String ref){
|
2008-08-11 18:55:38 -04:00
|
|
|
//Trying to find if what ptg do we need
|
|
|
|
RangeAddress ra = new RangeAddress(ref);
|
|
|
|
Ptg oldPtg;
|
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
if (field_13_name_definition.length < 1){
|
2008-08-11 18:55:38 -04:00
|
|
|
oldPtg = createNewPtg();
|
|
|
|
} else {
|
|
|
|
//Trying to find extern sheet index
|
2008-09-03 15:22:53 -04:00
|
|
|
oldPtg = field_13_name_definition[0];
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
List temp = new ArrayList();
|
2008-09-17 18:35:09 -04:00
|
|
|
int externSheetIndex = 0;
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
if (oldPtg.getClass() == Area3DPtg.class){
|
|
|
|
externSheetIndex = ((Area3DPtg) oldPtg).getExternSheetIndex();
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
} else if (oldPtg.getClass() == Ref3DPtg.class){
|
|
|
|
externSheetIndex = ((Ref3DPtg) oldPtg).getExternSheetIndex();
|
|
|
|
}
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
if (ra.hasRange()) {
|
2008-08-11 17:24:19 -04:00
|
|
|
// Is it contiguous or not?
|
2008-09-03 15:22:53 -04:00
|
|
|
AreaReference[] refs = AreaReference.generateContiguous(ref);
|
2008-08-11 17:24:19 -04:00
|
|
|
|
2008-09-03 15:22:53 -04:00
|
|
|
// Add the area reference(s)
|
2008-08-11 17:24:19 -04:00
|
|
|
for(int i=0; i<refs.length; i++) {
|
2008-09-03 15:22:53 -04:00
|
|
|
Ptg ptg = new Area3DPtg(refs[i].formatAsString(), externSheetIndex);
|
|
|
|
temp.add(ptg);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
// And then a union if we had more than one area
|
|
|
|
if(refs.length > 1) {
|
2008-09-03 15:22:53 -04:00
|
|
|
Ptg ptg = UnionPtg.instance;
|
|
|
|
temp.add(ptg);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2008-08-11 18:55:38 -04:00
|
|
|
} else {
|
2008-09-16 16:17:30 -04:00
|
|
|
Ref3DPtg ptg = new Ref3DPtg(ra.getFromCell(), externSheetIndex);
|
2008-09-03 15:22:53 -04:00
|
|
|
temp.add(ptg);
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
Ptg[] ptgs = new Ptg[temp.size()];
|
|
|
|
temp.toArray(ptgs);
|
|
|
|
field_13_name_definition = ptgs;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* called by the constructor, should set class level fields. Should throw
|
|
|
|
* runtime exception for bad/icomplete data.
|
|
|
|
*
|
|
|
|
* @param in the RecordInputstream to read the record from
|
|
|
|
*/
|
|
|
|
protected void fillFields(RecordInputStream in) {
|
2008-09-03 15:22:53 -04:00
|
|
|
field_1_option_flag = in.readShort();
|
|
|
|
field_2_keyboard_shortcut = in.readByte();
|
|
|
|
int field_3_length_name_text = in.readByte();
|
|
|
|
int field_4_length_name_definition = in.readShort();
|
2008-09-08 15:49:03 -04:00
|
|
|
field_5_externSheetIndex_plus1 = in.readShort();
|
2008-09-03 15:22:53 -04:00
|
|
|
field_6_sheetNumber = in.readUShort();
|
|
|
|
int field_7_length_custom_menu = in.readUByte();
|
|
|
|
int field_8_length_description_text = in.readUByte();
|
|
|
|
int field_9_length_help_topic_text = in.readUByte();
|
|
|
|
int field_10_length_status_bar_text = in.readUByte();
|
|
|
|
|
|
|
|
//store the name in byte form if it's a built-in name
|
|
|
|
field_11_nameIsMultibyte = (in.readByte() != 0);
|
|
|
|
if (isBuiltInName()) {
|
|
|
|
field_12_built_in_code = in.readByte();
|
|
|
|
} else {
|
|
|
|
if (field_11_nameIsMultibyte) {
|
|
|
|
field_12_name_text = in.readUnicodeLEString(field_3_length_name_text);
|
|
|
|
} else {
|
|
|
|
field_12_name_text = in.readCompressedUnicode(field_3_length_name_text);
|
|
|
|
}
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
|
|
|
|
field_13_name_definition = Ptg.readTokens(field_4_length_name_definition, in);
|
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
//Who says that this can only ever be compressed unicode???
|
2008-09-03 15:22:53 -04:00
|
|
|
field_14_custom_menu_text = in.readCompressedUnicode(field_7_length_custom_menu);
|
|
|
|
field_15_description_text = in.readCompressedUnicode(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);
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* return the non static version of the id for this record.
|
|
|
|
*/
|
|
|
|
public short getSid() {
|
2008-08-11 18:55:38 -04:00
|
|
|
return sid;
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
|
|
|
/*
|
2008-09-03 15:22:53 -04:00
|
|
|
20 00
|
|
|
|
00
|
|
|
|
01
|
2008-08-11 17:24:19 -04:00
|
|
|
1A 00 // sz = 0x1A = 26
|
2008-09-03 15:22:53 -04:00
|
|
|
00 00
|
|
|
|
01 00
|
|
|
|
00
|
|
|
|
00
|
|
|
|
00
|
|
|
|
00
|
2008-08-11 17:24:19 -04:00
|
|
|
00 // unicode flag
|
|
|
|
07 // name
|
2008-09-03 15:22:53 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26
|
|
|
|
00 07 00 07 00 00 00 FF 00 10 // }
|
2008-09-03 15:22:53 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 00
|
|
|
|
00
|
|
|
|
01
|
2008-08-11 17:24:19 -04:00
|
|
|
0B 00 // sz = 0xB = 11
|
2008-09-03 15:22:53 -04:00
|
|
|
00 00
|
|
|
|
01 00
|
|
|
|
00
|
|
|
|
00
|
|
|
|
00
|
|
|
|
00
|
2008-08-11 17:24:19 -04:00
|
|
|
00 // unicode flag
|
|
|
|
07 // name
|
2008-09-03 15:22:53 -04:00
|
|
|
|
2008-08-11 17:24:19 -04:00
|
|
|
3B 00 00 07 00 07 00 00 00 FF 00 // { 11 }
|
2002-09-01 22:11:16 -04:00
|
|
|
*/
|
2008-08-11 17:24:19 -04:00
|
|
|
/*
|
2008-09-03 15:22:53 -04:00
|
|
|
18, 00,
|
|
|
|
1B, 00,
|
|
|
|
|
|
|
|
20, 00,
|
|
|
|
00,
|
|
|
|
01,
|
|
|
|
0B, 00,
|
|
|
|
00,
|
|
|
|
00,
|
|
|
|
00,
|
|
|
|
00,
|
|
|
|
00,
|
|
|
|
07,
|
|
|
|
3B 00 00 07 00 07 00 00 00 FF 00 ]
|
2008-08-11 17:24:19 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
public String toString() {
|
2008-09-03 15:22:53 -04:00
|
|
|
StringBuffer sb = new StringBuffer();
|
|
|
|
|
|
|
|
sb.append("[NAME]\n");
|
|
|
|
sb.append(" .option flags = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
|
|
|
|
sb.append(" .keyboard shortcut = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
|
|
|
|
sb.append(" .length of the name = ").append(getNameTextLength()).append("\n");
|
2008-09-08 15:49:03 -04:00
|
|
|
sb.append(" .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n");
|
|
|
|
sb.append(" .sheetTabIx = ").append(field_6_sheetNumber ).append("\n");
|
2008-09-03 15:22:53 -04:00
|
|
|
sb.append(" .Menu text length = ").append(field_14_custom_menu_text.length()).append("\n");
|
|
|
|
sb.append(" .Description text length= ").append(field_15_description_text.length()).append("\n");
|
|
|
|
sb.append(" .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n");
|
|
|
|
sb.append(" .Status bar text length = ").append(field_17_status_bar_text.length()).append("\n");
|
|
|
|
sb.append(" .NameIsMultibyte = ").append(field_11_nameIsMultibyte).append("\n");
|
|
|
|
sb.append(" .Name (Unicode text) = ").append( getNameText() ).append("\n");
|
|
|
|
sb.append(" .Formula (nTokens=").append(field_13_name_definition.length).append("):") .append("\n");
|
|
|
|
for (int i = 0; i < field_13_name_definition.length; i++) {
|
|
|
|
Ptg ptg = field_13_name_definition[i];
|
|
|
|
sb.append(" " + ptg.toString()).append(ptg.getRVAType()).append("\n");
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
|
|
|
|
sb.append(" .Menu text = ").append(field_14_custom_menu_text).append("\n");
|
|
|
|
sb.append(" .Description text= ").append(field_15_description_text).append("\n");
|
|
|
|
sb.append(" .Help topic text = ").append(field_16_help_topic_text).append("\n");
|
|
|
|
sb.append(" .Status bar text = ").append(field_17_status_bar_text).append("\n");
|
|
|
|
sb.append("[/NAME]\n");
|
|
|
|
|
|
|
|
return sb.toString();
|
2008-08-11 17:24:19 -04:00
|
|
|
}
|
2002-06-17 13:20:16 -04:00
|
|
|
|
2003-03-06 15:41:17 -05:00
|
|
|
/**Creates a human readable name for built in types
|
|
|
|
* @return Unknown if the built-in name cannot be translated
|
|
|
|
*/
|
2008-09-03 15:22:53 -04:00
|
|
|
private static String translateBuiltInName(byte name)
|
2003-03-06 15:41:17 -05:00
|
|
|
{
|
2008-08-11 18:55:38 -04:00
|
|
|
switch (name)
|
|
|
|
{
|
|
|
|
case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate";
|
|
|
|
case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close";
|
|
|
|
case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate";
|
|
|
|
case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open";
|
|
|
|
case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area";
|
|
|
|
case NameRecord.BUILTIN_CRITERIA : return "Criteria";
|
|
|
|
case NameRecord.BUILTIN_DATABASE : return "Database";
|
2008-09-03 15:22:53 -04:00
|
|
|
case NameRecord.BUILTIN_DATA_FORM : return "Data_Form";
|
2008-08-11 18:55:38 -04:00
|
|
|
case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area";
|
|
|
|
case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles";
|
|
|
|
case NameRecord.BUILTIN_RECORDER : return "Recorder";
|
|
|
|
case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title";
|
2008-09-03 15:22:53 -04:00
|
|
|
case NameRecord.BUILTIN_FILTER_DB : return "_FilterDatabase";
|
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
}
|
2008-09-03 15:22:53 -04:00
|
|
|
|
2008-08-11 18:55:38 -04:00
|
|
|
return "Unknown";
|
2003-03-06 15:41:17 -05:00
|
|
|
}
|
2002-04-23 18:28:58 -04:00
|
|
|
}
|