org.jboss.tools.jst.css.dialog.tabs.BaseTabControl.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.jst.css.dialog.tabs.BaseTabControl.java

Source

/*******************************************************************************
 * Copyright (c) 2007-2008 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is 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
 *
 * Contributor:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.jst.css.dialog.tabs;

import java.util.List;
import java.util.Map;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.jboss.tools.common.web.WebUtils;
import org.jboss.tools.jst.css.CSSPlugin;
import org.jboss.tools.jst.css.dialog.FontFamilyDialog;
import org.jboss.tools.jst.css.dialog.ImageSelectionDialog;
import org.jboss.tools.jst.css.dialog.common.CSSConstants;
import org.jboss.tools.jst.css.dialog.common.CSSStyleValueValidator;
import org.jboss.tools.jst.css.dialog.common.StyleAttributes;
import org.jboss.tools.jst.css.dialog.common.Util;
import org.jboss.tools.jst.css.dialog.widgets.CSSTreeItemWidgetValueProperty;
import org.jboss.tools.jst.css.dialog.widgets.CSSWidget;
import org.jboss.tools.jst.css.dialog.widgets.CSSWidgetValueProperty;
import org.jboss.tools.jst.css.dialog.widgets.ImageCombo;
import org.jboss.tools.jst.css.dialog.widgets.SizeCombo;
import org.jboss.tools.jst.css.dialog.widgets.SizeText;
import org.jboss.tools.jst.jsp.messages.JstUIMessages;
import org.jboss.tools.jst.jsp.util.Constants;

/**
 * This is base tab control component that should be re-implemented by
 * successor.
 * 
 * @author Igor Zhukov
 */
public abstract class BaseTabControl extends Composite implements ICSSTabControl {

    private StyleAttributes styleAttributes = null;

    private DataBindingContext bindingContext;

    final static protected int NAME_ATTRIBUTE_COLUMN = 0;
    final static protected int VALUE_ATTRIBUTE_COLUMN = 1;
    final static protected int COMPOSITE_NUM_COLUMNS = 2;

    private static final int COLUMNS = 3;

    /**
     * Constructs a new instance of this class given its parent and a style
     * value describing its behavior and appearance.
     * 
     * @param parent
     *            a widget which will be the parent of the new instance (cannot
     *            be null)
     * @param style
     *            the style of widget to construct
     */
    public BaseTabControl(DataBindingContext bindingContext, StyleAttributes styleAttributes, Composite parent,
            int style) {
        super(parent, style);
        setLayout(new GridLayout(COLUMNS, false));
        this.styleAttributes = styleAttributes;
        this.bindingContext = bindingContext;
    }

    /**
     * @return the styleAttributes
     */
    public StyleAttributes getStyleAttributes() {
        return styleAttributes;
    }

    public void setStyleAttributes(StyleAttributes styleAttributes) {
        this.styleAttributes = styleAttributes;
    }

    public DataBindingContext getBindingContext() {
        return this.bindingContext;
    }

    public void setBindingContext(DataBindingContext bindingContext) {
        this.bindingContext = bindingContext;
    }

    /**
     * 
     * @param parent
     * @param label
     */
    protected Label addLabel(Composite parent, String label) {
        Label labelControl = new Label(parent, SWT.LEFT);
        labelControl.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
        labelControl.setText(label);
        return labelControl;
    }

    /**
     * 
     * @param parent
     * @param label
     */
    protected Label addSectionLabel(Composite parent, String label) {

        Label labelControl = new Label(parent, SWT.NONE);
        labelControl.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false, 3, 1));
        labelControl.setFont(JFaceResources.getFontRegistry().get(JFaceResources.BANNER_FONT));
        labelControl.setText(label);

        return labelControl;
    }

    /**
     * 
     * @param parent
     * @param attribute
     */
    protected Composite addFontComposite(Composite parent, String attribute) {

        Composite wrapper = createWrapperComposite(parent);

        final Text fontFamilyText = new Text(wrapper, SWT.BORDER | SWT.SINGLE);
        fontFamilyText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

        Button button = createButton(wrapper, Util.IMAGE_FONTLARGE_FILE_LOCATION, JstUIMessages.FONT_FAMILY_TIP);
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                FontFamilyDialog dialog = new FontFamilyDialog(getShell(), fontFamilyText.getText());
                if (dialog.open() == Window.OK) {
                    fontFamilyText.setText(dialog.getFontFamily());
                }
            }
        });

        bind(fontFamilyText, attribute);

        return wrapper;

    }

    /**
     * 
     * @param parent
     * @param attribute
     */
    protected Composite addColorComposite(Composite parent, String attribute) {

        Composite wrapper = createWrapperComposite(parent);

        final ImageCombo colorCombo = new ImageCombo(wrapper, SWT.BORDER);

        colorCombo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

        for (Map.Entry<String, String> me : CSSConstants.COLORS_BY_NAME.entrySet()) {
            RGB rgb = Util.getColor(me.getValue());
            String name = CSSConstants.COLORS_BY_RGB.get(me.getValue());
            if (name == null) {
                name = me.getKey();
            }
            colorCombo.add(name, rgb);
        }

        Button button = createButton(wrapper, Util.IMAGE_COLORLARGE_FILE_LOCATION, JstUIMessages.COLOR_TIP);

        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                ColorDialog dlg = new ColorDialog(getShell());

                dlg.setRGB((Util.getColor((colorCombo.getText().trim())) == null) ? Constants.RGB_BLACK
                        : Util.getColor((colorCombo.getText().trim())));
                dlg.setText(JstUIMessages.COLOR_DIALOG_TITLE);

                RGB rgb = dlg.open();
                if (rgb != null) {
                    String colorStr = Util.createColorString(rgb);
                    colorCombo.setText(colorStr);
                }
            }
        });

        bind(colorCombo, attribute);

        return wrapper;
    }

    protected Composite addImageFileComposite(Composite parent, List<String> comboValues, final String attribute) {

        Composite wrapper = createWrapperComposite(parent);

        final Combo combo = new Combo(wrapper, SWT.BORDER);
        combo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

        for (String string : comboValues) {
            combo.add(string);
        }

        Button button = createButton(wrapper, Util.IMAGE_FOLDERLARGE_FILE_LOCATION, JstUIMessages.BACKGROUND_IMAGE);

        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                IAdaptable project = Util.getCurrentProject();
                ImageSelectionDialog dialog = new ImageSelectionDialog(getShell(), new WorkbenchLabelProvider(),
                        new WorkbenchContentProvider());
                dialog.setTitle(JstUIMessages.IMAGE_DIALOG_TITLE);
                dialog.setMessage(JstUIMessages.IMAGE_DIALOG_MESSAGE);
                dialog.setEmptyListMessage(JstUIMessages.IMAGE_DIALOG_EMPTY_MESSAGE);
                dialog.setAllowMultiple(false);
                dialog.setInput(project);

                IFile pageFile = getPageFile();
                String text = combo.getText();
                if (pageFile != null && text != null && text.length() > 0) {
                    if (text.startsWith("url(") && text.endsWith(")")) {
                        text = text.substring(4, text.length() - 1);
                    }
                    text = text.replace('\\', '/');
                    IPath path = pageFile.getFullPath().removeLastSegments(1);
                    IFile selectedFile = null;
                    if (text.startsWith("/")) {
                        IPath[] paths = WebUtils.getWebContentPaths(pageFile.getProject());
                        for (IPath p : paths) {
                            selectedFile = ResourcesPlugin.getWorkspace().getRoot()
                                    .getFile(p.append(text.substring(1)));
                            if (!selectedFile.exists()) {
                                selectedFile = null;
                            } else {
                                break;
                            }
                        }
                    }
                    if (selectedFile == null) {
                        while (true) {
                            if (path.segmentCount() < 2)
                                break;
                            if (text.startsWith("/")) {
                                text = text.substring(1);
                            } else if (text.startsWith("./")) {
                                text = text.substring(2);
                            } else if (text.startsWith("../")) {
                                text = text.substring(3);
                                path = path.removeLastSegments(1);
                            } else {
                                break;
                            }
                        }
                        path = path.append(text);
                        selectedFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
                    }
                    if (selectedFile.exists()) {
                        dialog.setInitialSelection(selectedFile);
                    }
                }

                if (dialog.open() == ImageSelectionDialog.OK) {
                    if (pageFile != null) {
                        IFile imageFile = (IFile) dialog.getFirstResult();
                        String relativePath = BaseTabControl.computeRelativePath(pageFile, imageFile);
                        combo.add(relativePath);
                        combo.setText(relativePath);
                    }
                }
            }
        });

        bind(combo, attribute, new UpdateValueStrategy() {

            @Override
            protected IStatus doSet(IObservableValue observableValue, Object value) {

                List<String> values = CSSConstants.CSS_STYLE_VALUES_MAP.get(attribute);

                if ((values != null) && !values.contains(value))
                    value = adjustBackgroundURL((String) value);

                return super.doSet(observableValue, value);
            }
        }, null);

        return wrapper;
    }

    private IFile getPageFile() {
        IWorkbenchPage page = CSSPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
        if (page != null && page.getActiveEditor() != null
                && page.getActiveEditor().getEditorInput() instanceof IFileEditorInput) {
            return ((IFileEditorInput) page.getActiveEditor().getEditorInput()).getFile();
        }
        return null;
    }

    /**
     * Build a relative path to the given base path.
     * 
     * @param base
     *            - the path used as the base
     * @param path
     *            - the path to compute relative to the base path
     * @return A relative path from base to path
     */

    private static String computeRelativePath(IFile baseFile, IFile otherFile) {

        IPath basePath = baseFile.getLocation();
        IPath otherPath = otherFile.getLocation();

        String relativePath = otherPath.makeRelativeTo(basePath).toPortableString();

        if (relativePath.startsWith("..")) {
            relativePath = relativePath.replaceFirst("..", ".");
        }

        return relativePath;
    }

    protected Composite createWrapperComposite(Composite parent) {
        Composite wrapper = new Composite(parent, SWT.None);
        GridLayout layout = new GridLayout(COMPOSITE_NUM_COLUMNS, false);

        layout.marginWidth = 0;
        layout.marginHeight = 0;
        wrapper.setLayout(layout);
        wrapper.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1));
        return wrapper;
    }

    /**
     * 
     * @param parent
     * @param comboValues
     * @param attribute
     */
    protected Composite addSizeCombo(Composite parent, List<String> comboValues, String attribute) {

        SizeCombo combo = new SizeCombo(parent, comboValues);

        bind(combo, attribute);

        return combo;

    }

    /**
     * 
     * @param parent
     * @param comboValues
     * @param attribute
     */
    protected Composite addSizeText(Composite parent, String attribute) {

        SizeText combo = new SizeText(parent);

        bind(combo, attribute);

        return combo;

    }

    /**
     * 
     * @param parent
     * @param attribute
     */
    protected Text addText(Composite parent, String attribute) {

        GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
        gridData.horizontalSpan = 2;

        Text text = new Text(parent, SWT.BORDER);
        text.setLayoutData(gridData);

        bind(text, attribute);

        return text;

    }

    /**
     * 
     * @param parent
     * @param comboValues
     * @param attribute
     */
    protected Combo addCombo(Composite parent, List<String> comboValues, String attribute) {

        GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
        gridData.horizontalSpan = 2;

        Combo combo = new Combo(parent, SWT.BORDER);
        combo.setLayoutData(gridData);

        for (String str : comboValues) {
            combo.add(str);
        }

        bind(combo, attribute);

        return combo;
    }

    protected TreeItem createBindedTreeItem(TreeItem parent, String attribute) {

        TreeItem item = new TreeItem(parent, SWT.NONE);
        item.setText(NAME_ATTRIBUTE_COLUMN, attribute);
        bind(item, attribute);

        return item;
    }

    protected TreeItem createTreeItem(Tree parent, String text) {

        TreeItem item = new TreeItem(parent, SWT.NONE);
        item.setText(text);

        return item;
    }

    /**
     * 
     * @param parent
     * @param imageFile
     * @param tooltip
     * @return
     */
    private Button createButton(Composite parent, String imageFile, String tooltip) {
        Button button = new Button(parent, SWT.PUSH);
        button.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
        button.setToolTipText(tooltip);

        button.setImage(CSSPlugin.getImageDescriptor(imageFile).createImage());
        button.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                Button button = (Button) e.getSource();
                button.getImage().dispose();
            }
        });

        return button;
    }

    /**
     * create control by css property
     * 
     * @param parent
     * @param key
     * @return
     */
    protected Control createControl(Composite parent, String property) {

        Control control = null;
        if (CSSConstants.CSS_STYLE_VALUES_MAP.keySet().contains(property)) {

            if (property.indexOf(Constants.COLOR) != Constants.DONT_CONTAIN) {
                control = addColorComposite(parent, property);
            } else if (Constants.elemFolder.contains(property)) {
                control = addImageFileComposite(parent, CSSConstants.CSS_STYLE_VALUES_MAP.get(property), property);
            } else if (Constants.extElem.contains(property)) {
                control = addSizeCombo(parent, CSSConstants.CSS_STYLE_VALUES_MAP.get(property), property);
            } else {
                control = addCombo(parent, CSSConstants.CSS_STYLE_VALUES_MAP.get(property), property);
            }

        } else {
            if (property.equalsIgnoreCase(CSSConstants.FONT_FAMILY)) {
                control = addFontComposite(parent, property);
            } else if (Constants.extElem.contains(property)) {
                control = addSizeText(parent, property);
            } else {
                control = addText(parent, property);
            }
        }
        return control;
    }

    private static String adjustBackgroundURL(String backgroundURL) {
        if ((backgroundURL != null && !backgroundURL.trim().equals(Constants.EMPTY))
                && (backgroundURL.matches("(url)\\(.*\\)") == false)) { //$NON-NLS-1$
            return "url(" + backgroundURL + ")"; //$NON-NLS-1$//$NON-NLS-2$
        }

        return backgroundURL;
    }

    private IObservableValue createAttributeObservableValue(String attributeName) {
        return Observables.observeMapEntry(getStyleAttributes().getObservableMap(), attributeName, String.class);
    }

    private void bind(Widget widget, String attribute) {
        bind(widget, attribute, null, null);
    }

    private void bind(Widget widget, String attribute, UpdateValueStrategy targetToModel,
            UpdateValueStrategy modelToTarget) {

        IObservableValue attributeValue = createAttributeObservableValue(attribute);

        if (targetToModel == null) {
            targetToModel = new UpdateValueStrategy();
        }

        targetToModel.setBeforeSetValidator(CSSStyleValueValidator.getInstance());

        if (widget instanceof Text) {
            getBindingContext().bindValue(SWTObservables.observeText((Text) widget, SWT.Modify), attributeValue,
                    targetToModel, modelToTarget);
        } else if ((widget instanceof Combo)) {
            getBindingContext().bindValue(SWTObservables.observeText(widget), attributeValue, targetToModel,
                    modelToTarget);
        } else if (widget instanceof CSSWidget) {
            getBindingContext().bindValue(new CSSWidgetValueProperty().observe(widget), attributeValue,
                    targetToModel, modelToTarget);
        } else if (widget instanceof TreeItem) {
            getBindingContext().bindValue(
                    new CSSTreeItemWidgetValueProperty(VALUE_ATTRIBUTE_COLUMN).observe(widget), attributeValue,
                    targetToModel, modelToTarget);
        }

    }

    public void update() {

    }

}