com.arm.cmsis.pack.widgets.RteComponentTreeWidget.java Source code

Java tutorial

Introduction

Here is the source code for com.arm.cmsis.pack.widgets.RteComponentTreeWidget.java

Source

/*******************************************************************************
* Copyright (c) 2014 ARM Ltd.
* 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 com.arm.cmsis.pack.widgets;

import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.Collection;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

import com.arm.cmsis.pack.enums.EEvaluationResult;
import com.arm.cmsis.pack.events.IRteConfigurationProxy;
import com.arm.cmsis.pack.events.RteEvent;
import com.arm.cmsis.pack.generic.IAttributes;
import com.arm.cmsis.pack.info.ICpComponentInfo;
import com.arm.cmsis.pack.rte.components.IRteComponent;
import com.arm.cmsis.pack.rte.components.IRteComponentBundle;
import com.arm.cmsis.pack.rte.components.IRteComponentClass;
import com.arm.cmsis.pack.rte.components.IRteComponentGroup;
import com.arm.cmsis.pack.rte.components.IRteComponentItem;
import com.arm.cmsis.pack.tree.AdvisedCellLabelProvider;
import com.arm.cmsis.pack.tree.AdvisedEditingSupport;
import com.arm.cmsis.pack.tree.IColumnAdvisor;
import com.arm.cmsis.pack.ui.CpPlugInUI;

/**
 * This class displays the component tree for selection. 
 *
 */
public class RteComponentTreeWidget extends RteWidget {

    TreeViewer viewer = null; // the Tree Viewer
    private static final String SOFTWARECOMPONENT = "Software Components";

    private static final Color GREEN = new Color(Display.getCurrent(), 189, 249, 181);
    private static final Color YELLOW = new Color(Display.getCurrent(), 252, 200, 46);

    /**
     *   Return the effective component
     */
    public IRteComponentItem getComponentItem(Object obj) {
        if (obj instanceof IRteComponentItem) {
            return ((IRteComponentItem) obj).getEffectiveItem();
        }
        return null;
    }

    /** Column label provider for RteComponentTreeWidget 
     *
     */
    public class ColumnAdvisor implements IColumnAdvisor {

        // constants for column number
        private static final int COLSWCOMP = 0;
        private static final int COLSEL = 1;
        private static final int COLVARIANT = 2;
        private static final int COLVENDOR = 3;
        private static final int COLVERSION = 4;
        private static final int COLDESCR = 5;

        /**
         * Return true if the tree item (RTE component) at column index contains a check box
         * @param obj
         * @return true if tree item at columnIndex is check box
         */
        private CellControlType getSelectionControlType(Object obj) {
            IRteComponentItem item = getComponentItem(obj);
            if (item != null) {
                if (item instanceof IRteComponent) {
                    int count = ((IRteComponent) item).getMaxInstanceCount();
                    if (count == 1) {
                        return CellControlType.CHECK;
                    } else if (count > 1) {
                        return CellControlType.COMBO;
                    }
                }
            }
            return CellControlType.NONE;
        }

        @Override
        public CellControlType getCellControlType(Object obj, int columnIndex) {
            IRteComponentItem item = getComponentItem(obj);
            if (item == null)
                return CellControlType.NONE;
            Collection<String> strings = null;
            switch (columnIndex) {
            case COLSWCOMP:
                break;
            case COLSEL:
                return getSelectionControlType(obj);
            case COLVARIANT:
                strings = item.getVariantStrings();
                break;
            case COLVENDOR:
                strings = item.getVendorStrings();
                break;
            case COLVERSION:
                strings = item.getVersionStrings();
                break;
            case COLDESCR:
                String url = item.getUrl();
                if (url != null && !url.isEmpty()) {
                    return CellControlType.URL;
                }
                break;
            default:
                break;
            }

            if (strings != null && strings.size() > 0) {
                return CellControlType.COMBO;
            }

            return CellControlType.TEXT;
        }

        @Override
        public boolean getCheck(Object obj, int columnIndex) {
            if (getSelectionControlType(obj) == CellControlType.CHECK) {
                IRteComponentItem item = getComponentItem(obj);
                if (item instanceof IRteComponent) {
                    boolean check = item.isSelected();
                    return check;
                }
            }
            return false;
        }

        @Override
        public String getString(Object obj, int index) {
            IRteComponentItem item = getComponentItem(obj);
            if (item != null) {
                switch (index) {
                case COLSWCOMP: {
                    String label = item.getEffectiveName();
                    return label;
                }
                case COLSEL:
                    if (getSelectionControlType(obj) == CellControlType.COMBO) {
                        return Integer.toString(((IRteComponent) item).getSelectedCount());
                    }
                case COLVARIANT:
                    return item.getActiveVariant();
                case COLVENDOR:
                    return item.getActiveVendor();
                case COLVERSION:
                    return item.getActiveVersion(); // active variant
                case COLDESCR:
                    return item.getDescription();
                default:
                    break;
                }
            }
            return IAttributes.EMPTY_STRING;
        }

        @Override
        public int getCurrentSelectedIndex(Object element, int columnIndex) {
            int index = -1;
            IRteComponentItem item = getComponentItem(element);

            if (item != null) {
                switch (columnIndex) {
                case COLSEL:
                    if (getSelectionControlType(element) == CellControlType.COMBO) {
                        index = ((IRteComponent) item).getSelectedCount();
                    }
                    break;
                case COLVARIANT:
                    index = lookForIndex(item.getVariantStrings(), item.getActiveVariant());
                    break;
                case COLVENDOR:
                    index = lookForIndex(item.getVendorStrings(), item.getActiveVendor());
                    break;
                case COLVERSION:
                    index = lookForIndex(item.getVersionStrings(), item.getActiveVersion());
                    break;
                default:
                    break;
                }
            }

            return index;
        }

        /**
         * Look for the combo index based on the selected string 
         * @param stringCollection
         * @param str
         * @return Combo box index if found, otherwise -1 
         */
        private int lookForIndex(Collection<String> stringCollection, String str) {
            if (str != null && stringCollection != null) {
                int i = 0;
                for (String name : stringCollection) {
                    if (str.equals(name)) {
                        return i;
                    }
                    i++;
                }
            }
            return -1;
        }

        @Override
        public String[] getStringArray(Object obj, int columnIndex) {
            String[] strings = null;
            IRteComponentItem item = getComponentItem(obj);
            if (item != null) {
                switch (columnIndex) {
                case COLSWCOMP:
                    break;
                case COLSEL:
                    if (getSelectionControlType(obj) == CellControlType.COMBO) {
                        strings = getSelectionStrings(obj);
                    }
                    break;
                case COLVARIANT:
                    strings = item.getVariantStrings().toArray(new String[0]);
                    break;
                case COLVENDOR:
                    strings = item.getVendorStrings().toArray(new String[0]);
                    break;
                case COLVERSION:
                    strings = item.getVersionStrings().toArray(new String[0]);
                    break;
                case COLDESCR:
                default:
                    break;
                }
            }
            return strings;
        }

        @Override
        public boolean canEdit(Object obj, int columnIndex) {
            Collection<String> strings = null;
            IRteComponentItem item = getComponentItem(obj);
            if (item != null) {

                switch (columnIndex) {
                case COLSWCOMP:
                    break;
                case COLSEL:
                    CellControlType ct = getSelectionControlType(obj);
                    return ct == CellControlType.CHECK || ct == CellControlType.COMBO;
                case COLVARIANT:
                    strings = item.getVariantStrings();
                    break;
                case COLVENDOR:
                    strings = item.getVendorStrings();
                    break;
                case COLVERSION:
                    strings = item.getVersionStrings();
                    break;
                case COLDESCR:
                default:
                    break;
                }
            }

            if (strings != null) {
                return strings.size() > 1;
            }
            return false;
        }

        @Override
        public Image getImage(Object obj, int columnIndex) {
            IRteComponentItem item = getComponentItem(obj);
            if (item != null && columnIndex == 0) {
                if (item instanceof IRteComponentClass) {
                    return CpPlugInUI.getImage(CpPlugInUI.ICON_GROUP);
                } else if (item instanceof IRteComponentGroup) {
                    return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
                } else if (item instanceof IRteComponent) {
                    IRteComponent c = (IRteComponent) item;
                    ICpComponentInfo ci = c.getActiveCpComponentInfo();
                    if (ci != null && ci.getComponent() == null) {
                        if (c.getMaxInstanceCount() > 1)
                            return CpPlugInUI.getImage(CpPlugInUI.ICON_MULTICOMPONENT_ERROR);
                        else
                            return CpPlugInUI.getImage(CpPlugInUI.ICON_COMPONENT_ERROR);

                    } else {
                        if (c.getMaxInstanceCount() > 1)
                            return CpPlugInUI.getImage(CpPlugInUI.ICON_MULTICOMPONENT);
                        else
                            return CpPlugInUI.getImage(CpPlugInUI.ICON_COMPONENT);
                    }
                }
            }
            return null;
        }

        @Override
        public String getTooltipText(Object obj, int columnIndex) {
            return null;
        }

        @Override
        public void setCheck(Object element, int columnIndex, boolean newVal) {
            if (getSelectionControlType(element) == CellControlType.CHECK) {
                IRteComponentItem item = getComponentItem(element);
                ((IRteComponent) item).setSelected(newVal ? 1 : 0);
            }
        }

        /**
         * @param obj
         * @return a string array containing indexes starting from 0 to max instance count of the RTE component
         */
        private String[] getSelectionStrings(Object obj) {
            String[] strings = null;
            if (getSelectionControlType(obj) == CellControlType.COMBO) {
                int count = ((IRteComponent) obj).getMaxInstanceCount();
                strings = new String[count + 1];
                for (int i = 0; i <= count; ++i) {
                    strings[i] = Integer.toString(i);
                }
            }
            return strings;
        }

        /**
         * handle selection changes in combo box 
         */
        private void handleComboSelectionChange(PropertyChangeEvent event, int columnIndex) {

            IRteComponentItem item = getComponentItem(event.getSource());

            if (item == null || getConfiguration() == null)
                return;

            Integer tmp = (Integer) event.getNewValue();
            int selIndex = (tmp == null) ? 0 : tmp.intValue();
            Collection<String> strings = null;

            switch (columnIndex) {
            case COLSEL:
                if (getSelectionControlType(item) == CellControlType.COMBO) {
                    getConfiguration().selectComponent((IRteComponent) item, selIndex);
                }
                return;
            case COLVARIANT:
                strings = item.getVariantStrings();
                break;
            case COLVENDOR:
                strings = item.getVendorStrings();
                break;
            case COLVERSION:
                strings = item.getVersionStrings();
                break;
            case COLDESCR:
            default:
                return;
            }

            // currently item is valid only in case Cvariant has been changed
            if (strings != null) {
                String[] stringArr = strings.toArray(new String[0]);
                String name = stringArr[selIndex];
                switch (columnIndex) {
                case COLVARIANT:
                    getConfiguration().selectActiveVariant(item, name);
                    break;
                case COLVENDOR:
                    getConfiguration().selectActiveVendor(item, name);
                    break;
                case COLVERSION:
                    getConfiguration().selectActiveVersion(item, name);
                    break;
                default:
                    return;
                }
                viewer.update(item, null);
            }
        }

        @Override
        public void propertyChange(PropertyChangeEvent event, int columnIndex) {
            IRteComponentItem item = getComponentItem(event.getSource());
            if (item == null)
                return;

            switch (event.getProperty()) {
            case "ComboSelectionChanged":
                handleComboSelectionChange(event, columnIndex);
                break;
            case "CheckBox":
                if (getConfiguration() != null) {
                    // select or unselect an component.
                    boolean selected = ((Boolean) event.getNewValue()).booleanValue();
                    setCheck(item, columnIndex, selected);
                    viewer.update(item, null);
                    getConfiguration().selectComponent((IRteComponent) item, selected ? 1 : 0);
                }
                break;
            case "click":
                if (getCellControlType(item, columnIndex) == CellControlType.URL) {
                    Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
                    if (desktop != null) {
                        String url = item.getUrl();
                        if (url == null || url.isEmpty()) {
                            return;
                        }

                        String tmp = url.toLowerCase();
                        boolean isUrl = tmp.startsWith("http:") || tmp.startsWith("www.")
                                || tmp.startsWith("https:");
                        try {
                            if (isUrl && desktop.isSupported(Desktop.Action.BROWSE)) {
                                URI uri = new URI(url);
                                desktop.browse(uri);
                            } else {
                                File file = new File(url);
                                desktop.open(file);
                            }
                        } catch (Exception e) {
                            MessageDialog.openError(viewer.getControl().getShell(), SOFTWARECOMPONENT,
                                    "Cannot Open '" + url + "'");
                            e.printStackTrace();
                        }
                    }
                }
                break;
            }
        }

        @Override
        public Color getBgColor(Object obj, int columnIndex) {
            if (columnIndex != COLSEL)
                return null;
            IRteComponentItem item = getComponentItem(obj);
            if (item != null) {
                Device device = Display.getCurrent();
                EEvaluationResult res = getConfiguration().getEvaluationResult(item);
                switch (res) {
                case IGNORED:
                case UNDEFINED:
                    break;
                case CONFLICT:
                case ERROR:
                case FAILED:
                case INCOMPATIBLE:
                case INCOMPATIBLE_API:
                case INCOMPATIBLE_BUNDLE:
                case INCOMPATIBLE_VARIANT:
                case INCOMPATIBLE_VENDOR:
                case INCOMPATIBLE_VERSION:
                case MISSING:
                case MISSING_API:
                case MISSING_BUNDLE:
                case MISSING_VARIANT:
                case MISSING_VENDOR:
                case MISSING_VERSION:
                case UNAVAILABLE:
                case UNAVAILABLE_PACK:
                    return device.getSystemColor(SWT.COLOR_RED);
                case FULFILLED:
                    return GREEN;

                case INACTIVE:
                case INSTALLED:
                case SELECTABLE:
                    return YELLOW;
                default:
                    break;
                }
            }
            return null;
        }

    } /// end of ColumnAdviser

    /**   Content provider for RTEComponentTreeWidget
     *
     */
    public class RteContentProvider implements ITreeContentProvider {
        IRteComponentItem components = null;

        @Override
        public Object[] getElements(Object parent) {
            return getChildren(parent);
        }

        @Override
        public Object getParent(Object child) {
            IRteComponentItem item = getComponentItem(child);
            if (item != null) {
                return item.getEffectiveParent();
            }
            return null;
        }

        @Override
        public Object[] getChildren(Object parent) {
            IRteComponentItem item = getComponentItem(parent);
            if (item != null)
                return item.getEffectiveChildArray();
            return EMPTY_OBJECT_ARRAY;
        }

        @Override
        public boolean hasChildren(Object parent) {
            IRteComponentItem item = getComponentItem(parent);
            if (item != null)
                return item.hasEffectiveChildren();
            return false;
        }

        @Override
        public void dispose() {
            components = null;
        }

        @Override
        public void inputChanged(Viewer viewerRef, Object oldInput, Object newInput) {
            if (newInput != null && newInput instanceof IRteComponentItem)
                components = (IRteComponentItem) newInput;
            else
                components = null;
        }
    }

    /**
     * Set current configuration for this component tree widget
     * @param configuration A RTE configuration that contains RTE component
     */
    @Override
    public void setConfiguration(IRteConfigurationProxy configuration) {
        super.setConfiguration(configuration);
        if (viewer != null) {
            viewer.setInput(configuration.getComponents());
            //refresh();
        }
    }

    /**
     * Create a widget containing the RTE component
     * @param parent a parent composite containing this RTE component tree widget
     */
    public void createControl(Composite parent) {

        Tree tree = new Tree(parent, SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        tree.setHeaderVisible(true);
        viewer = new TreeViewer(tree);
        ColumnViewerToolTipSupport.enableFor(viewer);

        // Tree item name
        TreeViewerColumn column0 = new TreeViewerColumn(viewer, SWT.LEFT);
        tree.setLinesVisible(true);
        column0.getColumn().setAlignment(SWT.LEFT);
        column0.getColumn().setText(SOFTWARECOMPONENT);
        column0.getColumn().setWidth(180);
        IColumnAdvisor columnAdvisor = new ColumnAdvisor();
        column0.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 0));
        AdvisedCellLabelProvider col0LabelProvider = new AdvisedCellLabelProvider(columnAdvisor, 0);
        // workaround jface bug: first owner-draw column is not correctly painted when column is resized
        col0LabelProvider.setOwnerDrawEnabled(false);
        column0.setLabelProvider(col0LabelProvider);

        // Check box for selection
        TreeViewerColumn column1 = new TreeViewerColumn(viewer, SWT.CENTER);
        tree.setLinesVisible(true);
        column1.getColumn().setAlignment(SWT.CENTER);
        column1.getColumn().setText("Sel.");
        column1.getColumn().setWidth(35);
        column1.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 1));
        column1.setLabelProvider(new AdvisedCellLabelProvider(columnAdvisor, 1));

        // Variant
        TreeViewerColumn column2 = new TreeViewerColumn(viewer, SWT.RIGHT);
        column2.getColumn().setAlignment(SWT.LEFT);
        column2.getColumn().setText("Variant");
        column2.getColumn().setWidth(110);
        column2.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 2));
        column2.setLabelProvider(new AdvisedCellLabelProvider(columnAdvisor, 2));

        // Vendor
        TreeViewerColumn column3 = new TreeViewerColumn(viewer, SWT.RIGHT);
        column3.getColumn().setAlignment(SWT.LEFT);
        column3.getColumn().setText("Vendor");
        column3.getColumn().setWidth(110);
        column3.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 3));
        column3.setLabelProvider(new AdvisedCellLabelProvider(columnAdvisor, 3));

        // Version
        TreeViewerColumn column4 = new TreeViewerColumn(viewer, SWT.RIGHT);
        column4.getColumn().setAlignment(SWT.LEFT);
        column4.getColumn().setText("Version");
        column4.getColumn().setWidth(70);
        column4.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 4));
        column4.setLabelProvider(new AdvisedCellLabelProvider(columnAdvisor, 4));

        // Description/URL
        TreeViewerColumn column5 = new TreeViewerColumn(viewer, SWT.RIGHT);
        column5.getColumn().setAlignment(SWT.LEFT);
        column5.getColumn().setText("Description");
        column5.getColumn().setWidth(400);
        column5.setEditingSupport(new AdvisedEditingSupport(viewer, columnAdvisor, 5));
        column5.setLabelProvider(new AdvisedCellLabelProvider(columnAdvisor, 5));

        RteContentProvider rteContentProvider = new RteContentProvider();
        viewer.setContentProvider(rteContentProvider);

        GridData gridData = new GridData();
        gridData.horizontalAlignment = SWT.FILL;
        gridData.verticalAlignment = SWT.FILL;
        gridData.grabExcessHorizontalSpace = true;
        gridData.grabExcessVerticalSpace = true;
        gridData.horizontalSpan = 2;
        tree.setLayoutData(gridData);

        if (getConfiguration() != null) {
            viewer.setInput(getConfiguration().getComponents());
        }
    }

    @Override
    public void refresh() {
        // TODO Auto-generated method stub
        if (viewer != null) {
            viewer.refresh();
        }
    }

    /**
     * Refresh completely the tree viewer. 
     */
    @Override
    public void update() {
        viewer.refresh();
    }

    @Override
    public void handleRteEvent(RteEvent event) {
        if (event.getTopic().equals(RteEvent.COMPONENT_SHOW)) {
            showComponentItem((IRteComponentItem) event.getData());
            return;
        } else if (event.getTopic().equals(RteEvent.CONFIGURATION_MODIFIED)) {
            update();
        }
    }

    /**
     * Highlights given item expanding parent nodes if needed 
     * @param item Component item to select
     */
    public void showComponentItem(IRteComponentItem item) {
        if (viewer == null)
            return;
        if (item == null)
            return;

        IRteComponent c = item.getParentComponent();
        if (c != null) {
            // if supplied item has parent component, highlight it  
            item = c;
        }
        IRteComponentBundle b = item.getParentBundle();
        if (b != null && !b.isActive()) {
            // if bundle is not active, highlight bundle's parent (component class)
            item = b.getParent();
        }

        if (item == null)
            return;
        Object[] path = item.getEffectiveHierachyPath();
        TreePath tp = new TreePath(path);
        TreeSelection ts = new TreeSelection(tp);

        viewer.setSelection(ts, true);

    }

}