org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DisassemblyPane.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DisassemblyPane.java

Source

/*******************************************************************************
 * Copyright (c) 2008 ARM Limited 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:
 * ARM Limited - Initial API and implementation
 *******************************************************************************/

package org.eclipse.cdt.debug.internal.ui.disassembly.viewer;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationRulerColumn;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.IVerticalRulerColumn;
import org.eclipse.jface.text.source.OverviewRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Point;
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.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;

public class DisassemblyPane implements IPropertyChangeListener {

    private final static int VERTICAL_RULER_WIDTH = 12;
    private final static String CURRENT_LINE = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE;
    private final static String CURRENT_LINE_COLOR = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR;

    private Composite fControl;
    private VirtualSourceViewer fViewer;

    private IVerticalRuler fVerticalRuler;
    private IOverviewRuler fOverviewRuler;

    private SourceViewerDecorationSupport fSourceViewerDecorationSupport;
    private IAnnotationAccess fAnnotationAccess;
    private MarkerAnnotationPreferences fAnnotationPreferences;

    private String fViewContextMenuId;
    private String fRulerContextMenuId;

    private MenuManager fTextMenuManager;
    private MenuManager fRulerMenuManager;

    private Menu fRulerContextMenu;
    private Menu fTextContextMenu;

    private IMenuListener fMenuListener;
    private MouseListener fMouseListener;

    private Map<String, IAction> fActions = new HashMap<String, IAction>(10);

    public DisassemblyPane(String contextMenuId, String rulerMenuId) {
        fAnnotationPreferences = new MarkerAnnotationPreferences();
        setViewContextMenuId(contextMenuId);
        setRulerContextMenuId(rulerMenuId);
    }

    public void create(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new GridLayout());
        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(data);

        fVerticalRuler = createCompositeRuler();
        fOverviewRuler = createOverviewRuler(getSharedColors());

        createActions();

        fViewer = createViewer(composite, fVerticalRuler, fOverviewRuler);

        fControl = composite;

        createViewContextMenu();
        createRulerContextMenu();

        if (fSourceViewerDecorationSupport != null) {
            fSourceViewerDecorationSupport.install(getEditorPreferenceStore());
        }
    }

    public Control getControl() {
        return fControl;
    }

    public VirtualSourceViewer getViewer() {
        return fViewer;
    }

    public void dispose() {
        getEditorPreferenceStore().removePropertyChangeListener(this);
        JFaceResources.getFontRegistry().removeListener(this);
        JFaceResources.getColorRegistry().removeListener(this);
        if (fSourceViewerDecorationSupport != null) {
            fSourceViewerDecorationSupport.dispose();
            fSourceViewerDecorationSupport = null;
        }
        if (fActions != null) {
            fActions.clear();
            fActions = null;
        }
    }

    protected void createActions() {
    }

    public void setAction(String actionID, IAction action) {
        Assert.isNotNull(actionID);
        if (action == null) {
            fActions.remove(actionID);
        } else {
            fActions.put(actionID, action);
        }
    }

    public IAction getAction(String actionID) {
        Assert.isNotNull(actionID);
        return fActions.get(actionID);
    }

    protected void rulerContextMenuAboutToShow(IMenuManager menu) {
        menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
        menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        addAction(menu, IInternalCDebugUIConstants.ACTION_TOGGLE_BREAKPOINT);
        addAction(menu, IInternalCDebugUIConstants.ACTION_ENABLE_DISABLE_BREAKPOINT);
        addAction(menu, IInternalCDebugUIConstants.ACTION_BREAKPOINT_PROPERTIES);
    }

    protected void viewContextMenuAboutToShow(IMenuManager menu) {
        menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
        menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    protected void addAction(IMenuManager menu, String group, String actionId) {
        IAction action = getAction(actionId);
        if (action != null) {
            if (action instanceof IUpdate)
                ((IUpdate) action).update();
            IMenuManager subMenu = menu.findMenuUsingPath(group);
            if (subMenu != null)
                subMenu.add(action);
            else
                menu.appendToGroup(group, action);
        }
    }

    protected void addAction(IMenuManager menu, String actionId) {
        IAction action = getAction(actionId);
        if (action != null) {
            if (action instanceof IUpdate)
                ((IUpdate) action).update();
            menu.add(action);
        }
    }

    protected final IMenuListener getContextMenuListener() {
        if (fMenuListener == null) {
            fMenuListener = new IMenuListener() {

                @Override
                public void menuAboutToShow(IMenuManager menu) {
                    String id = menu.getId();
                    if (getRulerContextMenuId().equals(id)) {
                        //                        setFocus();
                        rulerContextMenuAboutToShow(menu);
                    } else if (getViewContextMenuId().equals(id)) {
                        //                        setFocus();
                        viewContextMenuAboutToShow(menu);
                    }
                }
            };
        }
        return fMenuListener;
    }

    protected final MouseListener getRulerMouseListener() {
        if (fMouseListener == null) {
            fMouseListener = new MouseListener() {

                private boolean fDoubleClicked = false;

                private void triggerAction(String actionID) {
                    IAction action = getAction(actionID);
                    if (action != null) {
                        if (action instanceof IUpdate)
                            ((IUpdate) action).update();
                        if (action.isEnabled())
                            action.run();
                    }
                }

                @Override
                public void mouseUp(MouseEvent e) {
                    //                    setFocus();
                    if (1 == e.button && !fDoubleClicked)
                        triggerAction(ITextEditorActionConstants.RULER_CLICK);
                    fDoubleClicked = false;
                }

                @Override
                public void mouseDoubleClick(MouseEvent e) {
                    if (1 == e.button) {
                        fDoubleClicked = true;
                        triggerAction(IInternalCDebugUIConstants.ACTION_TOGGLE_BREAKPOINT);
                    }
                }

                @Override
                public void mouseDown(MouseEvent e) {
                    StyledText text = getViewer().getTextWidget();
                    if (text != null && !text.isDisposed()) {
                        Display display = text.getDisplay();
                        Point location = display.getCursorLocation();
                        getRulerContextMenu().setLocation(location.x, location.y);
                    }
                }
            };
        }
        return fMouseListener;
    }

    private Menu getTextContextMenu() {
        return this.fTextContextMenu;
    }

    private void setTextContextMenu(Menu textContextMenu) {
        this.fTextContextMenu = textContextMenu;
    }

    protected Menu getRulerContextMenu() {
        return this.fRulerContextMenu;
    }

    private void setRulerContextMenu(Menu rulerContextMenu) {
        this.fRulerContextMenu = rulerContextMenu;
    }

    public String getRulerContextMenuId() {
        return fRulerContextMenuId;
    }

    private void setRulerContextMenuId(String rulerContextMenuId) {
        Assert.isNotNull(rulerContextMenuId);
        fRulerContextMenuId = rulerContextMenuId;
    }

    public String getViewContextMenuId() {
        return fViewContextMenuId;
    }

    private void setViewContextMenuId(String viewContextMenuId) {
        Assert.isNotNull(viewContextMenuId);
        fViewContextMenuId = viewContextMenuId;
    }

    private void createViewContextMenu() {
        String id = getViewContextMenuId();
        fTextMenuManager = new MenuManager(id, id);
        fTextMenuManager.setRemoveAllWhenShown(true);
        fTextMenuManager.addMenuListener(getContextMenuListener());
        StyledText styledText = getViewer().getTextWidget();
        setTextContextMenu(fTextMenuManager.createContextMenu(styledText));
        styledText.setMenu(getTextContextMenu());
    }

    private void createRulerContextMenu() {
        String id = getRulerContextMenuId();
        fRulerMenuManager = new MenuManager(id, id);
        fRulerMenuManager.setRemoveAllWhenShown(true);
        fRulerMenuManager.addMenuListener(getContextMenuListener());
        Control rulerControl = fVerticalRuler.getControl();
        setRulerContextMenu(fRulerMenuManager.createContextMenu(rulerControl));
        rulerControl.setMenu(getRulerContextMenu());
        rulerControl.addMouseListener(getRulerMouseListener());
    }

    protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) {
        if (fSourceViewerDecorationSupport == null) {
            fSourceViewerDecorationSupport = new SourceViewerDecorationSupport(viewer, getOverviewRuler(),
                    getAnnotationAccess(), getSharedColors());
            configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport);
        }
        return fSourceViewerDecorationSupport;
    }

    protected VirtualSourceViewer createViewer(Composite parent, IVerticalRuler vertRuler, IOverviewRuler ovRuler) {
        int styles = SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
        VirtualSourceViewer viewer = new VirtualSourceViewer(parent, fVerticalRuler, fOverviewRuler, true, styles);
        viewer.getControl().setLayoutData(parent.getLayoutData());
        viewer.setEditable(false);
        viewer.getTextWidget().setFont(JFaceResources.getFont(IInternalCDebugUIConstants.DISASSEMBLY_FONT));
        viewer.setRangeIndicator(new DefaultRangeIndicator());
        getSourceViewerDecorationSupport(viewer);
        viewer.configure(new SourceViewerConfiguration());
        JFaceResources.getFontRegistry().addListener(this);
        JFaceResources.getColorRegistry().addListener(this);
        getEditorPreferenceStore().addPropertyChangeListener(this);
        return viewer;
    }

    private IAnnotationAccess createAnnotationAccess() {
        return new DefaultMarkerAnnotationAccess();
    }

    private void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
        for (Object pref : fAnnotationPreferences.getAnnotationPreferences()) {
            support.setAnnotationPreference((AnnotationPreference) pref);
        }
        support.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR);
    }

    private IAnnotationAccess getAnnotationAccess() {
        if (fAnnotationAccess == null)
            fAnnotationAccess = createAnnotationAccess();
        return fAnnotationAccess;
    }

    private ISharedTextColors getSharedColors() {
        return EditorsUI.getSharedTextColors();
    }

    @SuppressWarnings("unchecked")
    protected IVerticalRuler createCompositeRuler() {
        CompositeRuler ruler = new CompositeRuler();
        ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()));
        for (Iterator iter = ruler.getDecoratorIterator(); iter.hasNext();) {
            IVerticalRulerColumn col = (IVerticalRulerColumn) iter.next();
            if (col instanceof AnnotationRulerColumn) {
                AnnotationRulerColumn column = (AnnotationRulerColumn) col;
                for (Iterator iter2 = fAnnotationPreferences.getAnnotationPreferences().iterator(); iter2
                        .hasNext();) {
                    AnnotationPreference preference = (AnnotationPreference) iter2.next();
                    column.addAnnotationType(preference.getAnnotationType());
                }
                column.addAnnotationType(Annotation.TYPE_UNKNOWN);
                break;
            }
        }
        return ruler;
    }

    private IOverviewRuler createOverviewRuler(ISharedTextColors sharedColors) {
        IOverviewRuler ruler = new OverviewRuler(getAnnotationAccess(), VERTICAL_RULER_WIDTH, sharedColors);
        for (Object o : fAnnotationPreferences.getAnnotationPreferences()) {
            AnnotationPreference preference = (AnnotationPreference) o;
            if (preference.contributesToHeader())
                ruler.addHeaderAnnotationType(preference.getAnnotationType());
        }
        return ruler;
    }

    private IOverviewRuler getOverviewRuler() {
        if (fOverviewRuler == null)
            fOverviewRuler = createOverviewRuler(getSharedColors());
        return fOverviewRuler;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
     */
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        // TODO Auto-generated method stub

    }

    private IPreferenceStore getEditorPreferenceStore() {
        return EditorsUI.getPreferenceStore();
    }

    public MenuManager getTextMenuManager() {
        return fTextMenuManager;
    }

    public MenuManager getRulerMenuManager() {
        return fRulerMenuManager;
    }

    public IVerticalRuler getVerticalRuler() {
        return fVerticalRuler;
    }
}