Package org.pentaho.openformula.ui.table

Source Code of org.pentaho.openformula.ui.table.FormulaFragmentCellEditor$SelectionAction

package org.pentaho.openformula.ui.table;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.EventObject;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.table.TableCellEditor;

import org.pentaho.openformula.ui.FieldDefinition;
import org.pentaho.openformula.ui.FormulaEditorDialog;
import org.pentaho.reporting.libraries.base.util.DebugLog;
import org.pentaho.reporting.libraries.designtime.swing.EllipsisButton;
import org.pentaho.reporting.libraries.designtime.swing.EmptyValueListCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.NonFilteringPlainDocument;
import org.pentaho.reporting.libraries.formula.DefaultFormulaContext;
import org.pentaho.reporting.libraries.formula.FormulaContext;
import org.pentaho.reporting.libraries.formula.util.FormulaUtil;

public class FormulaFragmentCellEditor extends JPanel implements TableCellEditor
{
  protected class ExtendedEditorAction extends AbstractAction
  {
    /**
     * Defines an <code>Action</code> object with a default description string and default icon.
     */
    protected ExtendedEditorAction()
    {
    }

    /**
     * Invoked when an action occurs.
     */
    public void actionPerformed(final ActionEvent e)
    {
      final JComboBox comboBox = getComboBox();
      final FormulaEditorDialog editorDialog = FormulaFragmentCellEditor.this.createEditorDialog();
      final String originalFormula = (String) comboBox.getSelectedItem();
      final String formula = editorDialog.editFormula(originalFormula, getFields());
      if (formula != null)
      {
        comboBox.setSelectedItem(formula);
      }
      stopCellEditing();
    }
  }

  protected FormulaEditorDialog createEditorDialog()
  {
    Window windowAncestor = SwingUtilities.getWindowAncestor(this);
    if (windowAncestor instanceof Dialog)
    {
      return new FormulaEditorDialog((Dialog) windowAncestor);
    }
    else if (windowAncestor instanceof Frame)
    {
      return new FormulaEditorDialog((Frame) windowAncestor);
    }
    else
    {
      return new FormulaEditorDialog();
    }
  }

  protected class SelectionAction extends AbstractAction
  {
    /**
     * Defines an <code>Action</code> object with a default
     * description string and default icon.
     */
    public SelectionAction()
    {
      putValue(Action.NAME, EditorMessages.getInstance().getString("AbstractStringValueCellEditor.SelectValue"));
    }

    /**
     * Invoked when an action occurs.
     */
    public void actionPerformed(final ActionEvent e)
    {
      if (filterEvents)
      {
        return;
      }
      stopCellEditing();
    }
  }

  protected class CancelAction extends AbstractAction
  {
    public CancelAction()
    {
    }

    /**
     * Invoked when an action occurs.
     */
    public void actionPerformed(final ActionEvent e)
    {
      cancelCellEditing();
    }
  }

  protected static final String POPUP_EDITOR = "popupEditor";
  protected static final FieldDefinition[] EMPTY_FIELDS = new FieldDefinition[0];

  private EventListenerList eventListenerList;
  private boolean nullable;

  private JButton ellipsisButton;
  private JComboBox comboBox;
  private transient Object originalValue;
  private volatile boolean filterEvents;
  private boolean formulaFragment;
  private FieldDefinition[] fields;
  private FormulaContext formulaContext;

  public FormulaFragmentCellEditor()
  {
    setLayout(new BorderLayout());

    final Action action = createExtendedEditorAction();

    this.eventListenerList = new EventListenerList();

    ellipsisButton = new EllipsisButton("...");
    ellipsisButton.addActionListener(action);

    comboBox = new JComboBox();
    final ComboBoxEditor boxEditor = comboBox.getEditor();
    if (boxEditor instanceof BasicComboBoxEditor)
    {
      final BasicComboBoxEditor basicComboBoxEditor = (BasicComboBoxEditor) boxEditor;
      final Object editorComponent = basicComboBoxEditor.getEditorComponent();
      if (editorComponent instanceof JTextField)
      {
        final JTextField editorTextField = (JTextField) editorComponent;
        editorTextField.setDocument(new NonFilteringPlainDocument());
      }
    }
    comboBox.setRenderer(new EmptyValueListCellRenderer());
    comboBox.addActionListener(new SelectionAction());
    comboBox.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), new CancelAction());
    comboBox.getInputMap().put(EditorMessages.getInstance().getKeyStroke
        ("AbstractStringValueCellEditor.Popup.Accelerator"), POPUP_EDITOR);
    comboBox.setBorder(BorderFactory.createEmptyBorder());
    comboBox.setEditable(true);

    add(comboBox, BorderLayout.CENTER);
    add(ellipsisButton, BorderLayout.EAST);

    formulaContext = new DefaultFormulaContext();

    nullable = false;
  }

  public boolean isFormulaFragment()
  {
    return formulaFragment;
  }

  public void setFormulaFragment(final boolean formulaFragment)
  {
    this.formulaFragment = formulaFragment;
  }

  public FormulaContext getFormulaContext()
  {
    return formulaContext;
  }

  public void setFormulaContext(final FormulaContext formulaContext)
  {
    this.formulaContext = formulaContext;
  }

  protected Action createExtendedEditorAction()
  {
    return new ExtendedEditorAction();
  }

  public Component getTableCellEditorComponent(final JTable table,
                                               final Object value,
                                               final boolean isSelected,
                                               final int row,
                                               final int column)
  {
    return create(value);
  }

  protected Component create(final Object value)
  {
    try
    {
      filterEvents = true;

      final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
      final FieldDefinition[] definitions = getFields();
      for (int i = 0; i < definitions.length; i++)
      {
        final FieldDefinition fieldDefinition = definitions[i];
        comboBoxModel.addElement("=" + FormulaUtil.quoteReference(fieldDefinition.getName()));
      }
      comboBox.setModel(comboBoxModel);
      comboBox.setRenderer(new EmptyValueListCellRenderer());
      comboBox.setEditable(true);
      add(comboBox, BorderLayout.CENTER);
      add(ellipsisButton, BorderLayout.EAST);
      comboBox.requestFocus();

      if (value == null)
      {
        comboBox.setSelectedItem(null);
      }
      else
      {
        String rawFormulaText;
        if (isFormulaFragment() == false)
        {
          rawFormulaText = FormulaUtil.extractFormula(String.valueOf(value));
        }
        else
        {
          rawFormulaText = String.valueOf(value);
        }

        String formulaText = FormulaUtil.createEditorTextFromFormula(rawFormulaText, formulaContext);
        comboBox.setSelectedItem(formulaText);
      }

      originalValue = value;
      return this;
    }
    finally
    {
      filterEvents = false;
    }
  }

  protected void configureEditorStyle(final Font font, final Color foreground, final Color background)
  {
    comboBox.setFont(font);
    comboBox.setForeground(foreground);
    comboBox.setBackground(background);
  }

  protected JComboBox getComboBox()
  {
    return comboBox;
  }

  protected boolean isNullable()
  {
    return nullable;
  }

  protected void setNullable(final boolean nullable)
  {
    this.nullable = nullable;
  }

  public void requestFocus()
  {
    comboBox.requestFocus();
  }

  protected JButton getEllipsisButton()
  {
    return ellipsisButton;
  }

  /**
   * Returns the value contained in the editor.
   *
   * @return the value contained in the editor
   */
  public Object getCellEditorValue()
  {
    final Object selectedItem = comboBox.getSelectedItem();
    if ("".equals(selectedItem) || selectedItem == null)
    {
      return null;
    }

    String text = String.valueOf(selectedItem);
    if (text.startsWith("'")) {
      text = "=" + FormulaUtil.quoteString(text.substring(1));
    }

    if (isFormulaFragment())
    {
      return FormulaUtil.createFormulaFromUIText(text);
    }
    return text;
  }

  /**
   * Asks the editor if it can start editing using <code>anEvent</code>. <code>anEvent</code> is in the invoking
   * component coordinate system. The editor can not assume the Component returned by
   * <code>getCellEditorComponent</code> is installed.  This method is intended for the use of client to avoid the cost
   * of setting up and installing the editor component if editing is not possible. If editing can be started this method
   * returns true.
   *
   * @param anEvent the event the editor should use to consider whether to begin editing or not
   * @return true if editing can be started
   */
  public boolean isCellEditable(final EventObject anEvent)
  {
    return true;
  }

  /**
   * Returns true if the editing cell should be selected, false otherwise. Typically, the return value is true, because
   * is most cases the editing cell should be selected.  However, it is useful to return false to keep the selection
   * from changing for some types of edits. eg. A table that contains a column of check boxes, the user might want to be
   * able to change those checkboxes without altering the selection.  (See Netscape Communicator for just such an
   * example) Of course, it is up to the client of the editor to use the return value, but it doesn't need to if it
   * doesn't want to.
   *
   * @param anEvent the event the editor should use to start editing
   * @return true if the editor would like the editing cell to be selected; otherwise returns false
   */
  public boolean shouldSelectCell(final EventObject anEvent)
  {
    return true;
  }

  /**
   * Tells the editor to stop editing and accept any partially edited value as the value of the editor.  The editor
   * returns false if editing was not stopped; this is useful for editors that validate and can not accept invalid
   * entries.
   *
   * @return true if editing was stopped; false otherwise
   */
  public boolean stopCellEditing()
  {
    try
    {
      // ugly hack to make the combobox editor commit any changes before we go out of focus.
      comboBox.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, comboBox.getActionCommand()));
      fireEditingStopped();
      return true;
    }
    catch (final Exception e)
    {
      DebugLog.log("Exception caught while editing cell-value", e); // NON-NLS
      // exception ignored
      fireEditingCanceled();
      return true;
    }
  }

  /**
   * Tells the editor to cancel editing and not accept any partially edited value.
   */
  public void cancelCellEditing()
  {
    try
    {
      filterEvents = true;
      comboBox.setSelectedItem(originalValue);
    }
    finally
    {
      filterEvents = false;
    }
    fireEditingCanceled();
  }

  protected void fireEditingCanceled()
  {
    final CellEditorListener[] listeners = eventListenerList.getListeners(CellEditorListener.class);
    final ChangeEvent event = new ChangeEvent(this);
    for (int i = 0; i < listeners.length; i++)
    {
      final CellEditorListener listener = listeners[i];
      listener.editingCanceled(event);
    }
  }

  protected void fireEditingStopped()
  {
    final CellEditorListener[] listeners = eventListenerList.getListeners(CellEditorListener.class);
    final ChangeEvent event = new ChangeEvent(this);
    for (int i = 0; i < listeners.length; i++)
    {
      final CellEditorListener listener = listeners[i];
      listener.editingStopped(event);
    }
  }

  /**
   * Adds a listener to the list that's notified when the editor stops, or cancels editing.
   *
   * @param l the CellEditorListener
   */
  public void addCellEditorListener(final CellEditorListener l)
  {
    eventListenerList.add(CellEditorListener.class, l);
  }

  /**
   * Removes a listener from the list that's notified
   *
   * @param l the CellEditorListener
   */
  public void removeCellEditorListener(final CellEditorListener l)
  {
    eventListenerList.remove(CellEditorListener.class, l);
  }

  public FieldDefinition[] getFields()
  {
    return fields;
  }

  public void setFields(final FieldDefinition[] fields)
  {
    this.fields = fields;
  }
}
TOP

Related Classes of org.pentaho.openformula.ui.table.FormulaFragmentCellEditor$SelectionAction

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.