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

Java tutorial

Introduction

Here is the source code for com.google.gdt.eclipse.designer.model.property.css.StylesEditComposite.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.Maps;
import com.google.gdt.eclipse.designer.Activator;
import com.google.gdt.eclipse.designer.common.Constants;

import org.eclipse.wb.internal.core.DesignerPlugin;
import org.eclipse.wb.internal.core.utils.dialogfields.DialogField;
import org.eclipse.wb.internal.core.utils.dialogfields.StringItemDialogField;
import org.eclipse.wb.internal.core.utils.dialogfields.StringItemDialogField.IStringItemAdapter;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.utils.ui.GridDataFactory;
import org.eclipse.wb.internal.core.utils.ui.GridLayoutFactory;
import org.eclipse.wb.internal.css.dialogs.style.StyleEditDialog;
import org.eclipse.wb.internal.css.dialogs.style.StyleEditOptions;
import org.eclipse.wb.internal.css.model.CssDocument;
import org.eclipse.wb.internal.css.model.CssRuleNode;
import org.eclipse.wb.internal.css.parser.CssEditContext;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;

import org.apache.commons.lang.StringUtils;

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

/**
 * Dialog for editing CSS file.
 * 
 * @author sablin_aa
 * @author scheglov_ke
 */
public class StylesEditComposite extends org.eclipse.wb.internal.css.editors.multi.StylesEditComposite {
    private final List<IFile> m_files;

    ////////////////////////////////////////////////////////////////////////////
    //
    // Constructor
    //
    ////////////////////////////////////////////////////////////////////////////
    public StylesEditComposite(Composite parent, List<IFile> files, int style,
            ICommandExceptionHandler exceptionHandler) {
        super(parent, style, exceptionHandler);
        m_files = files;
        m_filesViewer.setInput(m_files);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // GUI
    //
    ////////////////////////////////////////////////////////////////////////////
    protected StringItemDialogField m_searchField;
    protected ListViewer m_filesViewer;

    @Override
    protected void createRulesGroup(Composite parent) {
        Composite explorerComposite = new Composite(parent, SWT.NONE);
        GridLayoutFactory.create(explorerComposite).columns(1);
        GridDataFactory.create(explorerComposite).grab().fill();
        createFileGroup(explorerComposite);
        super.createRulesGroup(explorerComposite);
    }

    /**
     * Create CSS-file viewer.
     */
    protected void createFileGroup(Composite parent) {
        final int columns = 3;
        Group filesGroup = new Group(parent, SWT.NONE);
        filesGroup.setText("CSS files referenced from HTML");
        GridLayoutFactory.create(filesGroup).columns(columns);
        GridDataFactory.create(filesGroup).grabH().fill();
        // search
        {
            m_searchField = new StringItemDialogField(new IStringItemAdapter() {
                public void itemPressed(DialogField field) {
                    searchRule();
                }
            });
            m_searchField.setLabelText("&Search CSS rule in files:");
            m_searchField.setItemImage(DesignerPlugin.getImage("find.png"));
            m_searchField.setItemToolTip("Search");
            m_searchField.doFillIntoGrid(filesGroup, 3);
        }
        {
            m_filesViewer = new ListViewer(filesGroup, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
            GridDataFactory.create(m_filesViewer.getControl()).spanH(columns).grab().fill().hintC(80, 6);
            // set providers and input
            {
                m_filesViewer.setContentProvider(new DefaultStructuredContextProvider() {
                    @SuppressWarnings("unchecked")
                    public Object[] getElements(Object inputElement) {
                        List<IFile> files = (List<IFile>) inputElement;
                        return files.toArray();
                    }
                });
                m_filesViewer.setLabelProvider(new LabelProvider() {
                    @Override
                    public String getText(Object element) {
                        IFile file = (IFile) element;
                        return file.getFullPath().toPortableString();
                    }
                });
            }
            // add selection listener
            m_filesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
                public void selectionChanged(SelectionChangedEvent event) {
                    IFile file = (IFile) ((IStructuredSelection) event.getSelection()).getFirstElement();
                    setContext(getContext(file));
                    {
                        Object firstElement = m_rulesViewer.getElementAt(0);
                        if (firstElement != null) {
                            m_rulesViewer.setSelection(new StructuredSelection(firstElement));
                        }
                    }
                }
            });
        }
    }

    public void initializeState(String selectionValue) {
        // always show rules of first CSS file
        if (!m_files.isEmpty()) {
            m_initialValue = selectionValue;
            // locate initial CSS style
            if (!StringUtils.isEmpty(selectionValue)) {
                if (locateRuleInFiles(selectionValue)) {
                    return;
                }
            }
            m_filesViewer.setSelection(new StructuredSelection(m_files.get(0)));
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // GUI: Edit actions
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    protected StyleEditDialog getStyleEditDialog(CssRuleNode rule) {
        StyleEditDialog dialog = super.getStyleEditDialog(rule);
        StyleEditOptions options = dialog.getOptions();
        IPreferenceStore store = Activator.getStore();
        options.useNamedColors = store.getBoolean(Constants.P_CSS_USE_NAMED_COLORS);
        return dialog;
    }

    protected String m_initialValue = null;

    @Override
    protected String getDefaultNewSelector() {
        if (StringUtils.isEmpty(m_initialValue)) {
            return super.getDefaultNewSelector();
        } else {
            if (isSelectorExists(m_initialValue)) {
                return m_initialValue + "-new";
            } else {
                return m_initialValue;
            }
        }
    }

    protected final boolean isSelectorExists(String selector) {
        CssDocument document = getContext().getCssDocument();
        List<CssRuleNode> rules = document.getRules();
        for (CssRuleNode rule : rules) {
            String ruleSelector = rule.getSelector().getValue();
            if (selector.equalsIgnoreCase(ruleSelector)) {
                return true;
            }
        }
        return false;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Access
    //
    ////////////////////////////////////////////////////////////////////////////
    /**
     * Returns {@link IFile} for selected CSS file.
     */
    protected IFile getSelectedFile() {
        return (IFile) ((IStructuredSelection) m_filesViewer.getSelection()).getFirstElement();
    }

    /**
     * Returns {@link CssEditContext} for selected CSS file.
     */
    protected CssEditContext getSelectedContext() {
        return getContext(getSelectedFile());
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Contexts
    //
    ////////////////////////////////////////////////////////////////////////////
    private final Map<IFile, CssEditContext> m_fileToContext = Maps.newHashMap();

    /**
     * Returns {@link CssEditContext} for given file.
     */
    public CssEditContext getContext(IFile file) {
        try {
            CssEditContext context = m_fileToContext.get(file);
            if (context == null) {
                context = new CssEditContext(file);
                m_fileToContext.put(file, context);
            }
            return context;
        } catch (Throwable e) {
            throw ReflectionUtils.propagate(e);
        }
    }

    /**
     * Saves and removes {@link CssEditContext}'s.
     */
    public void saveContexts() throws CoreException {
        for (Iterator<CssEditContext> I = m_fileToContext.values().iterator(); I.hasNext();) {
            CssEditContext context = I.next();
            context.commit();
            context.disconnect();
            I.remove();
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Utils
    //
    ////////////////////////////////////////////////////////////////////////////
    protected boolean locateRuleInFiles(String ruleValue) {
        for (IFile file : m_files) {
            if (locateRuleInFile(file, ruleValue)) {
                return true;
            }
        }
        return false;
    }

    protected boolean locateRuleInFile(IFile file, String searchValue) {
        CssEditContext context = getContext(file);
        List<CssRuleNode> rules = context.getCssDocument().getRules();
        for (CssRuleNode rule : rules) {
            String ruleValue = rule.getSelector().getValue();
            if (ruleValue.equals(searchValue)
                    || ruleValue.startsWith(".") && ruleValue.substring(1).equals(searchValue)) {
                // select file
                m_filesViewer.setSelection(new StructuredSelection(file));
                // select rule
                RuleWrapper wrapper = new RuleWrapper(rule);
                m_rulesViewer.setSelection(new StructuredSelection(wrapper), true);
                return true;
            }
        }
        return false;
    }

    private void searchRule() {
        String searchText = m_searchField.getText();
        if (!StringUtils.isEmpty(searchText)) {
            if (!locateRuleInFiles(searchText)) {
                MessageDialog.openWarning(getShell(), "Search", "Rule selector \"" + searchText + "\" not found.");
            }
        }
    }
}