changeset 110:a26bb7394581

Add two field editor from the CDT project, thanks yidabu for the port.
author Frank Benoit <benoit@tionex.de>
date Thu, 07 Aug 2008 17:37:04 +0200
parents 8ab6fb387666
children c0489adc02b9
files dwtx/cdt/managedbuilder/ui/properties/MultiLineTextFieldEditor.d dwtx/cdt/managedbuilder/ui/properties/PasswordFieldEditor.d
diffstat 2 files changed, 736 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/cdt/managedbuilder/ui/properties/MultiLineTextFieldEditor.d	Thu Aug 07 17:37:04 2008 +0200
@@ -0,0 +1,562 @@
+/**********************************************************************
+ * Copyright (c) 2004 BitMethods Inc and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * BitMethods Inc - Initial API and implementation
+ * Ported to the D programming language
+ *     yidabu ( D Programming Language China : http://www.d-programming-language-china.org/ )
+ ***********************************************************************/
+module dwtx.cdt.managedbuilder.ui.properties.MultiLineTextFieldEditor;
+
+//import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages;
+import dwtx.jface.preference.FieldEditor;
+import dwtx.jface.util.Assert;
+import dwt.DWT;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusAdapter;
+import dwt.events.FocusEvent;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.layout.GridData;
+import dwt.widgets.Composite;
+import dwt.widgets.Label;
+import dwt.widgets.Text;
+
+import dwt.dwthelper.utils;
+
+/**
+ *  MultiLineTextFieldEditor.
+ *  Field editor that is same as string field editor but
+ *  will have the multi line text field for user input.
+ */
+public class MultiLineTextFieldEditor : FieldEditor {
+
+    alias FieldEditor.showErrorMessage showErrorMessage;
+    private static final String ERROR_MESSAGE = "Multiline.error.message";  //$NON-NLS-1$
+    private static final String ERROR_MESSAGE_CONST = "Please give correct input";  //$NON-NLS-1$
+
+    /**
+     * Validation strategy constant (value <code>0</code>) indicating that
+     * the editor should perform validation after every key stroke.
+     *
+     * @see #setValidateStrategy
+     */
+    public static const int VALIDATE_ON_KEY_STROKE = 0;
+
+    /**
+     * Validation strategy constant (value <code>1</code>) indicating that
+     * the editor should perform validation only when the text widget
+     * loses focus.
+     *
+     * @see #setValidateStrategy
+     */
+    public static const int VALIDATE_ON_FOCUS_LOST = 1;
+
+    /**
+     * Text limit constant (value <code>-1</code>) indicating unlimited
+     * text limit and width.
+     */
+    public static int UNLIMITED = -1;
+
+    /**
+     * Cached valid state.
+     */
+    private bool isValid_;
+
+    /**
+     * Old text value.
+     */
+    private String oldValue;
+    private String compTitle;
+    private Label title;
+
+    /**
+     * The text field, or <code>null</code> if none.
+     */
+    private Text textField;
+
+    /**
+     * Width of text field in characters; initially unlimited.
+     */
+    private int widthInChars;
+
+    /**
+     * Text limit of text field in characters; initially unlimited.
+     */
+    private int textLimit;
+
+    /**
+     * 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 bool emptyStringAllowed = true;
+
+    /**
+     * The validation strategy;
+     * <code>VALIDATE_ON_KEY_STROKE</code> by default.
+     */
+    private int validateStrategy;
+    /**
+     * Creates a new string field editor
+     */
+    protected this() {
+        widthInChars = UNLIMITED;
+        textLimit = UNLIMITED;
+        validateStrategy = VALIDATE_ON_KEY_STROKE;
+    }
+    /**
+     * 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 strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+     *  on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+     *  perform validation only after the text has been typed in
+     * @param parent the parent of the field editor's control
+     * @since 2.0
+     */
+    public this(
+        String name,
+        String labelText,
+        int width,
+        int strategy,
+        Composite parent) {
+        this();
+        init(name, labelText);
+        widthInChars = width;
+        setValidateStrategy(strategy);
+        isValid_ = false;
+        //errorMessage = ManagedBuilderUIMessages.getResourceString(ERROR_MESSAGE);
+        errorMessage = ERROR_MESSAGE_CONST;
+        createControl(parent);
+    }
+
+    /**
+     * 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 this(String name, String labelText, int width, Composite parent) {
+        this(name, labelText, width, VALIDATE_ON_KEY_STROKE, parent);
+        this.compTitle = labelText;
+    }
+    /**
+     * 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 this(String name, String labelText, Composite parent) {
+        this(name, labelText, UNLIMITED, parent);
+    }
+
+    /**
+     * Adjusts the horizontal span of this field editor's basic controls
+     * <p>
+     * Subclasses must implement this method to adjust the horizontal span
+     * of controls so they appear correct in the given number of columns.
+     * </p>
+     * <p>
+     * The number of columns will always be equal to or greater than the
+     * value returned by this editor's <code>getNumberOfControls</code> method.
+     *
+     * @param numColumns the number of columns
+     */
+    protected void adjustForNumColumns(int numColumns) {
+        GridData gd = cast(GridData) 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;
+    }
+    /**
+     * 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 bool checkState() {
+        bool result = false;
+        if (emptyStringAllowed)
+            result = true;
+
+        if (textField is null)
+            result = false;
+
+        String txt = textField.getText();
+
+        if (txt is null)
+            result = false;
+
+        result = (txt.trim().length > 0) || emptyStringAllowed;
+
+        // call hook for subclasses
+        result = result && doCheckState();
+
+        if (result)
+            clearErrorMessage();
+        else
+            showErrorMessage(errorMessage);
+
+        return result;
+    }
+    /**
+     * 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 bool doCheckState() {
+        return true;
+    }
+    /**
+     * Fills this field editor's basic controls into the given parent.
+     * <p>
+     * The string field implementation of this <code>FieldEditor</code>
+     * framework method contributes the text field. Subclasses may override
+     * but must call <code>super.doFillIntoGrid</code>.
+     * </p>
+     */
+    protected void doFillIntoGrid(Composite parent, int numColumns) {
+
+        title = new Label(parent, DWT.UP);
+        title.setFont(parent.getFont());
+        this.compTitle = getLabelText();
+        title.setText(this.compTitle);
+        title.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+        textField = getTextControl(parent);
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.widthHint = 100;
+        gd.heightHint = 70;
+        textField.setLayoutData(gd);
+
+    }
+
+    /**
+     * Initializes this field editor with the preference value from
+     * the preference store.
+     * <p>
+     * Subclasses must implement this method to properly initialize
+     * the field editor.
+     * </p>
+     */
+    protected void doLoad() {
+        if (textField !is null) {
+            String value = getPreferenceStore().getString(getPreferenceName());
+            textField.setText(value);
+            oldValue = value;
+        }
+    }
+
+    /**
+     * Initializes this field editor with the default preference value from
+     * the preference store.
+     * <p>
+     * Subclasses must implement this method to properly initialize
+     * the field editor.
+     * </p>
+     */
+    protected void doLoadDefault() {
+        if (textField !is null) {
+            String value =
+                getPreferenceStore().getDefaultString(getPreferenceName());
+            textField.setText(value);
+        }
+        valueChanged();
+    }
+
+    /* (non-Javadoc)
+     * @see dwtx.jface.preference.FieldEditor#doStore()
+     */
+    protected void doStore() {
+        getPreferenceStore().setValue(getPreferenceName(), 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 errorMessage;
+    }
+    /**
+        * Returns the number of basic controls this field editor consists of.
+        *
+        * @return the number of controls
+        */
+    public int getNumberOfControls() {
+        return 2;
+    }
+    /**
+     * Returns the field editor's value.
+     *
+     * @return the current value
+     */
+    public String getStringValue() {
+        if (textField !is null)
+            return textField.getText();
+        else
+            return getPreferenceStore().getString(getPreferenceName());
+    }
+
+    /**
+     * Returns this field editor's text control.
+     *
+     * @param parent the parent
+     * @return the text control, or <code>null</code> if no
+     * text field is created yet
+     */
+    protected Text getTextControl() {
+        return 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 Text getTextControl(Composite parent) {
+        if (textField is null) {
+            textField =
+                new Text(
+                    parent,
+                    DWT.MULTI | DWT.V_SCROLL | DWT.BORDER | DWT.WRAP);
+            textField.setFont(parent.getFont());
+            switch (validateStrategy) {
+                case VALIDATE_ON_KEY_STROKE :
+                    textField.addKeyListener(new class() KeyAdapter {
+                        public void keyPressed(KeyEvent e) {
+                            valueChanged();
+                        }
+                    });
+
+                    textField.addFocusListener(new class() FocusAdapter {
+                        public void focusGained(FocusEvent e) {
+                            refreshValidState();
+                        }
+                        public void focusLost(FocusEvent e) {
+                            clearErrorMessage();
+                        }
+                    });
+                    break;
+                case VALIDATE_ON_FOCUS_LOST :
+                    textField.addKeyListener(new class() KeyAdapter {
+                        public void keyPressed(KeyEvent e) {
+                            clearErrorMessage();
+                        }
+                    });
+                    textField.addFocusListener(new class() FocusAdapter {
+                        public void focusGained(FocusEvent e) {
+                            refreshValidState();
+                        }
+                        public void focusLost(FocusEvent e) {
+                            valueChanged();
+                            clearErrorMessage();
+                        }
+                    });
+                    break;
+                default :
+                    Assert.isTrue(false, "Unknown validate strategy"); //$NON-NLS-1$
+            }
+            textField.addDisposeListener(new class() DisposeListener {
+                public void widgetDisposed(DisposeEvent event) {
+                    textField = null;
+                }
+            });
+            if (textLimit > 0) { //Only set limits above 0 - see SWT spec
+                textField.setTextLimit(textLimit);
+            }
+        } else {
+            checkParent(textField, parent);
+        }
+        return 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 bool isEmptyStringAllowed() {
+        return emptyStringAllowed;
+    }
+
+    /**
+     * Returns whether this field editor contains a valid value.
+     * <p>
+     * The default implementation of this framework method
+     * returns <code>true</code>. Subclasses wishing to perform
+     * validation should override both this method and
+     * <code>refreshValidState</code>.
+     * </p>
+     *
+     * @return <code>true</code> if the field value is valid,
+     * and <code>false</code> if invalid
+     * @see #refreshValidState
+     */
+    public bool isValid() {
+        return isValid_;
+    }
+
+    /**
+     * Refreshes this field editor's valid state after a value change
+     * and fires an <code>IS_VALID</code> property change event if
+     * warranted.
+     * <p>
+     * The default implementation of this framework method does
+     * nothing. Subclasses wishing to perform validation should override
+     * both this method and <code>isValid_</code>.
+     * </p>
+     * @see #isValid_
+     */
+    protected void refreshValidState() {
+        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(bool b) {
+        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) {
+        errorMessage = message;
+    }
+
+    /**
+     * Sets the focus to this field editor.
+     * <p>
+     * The default implementation of this framework method
+     * does nothing. Subclasses may reimplement.
+     * </p>
+    */
+    public void setFocus() {
+        if (textField !is null) {
+            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 (textField !is null) {
+            if (value is null)
+                value = ""; //$NON-NLS-1$
+            oldValue = textField.getText();
+            if (!oldValue.equals(value)) {
+                textField.setText(value);
+                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) {
+        textLimit = limit;
+        if (textField !is null)
+            textField.setTextLimit(limit);
+    }
+
+    /**
+     * Sets the strategy for validating the text.
+     * <p>
+     * Calling this method has no effect after <code>createPartControl</code>
+     * is called. Thus this method is really only useful for subclasses to call
+     * in their constructor. However, it has public visibility for backward
+     * compatibility.
+     * </p>
+     *
+     * @param value either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+     *  on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+     *  perform validation only after the text has been typed in
+     */
+    public void setValidateStrategy(int value) {
+        Assert.isTrue(
+            value == VALIDATE_ON_FOCUS_LOST || value == VALIDATE_ON_KEY_STROKE);
+        validateStrategy = value;
+    }
+
+    /**
+     * Shows the error message set via <code>setErrorMessage</code>.
+     */
+    public void showErrorMessage() {
+        showErrorMessage(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);
+        bool oldState = isValid_;
+        refreshValidState();
+
+        if (isValid_ !is oldState)
+            fireStateChanged(IS_VALID, oldState, isValid_);
+
+        String newValue = textField.getText();
+        if (!newValue.equals(oldValue)) {
+            fireValueChanged(VALUE, stringcast(oldValue), stringcast(newValue));
+            oldValue = newValue;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/cdt/managedbuilder/ui/properties/PasswordFieldEditor.d	Thu Aug 07 17:37:04 2008 +0200
@@ -0,0 +1,174 @@
+/**********************************************************************
+ * Copyright (c) 2004 BitMethods Inc and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ *
+ * Contributors:
+ * BitMethods Inc - Initial API and implementation
+ * Ported to the D programming language
+ *     yidabu ( D Programming Language China : http://www.d-programming-language-china.org/ )
+ ***********************************************************************/
+module dwtx.cdt.managedbuilder.ui.properties.PasswordFieldEditor;
+
+/// https://bugs.eclipse.org/bugs/attachment.cgi?id=33204
+/// https://bugs.eclipse.org/bugs/show_bug.cgi?id=23495
+
+import dwtx.jface.util.Assert;
+import dwt.DWT;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusAdapter;
+import dwt.events.FocusEvent;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.widgets.Composite;
+import dwt.widgets.Text;
+
+import dwt.dwthelper.utils;
+import dwtx.jface.preference.StringFieldEditor;
+
+/**
+ * A field editor for a password type preference. This is essentially
+ * a StringFieldEditor, but will replace each character in the input
+ * box with an '*'.
+ * <p>
+ * This class may be used as is, or subclassed as required.
+ * </p>
+ */
+public class PasswordFieldEditor : StringFieldEditor {
+
+    /**
+     * The validation strategy;
+     * <code>VALIDATE_ON_KEY_STROKE</code> by default.
+     */
+    private int validateStrategy;
+
+    /**
+     * Text limit of text field in characters; initially unlimited.
+     */
+    private int textLimit;
+
+    /**
+     * The text field, or <code>null</code> if none.
+     */
+    Text textField;
+
+    /**
+     * Creates a new password field editor
+     */
+    protected this() {
+        //widthInChars = UNLIMITED;
+        textLimit = UNLIMITED;
+        validateStrategy = VALIDATE_ON_KEY_STROKE;
+    }
+
+    /**
+     * Creates a password 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 strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
+     *  on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
+     *  perform validation only after the text has been typed in
+     * @param parent the parent of the field editor's control
+     */
+    public this(String name, String labelText, int width,
+            int strategy, Composite parent) {
+        super(name, labelText, width, strategy, parent);
+    }
+
+    /**
+     * Creates a password 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 this(String name, String labelText, int width,
+            Composite parent) {
+        this(name, labelText, width, VALIDATE_ON_KEY_STROKE, parent);
+    }
+
+    /**
+     * Creates a password 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 this(String name, String labelText, Composite parent) {
+        this(name, labelText, UNLIMITED, parent);
+    }
+
+
+
+    /**
+     * 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 Text getTextControl(Composite parent) {
+        if (textField is null) {
+            textField = new Text(parent, DWT.PASSWORD | DWT.SINGLE | DWT.BORDER);
+            textField.setFont(parent.getFont());
+            switch (validateStrategy) {
+            case VALIDATE_ON_KEY_STROKE:
+                textField.addKeyListener(new class() KeyAdapter {
+
+                    /* (non-Javadoc)
+                     * @see dwt.events.KeyAdapter#keyReleased(dwt.events.KeyEvent)
+                     */
+                    public void keyReleased(KeyEvent e) {
+                        valueChanged();
+                    }
+                });
+
+                break;
+            case VALIDATE_ON_FOCUS_LOST:
+                textField.addKeyListener(new class() KeyAdapter {
+                    public void keyPressed(KeyEvent e) {
+                        clearErrorMessage();
+                    }
+                });
+                textField.addFocusListener(new class() FocusAdapter {
+                    public void focusGained(FocusEvent e) {
+                        refreshValidState();
+                    }
+
+                    public void focusLost(FocusEvent e) {
+                        valueChanged();
+                        clearErrorMessage();
+                    }
+                });
+                break;
+            default:
+                Assert.isTrue(false, "Unknown validate strategy");//$NON-NLS-1$
+            }
+            textField.addDisposeListener(new class() DisposeListener {
+                public void widgetDisposed(DisposeEvent event) {
+                    textField = null;
+                }
+            });
+            if (textLimit > 0) {//Only set limits above 0 - see SWT spec
+                textField.setTextLimit(textLimit);
+            }
+        } else {
+            checkParent(textField, parent);
+        }
+        return textField;
+    }
+
+}