/** @param e */
  public void valueChange(ValueChangeEvent e) {
    if (gridTab.isProcessed()) //  only active records
    {
      Object source = e.getSource();
      if (source instanceof WEditor) {
        // Elaine 2009/05/06
        WEditor editor = (WEditor) source;
        GridField gridField = editor.getGridField();

        if (gridField != null) {
          if (!gridField.isEditable(true)) {
            logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
            return;
          }
        } else if (!editor.isReadWrite()) {
          logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
          return;
        }
      } else {
        logger.config("(" + gridTab.toString() + ") " + e.getPropertyName());
        return;
      }
    } //  processed
    logger.config(
        "("
            + gridTab.toString()
            + ") "
            + e.getPropertyName()
            + "="
            + e.getNewValue()
            + " ("
            + e.getOldValue()
            + ") "
            + (e.getOldValue() == null ? "" : e.getOldValue().getClass().getName()));

    //  Get Row/Col Info
    GridTable mTable = gridTab.getTableModel();
    int row = gridTab.getCurrentRow();
    int col = mTable.findColumn(e.getPropertyName());
    //
    if (e.getNewValue() == null
        && e.getOldValue() != null
        && e.getOldValue().toString().length() > 0) //  some editors return "" instead of null
      //        	  this is the original code from GridController, don't know what it does there but
      // it breaks ignore button for web ui
      //            mTable.setChanged (true);
      mTable.setValueAt(e.getNewValue(), row, col);
    else {

      Object newValue = e.getNewValue();
      Integer newValues[] = null;

      if (newValue instanceof Integer[]) {
        newValues = ((Integer[]) newValue);
        newValue = newValues[0];

        if (newValues.length > 1) {
          Integer valuesCopy[] = new Integer[newValues.length - 1];
          System.arraycopy(newValues, 1, valuesCopy, 0, valuesCopy.length);
          newValues = valuesCopy;
        } else {
          newValues = null;
        }
      } else if (newValue instanceof Object[]) {
        logger.severe("Multiple values can only be processed for IDs (Integer)");
        throw new IllegalArgumentException(
            "Multiple Selection values not available for this field. " + e.getPropertyName());
      }

      mTable.setValueAt(newValue, row, col);
      //  Force Callout
      if (e.getPropertyName().equals("S_ResourceAssignment_ID")) {
        GridField mField = gridTab.getField(col);
        if (mField != null && mField.getCallout().length() > 0) {
          gridTab.processFieldChange(mField); //  Dependencies & Callout
        }
      }

      if (newValues != null && newValues.length > 0) {
        // Save data, since record need to be used for generating clones.
        if (!gridTab.dataSave(false)) {
          throw new AdempiereException("SaveError");
        }

        // Retrieve the current record ID
        int recordId = gridTab.getKeyID(gridTab.getCurrentRow());

        Trx trx = Trx.get(Trx.createTrxName(), true);
        trx.start();
        try {
          saveMultipleRecords(
              Env.getCtx(),
              gridTab.getTableName(),
              e.getPropertyName(),
              recordId,
              newValues,
              trx.getTrxName());
          trx.commit();
          gridTab.dataRefreshAll();
        } catch (Exception ex) {
          trx.rollback();
          logger.severe(ex.getMessage());
          throw new AdempiereException("SaveError");
        } finally {
          trx.close();
        }
      }
    }
  } // ValueChange
  /** Start dialog */
  private void cmd_dialog() {
    //
    Integer oldValue = (Integer) getValue();
    int oldValueInt = oldValue == null ? 0 : oldValue.intValue();
    int M_AttributeSetInstance_ID = oldValueInt;
    int M_Product_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_Product_ID");
    int M_ProductBOM_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "M_ProductBOM_ID");

    log.config(
        "M_Product_ID="
            + M_Product_ID
            + "/"
            + M_ProductBOM_ID
            + ",M_AttributeSetInstance_ID="
            + M_AttributeSetInstance_ID
            + ", AD_Column_ID="
            + gridField.getAD_Column_ID());

    //	M_Product.M_AttributeSetInstance_ID = 8418
    boolean productWindow = (gridField.getAD_Column_ID() == 8418); // 	HARDCODED

    //	Exclude ability to enter ASI
    boolean exclude = true;

    if (M_Product_ID != 0) {
      MProduct product = MProduct.get(Env.getCtx(), M_Product_ID);
      int M_AttributeSet_ID = Services.get(IProductBL.class).getM_AttributeSet_ID(product);
      if (M_AttributeSet_ID != 0) {
        final IAttributeExcludeBL excludeBL = Services.get(IAttributeExcludeBL.class);
        final I_M_AttributeSet attributeSet =
            InterfaceWrapperHelper.create(
                Env.getCtx(), M_AttributeSet_ID, I_M_AttributeSet.class, ITrx.TRXNAME_None);
        final I_M_AttributeSetExclude asExclude =
            excludeBL.getAttributeSetExclude(
                attributeSet, gridField.getAD_Column_ID(), Env.isSOTrx(Env.getCtx(), m_WindowNo));
        if ((null == asExclude) || (!excludeBL.isFullExclude(asExclude))) {
          exclude = false;
        }
      }
    }

    boolean changed = false;
    if (M_ProductBOM_ID != 0) // 	Use BOM Component
    M_Product_ID = M_ProductBOM_ID;
    //
    if (!productWindow && (M_Product_ID == 0 || exclude)) {
      changed = true;
      getComponent().setText(null);
      M_AttributeSetInstance_ID = 0;
    } else {
      WPAttributeDialog vad =
          new WPAttributeDialog(
              M_AttributeSetInstance_ID,
              M_Product_ID,
              m_C_BPartner_ID,
              productWindow,
              gridField.getAD_Column_ID(),
              m_WindowNo);
      if (vad.isChanged()) {
        getComponent().setText(vad.getM_AttributeSetInstanceName());
        M_AttributeSetInstance_ID = vad.getM_AttributeSetInstance_ID();
        if (m_GridTab != null && !productWindow && vad.getM_Locator_ID() > 0)
          m_GridTab.setValue("M_Locator_ID", vad.getM_Locator_ID());
        changed = true;
      }
    }
    /**
     * Selection { // Get Model MAttributeSetInstance masi = MAttributeSetInstance.get(Env.getCtx(),
     * M_AttributeSetInstance_ID, M_Product_ID); if (masi == null) { log.log(Level.SEVERE, "No Model
     * for M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID + ", M_Product_ID=" +
     * M_Product_ID); } else { Env.setContext(Env.getCtx(), m_WindowNo, "M_AttributeSet_ID",
     * masi.getM_AttributeSet_ID()); // Get Attribute Set MAttributeSet as =
     * masi.getMAttributeSet(); // Product has no Attribute Set if (as == null)
     * ADialog.error(m_WindowNo, this, "PAttributeNoAttributeSet"); // Product has no Instance
     * Attributes else if (!as.isInstanceAttribute()) ADialog.error(m_WindowNo, this,
     * "PAttributeNoInstanceAttribute"); else { int M_Warehouse_ID = Env.getContextAsInt (Env.getCtx
     * (), m_WindowNo, "M_Warehouse_ID"); int M_Locator_ID = Env.getContextAsInt (Env.getCtx (),
     * m_WindowNo, "M_Locator_ID"); String title = ""; PAttributeInstance pai = new
     * PAttributeInstance ( Env.getFrame(this), title, M_Warehouse_ID, M_Locator_ID, M_Product_ID,
     * m_C_BPartner_ID); if (pai.getM_AttributeSetInstance_ID() != -1) {
     * m_text.setText(pai.getM_AttributeSetInstanceName()); M_AttributeSetInstance_ID =
     * pai.getM_AttributeSetInstance_ID(); changed = true; } } } }
     */

    //	Set Value
    if (changed) {
      log.finest("Changed M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID);
      m_value = new Object(); // 	force re-query display
      if (M_AttributeSetInstance_ID == 0) setValue(null);
      else setValue(new Integer(M_AttributeSetInstance_ID));

      ValueChangeEvent vce =
          new ValueChangeEvent(this, gridField.getColumnName(), new Object(), getValue());
      fireValueChange(vce);
      if (M_AttributeSetInstance_ID == oldValueInt && m_GridTab != null && gridField != null) {
        //  force Change - user does not realize that embedded object is already saved.
        m_GridTab.processFieldChange(gridField);
      }
    } //	change
  } //  cmd_file