de.hentschel.visualdbc.statistic.ui.control.StatisticComposite.java Source code

Java tutorial

Introduction

Here is the source code for de.hentschel.visualdbc.statistic.ui.control.StatisticComposite.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Karlsruhe Institute of Technology, Germany
 *                    Technical University Darmstadt, Germany
 *                    Chalmers University of Technology, Sweden
 * 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:
 *    Technical University Darmstadt - initial API and implementation and/or initial documentation
 *******************************************************************************/

package de.hentschel.visualdbc.statistic.ui.control;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.ocl.util.ObjectUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TreeColumn;

import de.hentschel.visualdbc.dbcmodel.DbcModel;
import de.hentschel.visualdbc.dbcmodel.DbcProofObligation;
import de.hentschel.visualdbc.dbcmodel.DbcmodelPackage;
import de.hentschel.visualdbc.statistic.ui.emfAdapter.StatisticDbcmodelItemProviderAdapterFactory;
import de.hentschel.visualdbc.statistic.ui.util.StatisticColorDecorator;
import de.hentschel.visualdbc.statistic.ui.wizard.SelectProofObligationsWizard;

/**
 * Shows the static tree with the content provided by an {@link IStatisticProvider}.
 * @author Martin Hentschel
 */
public class StatisticComposite extends Composite {
    /**
     * The used {@link ComposedAdapterFactory}.
     */
    private ComposedAdapterFactory adapterFactory;

    /**
     * The shown model
     */
    private DbcModel model;

    /**
     * The shown {@link TreeViewer}.
     */
    private TreeViewer viewer;

    /**
     * The layout used to arrange in the columns in {@link #viewer}.
     */
    private TreeColumnLayout viewerLayout;

    /**
     * Contains all observed obligations.
     */
    private List<DbcProofObligation> observedObligations = new LinkedList<DbcProofObligation>();

    /**
     * The currently selected proof obligations.
     */
    private List<DbcProofObligation> selectedObligations = new LinkedList<DbcProofObligation>();

    /**
     * The {@link IStatisticProvider} that is used.
     */
    private IStatisticProvider statisticProvider;

    /**
     * Listens for changes on {@link #model} and {@link #observedObligations}.
     */
    private Adapter modelListener = new AdapterImpl() {
        @Override
        public void notifyChanged(Notification msg) {
            handleModelChanged(msg);
        }
    };

    /**
     * The used {@link StatisticColorDecorator}
     */
    private StatisticColorDecorator colorDecorator;

    /**
     * Constructor.
     * @param parent The parent {@link Composite}.
     * @param style The style to use.
     * @param statisticProvider The {@link IStatisticProvider} to use.
     */
    public StatisticComposite(Composite parent, int style, IStatisticProvider statisticProvider) {
        super(parent, style);
        Assert.isNotNull(statisticProvider);
        this.statisticProvider = statisticProvider;
        // Set layout
        viewerLayout = new TreeColumnLayout();
        setLayout(viewerLayout);
        // Get model
        model = statisticProvider.getModel();
        if (model != null) {
            model.eAdapters().add(modelListener);
            selectedObligations = new LinkedList<DbcProofObligation>(model.getProofObligations());
        }
        // Create viewer
        updateViewer();
    }

    /**
     * Disposes the old viewer and creates a new one.
     */
    protected void updateViewer() {
        // Remove old viewer
        if (colorDecorator != null) {
            colorDecorator.dispose();
        }
        if (viewer != null) {
            viewer.getTree().dispose();
        }
        removeListenerFromProofObligations();
        if (adapterFactory != null) {
            adapterFactory.dispose();
        }
        // Create viewer
        viewer = new TreeViewer(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        viewer.getTree().setHeaderVisible(true);
        List<DbcProofObligation> columnProofObligations = addColumsnToViewer(viewer, viewerLayout, model);
        adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
        adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
        adapterFactory.addAdapterFactory(new StatisticDbcmodelItemProviderAdapterFactory(columnProofObligations));
        adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
        viewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
        AdapterFactoryLabelProvider labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
        labelProvider.setFireLabelUpdateNotifications(true);
        viewer.setLabelProvider(labelProvider);
        viewer.setInput(model);
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {
                handleDoubleClick(event);
            }
        });
        colorDecorator = new StatisticColorDecorator(viewer, 1, selectedObligations, adapterFactory);
        colorDecorator.initTreeItems();
        // Update UI
        layout();
    }

    /**
     * Handles a double click in the viewer.
     * @param event The event.
     */
    protected void handleDoubleClick(DoubleClickEvent event) {
        if (statisticProvider != null) {
            statisticProvider.select(viewer.getSelection());
        }
    }

    /**
     * When the model has changed.
     * @param msg The change {@link Notification}.
     */
    protected void handleModelChanged(Notification msg) {
        if (DbcmodelPackage.Literals.DBC_MODEL__PROOF_OBLIGATIONS.equals(msg.getFeature())) {
            if (Notification.ADD == msg.getEventType() || Notification.ADD_MANY == msg.getEventType()
                    || Notification.REMOVE == msg.getEventType()
                    || Notification.REMOVE_MANY == msg.getEventType()) {
                updateViewer();
            }
        } else if (DbcmodelPackage.Literals.DBC_PROOF_OBLIGATION__OBLIGATION.equals(msg.getFeature())) {
            if (Notification.SET == msg.getEventType()) {
                updateColumnText(msg.getNotifier(), msg.getNewStringValue());
            }
        }
    }

    /**
     * Updates the column text on the column of {@link #viewer} that
     * has the given column data.
     * @param columnData The column data of the column to update.
     * @param newText The new text to set on the column.
     */
    protected void updateColumnText(Object columnData, String newText) {
        // Search column with the given column data.
        TreeColumn column = null;
        int i = 0;
        while (column == null && i < viewer.getTree().getColumnCount()) {
            TreeColumn currentColumn = viewer.getTree().getColumn(i);
            if (ObjectUtil.equal(columnData, currentColumn.getData())) {
                column = currentColumn;
            }
            i++;
        }
        // Update title
        if (column != null) {
            column.setText(newText);
        }
    }

    /**
     * Adds the columns to the viewer.
     * @param viewer The parent {@link TreeViewer}
     * @param viewerLayout The layout to arrange the columns in the {@link TreeViewer}.
     * @param model The {@link DbcModel} that contains the available proof obligations.
     */
    protected List<DbcProofObligation> addColumsnToViewer(TreeViewer viewer, TreeColumnLayout viewerLayout,
            DbcModel model) {
        TreeViewerColumn mainColumn = new TreeViewerColumn(viewer, SWT.NONE);
        mainColumn.getColumn().setText("Main");
        mainColumn.getColumn().setMoveable(true);
        viewerLayout.setColumnData(mainColumn.getColumn(), new ColumnWeightData(100));
        List<DbcProofObligation> result = new LinkedList<DbcProofObligation>();
        if (model != null) {
            for (DbcProofObligation obligation : model.getProofObligations()) {
                if (selectedObligations.contains(obligation)) {
                    TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.NONE);
                    column.getColumn().setText(obligation.getObligation());
                    column.getColumn().setData(obligation);
                    column.getColumn().setMoveable(true);
                    viewerLayout.setColumnData(column.getColumn(), new ColumnWeightData(10));
                    observedObligations.add(obligation);
                    obligation.eAdapters().add(modelListener);
                    result.add(obligation);
                }
            }
        }
        return result;
    }

    /**
     * Removes the listener from all observed {@link ProofObligation} in
     * {@link #observedObligations}.
     */
    protected void removeListenerFromProofObligations() {
        for (DbcProofObligation obligation : observedObligations) {
            obligation.eAdapters().remove(modelListener);
        }
        observedObligations.clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose() {
        if (model != null) {
            model.eAdapters().remove(modelListener);
        }
        removeListenerFromProofObligations();
        if (colorDecorator != null) {
            colorDecorator.dispose();
        }
        if (adapterFactory != null) {
            adapterFactory.dispose();
        }
        selectedObligations.clear();
        super.dispose();
    }

    /**
     * Opens the dialog to select proof obligations.
     */
    public void openSelectProofObligationsDialog() {
        List<DbcProofObligation> newSelectedObligations = SelectProofObligationsWizard.open(getShell(),
                model.getProofObligations(), observedObligations);
        if (newSelectedObligations != null) {
            this.selectedObligations = newSelectedObligations;
            updateViewer();
        }
    }
}