/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.viewers;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
/**
 * Abstract base class for cell editors. Implements property change listener handling,
 * and SWT window management.
 * <p>
 * Subclasses implement particular kinds of cell editors. This package contains various
 * specialized cell editors:
 * <ul>
 *   <li><code>TextCellEditor</code> - for simple text strings</li>
 *   <li><code>ColorCellEditor</code> - for colors</li>
 *   <li><code>ComboBoxCellEditor</code> - value selected from drop-down combo box</li>
 *   <li><code>CheckboxCellEditor</code> - boolean valued checkbox</li>
 *   <li><code>DialogCellEditor</code> - value from arbitrary dialog</li>
 * </ul>
 * </p>
 */
public abstract class CellEditor {

	/**
	 * List of cell editor listeners (element type: <code>ICellEditorListener</code>).
	 */
	private ListenerList listeners = new ListenerList(3);
	/**
	 * List of cell editor property change listeners 
	 * (element type: <code>IPropertyChangeListener</code>).
	 */
	private ListenerList propertyChangeListeners = new ListenerList(3);
	
	/**
	 * Indicates whether this cell editor's current value is valid.
	 */
	private boolean valid = false;
	
	/**
	 * Optional cell editor validator; <code>null</code> if none.
	 */
	private ICellEditorValidator validator = null;

	/**
	 * The error message string to display for invalid values;
	 * <code>null</code> if none (that is, the value is valid).
	 */
	private String errorMessage = null;
	
	/**
	 * Indicates whether this cell editor has been changed recently.
	 */
	private boolean dirty = false;

	/**
	 * This cell editor's control, or <code>null</code>
	 * if not created yet.
	 */
	private Control control = null;

	/**
	 * Default cell editor style
	 */
	private static final int defaultStyle = SWT.NONE;

	/**
	 * This cell editor's style
	 */
	private int style = defaultStyle;

	/** 
	 * Struct-like layout data for cell editors, with reasonable defaults
	 * for all fields.
	 */	
	public static class LayoutData {
		/**
		 * Horizontal alignment; <code>SWT.LEFT</code> by default.
		 */
		public int horizontalAlignment = SWT.LEFT;

		/**
		 * Indicates control grabs additional space; <code>true</code> by default.
		 */
		public boolean grabHorizontal = true;

		/**
		 * Minimum width in pixels; <code>50</code> pixels by default.
		 */
		public int minimumWidth = 50;
	}

	/**
	 * Property name for the copy action
	 */
	public static final String COPY = "copy"; //$NON-NLS-1$

	/**
	 * Property name for the cut action
	 */
	public static final String CUT = "cut"; //$NON-NLS-1$
	
	/**
	 * Property name for the delete action
	 */
	public static final String DELETE = "delete"; //$NON-NLS-1$

	/**
	 * Property name for the find action
	 */
	public static final String FIND = "find"; //$NON-NLS-1$

	/**
	 * Property name for the paste action
	 */
	public static final String PASTE = "paste"; //$NON-NLS-1$

	/**
	 * Property name for the redo action
	 */
	public static final String REDO = "redo"; //$NON-NLS-1$

	/**
	 * Property name for the select all action
	 */
	public static final String SELECT_ALL = "selectall"; //$NON-NLS-1$

	/**
	 * Property name for the undo action
	 */
	public static final String UNDO = "undo"; //$NON-NLS-1$

/**
 * Creates a new cell editor with no control 
 * The cell editor has no cell validator.
 * @since 2.1
 */
protected CellEditor() {
}
/**
 * Creates a new cell editor under the given parent control.
 * The cell editor has no cell validator.
 *
 * @param parent the parent control
 */
protected CellEditor(Composite parent) {
	this(parent, defaultStyle);
}
/**
 * Creates a new cell editor under the given parent control.
 * The cell editor has no cell validator.
 *
 * @param parent the parent control
 * @param style the style bits
 * @since 2.1
 */
protected CellEditor(Composite parent, int style) {
	this.style = style;
	create(parent);
}
/**
 * Activates this cell editor.
 * <p>
 * The default implementation of this framework method
 * does nothing. Subclasses may reimplement.
 * </p>
 */
public void activate() {
}
/**
 * Adds a listener to this cell editor.
 * Has no effect if an identical listener is already registered.
 *
 * @param listener a cell editor listener
 */
public void addListener(ICellEditorListener listener) {
	listeners.add(listener);
}
/**
 * Adds a property change listener to this cell editor.
 * Has no effect if an identical property change listener 
 * is already registered.
 *
 * @param listener a property change listener
 */
public void addPropertyChangeListener(IPropertyChangeListener listener) {
	propertyChangeListeners.add(listener);
}
/**
 * Creates the control for this cell editor under the given parent control.
 * <p>
 * This framework method must be implemented by concrete
 * subclasses.
 * </p>
 *
 * @param parent the parent control
 * @return the new control, or <code>null</code> if this cell editor has no control
 */
protected abstract Control createControl(Composite parent);
/**
 * Creates the control for this cell editor under the given parent control.
 * 
 * @param parent the parent control
 * @since 2.1
 */
public void create(Composite parent) {
	Assert.isTrue(control==null);
	control = createControl(parent);
	// See 1GD5CA6: ITPUI:ALL - TaskView.setSelection does not work
	// Control is created with isVisible()==true by default.
	// This causes composite.setFocus() to work incorrectly.
	// The cell editor's control grabs focus instead, even if it is not active.
	// Make the control invisible here by default.
	deactivate();
}
/**
 * Hides this cell editor's control. Does nothing if this 
 * cell editor is not visible.
 */
public void deactivate() {
	if (control != null && !control.isDisposed())
		control.setVisible(false);
}
/**
 * Disposes of this cell editor and frees any associated SWT resources.
 */
public void dispose() {
	if (control != null && !control.isDisposed()) {
		control.dispose();
	}
	control = null;
}
/**
 * Returns this cell editor's value.
 * <p>
 * This framework method must be implemented by concrete subclasses.
 * </p>
 *
 * @return the value of this cell editor
 * @see #getValue
 */
protected abstract Object doGetValue();
/**
 * Sets the focus to the cell editor's control.
 * <p>
 * This framework method must be implemented by concrete subclasses.
 * </p>
 *
 * @see #setFocus
 */
protected abstract void doSetFocus();
/**
 * Sets this cell editor's value.
 * <p>
 * This framework method must be implemented by concrete subclasses.
 * </p>
 *
 * @param value the value of this cell editor
 * @see #setValue
 */
protected abstract void doSetValue(Object value);
/**
 * Notifies all registered cell editor listeners of an apply event.
 * Only listeners registered at the time this method is called are notified.
 *
 * @see ICellEditorListener#applyEditorValue
 */
protected void fireApplyEditorValue() {
	Object[] array = listeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final ICellEditorListener l = (ICellEditorListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.applyEditorValue();
			}
		});
	}	
}
/**
 * Notifies all registered cell editor listeners that editing has been
 * canceled.
 *
 * @see ICellEditorListener#cancelEditor
 */
protected void fireCancelEditor() {
	Object[] array = listeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final ICellEditorListener l = (ICellEditorListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.cancelEditor();
			}
		});
	}	
}
/**
 * Notifies all registered cell editor listeners of a value change.
 *
 * @param oldValidState the valid state before the end user changed the value
 * @param newValidState the current valid state
 * @see ICellEditorListener#editorValueChanged
 */
protected void fireEditorValueChanged(final boolean oldValidState, final boolean newValidState) {
	Object[] array = listeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final ICellEditorListener l = (ICellEditorListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.editorValueChanged(oldValidState, newValidState);
			}
		});
	}	
}
/**
 * Notifies all registered property listeners
 * of an enablement change.
 *
 * @param actionId the id indicating what action's enablement has changed.
 */
protected void fireEnablementChanged(final String actionId) {
	Object[] array = propertyChangeListeners.getListeners();
	for (int i = 0; i < array.length; i ++) {
		final IPropertyChangeListener l = (IPropertyChangeListener)array[i];
		Platform.run(new SafeRunnable() {
			public void run() {
				l.propertyChange(new PropertyChangeEvent(this, actionId, null, null));
			}
		});
	}	
}
/**
 * Sets the style bits for this cell editor.
 * 
 * @param style the SWT style bits for this cell editor
 * @since 2.1
 */
public void setStyle(int style) {
	this.style = style;
}

/**
 * Returns the style bits for this cell editor.
 *
 * @return the style for this cell editor
 * @since 2.1
 */
public int getStyle() {
	return style;
}
/**
 * Returns the control used to implement this cell editor.
 *
 * @return the control, or <code>null</code> if this cell editor has no control
 */
public Control getControl() {
	return control;
}
/**
 * Returns the current error message for this cell editor.
 * 
 * @return the error message if the cell editor is in an invalid state,
 *  and <code>null</code> if the cell editor is valid
 */
public String getErrorMessage() {
	return errorMessage;
}
/**
 * Returns a layout data object for this cell editor.
 * This is called each time the cell editor is activated
 * and controls the layout of the SWT table editor.
 * <p>
 * The default implementation of this method sets the 
 * minimum width to the control's preferred width.
 * Subclasses may extend or reimplement.
 * </p>
 *
 * @return the layout data object 
 */
public LayoutData getLayoutData() {
	LayoutData result = new LayoutData();
	Control control = getControl();
	if (control != null) {
		result.minimumWidth = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
	}
	return result;
}
/**
 * Returns the input validator for this cell editor.
 *
 * @return the input validator, or <code>null</code> if none
 */
public ICellEditorValidator getValidator() {
	return validator;
}
/**
 * Returns this cell editor's value provided that it has a valid one.
 *
 * @return the value of this cell editor, or <code>null</code>
 *   if the cell editor does not contain a valid value
 */
public final Object getValue() {
	if (!valid)
		return null;

	return doGetValue();
}
/**
 * Returns whether this cell editor is activated.
 *
 * @return <code>true</code> if this cell editor's control is
 *   currently visible, and <code>false</code> if not visible
 */
public boolean isActivated() {
	return control != null && control.isVisible();
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the copy action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if copy is possible,
 *  <code>false</code> otherwise
 */
public boolean isCopyEnabled() {
	return false;
}
/**
 * Returns whether the given value is valid for this cell editor.
 * This cell editor's validator (if any) makes the actual determination.
 *
 * @return <code>true</code> if the value is valid, and <code>false</code>
 *  if invalid
 */
protected boolean isCorrect(Object value) {
	errorMessage = null;
	if (validator == null)
		return true;

	errorMessage = validator.isValid(value);
	return (errorMessage == null || errorMessage.equals(""));//$NON-NLS-1$
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the cut action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if cut is possible,
 *  <code>false</code> otherwise
 */
public boolean isCutEnabled() {
	return false;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the delete action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if delete is possible,
 *  <code>false</code> otherwise
 */
public boolean isDeleteEnabled() {
	return false;
}
/**
 * Returns whether the value of this cell editor has changed since the
 * last call to <code>setValue</code>.
 *
 * @return <code>true</code> if the value has changed, and <code>false</code>
 *  if unchanged
 */
public boolean isDirty() {
	return dirty;
}
/**
 * Marks this cell editor as dirty.
 * @since 2.1
 */
protected void markDirty() {
	dirty = true;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the find action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if find is possible,
 *  <code>false</code> otherwise
 */
public boolean isFindEnabled() {
	return false;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the paste action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if paste is possible,
 *  <code>false</code> otherwise
 */
public boolean isPasteEnabled() {
	return false;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the redo action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if redo is possible,
 *  <code>false</code> otherwise
 */
public boolean isRedoEnabled() {
	return false;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the select all action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if select all is possible,
 *  <code>false</code> otherwise
 */
public boolean isSelectAllEnabled() {
	return false;
}
/**
 * Returns <code>true</code> if this cell editor is
 * able to perform the undo action.
 * <p>
 * This default implementation always returns 
 * <code>false</code>.
 * </p>
 * <p>
 * Subclasses may override
 * </p>
 * @return <code>true</code> if undo is possible,
 *  <code>false</code> otherwise
 */
public boolean isUndoEnabled() {
	return false;
}
/**
 * Returns whether this cell editor has a valid value.
 * The default value is false.
 *
 * @return <code>true</code> if the value is valid, and <code>false</code>
 *  if invalid
 *
 * @see #setValueValid
 */
public boolean isValueValid() {
	return valid;
}
/**
 * Processes a key release event that occurred in this cell editor.
 * <p>
 * The default implementation of this framework method cancels editing
 * when the ESC key is pressed.  When the RETURN key is pressed the current
 * value is applied and the cell editor deactivates.
 * Subclasses should call this method at appropriate times. 
 * Subclasses may also extend or reimplement.
 * </p>
 *
 * @param keyEvent the key event
 */
protected void keyReleaseOccured(KeyEvent keyEvent) {
	if (keyEvent.character == '\u001b') { // Escape character
		fireCancelEditor();
	} else if (keyEvent.character == '\r') { // Return key
		fireApplyEditorValue();
		deactivate();
	}
}
/**
 * Processes a focus lost event that occurred in this cell editor.
 * <p>
 * The default implementation of this framework method applies the current
 * value and deactivates the cell editor.
 * Subclasses should call this method at appropriate times. 
 * Subclasses may also extend or reimplement.
 * </p>
 */
protected void focusLost() {
	if (isActivated()) {
		fireApplyEditorValue();
		deactivate();
	}
}
/**
 * Performs the copy action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performCopy() {
}
/**
 * Performs the cut action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performCut() {
}
/**
 * Performs the delete action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performDelete() {
}
/**
 * Performs the find action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performFind() {
}
/**
 * Performs the paste action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performPaste() {
}
/**
 * Performs the redo action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performRedo() {
}
/**
 * Performs the select all action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performSelectAll() {
}
/**
 * Performs the undo action.
 * This default implementation does nothing.
 * <p>
 * Subclasses may override
 * </p>
 */
public void performUndo() {
}
/**
 * Removes the given listener from this cell editor.
 * Has no affect if an identical listener is not registered.
 *
 * @param listener a cell editor listener
 */
public void removeListener(ICellEditorListener listener) {
	listeners.remove(listener);
}
/**
 * Removes the given property change listener from this cell editor.
 * Has no affect if an identical property change listener is not 
 * registered.
 *
 * @param listener a property change listener
 */
public void removePropertyChangeListener(IPropertyChangeListener listener) {
	propertyChangeListeners.remove(listener);
}
/**
 * Sets or clears the current error message for this cell editor.
 * 
 * @param message the error message, or <code>null</code> to clear
 */
protected void setErrorMessage(String message) {
	errorMessage = message;
}
/**
 * Sets the focus to the cell editor's control.
 */
public void setFocus() {
	doSetFocus();
}
/**
 * Sets the input validator for this cell editor.
 *
 * @param validator the input validator, or <code>null</code> if none
 */
public void setValidator(ICellEditorValidator validator) {
	this.validator = validator;
}
/**
 * Sets this cell editor's value.
 *
 * @param value the value of this cell editor
 */
public final void setValue(Object value) {
	valid = isCorrect(value);
	dirty = false;
	doSetValue(value);
}
/**
 * Sets the valid state of this cell editor.
 * The default value is false.
 * Subclasses should call this method on construction.
 *
 * @param valid <code>true</code> if the current valie is valid,
 *  and <code>false</code> if invalid
 *
 * @see #isValueValid
 */
protected void setValueValid(boolean valid) {
	this.valid = valid;
}
/**
 * The value has changed.  
 * Updates the valid state flag, marks this cell editor as dirty,
 * and notifies all registered cell editor listeners of a value change.
 *
 * @param oldValidState the valid state before the end user changed the value
 * @param newValidState the current valid state
 * @see ICellEditorListener#editorValueChanged
 */
protected void valueChanged(boolean oldValidState, boolean newValidState) {
	valid = newValidState;
	dirty = true;
	fireEditorValueChanged(oldValidState, newValidState);
}
}
