org.eclipse.rcptt.verifications.tree.ui.TreeVerificationEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.rcptt.verifications.tree.ui.TreeVerificationEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2016 Xored Software Inc and others.
 * 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:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.verifications.tree.ui;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
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.TreeViewerEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import org.eclipse.rcptt.verifications.status.TreeItemVerificationError;
import org.eclipse.rcptt.core.model.ModelException;
import org.eclipse.rcptt.internal.ui.Q7UIPlugin;
import org.eclipse.rcptt.tesla.core.utils.WidgetModels;
import org.eclipse.rcptt.ui.controls.SectionWithComposite;
import org.eclipse.rcptt.ui.editors.EditorHeader;
import org.eclipse.rcptt.ui.verification.WidgetVerificationEditor;
import org.eclipse.rcptt.verifications.tree.Cell;
import org.eclipse.rcptt.verifications.tree.Column;
import org.eclipse.rcptt.verifications.tree.Row;
import org.eclipse.rcptt.verifications.tree.Tree;
import org.eclipse.rcptt.verifications.tree.TreePackage;
import org.eclipse.rcptt.verifications.tree.TreeVerification;
import org.eclipse.rcptt.verifications.tree.TreeVerificationUtils;
import org.eclipse.rcptt.verifications.tree.VerifyStyleType;

public class TreeVerificationEditor extends WidgetVerificationEditor {
    Binding treeDataBinding = null;
    TreeTableObservable widgetObservable = null;
    Combo verifyStyleCombo = null;

    public TreeVerification getVerificationElement() {
        try {
            return (TreeVerification) super.getElement().getNamedElement();
        } catch (ModelException e) {
            Q7UIPlugin.log(e);
            return null;
        }
    }

    public void dispose() {
        super.dispose();
    }

    public Control create(Composite parent, FormToolkit toolkit, IWorkbenchSite site, EditorHeader header) {

        Section section = new SectionWithComposite("Widget Tree",
                Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED).create(parent, toolkit);
        Composite client = (Composite) section.getClient();
        GridLayoutFactory.fillDefaults().numColumns(1).spacing(SWT.DEFAULT, 16).applyTo(client);
        createWidgetControls(client, toolkit, site, header);

        Composite box = toolkit.createComposite(client);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(box);
        GridLayoutFactory.fillDefaults().numColumns(1).spacing(16, 4).applyTo(box);
        createControls(toolkit, box);

        header.getRecordButton().addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                Boolean defaultValue = (Boolean) TreePackage.Literals.VERIFY_TREE_DATA__ENABLE_VERIFY_STYLE
                        .getDefaultValue();
                getVerificationElement().setEnableVerifyStyle(defaultValue);
            }
        });

        return section;
    }

    private void createControls(final FormToolkit toolkit, final Composite client) {
        final Composite propertiesComposite = toolkit.createComposite(client);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(propertiesComposite);
        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(propertiesComposite);
        createPropertiesControls(toolkit, propertiesComposite);

        Label introLabel = toolkit.createLabel(client, "Widget tree should be:");
        introLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
        introLabel.setBackground(null);
        GridDataFactory.fillDefaults().applyTo(introLabel);

        final Composite treeComposite = toolkit.createComposite(client, SWT.BORDER | SWT.DOUBLE_BUFFERED);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(treeComposite);
        GridLayoutFactory.fillDefaults().applyTo(treeComposite);

        widgetObservable = new TreeTableObservable(treeComposite);
        treeDataBinding = dbc.bindValue(widgetObservable, EMFObservables.observeValue(getVerificationElement(),
                TreePackage.Literals.COMMON_TREE_VERIFICATION_DATA__TREE));
    }

    private void createPropertiesControls(final FormToolkit toolkit, final Composite parent) {

        GridDataFactory align = GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER);

        Label verifyStyleLabel = toolkit.createLabel(parent, "Verify styles:");
        verifyStyleLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
        verifyStyleLabel.setBackground(null);
        align.applyTo(verifyStyleLabel);

        verifyStyleCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
        int selectedStyleInd = 0;
        dbc.bindValue(SWTObservables.observeSelection(verifyStyleCombo), EMFObservables.observeValue(
                getVerificationElement(), TreePackage.Literals.VERIFY_TREE_DATA__ENABLE_VERIFY_STYLE));
        for (VerifyStyleType type : VerifyStyleType.values()) {
            verifyStyleCombo.add(type.getLiteral());
            if (type.getValue() == getVerificationElement().getVerifyStyle().getValue()) {
                selectedStyleInd = verifyStyleCombo.getItemCount() - 1;
            }
        }
        verifyStyleCombo.select(selectedStyleInd);
        verifyStyleCombo.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                getVerificationElement().setVerifyStyle(VerifyStyleType.get(verifyStyleCombo.getText()));
                widgetObservable.updateOutputFormat();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
        align.applyTo(verifyStyleCombo);

        Button unverifiedChildrenCheck = new Button(parent, SWT.CHECK);
        unverifiedChildrenCheck.setText("Allow uncaptured children");
        unverifiedChildrenCheck
                .setToolTipText("Tree items from verification without chirdren, may contain children in UI. "
                        + "This might happen when tree was not fully expanded during capturing.");
        dbc.bindValue(SWTObservables.observeSelection(unverifiedChildrenCheck), EMFObservables.observeValue(
                getVerificationElement(), TreePackage.Literals.VERIFY_TREE_DATA__ALLOW_UNCAPTURED_CHILDREN));
        align.applyTo(unverifiedChildrenCheck);

        // Button missingColumnsCheck = new Button(parent, SWT.CHECK);
        // missingColumnsCheck.setText("Allow missing columns");
        // missingColumnsCheck.setToolTipText("This verification may contain columns, which are not present in UI");
        // dbc.bindValue(SWTObservables.observeSelection(missingColumnsCheck),
        // EMFObservables.observeValue(getVerificationElement(),
        // TreePackage.Literals.VERIFY_TREE_DATA__ALLOW_MISSING_COLUMNS));

        Button verifyIconsCheck = new Button(parent, SWT.CHECK);
        verifyIconsCheck.setText("Verify icons");

        dbc.bindValue(SWTObservables.observeSelection(verifyIconsCheck), EMFObservables
                .observeValue(getVerificationElement(), TreePackage.Literals.VERIFY_TREE_DATA__VERIFY_ICONS));
        verifyIconsCheck.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                widgetObservable.updateOutputFormat();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
        align.applyTo(verifyIconsCheck);
    }

    @Override
    public void select(Object data) {
        if (data instanceof TreeItemVerificationError) {
            TreeItemVerificationError err = (TreeItemVerificationError) data;

            widgetObservable.selectItemAt(err.getItemIndexPath());
        }
    }

    @Override
    public void setSelectionAtLine(int line) {
    }

    private class TreeTableObservable extends AbstractObservableValue {
        private Composite treeComposite = null;
        private TreeViewer viewer = null;
        private VerificationTreeLabelProvider labelProvider = null;
        private List<Image> columnImages = new ArrayList<Image>();

        public TreeTableObservable(Composite treeComposite) {
            this.treeComposite = treeComposite;
        }

        public void updateOutputFormat() {
            treeComposite.setRedraw(false);
            labelProvider.setDrawIcons(getVerificationElement().isVerifyIcons());
            labelProvider
                    .setIgnoreStyle(getVerificationElement().getVerifyStyle() == VerifyStyleType.IGNORE_STYLES);
            labelProvider.setSkipStyledText(
                    getVerificationElement().getVerifyStyle() == VerifyStyleType.IGNORE_STYLED_TEXT);
            TreeColumn[] cols = viewer.getTree().getColumns();
            if (getVerificationElement().isVerifyIcons()) {
                for (int i = 0; i < cols.length; i++) {
                    if (i < columnImages.size())
                        cols[i].setImage(columnImages.get(i));
                }
            } else {
                for (int i = 0; i < cols.length; i++) {
                    cols[i].setImage(null);
                }
            }
            viewer.refresh();
            verifyStyleCombo.setEnabled(getVerificationElement().isEnableVerifyStyle());
            treeComposite.setRedraw(true);
        }

        private TreePath toTreePath(List<Integer> indices) {
            @SuppressWarnings("unchecked")
            List<Row> rows = (List<Row>) viewer.getInput();
            List<Row> segments = new ArrayList<Row>();
            for (int i : indices) {
                if (i < 0 || i >= rows.size()) {
                    break;
                }
                Row curr = rows.get(i);
                segments.add(curr);
                rows = curr.getChildren();
            }
            return new TreePath(segments.toArray());
        }

        public void selectItemAt(List<Integer> itemIndexPath) throws IllegalArgumentException {
            if (viewer != null && viewer.getTree() != null && itemIndexPath.size() > 0) {
                TreePath treePath = toTreePath(itemIndexPath);
                viewer.setSelection(new TreeSelection(treePath), true);
            }
        }

        @Override
        public Object getValueType() {
            return null;
        }

        @Override
        protected Object doGetValue() {
            return null;
        }

        @Override
        protected void doSetValue(Object value) {
            if (value instanceof Tree) {
                Tree treeData = (Tree) value;
                Map<String, Image> images = deserializeImages(treeComposite.getDisplay(),
                        getVerificationElement().getImages());

                treeComposite.setRedraw(false);
                viewer = createTreeWidget(treeComposite, treeData, images);

                if (treeData.getSortColumnInd() != -1) {
                    viewer.getTree().setSortColumn(viewer.getTree().getColumn(treeData.getSortColumnInd()));
                    viewer.getTree().setSortDirection(treeData.getSortDirection());
                }
                labelProvider = new VerificationTreeLabelProvider(images, getVerificationElement().isVerifyIcons(),
                        getVerificationElement().getVerifyStyle() == VerifyStyleType.IGNORE_STYLES,
                        getVerificationElement().getVerifyStyle() == VerifyStyleType.IGNORE_STYLED_TEXT);
                viewer.setLabelProvider(labelProvider);
                viewer.setContentProvider(new VerificationTreeContentProvider());
                viewer.setInput(treeData.getRows());

                viewer.expandAll();

                widgetObservable.updateOutputFormat();

                treeComposite.setRedraw(true);
            }
        }

        private Map<String, Image> deserializeImages(Display display, EMap<String, byte[]> images) {
            Map<String, Image> result = new HashMap<String, Image>();
            for (Entry<String, byte[]> img : images.entrySet()) {
                result.put(img.getKey(), deserializeImage(display, img.getValue()));
            }
            return result;
        }

        private TreeViewer createTreeWidget(Composite parent, Tree treeData, Map<String, Image> images) {
            for (Control control : parent.getChildren()) {
                control.dispose();
            }
            TreeViewer viewer = new TreeViewer(parent, treeData.getStyle() | SWT.FULL_SELECTION);
            org.eclipse.swt.widgets.Tree tree = viewer.getTree();
            tree.setEnabled(treeData.isEnabled());
            tree.setHeaderVisible(treeData.isHeaderVisible());
            tree.setLinesVisible(treeData.isLinesVisible());
            tree.addListener(SWT.Selection, new Listener() {
                public void handleEvent(Event event) {
                    if (event.detail == SWT.CHECK && (event.item instanceof TreeItem)) {
                        TreeItem item = (TreeItem) event.item;
                        item.setChecked(!item.getChecked());
                    }
                }
            });

            TreeViewerEditor.create(viewer, new ColumnViewerEditorActivationStrategy(viewer) {
                protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
                    return (super.isEditorActivationEvent(event) && (getVerificationElement().getVerifyStyle()
                            .getValue() == VerifyStyleType.IGNORE_STYLED_TEXT_VALUE));
                }
            }, ColumnViewerEditor.DEFAULT);

            String[] columnProperties = new String[treeData.getColumns().size()];
            CellEditor[] cellEditors = new CellEditor[treeData.getColumns().size()];

            for (int columnNum = 0; columnNum < treeData.getColumns().size(); columnNum++) {
                final TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.NONE);

                // apply only for table verifications
                Column treeColumn = treeData.getColumns().get(columnNum);
                column.getColumn().setText(treeColumn.getName());
                column.getColumn().setWidth(treeColumn.getWidth());
                column.getColumn().setToolTipText(treeColumn.getTooltip());

                String imgPath = TreeVerificationUtils.getDecoratedImagePath(treeColumn.getImage());
                if (images.containsKey(imgPath)) {
                    Image img = images.get(imgPath);
                    columnImages.add(img);
                    if (getVerificationElement().isVerifyIcons()) {
                        column.getColumn().setImage(img);
                    }
                } else {
                    columnImages.add(null);
                }
                column.setLabelProvider(new ColumnLabelProvider());
                columnProperties[columnNum] = "" + columnNum;
                cellEditors[columnNum] = new TextCellEditor(tree);
            }

            if (treeData.getColumns().size() == 0) {
                //  initial for tree
                viewer.setColumnProperties(new String[] { "0" });
                viewer.setCellEditors(new CellEditor[] { new TextCellEditor(tree) });
            } else {
                viewer.setColumnProperties(columnProperties);
                viewer.setCellEditors(cellEditors);
            }

            viewer.setCellModifier(new ICellModifier() {
                public void modify(Object element, String property, Object value) {
                    String newValue = (String) value;
                    int index = Integer.parseInt(property);
                    if (((TreeItem) element).getData() instanceof Row) {
                        Cell cellItem = ((Row) ((TreeItem) element).getData()).getValues().get(index);
                        if (newValue != null && !cellItem.getData().getText().equals(newValue)) {
                            cellItem.getData().setText(newValue);
                            cellItem.getStyle().clear();
                            getVerificationElement().setEnableVerifyStyle(false);
                            updateOutputFormat();
                        }
                    }
                }

                public Object getValue(Object element, String property) {
                    String result = "";
                    if (element instanceof Row) {
                        int index = Integer.parseInt(property);
                        Cell cellItem = ((Row) element).getValues().get(index);
                        result = WidgetModels.getTextWithoutStyle(cellItem.getStyle(),
                                cellItem.getData().getText());
                    }
                    return result;
                }

                public boolean canModify(Object element, String property) {
                    return getVerificationElement().getVerifyStyle()
                            .getValue() == VerifyStyleType.IGNORE_STYLED_TEXT_VALUE;
                }
            });

            GridDataFactory.fillDefaults().grab(true, true).hint(100, 10).applyTo(viewer.getTree());
            parent.layout(true, true);

            return viewer;
        }
    }

    private static byte[] serializeImage(Image img) {
        ImageLoader imageLoader = new ImageLoader();
        imageLoader.data = new ImageData[] { img.getImageData() };
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        imageLoader.save(stream, SWT.IMAGE_PNG);
        return stream.toByteArray();
    }

    private static Image deserializeImage(Display display, byte[] img) {
        ImageLoader imageLoader = new ImageLoader();
        ByteArrayInputStream stream = new ByteArrayInputStream(img);
        ImageData[] data = imageLoader.load(stream);
        return new Image(display, data[0]);
    }
}