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

Java tutorial

Introduction

Here is the source code for org.eclipse.photran.internal.ui.browser.AnnotationsTab.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.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.photran.internal.core.util.Pair;
import org.eclipse.photran.internal.core.vpg.IVPGNode;
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.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;

/**
 * The Annotations tab in the VPG Browser.
 * 
 * @author Abhishek Sharma
 */
@SuppressWarnings("rawtypes")
class AnnotationsTab {
    private EclipseVPG vpg;
    private TabItem annotations;
    private SashForm annotationsSash;
    private StyledText styledText;
    private TabFolder annotationsTabFolder;
    private Composite composite;
    private Label label;
    private String filename;
    private List<Pair<? extends IVPGNode, Integer>> annotationsInFile;
    private Set<Pair<? extends IVPGNode, Integer>> annotationsToShow;
    private HashMap<Integer, TabItem> hashMap; //to decide which tab to display the annotation in depending upon the type

    public AnnotationsTab(TabItem annotations, TabFolder tabFolder, EclipseVPG vpg) {
        this.annotations = annotations;
        this.annotationsInFile = Collections.emptyList();
        this.annotationsToShow = Collections.emptySet();
        this.vpg = vpg;
        this.hashMap = new HashMap<Integer, TabItem>();
        createControls(tabFolder);
    }

    private void createControls(TabFolder tabFolder) {
        createHorizontalSash(tabFolder);
        createStyledText();
        createComposite();
        createAnnotationsTabFolder();
        createLabel();
    }

    private void createComposite() {
        composite = new Composite(annotationsSash, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        composite.setLayout(layout);
    }

    private void createAnnotationsTabFolder() {
        annotationsTabFolder = new TabFolder(composite, SWT.NULL | SWT.FILL);
        annotationsTabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    }

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

    private void createNewTab(int annotationType, String description) {
        if (!hashMap.containsKey(annotationType)) {
            TabItem tabItem = new TabItem(annotationsTabFolder, SWT.NULL);
            tabItem.setText(description);
            hashMap.put(annotationType, tabItem);
        }
    }

    private void createHorizontalSash(TabFolder tabFolder) {
        annotationsSash = new SashForm(tabFolder, SWT.VERTICAL);
        annotationsSash.setLayout(new FillLayout());
        annotationsSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        annotations.setControl(annotationsSash);
    }

    private void createStyledText() {
        styledText = new StyledText(annotationsSash, 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 RectanglePainter(styledText));
        styledText.addCaretListener(new ShowEdgeCaretListener());

    }

    @SuppressWarnings("unchecked")
    public void showAnnotations(String filename) {
        this.filename = filename;
        Object ast = vpg.acquireTransientAST(filename);

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

        annotationsInFile = new ArrayList<Pair<? extends IVPGNode, Integer>>();

        for (Pair<? extends IVPGNode, Integer> pair : (Iterable<Pair<? extends IVPGNode, Integer>>) vpg
                .getAllAnnotationsFor(filename)) {
            annotationsInFile.add(pair);
        }

        for (Pair<? extends IVPGNode, Integer> pair : annotationsInFile) {
            createNewTab(pair.snd, vpg.describeAnnotationType(pair.snd));
        }
    }

    private final class ShowEdgeCaretListener implements CaretListener {
        private Set<Pair<? extends IVPGNode, Integer>> collectSelectedAnnotations(int caretOffset) {
            // if the care offset happens to be within the edge 
            //then add the edge to the edgesToShow list
            HashSet<Pair<? extends IVPGNode, Integer>> AnnotationsToShow = new HashSet<Pair<? extends IVPGNode, Integer>>();

            for (Pair<? extends IVPGNode, Integer> pair : annotationsInFile) {
                IVPGNode tokenRef = pair.fst;

                if (tokenRef.getOffset() <= caretOffset && tokenRef.getEndOffset() >= caretOffset)
                    AnnotationsToShow.add(pair);

            }
            return AnnotationsToShow;
        }

        public void caretMoved(CaretEvent event) {
            annotationsToShow = collectSelectedAnnotations(event.caretOffset);
            displayAnnotations();
            displayCaretInformation(event);
            styledText.redraw();
        }

        private void displayAnnotations() {
            Text blankText = new Text(annotationsTabFolder,
                    SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.READ_ONLY);
            blankText.setText(Messages.AnnotationsTab_NoAnnotationsToShow);

            for (int type : hashMap.keySet()) {
                hashMap.get(type).setControl(blankText);
            }

            for (Pair<? extends IVPGNode, Integer> pair : annotationsToShow) {
                IVPGNode tokenRef = pair.fst;
                int annotationType = pair.snd;
                Text textField = new Text(annotationsTabFolder,
                        SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.READ_ONLY);
                textField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
                String text = tokenRef.getAnnotation(annotationType).toString();
                textField.setText(text);
                hashMap.get(annotationType).setControl(textField);
            }

        }

        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.AnnotationsTab_LineColOffset,
                    new Object[] { caretLine + 1, caretColumn, styledText.getCaretOffset() }));
            label.pack();
        }
    }

    private final class RectanglePainter implements PaintListener {
        @SuppressWarnings("unused")
        private final StyledText styledText;

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

        public void paintControl(PaintEvent e) {
            for (Pair<? extends IVPGNode, Integer> pair : annotationsInFile) {
                IVPGNode tokenRef = pair.fst;
                if (tokenRef.getFilename().equals(filename))
                    drawRectangle(e, tokenRef.getOffset(), tokenRef.getEndOffset());
            }
        }

    }

    private Rectangle drawRectangle(PaintEvent e, int startOffset, int endOffset) {
        if (isValid(startOffset) && isValid(endOffset)) {
            Rectangle srcRect = styledText.getTextBounds(startOffset,
                    Math.max(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();
    }

}