fr.lip6.move.coloane.core.ui.panels.ResultsView.java Source code

Java tutorial

Introduction

Here is the source code for fr.lip6.move.coloane.core.ui.panels.ResultsView.java

Source

/**
 * Copyright (c) 2006-2010 MoVe - Laboratoire d'Informatique de Paris 6 (LIP6).
 * 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:
 *   Jean-Baptiste VORON (LIP6) - Project Head / Initial contributor
 *   Clment DMOULINS (LIP6) - Project Manager
 *
 * Official contacts:
 *   coloane@lip6.fr
 *   http://coloane.lip6.fr
 */
package fr.lip6.move.coloane.core.ui.panels;

import fr.lip6.move.coloane.core.model.interfaces.ISpecialState;
import fr.lip6.move.coloane.core.results.ResultManager;
import fr.lip6.move.coloane.core.session.ISession;
import fr.lip6.move.coloane.core.session.ISessionManager;
import fr.lip6.move.coloane.core.session.SessionManager;
import fr.lip6.move.coloane.interfaces.model.IArc;
import fr.lip6.move.coloane.interfaces.model.IAttribute;
import fr.lip6.move.coloane.interfaces.model.IElement;
import fr.lip6.move.coloane.interfaces.model.IGraph;
import fr.lip6.move.coloane.interfaces.model.INode;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * Result View
 *
 * @author Jean-Baptiste Voron
 * @author Clment Dmoulins
 * @author Florian David
 */
public class ResultsView extends ViewPart {
    public static final String SELECTION_CHANGE = "ResultsView.SelectionChange"; //$NON-NLS-1$

    /** The SessionManager */
    private static final ISessionManager MANAGER = SessionManager.getInstance();

    /** Map that stores the special state for each object designed by results */
    private static Map<ISpecialState, Integer> checkStateMap = new HashMap<ISpecialState, Integer>();

    /** The tree view */
    private static CheckboxTreeViewer viewer;

    /** Action that deletes a result from the arc */
    private Action delete;

    /** Action that deletes all results from the result tree */
    private Action deleteAll;

    /** Action that collapses all children */
    private Action collapseAll;

    /** Action that expands all children */
    private Action expandAll;

    /** Listener on checkbox */
    private CheckStateListener checkStateListener;

    /**
     * Constructor
     */
    public ResultsView() {
        super();
        createActions();
    }

    /** {@inheritDoc} */
    @Override
    public final void dispose() {
        ISession session = MANAGER.getCurrentSession();
        if (session != null) {
            unHighlightAll(session.getGraph());
        }
        checkStateMap.clear();
        super.dispose();
    }

    /**
     * Remove a result from the view and modify the checkMap according to the new state of the view
     * @param result The result to remove from the view
     */
    public static void reinitResultView(IResultTree result) {
        uncheckAllResult(MANAGER.getCurrentSession(), result);
    }

    /** {@inheritDoc} */
    @Override
    public final void createPartControl(final Composite parent) {
        viewer = new CheckboxTreeViewer(parent, SWT.MULTI | SWT.BORDER | SWT.CHECK | SWT.FULL_SELECTION);
        viewer.getTree().setLinesVisible(true);
        viewer.setContentProvider(new ResultContentProvider());

        // Add the first column
        new TreeViewerColumn(viewer, SWT.LEFT).setLabelProvider(new ResultColumnLabelProvider(0));
        new TreeViewerColumn(viewer, SWT.LEFT).setLabelProvider(new ResultColumnLabelProvider(1));

        ResultManager resultsManager = null;
        if (MANAGER.getCurrentSession() != null) {
            resultsManager = MANAGER.getCurrentSession().getResultManager();
        }

        // Build an observer. It will observe a ResultTreeList.
        final Observer resultObserver = new Observer() {
            // Something has been updated !
            @Override
            public void update(final Observable o, Object arg) {
                final Integer width = (Integer) arg;
                // Update the UI... Take care !!
                parent.getDisplay().syncExec(new Runnable() {
                    @Override
                    public void run() {
                        // Add columns if necessary
                        for (int i = viewer.getTree().getColumnCount(); i < width; i++) {
                            TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.LEFT);
                            column.setLabelProvider(new ResultColumnLabelProvider(i));
                        }
                        updateColumnsWidth();
                        // Update the view
                        viewer.refresh();
                    }
                });
            }
        };

        // Add the observer to the result list
        if (resultsManager != null) {
            viewer.setInput(new MultiResultManager(MANAGER.getGlobalSession().getResultManager(), resultsManager));
            resultsManager.addObserver(resultObserver);
        } else {
            viewer.setInput(MANAGER.getGlobalSession().getResultManager());
        }
        MANAGER.getGlobalSession().getResultManager().addObserver(resultObserver);

        // Allow the user to delete a result that has been selected (activate the action)
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                delete.setEnabled(true);
            }
        });

        // When a result is selected... Add a listener to this checkbox
        checkStateListener = new CheckStateListener(viewer, checkStateMap);
        viewer.addCheckStateListener(checkStateListener);

        // Add an observer to observe session switch
        MANAGER.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals(ISessionManager.PROP_CURRENT_SESSION)) {
                    final ISession previous = (ISession) evt.getOldValue();
                    final ISession current = (ISession) evt.getNewValue();
                    if (!parent.isDisposed() && !parent.getDisplay().isDisposed()) {
                        parent.getDisplay().asyncExec(new Runnable() {
                            @Override
                            public void run() {
                                if (previous != null) {
                                    previous.getResultManager().deleteObserver(resultObserver);
                                }
                                if (current != null) {
                                    viewer.setInput(
                                            new MultiResultManager(MANAGER.getGlobalSession().getResultManager(),
                                                    current.getResultManager()));
                                    current.getResultManager().addObserver(resultObserver);
                                    viewer.refresh();
                                } else {
                                    viewer.setInput(MANAGER.getGlobalSession().getResultManager());
                                    viewer.refresh();
                                }
                            }
                        });
                    }
                }
            }
        });

        createToolbar();
        updateColumnsWidth();
        Tree tree = viewer.getTree();
        tree.setHeaderVisible(true);
        tree.setLayoutData(new GridData(GridData.FILL_BOTH));
    }

    /**
     * Create the toolbar
     */
    private void createToolbar() {
        IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
        toolbarManager.add(expandAll);
        toolbarManager.add(collapseAll);
        toolbarManager.add(new Separator());
        toolbarManager.add(delete);
        toolbarManager.add(deleteAll);
    }

    /**
     * Create actions associated to the result view
     */
    private void createActions() {
        ImageDescriptor cross = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.ui", //$NON-NLS-1$
                "$nl$/icons/full/elcl16/progress_rem.gif"); //$NON-NLS-1$
        ImageDescriptor doubleCross = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.ui", //$NON-NLS-1$
                "$nl$/icons/full/elcl16/progress_remall.gif"); //$NON-NLS-1$
        ImageDescriptor collapse = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.ui", //$NON-NLS-1$
                "$nl$/icons/full/elcl16/collapseall.gif"); //$NON-NLS-1$
        ImageDescriptor expand = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.ui.cheatsheets", //$NON-NLS-1$
                "$nl$/icons/elcl16/expandall.gif"); //$NON-NLS-1$

        // Action for collapsing all results
        collapseAll = new Action(Messages.ResultsView_4) {
            @Override
            public void run() {
                viewer.collapseAll();
            }
        };
        collapseAll.setToolTipText(Messages.ResultsView_4);
        collapseAll.setImageDescriptor(collapse);

        // Action for expanding all results
        expandAll = new Action(Messages.ResultsView_5) {
            @Override
            public void run() {
                viewer.expandAll();
            }
        };
        expandAll.setToolTipText(Messages.ResultsView_5);
        expandAll.setImageDescriptor(expand);

        // Action for deleting a result
        delete = new Action(Messages.ResultsView_0) {
            @Override
            public void run() {
                for (Object obj : ((ITreeSelection) viewer.getSelection()).toList()) {
                    IResultTree node = (IResultTree) obj;
                    ISession session = MANAGER.getCurrentSession();
                    ResultsView.uncheckAllResult(session, node);
                    node.remove();
                    viewer.refresh();
                    this.setEnabled(false);
                }
            }
        };
        delete.setEnabled(false);
        delete.setToolTipText(Messages.ResultsView_1);
        delete.setImageDescriptor(cross);

        // Action for deleting all results
        deleteAll = new Action(Messages.ResultsView_2) {
            @Override
            public void run() {
                ISession session = MANAGER.getCurrentSession();
                ResultManager list = session.getResultManager();
                ResultsView.this.unHighlightAll(session.getGraph());
                for (IResultTree result : list.getChildren()) {
                    ResultsView.this.removeTips(session, result);
                }
                list.removeAll();
            }
        };
        deleteAll.setToolTipText(Messages.ResultsView_3);
        deleteAll.setImageDescriptor(doubleCross);
    }

    /**
     * Remove all session tips recursively.
     * @param session the session where tips are removed.
     * @param result the current result tree which contained tips to remove.
     */
    private void removeTips(ISession session, IResultTree result) {
        session.removeTips(result.getTips());
        for (IResultTree child : result.getChildren()) {
            removeTips(session, child);
        }
    }

    /**
     * This method unchecks results provided by the IResultTree. It also modifies the checkStateMap consequently.
     * @param session The session in which is link the result.
     * @param result The result to be unchecked.
     */
    private static void uncheckAllResult(ISession session, IResultTree result) {
        // If the result is checked . . .
        if (viewer.getChecked(result)) {
            // Model objects which are only highlighted by this result will be unhighlighted
            for (int id : result.getHighlighted()) {
                // We get the associate element
                ISpecialState element = (ISpecialState) session.getGraph().getObject(id);
                if (element != null) {
                    // The checkStateMap is modified
                    Integer value = checkStateMap.get(element);
                    if (value != null) {
                        // If the object is checked strictly more than 1 time, we just decrement its check value
                        if (value > 1) {
                            value--;
                            checkStateMap.put(element, value);
                        } else if (value == 1) { // If the object is only check 1 time, it's only by this result so we unhighlight it
                            value--;
                            checkStateMap.put(element, value);
                            element.setSpecialState(false);
                        }
                    }
                }
            }

            // Now the attributes . . .
            Map<Integer, List<String>> attributesMap = result.getAttributesOutline();
            // For each object ID in the checkStateMap
            for (int id : attributesMap.keySet()) {
                // We get the associate element
                IElement element = session.getGraph().getObject(id);
                if (element != null) {
                    // Then we get the highlighted attributes list
                    List<String> listAttribute = attributesMap.get(id);
                    for (String strAttribute : listAttribute) {
                        // For each attribute, we get its check value
                        ISpecialState attribute = (ISpecialState) element.getAttribute(strAttribute);
                        Integer value = checkStateMap.get(attribute);
                        if (value != null) {
                            // If the attribute is checked strictly more than 1 time, we just decrement its check value
                            if (value > 1) {
                                value--;
                                checkStateMap.put(attribute, value);
                            } else if (value == 1) { // If the attribute is only check 1 time, it's only by this result so we unhighlight it
                                value--;
                                checkStateMap.put(attribute, value);
                                attribute.setSpecialState(false);
                            }
                        }
                    }
                }
            }
            session.removeTips(result.getTips());
        }

        // We call the method recursively on every child result
        for (IResultTree child : result.getChildren()) {
            uncheckAllResult(session, child);
        }
    }

    /**
     * Remove the highlight state on all graph elements.
     * @param graph the graph where highlight state has to be removed.
     */
    private void unHighlightAll(IGraph graph) {
        for (IArc arc : graph.getArcs()) {
            ((ISpecialState) arc).setSpecialState(false);
            for (IAttribute attribute : arc.getAttributes()) {
                ((ISpecialState) attribute).setSpecialState(false);
            }
        }
        for (INode node : graph.getNodes()) {
            ((ISpecialState) node).setSpecialState(false);
            for (IAttribute attribute : node.getAttributes()) {
                ((ISpecialState) attribute).setSpecialState(false);
            }
        }
    }

    /**
     * Update the columns width
     */
    private void updateColumnsWidth() {
        Tree tree = viewer.getTree();
        for (int i = 0, n = tree.getColumnCount(); i < n; i++) {
            tree.getColumn(i).setWidth(200);
        }
    }

    /** {@inheritDoc} */
    @Override
    public final void setFocus() {
        return;
    }
}