org.eclipse.photran.internal.ui.browser.EdgesTab.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.photran.internal.ui.browser.EdgesTab.java

Source

/*******************************************************************************
 * Copyright (c) 2010 University of Illinois at Urbana-Champaign 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:
 *    Abhishek Sharma, UIUC - Initial API and implementation
 *******************************************************************************/
package org.eclipse.photran.internal.ui.browser;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.photran.internal.core.vpg.IVPGNode;
import org.eclipse.photran.internal.core.vpg.VPGEdge;
import org.eclipse.photran.internal.core.vpg.eclipse.EclipseVPG;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CaretEvent;
import org.eclipse.swt.custom.CaretListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

/**
 * The Edges tab in the VPG Browser.
 * 
 * @author Abhishek Sharma
 */
@SuppressWarnings("rawtypes")
class EdgesTab {
    private TabItem edges;
    private Composite composite;
    private StyledText styledText;
    private Button showAll;
    private Button showSelected;
    private Button edgeButton;
    private String filename;
    private List<VPGEdge<?, ?, ?>> edgesInFile;
    private Set<VPGEdge<?, ?, ?>> showEdges;
    private EclipseVPG vpg;
    private Set<Integer> edgeTypes;
    private Set<Integer> edgeTypesToShow;
    private List<Color> color;
    private Label label;

    public EdgesTab(TabItem edges, TabFolder tabFolder, EclipseVPG vpg) {
        this.vpg = vpg;
        this.filename = null;
        this.edgesInFile = Collections.emptyList();
        this.showEdges = Collections.emptySet();
        this.edges = edges;
        this.edgeTypes = Collections.emptySet();
        this.edgeTypesToShow = new HashSet<Integer>();
        this.color = Collections.emptyList();

        color = new ArrayList<Color>();
        addColors();
        createControls(tabFolder);
    }

    /** Adds three new colors red,green and blue to the color list
     * 
     */
    private void addColors() {
        //Adds three new colors red,green and blue to the color list
        color.add(new Color(null, new RGB(192, 0, 0)));
        color.add(new Color(null, new RGB(0, 192, 0)));
        color.add(new Color(null, new RGB(0, 0, 192)));
    }

    private void createControls(TabFolder tabfolder) {
        createComposite(tabfolder);
        createRadioButtons();
        createEdgesMenu();
        createStyledText();
        createLabel();
    }

    private void createLabel() {
        label = new Label(composite, SWT.NONE);
        label.setText(""); //$NON-NLS-1$
    }

    private void createEdgesMenu() {
        edgeButton = new Button(composite, SWT.FLAT);
        edgeButton.setText(Messages.EdgesTab_EdgeTypes);
        edgeButton.addSelectionListener(new ShowEdgeTypesMenu());
    }

    private class ShowEdgeTypesMenu implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            Menu popupMenu = new Menu(edgeButton);

            //This loop creates the Menu items and adds them to the menu.The Menu items
            //are the types of edges present in the file
            for (Integer type : edgeTypes) {
                MenuItem menuItem = new MenuItem(popupMenu, SWT.CHECK);
                menuItem.setText(vpg.describeEdgeType(type));
                menuItem.addSelectionListener(new MenuItemSelectionListener(type));
                menuItem.setSelection(edgeTypesToShow.contains(type));
            }

            new MenuItem(popupMenu, SWT.SEPARATOR);

            MenuItem menuItem = new MenuItem(popupMenu, SWT.CHECK);
            menuItem.setText(Messages.EdgesTab_ShowAllEdges);
            menuItem.addSelectionListener(new SelectAllSelectionListener());
            popupMenu.setVisible(true);

            while (!popupMenu.isDisposed() && popupMenu.isVisible())
                if (!popupMenu.getDisplay().readAndDispatch())
                    popupMenu.getDisplay().sleep();
            popupMenu.dispose();
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }

    private class MenuItemSelectionListener implements SelectionListener {
        private int edgeType;

        public MenuItemSelectionListener(int type) {
            this.edgeType = type;
        }

        public void widgetSelected(SelectionEvent e) {
            //If the menu item has already been selected and clicked on once again
            //de-select it
            if (edgeTypesToShow.contains(edgeType)) {
                edgeTypesToShow.remove(edgeType);

            } else
                edgeTypesToShow.add(edgeType);

            styledText.redraw();
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }

    private class SelectAllSelectionListener implements SelectionListener {

        public SelectAllSelectionListener() {

        }

        /* (non-Javadoc)
         * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetSelected(SelectionEvent e) {
            edgeTypesToShow.addAll(edgeTypes);
            showEdges = collectSelectedEdges(styledText.getCaretOffset());
            styledText.redraw();
        }

        /* (non-Javadoc)
         * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);

        }
    }

    private Set<VPGEdge<?, ?, ?>> collectSelectedEdges(int caretOffset) {
        //if the care offset happens to be within the edge then add the edge to the edgesToShow list
        HashSet<VPGEdge<?, ?, ?>> edgesToShow = new HashSet<VPGEdge<?, ?, ?>>();
        for (VPGEdge<?, ?, ?> edge : edgesInFile) {
            if (edge.getSource().getOffset() <= caretOffset && edge.getSource().getEndOffset() >= caretOffset) {
                edgesToShow.add(edge);
            } else if (edge.getSink().getOffset() <= caretOffset && edge.getSink().getEndOffset() >= caretOffset) {
                edgesToShow.add(edge);
            }
        }
        return edgesToShow;
    }

    private void createComposite(TabFolder tabfolder) {
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        composite = new Composite(tabfolder, SWT.NONE);
        composite.setLayout(layout);
        edges.setControl(composite);
    }

    private void createRadioButtons() {
        createShowAllButton();
        createShowSelectedButton();
    }

    private void createShowAllButton() {
        showAll = new Button(composite, SWT.RADIO);
        showAll.setText(Messages.EdgesTab_ShowAllEdges);
        showAll.setSelection(false);
        showAll.addSelectionListener(new RadioButtonSelectionListener());
    }

    private void createShowSelectedButton() {
        showSelected = new Button(composite, SWT.RADIO);
        showSelected.setText(Messages.EdgesTab_ShowSelectedEdges);
        showSelected.setSelection(true);
        showSelected.addSelectionListener(new RadioButtonSelectionListener());
    }

    private final class RadioButtonSelectionListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            styledText.redraw();
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }

    private void createStyledText() {
        styledText = new StyledText(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);

        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.verticalAlignment = GridData.FILL;
        gridData.grabExcessVerticalSpace = true;
        gridData.grabExcessHorizontalSpace = true;
        gridData.horizontalSpan = 3;
        gridData.verticalSpan = 1;
        styledText.setLayoutData(gridData);

        styledText.setFont(JFaceResources.getTextFont());
        styledText.addPaintListener(new EdgePainter(styledText));
        styledText.addCaretListener(new ShowEdgeCaretListener());
    }

    private final class ShowEdgeCaretListener implements CaretListener {

        public void caretMoved(CaretEvent event) {
            showEdges = collectSelectedEdges(event.caretOffset);
            displayCaretInformation(event);
            styledText.redraw();
        }

        private void displayCaretInformation(CaretEvent event) {
            int caretLine = styledText.getLineAtOffset(styledText.getCaretOffset());
            int lineOffset = styledText.getOffsetAtLine(caretLine);
            int caretOffset = styledText.getCaretOffset();
            int caretColumn = caretOffset - lineOffset + 1;

            label.setText(Messages.bind(Messages.EdgesTab_LineColOffset,
                    new Object[] { caretLine + 1, caretColumn, styledText.getCaretOffset() }));
            label.pack();
        }
    }

    private final class EdgePainter implements PaintListener {

        private final StyledText styledText;

        private EdgePainter(StyledText styledText) {
            this.styledText = styledText;
        }

        public void paintControl(PaintEvent e) {
            //Depending  upon whether if edgesTypesToShow list contains an edge this loop draws a rectangle around
            //the edge and calls the constructor of the DrawEdgesAndArrows class to draw lines between the source and sink
            for (VPGEdge<?, ?, ?> edge : edgesInFile) {
                if (edgeTypesToShow.contains(edge.getType())) {
                    Color defaultColor = e.gc.getForeground();
                    //depending upon the type of edge the color of the edges and lines is decided.
                    e.gc.setForeground(setColor(edge.getType()));
                    IVPGNode source = edge.getSource();
                    IVPGNode sink = edge.getSink();

                    if (source.getFilename().equals(filename) && sink.getFilename().equals(filename)) {
                        Rectangle srcRect = drawRectangle(e, source.getOffset(), source.getEndOffset());
                        Rectangle sinkRect = drawRectangle(e, sink.getOffset(), sink.getEndOffset());

                        if (srcRect != null && sinkRect != null) {
                            if (showAll.getSelection() || showEdges.contains(edge)) {
                                displayEdgesAndArrows(e.gc, sinkRect, srcRect);

                            }

                        }
                    } else {
                        // TODO: Handle this case later
                    }
                    e.gc.setForeground(defaultColor);
                }
            }
        }

        private void displayEdgesAndArrows(GC gc, Rectangle sinkRect, Rectangle srcRect) {
            new EdgeArrow(srcRect, sinkRect).drawOn(gc);
        }

        private Color setColor(int type) {
            return color.get(type % color.size());
        }

        private Rectangle drawRectangle(PaintEvent e, int startOffset, int endOffset) {
            if (isValid(startOffset) && isValid(endOffset)) {
                Rectangle srcRect = styledText.getTextBounds(startOffset, Math.max(0, endOffset - 1));
                e.gc.drawRectangle(srcRect);
                return srcRect;
            } else
                return null;
        }

        private boolean isValid(int offset) {
            return offset >= 0 && offset < styledText.getCharCount();
        }
    }

    @SuppressWarnings("unchecked")
    public void showEdges(String file_selected, EclipseVPG vpg) {
        this.filename = file_selected;
        Object ast = vpg.acquireTransientAST(filename);

        if (ast == null)
            styledText.setText(Messages.bind(Messages.EdgesTab_UnableToParse, filename));
        else
            styledText.setText(vpg.getSourceCodeFromAST(ast));

        edgesInFile = new ArrayList<VPGEdge<?, ?, ?>>();

        for (VPGEdge<?, ?, ?> edge : (Iterable<VPGEdge<?, ?, ?>>) vpg.getAllEdgesFor(filename))
            edgesInFile.add(edge);

        edgeTypes = new HashSet<Integer>();

        for (VPGEdge<?, ?, ?> edge : (Iterable<VPGEdge<?, ?, ?>>) vpg.getAllEdgesFor(filename))
            edgeTypes.add(edge.getType());

        edgeButton.setEnabled(edgeTypes.size() != 0);
    }
}