org.cs3.pdt.analysis.views.AbstractAnalysisView.java Source code

Java tutorial

Introduction

Here is the source code for org.cs3.pdt.analysis.views.AbstractAnalysisView.java

Source

/*****************************************************************************
 * This file is part of the Prolog Development Tool (PDT)
 * 
 * Author: Andreas Becker (among others)
 * WWW: http://sewiki.iai.uni-bonn.de/research/pdt/start
 * Mail: pdt@lists.iai.uni-bonn.de
 * Copyright (C): 2014, CS Dept. III, University of Bonn
 * 
 * All rights reserved. This program is 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
 * 
 ****************************************************************************/
package org.cs3.pdt.analysis.views;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;

import org.cs3.pdt.analysis.ImageRepository;
import org.cs3.pdt.analysis.model.IAnalysis;
import org.cs3.pdt.analysis.model.IAnalysisCategory;
import org.cs3.pdt.analysis.model.IResult;
import org.cs3.pdt.analysis.model.IResultModel;
import org.cs3.pdt.common.PDTCommonUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.MarkerUtilities;

public abstract class AbstractAnalysisView extends ViewPart {

    private CheckboxTreeViewer analysisTreeViewer;
    private TreeViewer resultTreeViewer;

    private TreeViewerColumn[] analysisTreeViewerColumns;
    private TreeViewerColumn[] resultTreeViewerColumns;

    private AnalysisTableContentProvider analysisContentProvider;
    private ResultTableContentProvider resultContentProvider;

    public AbstractAnalysisView() {
    }

    protected abstract IResultModel getResultModel();

    protected abstract void log(Exception e);

    protected CheckboxTreeViewer getAnalysisTreeViewer() {
        return analysisTreeViewer;
    }

    protected TreeViewer getResultTreeViewer() {
        return resultTreeViewer;
    }

    protected TreeViewerColumn[] getAnalysisTreeViewerColumns() {
        return analysisTreeViewerColumns;
    }

    protected TreeViewerColumn[] getResultTreeViewerColumns() {
        return resultTreeViewerColumns;
    }

    protected AnalysisTableContentProvider getAnalysisContentProvider() {
        return analysisContentProvider;
    }

    protected ResultTableContentProvider getResultContentProvider() {
        return resultContentProvider;
    }

    @Override
    public void createPartControl(final Composite parent) {
        Composite compLeft = new Composite(parent, SWT.NONE);
        final Sash sash = new Sash(parent, SWT.VERTICAL);

        compLeft.setLayout(new GridLayout(1, false));
        Composite compRight = new Composite(parent, SWT.NONE);
        compRight.setLayout(new GridLayout(1, false));
        createControllerArea(compLeft);
        analysisTreeViewer = createAnalysisTreeViewer(compLeft);

        Label resultLabel = new Label(compRight, SWT.NONE);
        resultLabel.setText("Results for selected analyses");

        resultTreeViewer = createResultTreeViewer(compRight);
        initSashFormData(parent, compLeft, sash, compRight);
    }

    private void initSashFormData(final Composite parent, Composite compLeft, final Sash sash,
            Composite compRight) {
        final FormLayout form = new FormLayout();
        parent.setLayout(form);
        FormData button1Data = new FormData();
        button1Data.left = new FormAttachment(0, 0);
        button1Data.right = new FormAttachment(sash, 0);
        button1Data.top = new FormAttachment(0, 0);
        button1Data.bottom = new FormAttachment(100, 0);
        compLeft.setLayoutData(button1Data);

        final int limit = 20, percent = 50;
        final FormData sashData = new FormData();
        sashData.left = new FormAttachment(percent, 0);
        sashData.top = new FormAttachment(0, 0);
        sashData.bottom = new FormAttachment(100, 0);
        sash.setLayoutData(sashData);
        sash.addListener(SWT.Selection, new Listener() {
            @Override
            public void handleEvent(Event e) {
                Rectangle sashRect = sash.getBounds();
                Rectangle shellRect = parent.getClientArea();
                int right = shellRect.width - sashRect.width - limit;
                e.x = Math.max(Math.min(e.x, right), limit);
                if (e.x != sashRect.x) {
                    sashData.left = new FormAttachment(0, e.x);
                    parent.layout();
                }
            }
        });

        FormData button2Data = new FormData();
        button2Data.left = new FormAttachment(sash, 0);
        button2Data.right = new FormAttachment(100, 0);
        button2Data.top = new FormAttachment(0, 0);
        button2Data.bottom = new FormAttachment(100, 0);
        compRight.setLayoutData(button2Data);
    }

    protected Control createControllerArea(Composite parent) {
        Composite controllerArea = new Composite(parent, SWT.NONE);
        controllerArea.setLayout(new GridLayout(2, false));
        controllerArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        Control selector = createSelector(controllerArea);
        selector.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));

        ToolBar controllerToolBar = new ToolBar(controllerArea, SWT.HORIZONTAL);
        controllerToolBar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
        ToolBarManager controllerToolBarManager = new ToolBarManager(controllerToolBar);
        createToolbarActions(controllerToolBarManager);
        controllerToolBarManager.update(true);

        return controllerArea;
    }

    protected abstract Control createSelector(Composite parent);

    protected void createToolbarActions(IToolBarManager toolBarManager) {
        toolBarManager.add(new Action() {
            @Override
            public void run() {
                runEnabledAnalyses();
            }

            @Override
            public ImageDescriptor getImageDescriptor() {
                return ImageRepository.getImageDescriptor(ImageRepository.ICON_RUN);
            }

            @Override
            public String getToolTipText() {
                return getText();
            }

            @Override
            public String getText() {
                return "Run all enabled analyses";
            }
        });

        toolBarManager.add(new Action() {
            @Override
            public void run() {
                clearAllResults();
            }

            @Override
            public ImageDescriptor getImageDescriptor() {
                return ImageRepository.getImageDescriptor(ImageRepository.ICON_REMOVE);
            }

            @Override
            public String getToolTipText() {
                return getText();
            }

            @Override
            public String getText() {
                return "Clear all analysis results";
            }
        });
        toolBarManager.add(new Separator());
    }

    protected abstract void runEnabledAnalyses();

    protected abstract void clearAllResults();

    protected abstract void runSelectedAnalyses();

    protected abstract void clearSelectedAnalyses();

    protected abstract void refreshAnalysisEnablement();

    protected TreeViewer createResultTreeViewer(Composite parent) {
        final TreeViewer treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        GridData gridData = new GridData();
        gridData.grabExcessHorizontalSpace = true;
        gridData.horizontalAlignment = GridData.FILL;
        gridData.grabExcessVerticalSpace = true;
        gridData.verticalAlignment = GridData.FILL;

        Tree tree = treeViewer.getTree();

        tree.addMouseListener(new MouseListener() {

            @Override
            public void mouseUp(MouseEvent e) {
            }

            @Override
            public void mouseDown(MouseEvent e) {
            }

            @Override
            public void mouseDoubleClick(MouseEvent e) {
                ISelection selection = treeViewer.getSelection();
                if (selection instanceof ITreeSelection) {
                    Object o = ((ITreeSelection) selection).getFirstElement();
                    if (o instanceof IResult) {
                        selectResultInEditor((IResult) o);
                    }
                }
            }
        });
        tree.setLayoutData(gridData);
        tree.setHeaderVisible(true);
        tree.setLinesVisible(true);

        resultContentProvider = new ResultTableContentProvider(getResultModel());
        treeViewer.setContentProvider(resultContentProvider);
        treeViewer.setInput(new Object());

        resultTreeViewerColumns = new TreeViewerColumn[3];

        for (int i = 0; i < resultTreeViewerColumns.length; i++) {
            resultTreeViewerColumns[i] = new TreeViewerColumn(treeViewer, SWT.NONE);
            resultTreeViewerColumns[i].getColumn().setMoveable(true);
        }

        resultTreeViewerColumns[0].getColumn().setWidth(300);
        resultTreeViewerColumns[0].getColumn().setText("Description");
        resultTreeViewerColumns[0].setLabelProvider(new ResultTableDescriptionColumnLabelProvider());

        resultTreeViewerColumns[1].getColumn().setWidth(150);
        resultTreeViewerColumns[1].getColumn().setText("Resource");
        resultTreeViewerColumns[1].setLabelProvider(new ResultTableResourceColumnLabelProvider());

        resultTreeViewerColumns[2].getColumn().setWidth(100);
        resultTreeViewerColumns[2].getColumn().setText("Location");
        resultTreeViewerColumns[2].setLabelProvider(new ResultTableLocationColumnLabelProvider());

        return treeViewer;
    }

    protected void selectResultInEditor(IResult result) {
        IFile resource = result.getResource();
        int start = MarkerUtilities.getCharStart(result.getMarker());
        int end = MarkerUtilities.getCharEnd(result.getMarker());
        try {
            PDTCommonUtil.selectInEditor(start, end - start, resource, true, false);
        } catch (PartInitException e) {
            log(e);
        }
    }

    protected CheckboxTreeViewer createAnalysisTreeViewer(Composite parent) {
        final CheckboxTreeViewer treeViewer = new CheckboxTreeViewer(parent,
                SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        GridData gridData = new GridData();
        gridData.grabExcessHorizontalSpace = true;
        gridData.horizontalAlignment = GridData.FILL;
        gridData.grabExcessVerticalSpace = true;
        gridData.verticalAlignment = GridData.FILL;

        final Tree tree = treeViewer.getTree();
        tree.setLayoutData(gridData);
        tree.setHeaderVisible(true);
        tree.setLinesVisible(true);

        Menu menu = new Menu(tree.getShell(), SWT.POP_UP);

        MenuItem mnItemRun = new MenuItem(menu, SWT.PUSH);
        mnItemRun.setText("Run analysis");
        mnItemRun.setImage(ImageRepository.getImage(ImageRepository.ICON_RUN));
        mnItemRun.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent evt) {
                runSelectedAnalyses();
            }
        });

        MenuItem mnItemRemove = new MenuItem(menu, SWT.PUSH);
        mnItemRemove.setText("Clear analysis results");
        mnItemRemove.setImage(ImageRepository.getImage(ImageRepository.ICON_REMOVE));
        mnItemRemove.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                clearSelectedAnalyses();
            }
        });

        new MenuItem(menu, SWT.SEPARATOR);

        MenuItem mnItemSelectAll = new MenuItem(menu, SWT.PUSH);
        mnItemSelectAll.setText("Enable all");
        mnItemSelectAll.setImage(ImageRepository.getImage(ImageRepository.ICON_SELECT_ALL));
        mnItemSelectAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setEnabledOnAll(true);
                analysisCheckStateChanged();
            }
        });

        MenuItem mnItemSelectNone = new MenuItem(menu, SWT.PUSH);
        mnItemSelectNone.setText("Disable all");
        mnItemSelectNone.setImage(ImageRepository.getImage(ImageRepository.ICON_SELECT_NONE));
        mnItemSelectNone.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setEnabledOnAll(false);
                analysisCheckStateChanged();
            }
        });

        MenuItem mnItemExpandAll = new MenuItem(menu, SWT.PUSH);
        mnItemExpandAll.setText("Expand all");
        mnItemExpandAll.setImage(ImageRepository.getImage(ImageRepository.ICON_EXPAND_ALL));
        mnItemExpandAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                treeViewer.expandAll();
            }
        });

        MenuItem mnItemCollapseAll = new MenuItem(menu, SWT.PUSH);
        mnItemCollapseAll.setText("Collapse all");
        mnItemCollapseAll.setImage(ImageRepository.getImage(ImageRepository.ICON_COLLAPSE_ALL));
        mnItemCollapseAll.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                treeViewer.collapseAll();
            }
        });

        tree.setMenu(menu);
        treeViewer.addCheckStateListener(new ICheckStateListener() {
            @Override
            public void checkStateChanged(CheckStateChangedEvent event) {
                treeViewer.setSubtreeChecked(event.getElement(), event.getChecked());
                checkAncestorPath(event.getElement(), event.getChecked(), false, null);

                analysisCheckStateChanged();
            }
        });
        treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                analysisSelectionChanged(event.getSelection());
            }
        });

        analysisContentProvider = new AnalysisTableContentProvider(getResultModel());
        analysisContentProvider.setView(this);
        treeViewer.setContentProvider(analysisContentProvider);
        treeViewer.setInput(new Object());

        analysisTreeViewerColumns = new TreeViewerColumn[3];

        for (int i = 0; i < analysisTreeViewerColumns.length; i++) {
            analysisTreeViewerColumns[i] = new TreeViewerColumn(treeViewer, SWT.NONE);
            analysisTreeViewerColumns[i].getColumn().setMoveable(true);
        }

        analysisTreeViewerColumns[0].getColumn().setWidth(200);
        analysisTreeViewerColumns[0].getColumn().setText("Name");
        analysisTreeViewerColumns[0].setLabelProvider(new AnalysisTableNameColumnLabelProvider());

        analysisTreeViewerColumns[1].getColumn().setWidth(300);
        analysisTreeViewerColumns[1].getColumn().setText("Description");
        analysisTreeViewerColumns[1].setLabelProvider(new AnalysisTableDescriptionColumnLabelProvider());

        analysisTreeViewerColumns[2].getColumn().setWidth(100);
        analysisTreeViewerColumns[2].getColumn().setText("# Results");
        analysisTreeViewerColumns[2].setLabelProvider(new AnalysisTableCountColumnLabelProvider());

        ColumnViewerToolTipSupport.enableFor(treeViewer, ToolTip.NO_RECREATE);

        return treeViewer;
    }

    protected void analysisSelectionChanged(ISelection newSelection) {
        resultContentProvider.setSelectedAnalyses(getSelectedAnalyses(newSelection));
    }

    protected void analysisCheckStateChanged() {
    }

    protected List<IAnalysis> getSelectedAnalyses(ISelection selection) {
        TreeSet<IAnalysis> result = new TreeSet<IAnalysis>();
        if (!(selection instanceof ITreeSelection)) {
            return new ArrayList<>(result);
        }
        ITreeSelection treeSelection = (ITreeSelection) selection;
        for (Object o : treeSelection.toArray()) {
            if (o instanceof IAnalysis) {
                result.add((IAnalysis) o);
            } else if (o instanceof IAnalysisCategory) {
                result.addAll(((IAnalysisCategory) o).getAnalyses());
            }
        }
        return new ArrayList<>(result);
    }

    protected List<IAnalysis> getEnabledAnalyses() {
        TreeSet<IAnalysis> result = new TreeSet<IAnalysis>();
        for (Object element : analysisTreeViewer.getCheckedElements()) {
            if (element instanceof IAnalysis) {
                result.add((IAnalysis) element);
            }
        }
        return new ArrayList<>(result);
    }

    protected void setEnabledAnalyses(List<IAnalysis> analyses) {
        Object[] elements = analyses.toArray();

        analysisTreeViewer.setCheckedElements(elements);

        HashSet<Object> checkedElements = new HashSet<>();
        for (Object element : elements) {
            checkAncestorPath(element, true, false, checkedElements);
        }
    }

    protected void setEnabledOnAll(boolean enabled) {
        TreePath[] expandedTreePaths = analysisTreeViewer.getExpandedTreePaths();
        analysisTreeViewer.expandAll();

        for (Object element : analysisTreeViewer.getExpandedElements()) {
            analysisTreeViewer.setSubtreeChecked(element, enabled);
        }

        analysisTreeViewer.setExpandedTreePaths(expandedTreePaths);
    }

    private void checkAncestorPath(Object element, boolean checked, boolean grayed,
            HashSet<Object> checkedElements) {
        if (element == null) {
            return;
        }
        if (checkedElements != null && checkedElements.contains(element)) {
            return;
        }
        if (grayed) {
            checked = true;
        } else {
            Object[] children = analysisContentProvider.getChildren(element);
            for (Object child : children) {
                if (analysisTreeViewer.getGrayed(child) || checked != analysisTreeViewer.getChecked(child)) {
                    checked = true;
                    grayed = true;
                    break;
                }
            }
        }
        analysisTreeViewer.setChecked(element, checked);
        analysisTreeViewer.setGrayed(element, grayed);

        if (checkedElements != null) {
            checkedElements.add(element);
        }

        checkAncestorPath(analysisContentProvider.getParent(element), checked, grayed, checkedElements);
    }

    @Override
    public void setFocus() {
        analysisTreeViewer.getTree().setFocus();
    }

}