1 2 17 18 19 package org.apache.poi.hssf.record; 20 21 import java.util.List ; 22 import java.util.Stack ; 23 24 import org.apache.poi.hssf.model.Workbook; 25 import org.apache.poi.hssf.record.formula.Area3DPtg; 26 import org.apache.poi.hssf.record.formula.Ptg; 27 import org.apache.poi.hssf.record.formula.Ref3DPtg; 28 import org.apache.poi.hssf.util.RangeAddress; 29 import org.apache.poi.util.HexDump; 30 import org.apache.poi.util.LittleEndian; 31 import org.apache.poi.util.StringUtil; 32 33 42 43 public class NameRecord extends Record { 44 46 public final static short sid = 0x18; 48 50 public final static byte BUILTIN_CONSOLIDATE_AREA = (byte)1; 51 52 54 public final static byte BUILTIN_AUTO_OPEN = (byte)2; 55 56 58 public final static byte BUILTIN_AUTO_CLOSE = (byte)3; 59 60 62 public final static byte BUILTIN_DATABASE = (byte)4; 63 64 66 public final static byte BUILTIN_CRITERIA = (byte)5; 67 68 public final static byte BUILTIN_PRINT_AREA = (byte)6; 69 public final static byte BUILTIN_PRINT_TITLE = (byte)7; 70 71 73 public final static byte BUILTIN_RECORDER = (byte)8; 74 75 77 public final static byte BUILTIN_DATA_FORM = (byte)9; 78 79 81 82 public final static byte BUILTIN_AUTO_ACTIVATE = (byte)10; 83 84 86 87 public final static byte BUILTIN_AUTO_DEACTIVATE = (byte)11; 88 89 91 public final static byte BUILTIN_SHEET_TITLE = (byte)12; 92 93 public static final short OPT_HIDDEN_NAME = (short) 0x0001; 94 public static final short OPT_FUNCTION_NAME = (short) 0x0002; 95 public static final short OPT_COMMAND_NAME = (short) 0x0004; 96 public static final short OPT_MACRO = (short) 0x0008; 97 public static final short OPT_COMPLEX = (short) 0x0010; 98 public static final short OPT_BUILTIN = (short) 0x0020; 99 public static final short OPT_BINDATA = (short) 0x1000; 100 101 102 private short field_1_option_flag; 103 private byte field_2_keyboard_shortcut; 104 private byte field_3_length_name_text; 105 private short field_4_length_name_definition; 106 private short field_5_index_to_sheet; private short field_6_equals_to_index_to_sheet; 108 private byte field_7_length_custom_menu; 109 private byte field_8_length_description_text; 110 private byte field_9_length_help_topic_text; 111 private byte field_10_length_status_bar_text; 112 private byte field_11_compressed_unicode_flag; private byte field_12_builtIn_name; 114 private String field_12_name_text; 115 private Stack field_13_name_definition; 116 private byte[] field_13_raw_name_definition; private String field_14_custom_menu_text; 118 private String field_15_description_text; 119 private String field_16_help_topic_text; 120 private String field_17_status_bar_text; 121 122 123 124 public NameRecord() { 125 field_13_name_definition = new Stack (); 126 127 field_12_name_text = new String (); 128 field_14_custom_menu_text = new String (); 129 field_15_description_text = new String (); 130 field_16_help_topic_text = new String (); 131 field_17_status_bar_text = new String (); 132 } 133 134 141 public NameRecord(short id, short size, byte [] data) { 142 super(id, size, data); 143 } 144 145 153 public NameRecord(short id, short size, byte [] data, int offset) { 154 super(id, size, data, offset); 155 } 156 157 162 public NameRecord(byte builtin, short index) 163 { 164 this(); 165 this.field_12_builtIn_name = builtin; 166 this.setOptionFlag((short)(this.getOptionFlag() | OPT_BUILTIN)); 167 this.setNameTextLength((byte)1); 168 this.setEqualsToIndexToSheet(index); 170 this.setCustomMenuLength((byte)0); 172 this.setDescriptionTextLength((byte)0); 173 this.setHelpTopicLength((byte)0); 174 this.setStatusBarLength((byte)0); 175 176 177 } 178 179 182 public void setOptionFlag(short flag){ 183 field_1_option_flag = flag; 184 } 185 186 187 190 public void setKeyboardShortcut(byte shortcut){ 191 field_2_keyboard_shortcut = shortcut; 192 } 193 194 197 public void setNameTextLength(byte length){ 198 field_3_length_name_text = length; 199 } 200 201 204 public void setDefinitionTextLength(short length){ 205 field_4_length_name_definition = length; 206 } 207 208 212 public void setUnused(short index){ 213 field_5_index_to_sheet = index; 214 215 } 218 219 public short getEqualsToIndexToSheet() 220 { 221 return field_6_equals_to_index_to_sheet; 222 } 223 224 229 public short getIndexToSheet() { 230 return getEqualsToIndexToSheet(); 231 } 232 233 237 public byte getFnGroup() { 238 int masked = field_1_option_flag & 0x0fc0; 239 return (byte) (masked >> 4); 240 } 241 242 public void setEqualsToIndexToSheet(short value) 243 { 244 field_6_equals_to_index_to_sheet = value; 245 } 246 247 248 251 public void setCustomMenuLength(byte length){ 252 field_7_length_custom_menu = length; 253 } 254 255 258 public void setDescriptionTextLength(byte length){ 259 field_8_length_description_text = length; 260 } 261 262 265 public void setHelpTopicLength(byte length){ 266 field_9_length_help_topic_text = length; 267 } 268 269 272 public void setStatusBarLength(byte length){ 273 field_10_length_status_bar_text = length; 274 } 275 276 279 public void setCompressedUnicodeFlag(byte flag) { 280 field_11_compressed_unicode_flag = flag; 281 } 282 283 286 public void setNameText(String name){ 287 field_12_name_text = name; 288 } 289 290 294 297 public void setCustomMenuText(String text){ 298 field_14_custom_menu_text = text; 299 } 300 301 304 public void setDescriptionText(String text){ 305 field_15_description_text = text; 306 } 307 308 311 public void setHelpTopicText(String text){ 312 field_16_help_topic_text = text; 313 } 314 315 318 public void setStatusBarText(String text){ 319 field_17_status_bar_text = text; 320 } 321 322 325 public short getOptionFlag(){ 326 return field_1_option_flag; 327 } 328 329 332 public byte getKeyboardShortcut(){ 333 return field_2_keyboard_shortcut ; 334 } 335 336 339 public byte getNameTextLength(){ 340 return field_3_length_name_text; 341 } 342 343 346 public short getDefinitionTextLength(){ 347 return field_4_length_name_definition; 348 } 349 350 353 public short getUnused(){ 354 return field_5_index_to_sheet; 355 } 356 357 360 public byte getCustomMenuLength(){ 361 return field_7_length_custom_menu; 362 } 363 364 367 public byte getDescriptionTextLength(){ 368 return field_8_length_description_text; 369 } 370 371 374 public byte getHelpTopicLength(){ 375 return field_9_length_help_topic_text; 376 } 377 378 381 public byte getStatusBarLength(){ 382 return field_10_length_status_bar_text; 383 } 384 385 388 public byte getCompressedUnicodeFlag() { 389 return field_11_compressed_unicode_flag; 390 } 391 392 395 public boolean isHiddenName() { 396 return (field_1_option_flag & OPT_HIDDEN_NAME) != 0; 397 } 398 399 402 public boolean isFunctionName() { 403 return (field_1_option_flag & OPT_FUNCTION_NAME) != 0; 404 } 405 406 409 public boolean isCommandName() { 410 return (field_1_option_flag & OPT_COMMAND_NAME) != 0; 411 } 412 413 416 public boolean isMacro() { 417 return (field_1_option_flag & OPT_MACRO) != 0; 418 } 419 420 423 public boolean isComplexFunction() { 424 return (field_1_option_flag & OPT_COMPLEX) != 0; 425 } 426 427 428 430 public boolean isBuiltInName() 431 { 432 return ((this.getOptionFlag() & OPT_BUILTIN) != 0); 433 } 434 435 436 439 public String getNameText(){ 440 441 return this.isBuiltInName() ? this.translateBuiltInName(this.getBuiltInName()) : field_12_name_text; 442 } 443 444 447 public byte getBuiltInName() 448 { 449 return this.field_12_builtIn_name; 450 } 451 452 453 456 public List getNameDefinition() { 457 return field_13_name_definition; 458 } 459 460 public void setNameDefinition(Stack nameDefinition) { 461 field_13_name_definition = nameDefinition; 462 } 463 464 467 public String getCustomMenuText(){ 468 return field_14_custom_menu_text; 469 } 470 471 474 public String getDescriptionText(){ 475 return field_15_description_text; 476 } 477 478 481 public String getHelpTopicText(){ 482 return field_16_help_topic_text; 483 } 484 485 488 public String getStatusBarText(){ 489 return field_17_status_bar_text; 490 } 491 492 498 protected void validateSid(short id) { 499 if (id != sid) { 500 throw new RecordFormatException("NOT A valid Name RECORD"); 501 } 502 } 503 504 513 public int serialize( int offset, byte[] data ) 514 { 515 LittleEndian.putShort( data, 0 + offset, sid ); 516 LittleEndian.putShort( data, 4 + offset, getOptionFlag() ); 518 data[6 + offset] = getKeyboardShortcut(); 519 data[7 + offset] = getNameTextLength(); 520 LittleEndian.putShort( data, 8 + offset, getDefinitionTextLength() ); 521 LittleEndian.putShort( data, 10 + offset, getUnused() ); 522 LittleEndian.putShort( data, 12 + offset, getEqualsToIndexToSheet() ); 523 data[14 + offset] = getCustomMenuLength(); 524 data[15 + offset] = getDescriptionTextLength(); 525 data[16 + offset] = getHelpTopicLength(); 526 data[17 + offset] = getStatusBarLength(); 527 data[18 + offset] = getCompressedUnicodeFlag(); 528 529 541 LittleEndian.putShort( data, 2 + offset, (short) ( 15 + getTextsLength() ) ); 542 543 int start_of_name_definition = 19 + field_3_length_name_text; 544 545 if (this.isBuiltInName()) { 546 data [19 + offset] = this.getBuiltInName(); 548 } else { 549 StringUtil.putCompressedUnicode( getNameText(), data, 19 + offset ); 550 551 } 552 553 554 if ( this.field_13_name_definition != null ) 555 { 556 serializePtgs( data, start_of_name_definition + offset ); 557 } 558 else 559 { 560 System.arraycopy( field_13_raw_name_definition, 0, data 561 , start_of_name_definition + offset, field_13_raw_name_definition.length ); 562 } 563 564 565 int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition; 566 StringUtil.putCompressedUnicode( getCustomMenuText(), data, start_of_custom_menu_text + offset ); 567 568 int start_of_description_text = start_of_custom_menu_text + field_7_length_custom_menu; 569 StringUtil.putCompressedUnicode( getDescriptionText(), data, start_of_description_text + offset ); 570 571 int start_of_help_topic_text = start_of_description_text + field_8_length_description_text; 572 StringUtil.putCompressedUnicode( getHelpTopicText(), data, start_of_help_topic_text + offset ); 573 574 int start_of_status_bar_text = start_of_help_topic_text + field_9_length_help_topic_text; 575 StringUtil.putCompressedUnicode( getStatusBarText(), data, start_of_status_bar_text + offset ); 576 577 return getRecordSize(); 578 579 } 580 581 private void serializePtgs(byte [] data, int offset) { 582 int pos = offset; 583 584 for (int k = 0; k < field_13_name_definition.size(); k++) { 585 Ptg ptg = ( Ptg ) field_13_name_definition.get(k); 586 587 ptg.writeBytes(data, pos); 588 pos += ptg.getSize(); 589 } 590 } 591 592 593 596 public int getTextsLength(){ 597 int result; 598 599 result = getNameTextLength() + getDefinitionTextLength() + getDescriptionTextLength() + 600 getHelpTopicLength() + getStatusBarLength(); 601 602 603 return result; 604 } 605 606 608 public int getRecordSize(){ 609 int result; 610 611 result = 19 + getTextsLength(); 612 613 return result; 614 } 615 616 619 public short getExternSheetNumber(){ 620 if (field_13_name_definition == null) return 0; 621 Ptg ptg = (Ptg) field_13_name_definition.peek(); 622 short result = 0; 623 624 if (ptg.getClass() == Area3DPtg.class){ 625 result = ((Area3DPtg) ptg).getExternSheetIndex(); 626 627 } else if (ptg.getClass() == Ref3DPtg.class){ 628 result = ((Ref3DPtg) ptg).getExternSheetIndex(); 629 } 630 631 return result; 632 } 633 634 637 public void setExternSheetNumber(short externSheetNumber){ 638 Ptg ptg; 639 640 if (field_13_name_definition == null || field_13_name_definition.isEmpty()){ 641 field_13_name_definition = new Stack (); 642 ptg = createNewPtg(); 643 } else { 644 ptg = (Ptg) field_13_name_definition.peek(); 645 } 646 647 if (ptg.getClass() == Area3DPtg.class){ 648 ((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber); 649 650 } else if (ptg.getClass() == Ref3DPtg.class){ 651 ((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber); 652 } 653 654 } 655 656 private Ptg createNewPtg(){ 657 Ptg ptg = new Area3DPtg(); 658 field_13_name_definition.push(ptg); 659 660 return ptg; 661 } 662 663 666 public String getAreaReference(Workbook book){ 667 if (field_13_name_definition == null) return "#REF!"; 668 Ptg ptg = (Ptg) field_13_name_definition.peek(); 669 String result = ""; 670 671 if (ptg.getClass() == Area3DPtg.class){ 672 result = ptg.toFormulaString(book); 673 674 } else if (ptg.getClass() == Ref3DPtg.class){ 675 result = ptg.toFormulaString(book); 676 } 677 678 return result; 679 } 680 681 684 public void setAreaReference(String ref){ 685 RangeAddress ra = new RangeAddress(ref); 687 Ptg oldPtg; 688 Ptg ptg; 689 690 if (field_13_name_definition==null ||field_13_name_definition.isEmpty()){ 691 field_13_name_definition = new Stack (); 692 oldPtg = createNewPtg(); 693 } else { 694 oldPtg = (Ptg) field_13_name_definition.pop(); 696 } 697 698 short externSheetIndex = 0; 699 700 if (oldPtg.getClass() == Area3DPtg.class){ 701 externSheetIndex = ((Area3DPtg) oldPtg).getExternSheetIndex(); 702 703 } else if (oldPtg.getClass() == Ref3DPtg.class){ 704 externSheetIndex = ((Ref3DPtg) oldPtg).getExternSheetIndex(); 705 } 706 707 if (ra.hasRange()) { 708 ptg = new Area3DPtg(); 709 ((Area3DPtg) ptg).setExternSheetIndex(externSheetIndex); 710 ((Area3DPtg) ptg).setArea(ref); 711 this.setDefinitionTextLength((short)ptg.getSize()); 712 } else { 713 ptg = new Ref3DPtg(); 714 ((Ref3DPtg) ptg).setExternSheetIndex(externSheetIndex); 715 ((Ref3DPtg) ptg).setArea(ref); 716 this.setDefinitionTextLength((short)ptg.getSize()); 717 } 718 719 field_13_name_definition.push(ptg); 720 721 } 722 723 731 protected void fillFields(byte[] data, short size, int offset) { 732 field_1_option_flag = LittleEndian.getShort(data, 0 + offset); 733 field_2_keyboard_shortcut = data [2 + offset]; 734 field_3_length_name_text = data [3 + offset]; 735 field_4_length_name_definition = LittleEndian.getShort(data, 4 + offset); 736 field_5_index_to_sheet = LittleEndian.getShort(data, 6 + offset); 737 field_6_equals_to_index_to_sheet= LittleEndian.getShort(data, 8 + offset); 738 field_7_length_custom_menu = data [10 + offset]; 739 field_8_length_description_text = data [11 + offset]; 740 field_9_length_help_topic_text = data [12 + offset]; 741 field_10_length_status_bar_text = data [13 + offset]; 742 743 744 767 768 field_11_compressed_unicode_flag= data [14 + offset]; 769 770 771 if (this.isBuiltInName()) { 773 field_12_builtIn_name = data[ 15 + offset ]; 774 } 775 776 field_12_name_text = StringUtil.getFromCompressedUnicode(data, 15 + offset, 777 LittleEndian.ubyteToInt(field_3_length_name_text)); 778 779 int start_of_name_definition = 15 + field_3_length_name_text; 780 field_13_name_definition = getParsedExpressionTokens(data, field_4_length_name_definition, 781 offset, start_of_name_definition); 782 783 int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition; 784 field_14_custom_menu_text = StringUtil.getFromCompressedUnicode(data, start_of_custom_menu_text + offset, 785 LittleEndian.ubyteToInt(field_7_length_custom_menu)); 786 787 int start_of_description_text = start_of_custom_menu_text + field_7_length_custom_menu;; 788 field_15_description_text = StringUtil.getFromCompressedUnicode(data, start_of_description_text + offset, 789 LittleEndian.ubyteToInt(field_8_length_description_text)); 790 791 int start_of_help_topic_text = start_of_description_text + field_8_length_description_text; 792 field_16_help_topic_text = StringUtil.getFromCompressedUnicode(data, start_of_help_topic_text + offset, 793 LittleEndian.ubyteToInt(field_9_length_help_topic_text)); 794 795 int start_of_status_bar_text = start_of_help_topic_text + field_9_length_help_topic_text; 796 field_17_status_bar_text = StringUtil.getFromCompressedUnicode(data, start_of_status_bar_text + offset, 797 LittleEndian.ubyteToInt(field_10_length_status_bar_text)); 798 799 } 800 801 private Stack getParsedExpressionTokens(byte [] data, short size, 802 int offset, int start_of_expression) { 803 Stack stack = new Stack (); 804 int pos = start_of_expression + offset; 805 int sizeCounter = 0; 806 try { 807 while (sizeCounter < size) { 808 Ptg ptg = Ptg.createPtg(data, pos); 809 810 pos += ptg.getSize(); 811 sizeCounter += ptg.getSize(); 812 stack.push(ptg); 813 field_13_raw_name_definition=new byte[size]; 814 System.arraycopy(data,offset,field_13_raw_name_definition,0,size); 815 } 816 } catch (java.lang.UnsupportedOperationException uoe) { 817 System.err.println("[WARNING] Unknown Ptg " 818 + uoe.getMessage() ); 819 field_13_raw_name_definition=new byte[size]; 820 System.arraycopy(data,offset,field_13_raw_name_definition,0,size); 821 return null; 822 } 823 return stack; 824 } 825 826 827 830 public short getSid() { 831 return this.sid; 832 } 833 867 883 884 887 public String toString() { 888 StringBuffer buffer = new StringBuffer (); 889 890 buffer.append("[NAME]\n"); 891 buffer.append(" .option flags = ").append( HexDump.toHex( field_1_option_flag ) ) 892 .append("\n"); 893 buffer.append(" .keyboard shortcut = ").append( HexDump.toHex( field_2_keyboard_shortcut ) ) 894 .append("\n"); 895 buffer.append(" .length of the name = ").append( field_3_length_name_text ) 896 .append("\n"); 897 buffer.append(" .size of the formula data = ").append( field_4_length_name_definition ) 898 .append("\n"); 899 buffer.append(" .unused = ").append( field_5_index_to_sheet ) 900 .append("\n"); 901 buffer.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_equals_to_index_to_sheet ) 902 .append("\n"); 903 buffer.append(" .Length of menu text (character count) = ").append( field_7_length_custom_menu ) 904 .append("\n"); 905 buffer.append(" .Length of description text (character count) = ").append( field_8_length_description_text ) 906 .append("\n"); 907 buffer.append(" .Length of help topic text (character count) = ").append( field_9_length_help_topic_text ) 908 .append("\n"); 909 buffer.append(" .Length of status bar text (character count) = ").append( field_10_length_status_bar_text ) 910 .append("\n"); 911 buffer.append(" .Name (Unicode flag) = ").append( field_11_compressed_unicode_flag ) 912 .append("\n"); 913 buffer.append(" .Name (Unicode text) = ").append( getNameText() ) 914 .append("\n"); 915 buffer.append(" .Formula data (RPN token array without size field) = ").append( HexDump.toHex( 916 ((field_13_raw_name_definition != null) ? field_13_raw_name_definition : new byte[0] ) ) ) 917 .append("\n"); 918 919 buffer.append(" .Menu text (Unicode string without length field) = ").append( field_14_custom_menu_text ) 920 .append("\n"); 921 buffer.append(" .Description text (Unicode string without length field) = ").append( field_15_description_text ) 922 .append("\n"); 923 buffer.append(" .Help topic text (Unicode string without length field) = ").append( field_16_help_topic_text ) 924 .append("\n"); 925 buffer.append(" .Status bar text (Unicode string without length field) = ").append( field_17_status_bar_text ) 926 .append("\n"); 927 if (field_13_raw_name_definition != null) 928 buffer.append(org.apache.poi.util.HexDump.dump(this.field_13_raw_name_definition,0,0)); 929 buffer.append("[/NAME]\n"); 930 931 return buffer.toString(); 932 } 933 934 937 protected String translateBuiltInName(byte name) 938 { 939 switch (name) 940 { 941 case NameRecord.BUILTIN_AUTO_ACTIVATE : return "Auto_Activate"; 942 case NameRecord.BUILTIN_AUTO_CLOSE : return "Auto_Close"; 943 case NameRecord.BUILTIN_AUTO_DEACTIVATE : return "Auto_Deactivate"; 944 case NameRecord.BUILTIN_AUTO_OPEN : return "Auto_Open"; 945 case NameRecord.BUILTIN_CONSOLIDATE_AREA : return "Consolidate_Area"; 946 case NameRecord.BUILTIN_CRITERIA : return "Criteria"; 947 case NameRecord.BUILTIN_DATABASE : return "Database"; 948 case NameRecord.BUILTIN_DATA_FORM : return "Data_Form"; 949 case NameRecord.BUILTIN_PRINT_AREA : return "Print_Area"; 950 case NameRecord.BUILTIN_PRINT_TITLE : return "Print_Titles"; 951 case NameRecord.BUILTIN_RECORDER : return "Recorder"; 952 case NameRecord.BUILTIN_SHEET_TITLE : return "Sheet_Title"; 953 954 } 955 956 return "Unknown"; 957 } 958 959 960 } 961 | Popular Tags |