org.deved.antlride.internal.viz.RuleBasedGraphViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.deved.antlride.internal.viz.RuleBasedGraphViewer.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2008 Edgar Espina.
 * 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
 *
 *******************************************************************************/
package org.deved.antlride.internal.viz;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.deved.antlride.common.ui.AntlrImages;
import org.deved.antlride.core.model.IGrammar;
import org.deved.antlride.core.model.IRule;
import org.deved.antlride.ui.AntlrPreferenceConstants;
import org.deved.antlride.viz.AntlrViz;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.ScalableLayeredPane;
import org.eclipse.draw2d.ScrollPane;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.services.IDisposable;

public abstract class RuleBasedGraphViewer extends Viewer implements IDisposable {

    protected class ExportAsImage extends Action {
        private int format;
        private String formatName;

        public ExportAsImage(String formatName, int format) {
            super("Export as " + formatName, IAction.AS_PUSH_BUTTON);
            this.formatName = formatName;
            this.format = format;
            setImageDescriptor(AntlrImages.getDescriptor(AntlrImages.SAVE_AS));
            setToolTipText(getText());
        }

        @Override
        public void run() {
            FileDialog dialog = new FileDialog(getControl().getShell(), SWT.SAVE);
            dialog.setFileName(getSelectedRuleName() + "." + formatName);
            String path = dialog.open();
            if (path != null) {
                File out = new File(path);
                exportAsImage(out, format);
            }
        }
    }

    private class RuleLabelProvider extends LabelProvider {
        @Override
        public String getText(Object element) {
            return ((IRule) element).getElementName();
        }

        @Override
        public Image getImage(Object element) {
            return AntlrImages.getImage(AntlrImages.RULE);
        }
    }

    private class RuleContentProvider implements ITreeContentProvider {

        public Object[] getChildren(Object element) {
            return null;
        }

        public Object getParent(Object element) {
            return null;
        }

        public boolean hasChildren(Object element) {
            return false;
        }

        public Object[] getElements(Object element) {
            return (Object[]) element;
        }

        public void dispose() {

        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

    private class GraphSelectionListener implements ISelectionChangedListener {

        public void selectionChanged(SelectionChangedEvent event) {
            ISelection selection = event.getSelection();
            if (selection.isEmpty()) {
                clearGraph();
            } else {
                IStructuredSelection ss = (IStructuredSelection) selection;
                IRule element = (IRule) ss.getFirstElement();
                draw(element);
            }
        }
    }

    private class ZoomInAction extends Action {
        public ZoomInAction() {
            setText("Zoom In");
            setToolTipText("Zoom In");
            setImageDescriptor(AntlrImages.getDescriptor(AntlrImages.ZOOM_IN));
        }

        @Override
        public void run() {
            zoomIn();
        }
    }

    private class ZoomOutAction extends Action {

        public ZoomOutAction() {
            setText("Zoom out");
            setToolTipText("Zoom out");
            setImageDescriptor(AntlrImages.getDescriptor(AntlrImages.ZOOM_OUT));
        }

        @Override
        public void run() {
            zoomOut();
        }
    }

    private class ClearAction extends Action {

        public ClearAction() {
            setText("Clear");
            setToolTipText("Clear");
            setImageDescriptor(AntlrImages.getDescriptor(AntlrImages.CLEAR));
        }

        @Override
        public void run() {
            onClearGraph();
            clearGraph();
        }
    }

    private TreeViewer ruleViewer;

    protected IGrammar grammar;

    private SashForm control;

    private Canvas canvas;

    private LightweightSystem lightweightSystem;

    private ScalableLayeredPane scalableLayeredPane;

    private ScrollPane scrollPane;

    public RuleBasedGraphViewer(Composite composite) {
        createControl(composite);
    }

    public final String getSelectedRuleName() {
        IRule rule = getSelectedRule();
        return rule == null ? null : rule.getElementName();
    }

    public final IRule getSelectedRule() {
        IStructuredSelection selection = (IStructuredSelection) ruleViewer.getSelection();
        if (selection.isEmpty())
            return null;
        return ((IRule) selection.getFirstElement());
    }

    public final void draw(IRule element) {
        clearGraph();

        IFigure figure = doDraw(element);

        scalableLayeredPane.add(figure);

        scrollPane.setContents(scalableLayeredPane);

        lightweightSystem.setContents(scrollPane);
    }

    protected abstract IFigure doDraw(IRule rule);

    protected void onClearGraph() {
    }

    private final void clearGraph() {
        try {
            if (scalableLayeredPane != null) {
                @SuppressWarnings("unchecked")
                List<IFigure> children = scalableLayeredPane.getChildren();
                if (children != null && children.size() > 0) {
                    IFigure root = children.get(0);
                    root.erase();
                    scalableLayeredPane.remove(root);
                }
                scalableLayeredPane.erase();
            }
            if (scrollPane != null) {
                IFigure contents = scrollPane.getContents();
                if (contents != null) {
                    contents.erase();
                }
                scrollPane.erase();
            }
            scrollPane = createScrollPane();
            scalableLayeredPane = createScalableLayeredPane();
        } catch (Exception ex) {
            AntlrViz.error("Couldn't clear graph", ex);
        }
    }

    private void zoomIn() {
        if (scalableLayeredPane == null)
            return;
        double scale = scalableLayeredPane.getScale();
        scale += zoomFactor();
        scalableLayeredPane.setScale(scale);
    }

    private void zoomOut() {
        if (scalableLayeredPane == null)
            return;
        double scale = scalableLayeredPane.getScale();
        scale -= zoomFactor();
        if (scale <= 0) {
            return;
        }
        scalableLayeredPane.setScale(scale);
    }

    protected double zoomFactor() {
        return 0.125;
    }

    protected ScalableLayeredPane createScalableLayeredPane() {
        return new ScalableLayeredPane();
    }

    protected ScrollPane createScrollPane() {
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setViewport(new Viewport(useGraphicsTransalate()));
        return scrollPane;
    }

    protected void createControl(Composite composite) {
        GridData gd;

        SashForm sashForm = new SashForm(composite, SWT.HORIZONTAL);

        Composite leftPane = new Composite(sashForm, SWT.NONE);
        leftPane.setLayout(new GridLayout(3, false));

        Label label = new Label(leftPane, SWT.NONE);
        label.setText("Rule:");
        label.setToolTipText("Search Rule");

        final Text ruleText = new Text(leftPane, SWT.BORDER);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        ruleText.setLayoutData(gd);
        ruleText.setToolTipText("Search Rule");
        ruleText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                ruleViewer.refresh();
            }
        });

        ToolBar bar = new ToolBar(leftPane, SWT.HORIZONTAL);
        ToolItem clearFilter = new ToolItem(bar, SWT.PUSH);
        clearFilter.setToolTipText("Clear");
        clearFilter.setImage(AntlrImages.getImage(AntlrImages.CLEAR));
        clearFilter.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                ruleText.setText("");
                ruleViewer.refresh();
            }

            public void widgetDefaultSelected(SelectionEvent e) {

            }
        });

        ruleViewer = new TreeViewer(leftPane);
        gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 3;
        ruleViewer.getTree().setLayoutData(gd);
        ruleViewer.addFilter(new ViewerFilter() {

            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                String ruleName = ruleText.getText().toLowerCase();
                if (ruleName.length() > 0) {
                    boolean select = false;
                    if (element instanceof IRule) {
                        IRule rule = (IRule) element;
                        select = rule.getElementName().toLowerCase().startsWith(ruleName);
                    }
                    if (select) {
                        ruleViewer.setSelection(new StructuredSelection(element));
                    }
                    return select;
                }
                return true;
            }
        });
        ruleViewer.setLabelProvider(new RuleLabelProvider());
        ruleViewer.setContentProvider(new RuleContentProvider());
        ruleViewer.addSelectionChangedListener(new GraphSelectionListener());

        Composite rightPane = new Composite(sashForm, SWT.NONE);

        rightPane.setLayout(new GridLayout(2, false));

        bar = new ToolBar(rightPane, SWT.FLAT | SWT.RIGHT | SWT.HORIZONTAL);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalAlignment = SWT.END;
        gd.horizontalSpan = 2;
        bar.setLayoutData(gd);

        // add actions
        IToolBarManager barManager = new ToolBarManager(bar);
        barManager.add(new ZoomInAction());
        barManager.add(new ZoomOutAction());
        barManager.add(new ClearAction());

        fillToolBar(barManager);

        barManager.update(true);

        canvas = new Canvas(rightPane, SWT.BORDER);
        gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 2;
        canvas.setLayoutData(gd);
        Color color = JFaceResources.getColorRegistry().get(AntlrPreferenceConstants.EDITOR_BACKGROUND_COLOR);
        canvas.setBackground(color == null ? ColorConstants.white : color);
        lightweightSystem = new LightweightSystem(canvas);

        sashForm.setWeights(new int[] { 30, 70 });
        control = sashForm;
    }

    protected void fillToolBar(IToolBarManager manager) {

    }

    /**
     * Returns <code>true</code> if this viewport uses graphics translation.
     * 
     * @return whether this viewport uses graphics translation
     */
    protected boolean useGraphicsTransalate() {
        return false;
    }

    @Override
    public Control getControl() {
        return control;
    }

    @Override
    public Object getInput() {
        return grammar;
    }

    @Override
    public ISelection getSelection() {
        return ruleViewer.getSelection();
    }

    @Override
    public void refresh() {
    }

    @Override
    public void setInput(Object input) {
        if (grammar != input) {
            grammar = (IGrammar) input;
            ruleViewer.setInput(grammar.getRules());
        }
    }

    @Override
    public void setSelection(ISelection selection, boolean reveal) {
    }

    public void dispose() {
        clearGraph();
    }

    private void exportAsImage(File file, int format) {
        IFigure figure = (IFigure) scalableLayeredPane.getChildren().get(0);
        Rectangle r = figure.getBounds();

        OutputStream out = null;

        Image image = null;
        GC gc = null;
        Graphics g = null;
        try {
            out = new BufferedOutputStream(new FileOutputStream(file));
            image = new Image(getControl().getDisplay(), r.width, r.height);
            gc = new GC(image);
            g = new SWTGraphics(gc);
            g.translate(r.x * -1, r.y * -1);

            figure.paint(g);

            ImageLoader imageLoader = new ImageLoader();
            imageLoader.data = new ImageData[] { image.getImageData() };
            imageLoader.save(out, format);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (g != null) {
                g.dispose();
            }
            if (gc != null) {
                gc.dispose();
            }
            if (image != null) {
                image.dispose();
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}