com.google.gdt.eclipse.designer.model.property.css.StylePropertyEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gdt.eclipse.designer.model.property.css.StylePropertyEditor.java

Source

/*******************************************************************************
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * 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
 *
 * 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 com.google.gdt.eclipse.designer.model.property.css;

import com.google.common.collect.Lists;
import com.google.gdt.eclipse.designer.Activator;
import com.google.gdt.eclipse.designer.model.widgets.support.IGwtStateProvider;

import org.eclipse.wb.core.controls.CComboBox;
import org.eclipse.wb.core.model.ObjectInfo;
import org.eclipse.wb.internal.core.DesignerPlugin;
import org.eclipse.wb.internal.core.model.property.ObjectProperty;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.property.editor.AbstractComboBoxPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.PropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.StringComboPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.complex.IComplexPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.presentation.ButtonPropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.editor.presentation.CompoundPropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.editor.presentation.PropertyEditorPresentation;
import org.eclipse.wb.internal.core.model.property.editor.string.StringPropertyEditor;
import org.eclipse.wb.internal.core.model.property.table.PropertyTable;
import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils;
import org.eclipse.wb.internal.core.utils.jdt.core.ProjectUtils;
import org.eclipse.wb.internal.css.model.CssRuleNode;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Image;

import org.apache.commons.lang.StringUtils;

import java.util.Collections;
import java.util.List;

/**
 * Combo {@link PropertyEditor} for selecting/editing CSS style.
 * 
 * @author sablin_aa
 * @author scheglov_ke
 * @coverage gwt.model.property
 */
public final class StylePropertyEditor extends AbstractComboBoxPropertyEditor implements IComplexPropertyEditor {
    ////////////////////////////////////////////////////////////////////////////
    //
    // Instance
    //
    ////////////////////////////////////////////////////////////////////////////
    public static final StylePropertyEditor INSTANCE = new StylePropertyEditor();

    private StylePropertyEditor() {
        m_compoundPresentation.add(m_presentationNew);
        m_compoundPresentation.add(m_presentationEdit);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Presentation
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    public PropertyEditorPresentation getPresentation() {
        return m_compoundPresentation;
    }

    @Override
    protected String getText(Property property) throws Exception {
        Object value = property.getValue();
        if (value instanceof String) {
            return (String) value;
        }
        return null;
    }

    private final CompoundPropertyEditorPresentation m_compoundPresentation = new CompoundPropertyEditorPresentation();
    private final PropertyEditorPresentation m_presentationEdit = new ButtonPropertyEditorPresentation() {
        @Override
        protected void onClick(PropertyTable propertyTable, Property property) throws Exception {
            openEditDialog(property);
        }

        @Override
        protected Image getImage() {
            return Activator.getImage("css_editor2.png");
        }
    };
    private final PropertyEditorPresentation m_presentationNew = new ButtonPropertyEditorPresentation() {
        @Override
        protected void onClick(PropertyTable propertyTable, Property property) throws Exception {
            openNewDialog(property);
        }

        @Override
        protected Image getImage() {
            return Activator.getImage("css_addStyle.png");
        }
    };

    private void openEditDialog(Property property) throws Exception {
        ObjectProperty objectProperty = (ObjectProperty) property;
        ObjectInfo objectInfo = objectProperty.getObjectInfo();
        IGwtStateProvider stateProvider = (IGwtStateProvider) objectInfo;
        // prepare not empty array of CSS files
        List<IFile> cssFiles = stateProvider.getState().getCssSupport().getFiles();
        if (cssFiles.isEmpty()) {
            MessageDialog.openError(DesignerPlugin.getShell(), "Error",
                    "There are no CSS files referenced from module or HTML.");
            return;
        }
        // prepare dialog
        StylesEditDialog stylesDialog;
        {
            String currentText = getText(property);
            stylesDialog = new StylesEditDialog(DesignerPlugin.getShell(), cssFiles,
                    StringUtils.isEmpty(currentText) ? "" : "." + currentText, true);
        }
        // open dialog and edit CSS files
        int result = stylesDialog.open();
        if (result == Window.CANCEL) {
            return;
        }
        // wait for auto-build - for coping CSS files from source folder to binary
        ProjectUtils.waitForAutoBuild();
        // check CSS files modification
        stateProvider.getState().isModified();
        // do edit
        switch (result) {
        case Window.OK:
            // "OK" button pressed, refresh for displaying modified styles
            ExecutionUtils.refresh(objectInfo);
            break;
        case IDialogConstants.PROCEED_ID:
            // "Apply" button pressed, set new style name
            String newSelector = stylesDialog.getSelectionValue();
            String newStyleName = extractStyleName(newSelector);
            property.setValue(newStyleName);
            break;
        }
    }

    private static String extractStyleName(String selector) {
        return StringUtils.removeStart(selector, ".");
    }

    private void openNewDialog(Property property) throws Exception {
        ObjectProperty objectProperty = (ObjectProperty) property;
        ObjectInfo objectInfo = objectProperty.getObjectInfo();
        IGwtStateProvider stateProvider = (IGwtStateProvider) objectInfo;
        // prepare default name
        String initialName = "newStyleName";
        if (property.getValue() instanceof String) {
            initialName = (String) property.getValue();
        }
        // ask for style name
        InputDialog inputDialog = new InputDialog(DesignerPlugin.getShell(), "New style name",
                "Enter new style name (without leading '.'):", initialName, null);
        if (inputDialog.open() == Window.CANCEL) {
            return;
        }
        String newStyleName = inputDialog.getValue();
        // actually add style
        {
            RuleAccessor ruleAccessor = RuleAccessor.get(objectInfo);
            List<ContextDescription> contexts = ruleAccessor.getContexts();
            ContextDescription context = getTargetContextDescription(contexts, newStyleName);
            if (context != null) {
                newStyleName = context.addNewStyle(newStyleName);
                context.commit();
            }
        }
        // check CSS files modification
        stateProvider.getState().isModified();
        // apply style name
        property.setValue(newStyleName);
    }

    /**
     * @return the {@link ContextDescription} for given new style name, e.g. file based for "gwt-"
     *         style, may be <code>null</code>.
     */
    private static ContextDescription getTargetContextDescription(List<ContextDescription> contexts,
            String newStyleName) {
        if (newStyleName.startsWith("gwt-")) {
            for (ContextDescription context : contexts) {
                if (context instanceof FileContextDescription) {
                    return context;
                }
            }
        }
        if (!contexts.isEmpty()) {
            return contexts.get(0);
        }
        return null;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Editing
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    protected void addItems(Property property, CComboBox combo) throws Exception {
        ObjectProperty objectProperty = (ObjectProperty) property;
        // prepare accessor
        ObjectInfo objectInfo = objectProperty.getObjectInfo();
        RuleAccessor accessor = RuleAccessor.get(objectInfo);
        // prepare style names
        List<String> styleNames = Lists.newArrayList();
        for (ContextDescription contextDescription : accessor.getContexts()) {
            for (CssRuleNode ruleNode : contextDescription.getRules()) {
                String styleName = contextDescription.getStyleName(ruleNode);
                if (styleName != null) {
                    styleNames.add(styleName);
                }
            }
        }
        // sort and fill combo box items
        Collections.sort(styleNames);
        for (String styleName : styleNames) {
            combo.addItem(styleName);
        }
        combo.setFullDropdownTableWidth(true);
    }

    @Override
    protected void selectItem(Property property, CComboBox combo) throws Exception {
        String currentStyleName = getText(property);
        int itemCount = combo.getItemCount();
        for (int i = 0; i < itemCount; i++) {
            if (combo.getItemLabel(i).equals(currentStyleName)) {
                combo.setSelectionIndex(i);
                break;
            }
        }
    }

    @Override
    protected void toPropertyEx(Property property, CComboBox combo) throws Exception {
        String styleName = combo.getEditText();
        if (!StringUtils.isBlank(styleName) && !StringUtils.equals(styleName, getText(property))) {
            property.setValue(StringUtils.isEmpty(styleName) ? Property.UNKNOWN_VALUE : styleName);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // IComplexPropertyEditor
    //
    ////////////////////////////////////////////////////////////////////////////
    public Property[] getProperties(Property property) throws Exception {
        final String styleName = getText(property);
        // prepare model
        ObjectProperty objectProperty = (ObjectProperty) property;
        ObjectInfo objectInfo = objectProperty.getObjectInfo();
        // use RuleAccessor
        final RuleAccessor accessor = RuleAccessor.get(objectInfo);
        if (accessor.hasSemantics(styleName)) {
            return new Property[] { new StyleColorValueProperty(accessor, styleName, "color", "color"),
                    new StyleComplexProperty(accessor, "background",
                            new Property[] {
                                    new StyleColorValueProperty(accessor, styleName, "background.color", "color"),
                                    new StyleSimpleValueProperty(accessor, styleName, "background.image", "image",
                                            StringPropertyEditor.INSTANCE),
                                    new StyleSimpleValueProperty(accessor, styleName, "background.repeat", "repeat",
                                            new StringComboPropertyEditor("", "repeat", "repeat-x", "repeat-y",
                                                    "no-repeat")),
                                    new StyleSimpleValueProperty(accessor, styleName, "background.attachment",
                                            "attachment", new StringComboPropertyEditor("", "scroll", "fixed")) }),
                    new StyleBorderProperty(accessor, styleName), new StyleFontProperty(accessor, styleName),
                    new StyleTextProperty(accessor, styleName),
                    new StyleLengthSidedProperty(accessor, styleName, "margin", "margin"),
                    new StyleLengthSidedProperty(accessor, styleName, "padding", "padding"), };
        }
        return new Property[0];
    }
}