org.codehaus.groovy.eclipse.dsl.inferencing.suggestions.ui.AbstractDialogue.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.groovy.eclipse.dsl.inferencing.suggestions.ui.AbstractDialogue.java

Source

/*
 * Copyright 2011 the original author or authors.
 *
 * 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 org.codehaus.groovy.eclipse.dsl.inferencing.suggestions.ui;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.codehaus.groovy.eclipse.dsl.GroovyDSLCoreActivator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

/**
 * 
 * @author Nieraj Singh
 * @created 2011-05-13
 */
public abstract class AbstractDialogue extends TitleAreaDialog {

    private Map<IDialogueControlDescriptor, SetValue> invalidValues;

    protected static final String EMPTY_ERROR_MESSAGE = "  ";

    public AbstractDialogue(Shell parentShell) {
        super(parentShell);
    }

    /**
     * Must not be null
     * 
     * @return
     */
    abstract protected DialogueDescriptor getDialogueDescriptor();

    protected boolean isResizable() {
        return true;
    }

    protected String iconLocation() {
        return null;
    }

    protected Control createDialogArea(Composite parent) {
        invalidValues = new HashMap<IDialogueControlDescriptor, SetValue>();
        DialogueDescriptor descriptor = getDialogueDescriptor();
        setTitle(descriptor.getTitle());
        setMessage(descriptor.getMessage());
        String iconLocation = descriptor.getIconLocation();
        if (iconLocation != null && iconLocation.length() > 0) {
            setTitleImage(GroovyDSLCoreActivator.getImageDescriptor(iconLocation).createImage());
        }
        Composite composite = new Composite(parent, SWT.NONE);

        GridLayoutFactory.fillDefaults().margins(getDefaultCompositeHMargin(), getDefaultCompositeVMargin())
                .spacing(convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING),
                        convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING))
                .applyTo(composite);

        Dialog.applyDialogFont(composite);

        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);

        createCommandArea(composite);

        return composite;
    }

    protected Control createContents(Composite parent) {

        Control control = super.createContents(parent);
        // Set "OK" button state after all dialogue contents are created to
        // ensure the
        // dialogue buttons have already been created.
        if (invalidValues != null) {
            for (SetValue setValue : invalidValues.values()) {
                if (setValue.getValue() == null) {
                    enableOKButton(false);
                }
            }
        }
        return control;
    }

    protected Point getOffsetLabelLocation(String[] labels) {

        int length = SWT.DEFAULT;
        int charLength = 0;

        for (String label : labels) {
            int nameLength = label.length();
            if (nameLength > charLength) {
                charLength = nameLength;
            }
        }
        if (charLength > 0) {
            Control control = getShell();
            GC gc = new GC(control);
            Font requiredLabelFont = getRequiredParameterFont();
            gc.setFont(requiredLabelFont != null ? requiredLabelFont : control.getFont());
            FontMetrics fontMetrics = gc.getFontMetrics();
            length = Dialog.convertWidthInCharsToPixels(fontMetrics, charLength);
            gc.dispose();
        }
        Point longestLabelWidth = new Point(length, -1);
        longestLabelWidth.x += getLabelNameSeparatorOffset();
        return longestLabelWidth;
    }

    protected int getLabelNameSeparatorOffset() {
        return 5;
    }

    protected Font getRequiredParameterFont() {
        return JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT);
    }

    protected int getDefaultCompositeVMargin() {
        return convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
    }

    protected int getDefaultCompositeHMargin() {
        return convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
    }

    abstract protected void createCommandArea(Composite parent);

    /**
     * Control listener to be used if the dialogue has required values that
     * determine if
     * the user can click "OK" on the dialogue. Two options exist:
     * 1. The value is not initially required (i.e. value is empty or null), but
     * once a value is set, it needs
     * to be verified before enabling the OK button
     * 2. The value is required, and an empty or null value is not acceptable.
     * 
     * @author Nieraj Singh
     * @created 2011-08-06
     */
    abstract protected class ValidatedValueSelectionListener implements IControlSelectionListener {

        /**
         * User this only if values should not be initially marked as required
         * until a value is actually set
         */
        public ValidatedValueSelectionListener() {

        }

        public ValidatedValueSelectionListener(IDialogueControlDescriptor descriptor, Object initialValue) {
            // Add any instances of the listener to the list of descriptors that
            // need to
            // be observed for value validation
            if (descriptor != null) {
                invalidValues.put(descriptor, new SetValue(initialValue, null));
            }
        }

        public void handleSelection(ControlSelectionEvent event) {
            handleValidatedValue(event);
            notifyValidValueSet(event.getControlDescriptor(), event.getSelectionData());
        }

        public void handleInvalidSelection(ControlSelectionEvent event) {
            IDialogueControlDescriptor descriptor = event.getControlDescriptor();
            invalidValues.put(descriptor, new SetValue(event.getSelectionData(), event.getErrorMessage()));
            displayInvalidValueError(descriptor, event.getErrorMessage(), true);
        }

        abstract protected void handleValidatedValue(ControlSelectionEvent event);
    }

    protected void notifyValidValueSet(IDialogueControlDescriptor descriptor, Object value) {
        invalidValues.remove(descriptor);

        // Check if there are any remaining inValid values and display the next
        // error
        if (invalidValues != null) {

            for (Entry<IDialogueControlDescriptor, SetValue> entry : invalidValues.entrySet()) {
                if (entry.getValue().getValue() == null) {
                    displayInvalidValueError(entry.getKey(), entry.getValue().getErrorMessage(), true);
                    return;
                }
            }
        }
        setErrorMessage(null);
        enableOKButton(true);
    }

    /**
     * Checks if any required values are set with valid values before enabling
     * the "OK" button.
     */
    protected void displayInvalidValueError(IDialogueControlDescriptor descriptor, String errorMessage,
            boolean displayErrorMessage) {

        StringBuffer missingFields = new StringBuffer();

        missingFields.append("Value (");
        missingFields.append(descriptor.getLabel());
        missingFields.append(')');
        if (errorMessage != null && errorMessage.length() > 0) {
            missingFields.append(':');
            missingFields.append(' ');

            missingFields.append(errorMessage);
        } else {
            missingFields.append(" is missing");
        }

        if (displayErrorMessage) {
            setErrorMessage(missingFields.toString());
        }
        enableOKButton(false);
    }

    /**
     * Should only be called once the button bars have been created for the
     * dialogue
     * 
     * @param enable
     */
    protected void enableOKButton(boolean enable) {
        Button okButton = getButton(IDialogConstants.OK_ID);
        if (okButton != null && !okButton.isDisposed()) {
            okButton.setEnabled(enable);
        }
    }

    protected class SetValue {

        private Object value;

        private String errorMessage;

        public SetValue(Object value, String errorMessage) {
            this.value = value;
            this.errorMessage = errorMessage;
        }

        public Object getValue() {
            return value;
        }

        public String getErrorMessage() {
            return errorMessage;
        }

    }

}