com.ebmwebsourcing.petals.common.internal.provisional.swt.QNameText.java Source code

Java tutorial

Introduction

Here is the source code for com.ebmwebsourcing.petals.common.internal.provisional.swt.QNameText.java

Source

/******************************************************************************
 * Copyright (c) 2011-2013, Linagora
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *       Linagora - initial API and implementation
 *******************************************************************************/

package com.ebmwebsourcing.petals.common.internal.provisional.swt;

import java.util.concurrent.ConcurrentLinkedQueue;

import javax.xml.namespace.QName;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;

import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;

/**
 * A widget for QNames, made up of two {@link Text}s separated by a {@link Label}.
 * <p>
 * We use {@link StyledText} because some OS draw borders around native widgets like Texts.
 * Styled texts are not native widgets.
 * </p>
 *
 * @author Vincent Zurczak - EBM WebSourcing
 * FIXME: review the model interaction, the widget and the value might be not synchronized correctly
 */
public class QNameText extends Composite {

    private final static String DEFAULT_LOCAL_PART = "local part";
    private final static String DEFAULT_NAMESPACE = "http://your.namespace.uri";

    private final String defaultLocalPart;
    private final PhantomText namespacePhantomText;
    private final StyledText localPartPhantomText;
    private final Label separatorLabel;
    private final ConcurrentLinkedQueue<ModifyListener> modifyListeners = new ConcurrentLinkedQueue<ModifyListener>();

    /**
     * Constructor.
     * @param parent
     */
    public QNameText(Composite parent) {
        this(parent, null, null);
    }

    /**
     * Constructor.
     * @param parent
     * @param defaultLocalPart
     * @param defaultNamespace
     */
    public QNameText(Composite parent, String defaultLocalPart, String defaultNamespace) {
        super(parent, SWT.BORDER);
        setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
        this.defaultLocalPart = defaultLocalPart == null ? DEFAULT_LOCAL_PART : defaultLocalPart;

        GridLayout layout = new GridLayout(3, false);
        layout.marginHeight = 1;
        layout.marginWidth = 1;
        setLayout(layout);

        // The local part
        this.localPartPhantomText = new StyledText(this, SWT.SINGLE);
        this.localPartPhantomText.setText(DEFAULT_LOCAL_PART);
        this.localPartPhantomText.setLayoutData(new GridData());
        this.localPartPhantomText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {

                int cpt = ((StyledText) e.widget).getText().length() + 1;
                GC gc = new GC(QNameText.this);
                gc.setFont(getFont());
                int width = Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), cpt);
                gc.dispose();

                ((GridData) ((StyledText) e.widget).getLayoutData()).widthHint = width;
                layout();

                for (ModifyListener listener : QNameText.this.modifyListeners)
                    listener.modifyText(e);
            }
        });

        // The separator
        this.separatorLabel = new Label(this, SWT.NONE);
        this.separatorLabel.setText("-");
        this.separatorLabel.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));

        // The name space
        this.namespacePhantomText = new PhantomText(this, SWT.SINGLE);
        this.namespacePhantomText.setDefaultValue(defaultNamespace == null ? DEFAULT_NAMESPACE : defaultNamespace);

        GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
        layoutData.minimumWidth = 60;
        this.namespacePhantomText.setLayoutData(layoutData);
        this.namespacePhantomText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                for (ModifyListener listener : QNameText.this.modifyListeners)
                    listener.modifyText(e);
            }
        });

        // Focus listener
        Listener listener = new Listener() {
            @Override
            public void handleEvent(Event event) {
                ((StyledText) event.widget).selectAll();
            }
        };

        this.localPartPhantomText.addListener(SWT.MouseDown, listener);
        this.localPartPhantomText.addListener(SWT.FocusIn, listener);
        this.namespacePhantomText.getTextWidget().addListener(SWT.MouseDown, listener);
        this.namespacePhantomText.getTextWidget().addListener(SWT.FocusIn, listener);

        // Display default values
        setValue(null);
    }

    /**
     * Sets the local part.
     * @param localPart the local part (can be null)
     */
    public void setLocalPart(String localPart) {
        this.localPartPhantomText.setText(localPart != null ? localPart : this.defaultLocalPart);
    }

    /**
     * Sets the name space.
     * @param namespace the name space (can be null)
     */
    public void setNamespace(String namespace) {
        this.namespacePhantomText.setTextValue(namespace);
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.swt.widgets.Control
     * #setEnabled(boolean)
     */
    @Override
    public void setEnabled(boolean enabled) {

        this.localPartPhantomText.setEnabled(enabled);
        this.namespacePhantomText.setEnabled(enabled);

        int colorId = enabled ? SWT.COLOR_WHITE : SWT.COLOR_WIDGET_BACKGROUND;
        Color color = getDisplay().getSystemColor(colorId);

        this.separatorLabel.setBackground(color);
        this.localPartPhantomText.setBackground(color);
        this.namespacePhantomText.setBackground(color);
        setBackground(color);

        super.setEnabled(enabled);
    }

    /**
     * Defines whether the text fields can be edited or not.
     * @param editable true if they are, false otherwise
     */
    public void setEditable(boolean editable) {
        setLocalPartEditable(editable);
        setNamespacePartEditable(editable);
    }

    /**
     * Sets the local part editable.
     * @param editable
     */
    public void setLocalPartEditable(boolean editable) {
        this.localPartPhantomText.setEditable(editable);

        Color color = getDisplay().getSystemColor(SWT.COLOR_WHITE);
        String tooltip = editable ? null : "This field cannot be edited";
        this.localPartPhantomText.setBackground(color);
        this.localPartPhantomText.setToolTipText(tooltip);
    }

    /**
     * Sets the namespace part editable.
     * @param editable
     */
    public void setNamespacePartEditable(boolean editable) {
        this.namespacePhantomText.getTextWidget().setEditable(editable);

        Color color = getDisplay().getSystemColor(SWT.COLOR_WHITE);
        String tooltip = editable ? null : "This field cannot be edited";
        this.namespacePhantomText.getTextWidget().setBackground(color);
        this.namespacePhantomText.getTextWidget().setToolTipText(tooltip);
    }

    /**
     * @param string
     * @see org.eclipse.swt.widgets.Control
     * #setToolTipText(java.lang.String)
     */
    @Override
    public void setToolTipText(String string) {
        this.localPartPhantomText.setToolTipText(string);
        this.separatorLabel.setToolTipText(string);
        this.namespacePhantomText.setToolTipText(string);
    }

    /**
     * @return the QName described by this widget
     */
    public QName getValue() {

        QName result;
        String ns = this.namespacePhantomText.getTextValue();
        String name = this.localPartPhantomText.getText();
        name = this.defaultLocalPart.equals(name) ? null : name;

        if (StringUtils.isEmpty(name))
            result = null;
        else if (ns == null || ns.length() == 0)
            result = new QName(name);
        else
            result = new QName(ns, name);

        return result;
    }

    /**
     * @param value the QName to display in this widget
     */
    public void setValue(QName value) {

        if (value != null) {
            setLocalPart(value.getLocalPart());
            setNamespace(value.getNamespaceURI());
        } else {
            setLocalPart(null);
            setNamespace(null);
        }
    }

    /**
     * @return the text widget for the local part
     */
    public StyledText getLocalPartText() {
        return this.localPartPhantomText;
    }

    /**
     * @return the text widget for the name space
     */
    public StyledText getNamespaceText() {
        return this.namespacePhantomText.getTextWidget();
    }

    /**
     * @param modifyListener
     */
    public void addModifyListener(ModifyListener modifyListener) {
        this.modifyListeners.add(modifyListener);
    }

    /**
     * @param modifyListener
     */
    public void removeModifyListener(ModifyListener modifyListener) {
        this.modifyListeners.remove(modifyListener);
    }
}