Package net.sf.commonclipse.preferences

Source Code of net.sf.commonclipse.preferences.ComboFieldEditor

/* ====================================================================
*   Copyright 2003-2004 Fabrizio Giustina.
*
*   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 net.sf.commonclipse.preferences;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;


/**
* Implementation identical to StringFieldEditor but using a combo instead of a Text field.
* @author fgiust
* @version $Revision: 1.4 $ ($Author: fgiust $)
*/
public class ComboFieldEditor extends FieldEditor
{

    /**
     * Text limit constant (value <code>-1</code>) indicating unlimited text limit and width.
     */
    public static final int UNLIMITED = -1;

    /**
     * The text field, or <code>null</code> if none.
     */
    Combo textField;

    /**
     * predefined values to be shown in list.
     */
    private String[] predefinedValues;

    /**
     * Cached valid state.
     */
    private boolean isValid;

    /**
     * Old text value.
     */
    private String oldValue;

    /**
     * Width of text field in characters; initially unlimited.
     */
    private int widthInChars = UNLIMITED;

    /**
     * Text limit of text field in characters; initially unlimited.
     */
    private int textLimit = UNLIMITED;

    /**
     * The error message, or <code>null</code> if none.
     */
    private String errorMessage;

    /**
     * Indicates whether the empty string is legal; <code>true</code> by default.
     */
    private boolean emptyStringAllowed = true;

    /**
     * Creates a new string field editor.
     */
    protected ComboFieldEditor()
    {
    }

    /**
     * Creates a string field editor. Use the method <code>setTextLimit</code> to limit the text.
     * @param name the name of the preference this field editor works on
     * @param labelText the label text of the field editor
     * @param width the width of the text input field in characters, or <code>UNLIMITED</code> for no limit
     * @param parent the parent of the field editor's control
     */
    public ComboFieldEditor(String name, String labelText, int width, Composite parent)
    {
        init(name, labelText);
        this.widthInChars = width;
        this.isValid = false;
        this.errorMessage = JFaceResources.getString("StringFieldEditor.errorMessage"); //$NON-NLS-1$
        createControl(parent);
    }

    /**
     * Creates a string field editor of unlimited width. Use the method <code>setTextLimit</code> to limit the text.
     * @param name the name of the preference this field editor works on
     * @param labelText the label text of the field editor
     * @param parent the parent of the field editor's control
     */
    public ComboFieldEditor(String name, String labelText, Composite parent)
    {
        this(name, labelText, UNLIMITED, parent);
    }

    /**
     * Checks whether the text input field contains a valid value or not.
     * @return <code>true</code> if the field value is valid, and <code>false</code> if invalid
     */
    protected boolean checkState()
    {
        boolean result = false;
        if (this.emptyStringAllowed)
        {
            result = true;
        }

        if (this.textField == null)
        {
            result = false;
        }

        String txt = this.textField.getText();

        if (txt == null)
        {
            result = false;
        }

        result = (txt.trim().length() > 0) || this.emptyStringAllowed;

        // call hook for subclasses
        result = result && doCheckState();

        if (result)
        {
            clearErrorMessage();
        }
        else
        {
            showErrorMessage(this.errorMessage);
        }

        return result;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doLoad()
     */
    protected void doLoad()
    {
        if (this.textField != null)
        {

            addDefaultOptions();
            String value = getPreferenceStore().getString(getPreferenceName());
            this.textField.setText(value);
            this.oldValue = value;

        }
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault()
     */
    protected void doLoadDefault()
    {
        if (this.textField != null)
        {
            addDefaultOptions();
            String value = getPreferenceStore().getDefaultString(getPreferenceName());
            this.textField.setText(value);

        }
        valueChanged();
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doStore()
     */
    protected void doStore()
    {
        getPreferenceStore().setValue(getPreferenceName(), this.textField.getText());
    }

    /**
     * Returns the error message that will be displayed when and if an error occurs.
     * @return the error message, or <code>null</code> if none
     */
    public String getErrorMessage()
    {
        return this.errorMessage;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls()
     */
    public int getNumberOfControls()
    {
        return 2;
    }

    /**
     * Returns the field editor's value.
     * @return the current value
     */
    public String getStringValue()
    {
        if (this.textField != null)
        {
            return this.textField.getText();
        }
        return getPreferenceStore().getString(getPreferenceName());
    }

    /**
     * Returns this field editor's text control.
     * @return the text control, or <code>null</code> if no text field is created yet
     */
    protected Combo getTextControl()
    {
        return this.textField;
    }

    /**
     * Returns this field editor's text control.
     * <p>
     * The control is created if it does not yet exist
     * </p>
     * @param parent the parent
     * @return the text control
     */
    public Combo getTextControl(Composite parent)
    {
        if (this.textField == null)
        {
            this.textField = new Combo(parent, SWT.SINGLE | SWT.BORDER);

            this.textField.setFont(parent.getFont());

            this.textField.addKeyListener(new KeyAdapter()
            {

                public void keyReleased(KeyEvent e)
                {
                    valueChanged();
                }
            });
            this.textField.addSelectionListener(new SelectionListener()
            {

                public void widgetSelected(SelectionEvent e)
                {
                    valueChanged();
                }

                public void widgetDefaultSelected(SelectionEvent e)
                {
                    valueChanged();
                }

            });
            this.textField.addFocusListener(new FocusAdapter()
            {

                public void focusGained(FocusEvent e)
                {
                    refreshValidState();
                }

                public void focusLost(FocusEvent e)
                {
                    valueChanged();
                    clearErrorMessage();
                }
            });

            this.textField.addDisposeListener(new DisposeListener()
            {

                public void widgetDisposed(DisposeEvent event)
                {
                    ComboFieldEditor.this.textField = null;
                }
            });
            if (this.textLimit > 0)
            { // Only set limits above 0 - see SWT spec
                this.textField.setTextLimit(this.textLimit);
            }
        }
        else
        {
            checkParent(this.textField, parent);
        }
        return this.textField;
    }

    /**
     * Returns whether an empty string is a valid value.
     * @return <code>true</code> if an empty string is a valid value, and <code>false</code> if an empty string is
     * invalid
     * @see #setEmptyStringAllowed
     */
    public boolean isEmptyStringAllowed()
    {
        return this.emptyStringAllowed;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor # isValid()
     */
    public boolean isValid()
    {
        return this.isValid;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#refreshValidState()
     */
    protected void refreshValidState()
    {
        this.isValid = checkState();
    }

    /**
     * Sets whether the empty string is a valid value or not.
     * @param b <code>true</code> if the empty string is allowed, and <code>false</code> if it is considered invalid
     */
    public void setEmptyStringAllowed(boolean b)
    {
        this.emptyStringAllowed = b;
    }

    /**
     * Sets the error message that will be displayed when and if an error occurs.
     * @param message the error message
     */
    public void setErrorMessage(String message)
    {
        this.errorMessage = message;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#setFocus()
     */
    public void setFocus()
    {
        if (this.textField != null)
        {
            this.textField.setFocus();
        }
    }

    /**
     * Sets this field editor's value.
     * @param value the new value, or <code>null</code> meaning the empty string
     */
    public void setStringValue(String value)
    {
        if (this.textField != null)
        {
            String newValue = value;
            if (newValue == null)
            {
                newValue = ""; //$NON-NLS-1$
            }

            this.oldValue = this.textField.getText();

            if (!this.oldValue.equals(newValue))
            {
                this.textField.setText(newValue);

                valueChanged();
            }
        }
    }

    /**
     * Sets this text field's text limit.
     * @param limit the limit on the number of character in the text input field, or <code>UNLIMITED</code> for no
     * limit
     */
    public void setTextLimit(int limit)
    {
        this.textLimit = limit;
        if (this.textField != null)
        {
            this.textField.setTextLimit(limit);
        }
    }

    /**
     * Shows the error message set via <code>setErrorMessage</code>.
     */
    public void showErrorMessage()
    {
        showErrorMessage(this.errorMessage);
    }

    /**
     * Informs this field editor's listener, if it has one, about a change to the value (<code>VALUE</code> property)
     * provided that the old and new values are different.
     * <p>
     * This hook is <em>not</em> called when the text is initialized (or reset to the default value) from the
     * preference store.
     * </p>
     */
    protected void valueChanged()
    {
        setPresentsDefaultValue(false);
        boolean oldState = this.isValid;
        refreshValidState();

        if (this.isValid != oldState)
        {
            fireStateChanged(IS_VALID, oldState, this.isValid);
        }

        String newValue = this.textField.getText();
        if (!newValue.equals(this.oldValue))
        {
            fireValueChanged(VALUE, this.oldValue, newValue);
            this.oldValue = newValue;
        }
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean,Composite).
     */
    public void setEnabled(boolean enabled, Composite parent)
    {
        super.setEnabled(enabled, parent);
        getTextControl(parent).setEnabled(enabled);
    }

    /**
     * Hook for subclasses to do specific state checks.
     * <p>
     * The default implementation of this framework method does nothing and returns <code>true</code>. Subclasses
     * should override this method to specific state checks.
     * </p>
     * @return <code>true</code> if the field value is valid, and <code>false</code> if invalid
     */
    protected boolean doCheckState()
    {
        return true;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int)
     */
    protected void adjustForNumColumns(int numColumns)
    {
        GridData gd = (GridData) this.textField.getLayoutData();
        gd.horizontalSpan = numColumns - 1;
        // We only grab excess space if we have to
        // If another field editor has more columns then
        // we assume it is setting the width.
        gd.grabExcessHorizontalSpace = gd.horizontalSpan == 1;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(Composite, int)
     */
    protected void doFillIntoGrid(Composite parent, int numColumns)
    {
        getLabelControl(parent);

        this.textField = getTextControl(parent);
        GridData gd = new GridData();
        gd.horizontalSpan = numColumns - 1;
        if (this.widthInChars != UNLIMITED)
        {
            GC gc = new GC(this.textField);
            try
            {
                Point extent = gc.textExtent("X"); //$NON-NLS-1$
                gd.widthHint = this.widthInChars * extent.x;
            }
            finally
            {
                gc.dispose();
            }
        }
        else
        {
            gd.horizontalAlignment = GridData.FILL;
            gd.grabExcessHorizontalSpace = true;
        }
        this.textField.setLayoutData(gd);
    }

    /**
     * Sets a list of predefined values that must be shown in the combo.
     * @param strings array of Strings added to the combo
     */
    public void setPredefinedValues(String[] strings)
    {
        this.predefinedValues = strings;
    }

    /**
     * Adds predefined options to the combo.
     */
    private void addDefaultOptions()
    {
        if (this.textField != null && this.predefinedValues != null)
        {
            this.textField.setItems(this.predefinedValues);
        }
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#clearErrorMessage()
     */
    protected void clearErrorMessage()
    {
        super.clearErrorMessage();
    }

}
TOP

Related Classes of net.sf.commonclipse.preferences.ComboFieldEditor

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.