Package org.apache.poi.hssf.record

Source Code of org.apache.poi.hssf.record.DVRecord

/* ====================================================================
   Copyright 2002-2004   Apache Software Foundation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hssf.record;

import org.apache.poi.hssf.record.UnicodeString.UnicodeRecordStats;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.CellRangeAddressList;
import org.apache.poi.util.BitField;
import org.apache.poi.util.LittleEndian;

/**
* Title:        DATAVALIDATION Record (0x01BE)<p/>
* Description:  This record stores data validation settings and a list of cell ranges
*               which contain these settings. The data validation settings of a sheet
*               are stored in a sequential list of DV records. This list is followed by
*               DVAL record(s)
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
* @author Josh Micich
*/
public final class DVRecord extends Record {
  public final static short sid = 0x01BE;
 
  /** the unicode string used for error/prompt title/text when not present */
  private static final UnicodeString NULL_TEXT_STRING = new UnicodeString("\0");

  /** Option flags */
  private int _option_flags;
  /** Title of the prompt box */
  private UnicodeString _promptTitle;
  /** Title of the error box */
  private UnicodeString _errorTitle;
  /** Text of the prompt box */
  private UnicodeString _promptText;
  /** Text of the error box */
  private UnicodeString _errorText;
  /** Not used - Excel seems to always write 0x3FE0 */
  private short _not_used_1 = 0x3FE0;
  /** Formula data for first condition (RPN token array without size field) */
  private Ptg[] _formula1;
  /** Not used - Excel seems to always write 0x0000 */
  private short _not_used_2 = 0x0000;
  /** Formula data for second condition (RPN token array without size field) */
  private Ptg[] _formula2;
  /** Cell range address list with all affected ranges */
  private CellRangeAddressList _regions;

  /**
   * Option flags field
   *
   * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
   */
  private static final BitField opt_data_type                    = new BitField(0x0000000F);
  private static final BitField opt_error_style                  = new BitField(0x00000070);
  private static final BitField opt_string_list_formula          = new BitField(0x00000080);
  private static final BitField opt_empty_cell_allowed           = new BitField(0x00000100);
  private static final BitField opt_suppress_dropdown_arrow      = new BitField(0x00000200);
  private static final BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000);
  private static final BitField opt_show_error_on_invalid_value  = new BitField(0x00080000);
  private static final BitField opt_condition_operator           = new BitField(0x00700000);

  public DVRecord(int validationType, int operator, int errorStyle, boolean emptyCellAllowed,
      boolean suppressDropDownArrow, boolean isExplicitList,
      boolean showPromptBox, String promptTitle, String promptText,
      boolean showErrorBox, String errorTitle, String errorText,
      Ptg[] formula1, Ptg[] formula2,
      CellRangeAddressList regions) {
   
    int flags = 0;
    flags = opt_data_type.setValue(flags, validationType);
    flags = opt_condition_operator.setValue(flags, operator);
    flags = opt_error_style.setValue(flags, errorStyle);
    flags = opt_empty_cell_allowed.setBoolean(flags, emptyCellAllowed);
    flags = opt_suppress_dropdown_arrow.setBoolean(flags, suppressDropDownArrow);
    flags = opt_string_list_formula.setBoolean(flags, isExplicitList);
    flags = opt_show_prompt_on_cell_selected.setBoolean(flags, showPromptBox);
    flags = opt_show_error_on_invalid_value.setBoolean(flags, showErrorBox);
    _option_flags = flags;
    _promptTitle = resolveTitleText(promptTitle);
    _promptText = resolveTitleText(promptText);
    _errorTitle = resolveTitleText(errorTitle);
    _errorText = resolveTitleText(errorText);
    _formula1 = formula1;
    _formula2 = formula2;
    _regions = regions;
  }

  public DVRecord(RecordInputStream in) {
   
     _option_flags = in.readInt();
    
     _promptTitle = readUnicodeString(in);
     _errorTitle = readUnicodeString(in);
     _promptText = readUnicodeString(in);
     _errorText = readUnicodeString(in);

     int field_size_first_formula = in.readUShort();
     _not_used_1 = in.readShort();

     //read first formula data condition
     _formula1 = Ptg.readTokens(field_size_first_formula, in);

     int field_size_sec_formula = in.readUShort();
     _not_used_2 = in.readShort();

     //read sec formula data condition
     _formula2 = Ptg.readTokens(field_size_sec_formula, in);

     //read cell range address list with all affected ranges
     _regions = new CellRangeAddressList(in);
  }

  // --> start option flags
  /**
   * @return the condition data type
   * @see DVConstraint.ValidationType
   */
  public int getDataType() {
     return opt_data_type.getValue(_option_flags);
  }

  /**
   * @return the condition error style
   * @see HSSFDataValidation.ErrorStyle
   */
  public int getErrorStyle() {
     return opt_error_style.getValue(_option_flags);
  }

  /**
   * @return <code>true</code> if in list validations the string list is explicitly given in the
   *  formula, <code>false</code> otherwise
    */
  public boolean getListExplicitFormula() {
     return (opt_string_list_formula.isSet(_option_flags));
  }

  /**
   * @return <code>true</code> if empty values are allowed in cells, <code>false</code> otherwise
   */
  public boolean getEmptyCellAllowed() {
     return (opt_empty_cell_allowed.isSet(_option_flags));
  }


  /**
    * @return <code>true</code> if drop down arrow should be suppressed when list validation is
    * used, <code>false</code> otherwise
   */
  public boolean getSuppressDropdownArrow() {
     return (opt_suppress_dropdown_arrow.isSet(_option_flags));
  }

  /**
   * @return <code>true</code> if a prompt window should appear when cell is selected, <code>false</code> otherwise
   */
  public boolean getShowPromptOnCellSelected() {
     return (opt_show_prompt_on_cell_selected.isSet(_option_flags));
  }

  /**
   * @return <code>true</code> if an error window should appear when an invalid value is entered
   *  in the cell, <code>false</code> otherwise
   */
  public boolean getShowErrorOnInvalidValue() {
     return (opt_show_error_on_invalid_value.isSet(_option_flags));
  }

  /**
   * get the condition operator
   * @return the condition operator
   * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
   */
  public int getConditionOperator() {
     return opt_condition_operator.getValue(_option_flags);
  }
  // <-- end option flags




  public CellRangeAddressList getCellRangeAddress() {
    return this._regions;
  }


  public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append("[DV]\n");
    sb.append(" options=").append(Integer.toHexString(_option_flags));
    sb.append(" title-prompt=").append(formatTextTitle(_promptTitle));
    sb.append(" title-error=").append(formatTextTitle(_errorTitle));
    sb.append(" text-prompt=").append(formatTextTitle(_promptText));
    sb.append(" text-error=").append(formatTextTitle(_errorText));
    sb.append("\n");
    appendFormula(sb, "Formula 1:",  _formula1);
    appendFormula(sb, "Formula 2:",  _formula2);
    sb.append("Regions: ");
    int nRegions = _regions.countRanges();
    for(int i=0; i<nRegions; i++) {
      if (i>0) {
        sb.append(", ");
      }
      CellRangeAddress addr = _regions.getCellRangeAddress(i);
      sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow());
      sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')');
    }
    sb.append("\n");
    sb.append("[/DV]");

    return sb.toString();
  }

  private static String formatTextTitle(UnicodeString us) {
    String str = us.getString();
    if (str.length() == 1 && str.charAt(0) == '\0') {
      return "'\\0'";
    }
    return str;
  }

  private void appendFormula(StringBuffer sb, String label, Ptg[] ptgs) {
    sb.append(label);
    if (ptgs.length < 1) {
      sb.append("<empty>\n");
      return;
    }
    sb.append("\n");
    for (int i = 0; i < ptgs.length; i++) {
      sb.append('\t').append(ptgs[i].toString()).append('\n');
    }
  }

  public int serialize(int offset, byte [] data) {
    int size = this.getRecordSize();
    LittleEndian.putShort(data, 0 + offset, sid);
    LittleEndian.putShort(data, 2 + offset, ( short ) (size-4));

    int pos = 4;
    LittleEndian.putInt(data, pos + offset, _option_flags);
    pos += 4;
   
    pos += serializeUnicodeString(_promptTitle, pos+offset, data);
    pos += serializeUnicodeString(_errorTitle, pos+offset, data);
    pos += serializeUnicodeString(_promptText, pos+offset, data);
    pos += serializeUnicodeString(_errorText, pos+offset, data);
    LittleEndian.putUShort(data, offset+pos, Ptg.getEncodedSize(_formula1));
    pos += 2;
    LittleEndian.putUShort(data, offset+pos, _not_used_1);
    pos += 2;

    pos += Ptg.serializePtgs(_formula1, data, pos+offset);

    LittleEndian.putUShort(data, offset+pos, Ptg.getEncodedSize(_formula2));
    pos += 2;
    LittleEndian.putShort(data, offset+pos, _not_used_2);
    pos += 2;
    pos += Ptg.serializePtgs(_formula2, data, pos+offset);
    _regions.serialize(pos+offset, data);
    return size;
  }

  /**
   * When entered via the UI, Excel translates empty string into "\0"
   * While it is possible to encode the title/text as empty string (Excel doesn't exactly crash),
   * the resulting tool-tip text / message box looks wrong.  It is best to do the same as the
   * Excel UI and encode 'not present' as "\0".
   */
  private static UnicodeString resolveTitleText(String str) {
    if (str == null || str.length() < 1) {
      return NULL_TEXT_STRING;
    }
    return new UnicodeString(str);
  }
 
  private static UnicodeString readUnicodeString(RecordInputStream in) {
    return new UnicodeString(in);
  }

  private static int serializeUnicodeString(UnicodeString us, int offset, byte[] data) {
    UnicodeRecordStats urs = new UnicodeRecordStats();
    us.serialize(urs, offset, data);
    return urs.recordSize;
  }
  private static int getUnicodeStringSize(UnicodeString str) {
    return 3 + str.getString().length();
  }

  public int getRecordSize()  {
    int size = 4+4+2+2+2+2;//header+options_field+first_formula_size+first_unused+sec_formula_size+sec+unused;
    size += getUnicodeStringSize(_promptTitle);
    size += getUnicodeStringSize(_errorTitle);
    size += getUnicodeStringSize(_promptText);
    size += getUnicodeStringSize(_errorText);
    size += Ptg.getEncodedSize(_formula1);
    size += Ptg.getEncodedSize(_formula2);
    size += _regions.getSize();
    return size;
  }

  public short getSid() {
    return sid;
  }
 
  /**
   * Clones the object. Uses serialisation, as the
   *  contents are somewhat complex
   */
  public Object clone() {
    return cloneViaReserialise();
  }
}
TOP

Related Classes of org.apache.poi.hssf.record.DVRecord

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.