From 2c2447767bfc30adc68694f0ce44f732a05827f4 Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Thu, 3 Apr 2008 17:06:41 +0000 Subject: [PATCH] Contributing new disassembly. --- .../META-INF/MANIFEST.MF | 1 + .../cdt/debug/core/ICDebugConstants.java | 12 +- .../ui/IInternalCDebugUIConstants.java | 7 +- .../commands/OpenDisassemblyHandler.java | 50 ++ .../disassembly/editor/DisassemblyEditor.java | 337 +++++++++++++ .../editor/DisassemblyEditorInput.java | 84 ++++ .../editor/DisassemblyEditorManager.java | 323 ++++++++++++ .../viewer/DisassemblyDocumentProvider.java | 219 +++++++++ .../disassembly/viewer/DisassemblyPane.java | 416 ++++++++++++++++ .../viewer/DocumentAnnotationProvider.java | 100 ++++ .../viewer/DocumentAnnotationUpdate.java | 71 +++ .../viewer/DocumentBaseChangeUpdate.java | 83 ++++ .../viewer/DocumentContentProvider.java | 465 ++++++++++++++++++ .../viewer/DocumentContentUpdate.java | 119 +++++ .../viewer/DocumentLabelProvider.java | 112 +++++ .../viewer/DocumentLabelUpdate.java | 65 +++ .../ui/disassembly/viewer/DocumentUpdate.java | 128 +++++ .../disassembly/viewer/VirtualDocument.java | 80 +++ .../viewer/VirtualSourceViewer.java | 133 +++++ .../eclipse/cdt/debug/ui/CDebugUIPlugin.java | 22 +- .../ui/disassembly/IDocumentPresentation.java | 28 ++ 21 files changed, 2846 insertions(+), 9 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/commands/OpenDisassemblyHandler.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditor.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorInput.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorManager.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyDocumentProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyPane.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationUpdate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentBaseChangeUpdate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentUpdate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelUpdate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentUpdate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualDocument.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualSourceViewer.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/IDocumentPresentation.java diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF index 0b9c5f5322e..926e8121351 100644 --- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF @@ -12,6 +12,7 @@ Export-Package: org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.core.cdi.event, org.eclipse.cdt.debug.core.cdi.model, org.eclipse.cdt.debug.core.cdi.model.type, + org.eclipse.cdt.debug.core.disassembly, org.eclipse.cdt.debug.core.executables, org.eclipse.cdt.debug.core.model, org.eclipse.cdt.debug.core.sourcelookup, diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugConstants.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugConstants.java index 5a2664d6657..0b6bde79755 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugConstants.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDebugConstants.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.debug.core; - /** * Constant definitions for C/C++ debug plug-in. */ @@ -101,5 +100,14 @@ public interface ICDebugConstants { /** * The default character set to use with unicode strings. */ - public static final String DEF_CHARSET = "UTF-16"; + public static final String DEF_CHARSET = "UTF-16"; //$NON-NLS-1$ + + /** + * Specifies the stepping mode (context/source/instruction) + */ + public static final String PREF_STEP_MODE = PLUGIN_ID + ".steppingMode"; //$NON-NLS-1$ + + public static final String PREF_VALUE_STEP_MODE_CONTEXT = "context"; //$NON-NLS-1$ + public static final String PREF_VALUE_STEP_MODE_SOURCE = "source"; //$NON-NLS-1$ + public static final String PREF_VALUE_STEP_MODE_INSTRUCTION = "instruction"; //$NON-NLS-1$ } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java index e1242c38116..959c154e5b2 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java @@ -24,7 +24,12 @@ public interface IInternalCDebugUIConstants { public static final String PREFIX = PLUGIN_ID + "."; //$NON-NLS-1$ - /** + /** + * Specifies the conditions under which the disassembly editor will be activated + */ + public static final String PREF_OPEN_DISASSEMBLY_MODE = PREFIX + "openDisassemblyMode"; //$NON-NLS-1$ + + /** * The name of the font to use for disassembly view. This font is managed via * the workbench font preference page. */ diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/commands/OpenDisassemblyHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/commands/OpenDisassemblyHandler.java new file mode 100644 index 00000000000..cb1522239d6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/commands/OpenDisassemblyHandler.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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.commands; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.debug.core.DebugException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * org.eclipse.cdt.debug.internal.ui.disassembly.commands.OpenDisassemblyHandler: + * //TODO Add description. + */ +public class OpenDisassemblyHandler extends AbstractHandler { + + /* (non-Javadoc) + * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + @Override + public Object execute( ExecutionEvent event ) throws ExecutionException { + ISelection s = HandlerUtil.getActiveMenuSelection( event ); + if ( s instanceof IStructuredSelection ) { + Object element = ((IStructuredSelection)s).getFirstElement(); + IWorkbenchSite site = HandlerUtil.getActiveSite( event ); + if ( element != null && site != null ) { + try { + CDebugUIPlugin.getDefault().getDisassemblyEditorManager().openEditor( site.getPage(), element ); + } + catch( DebugException e ) { + throw new ExecutionException( "Error openning disassembly.", e ); + } + } + } + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditor.java new file mode 100644 index 00000000000..0a1c5349f45 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditor.java @@ -0,0 +1,337 @@ +/******************************************************************************* + * 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.editor; + +import org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextProvider; +import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; +import org.eclipse.cdt.debug.internal.ui.actions.CBreakpointPropertiesRulerAction; +import org.eclipse.cdt.debug.internal.ui.actions.EnableDisableBreakpointRulerAction; +import org.eclipse.cdt.debug.internal.ui.actions.ToggleBreakpointRulerAction; +import org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DisassemblyPane; +import org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DocumentContentProvider; +import org.eclipse.cdt.debug.internal.ui.disassembly.viewer.VirtualDocument; +import org.eclipse.cdt.debug.internal.ui.disassembly.viewer.VirtualSourceViewer; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IReusableEditor; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +public class DisassemblyEditor extends EditorPart implements ITextEditor, IReusableEditor, IDebugContextListener { + + private DisassemblyPane fDisassemblyPane; + + public DisassemblyEditor() { + super(); + fDisassemblyPane = new DisassemblyPane(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void doSave( IProgressMonitor monitor ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#doSaveAs() + */ + @Override + public void doSaveAs() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput) + */ + @Override + public void init( IEditorSite site, IEditorInput input ) throws PartInitException { + setSite( site ); + setInput( input ); + DebugUITools.getDebugContextManager().addDebugContextListener( this ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#isDirty() + */ + @Override + public boolean isDirty() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed() + */ + @Override + public boolean isSaveAsAllowed() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl( Composite parent ) { + fDisassemblyPane.create( parent ); + createActions(); + + // register the context menu such that other plugins may contribute to it + if ( getSite() != null ) { + getSite().registerContextMenu( fDisassemblyPane.getViewContextMenuId(), fDisassemblyPane.getTextMenuManager(), getViewer() ); + } + + VirtualSourceViewer viewer = fDisassemblyPane.getViewer(); + IEditorInput input = getEditorInput(); + if ( input instanceof DisassemblyEditorInput ) { + Object debugContext = ((DisassemblyEditorInput)input).getDebugContext(); + VirtualDocument document = (VirtualDocument)getDocumentProvider().getDocument( input ); + IAnnotationModel annotationModel = getDocumentProvider().getAnnotationModel( input ); + viewer.setDocument( document, annotationModel ); + ((VirtualDocument)viewer.getDocument()).getContentProvider().changeInput( viewer, document.getPresentationContext(), null, debugContext, document.getCurrentOffset() ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#dispose() + */ + @Override + public void dispose() { + DebugUITools.getDebugContextManager().removeDebugContextListener( this ); + getDocumentProvider().disconnect( getEditorInput() ); + fDisassemblyPane.dispose(); + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput) + */ + @Override + public final void setInput( IEditorInput input ) { + super.setInput( input ); + Object debugContext = ((DisassemblyEditorInput)input).getDebugContext(); + try { + getDocumentProvider().connect( input ); + } + catch( CoreException e ) { + // shouldn't happen + } + VirtualDocument document = (VirtualDocument)getDocumentProvider().getDocument( input ); + VirtualSourceViewer viewer = getViewer(); + if ( document != null && viewer != null ) { + DocumentContentProvider contentProvider = document.getContentProvider(); + Object oldInput = contentProvider.getInput(); + if ( !oldInput.equals( debugContext ) ) { + contentProvider.changeInput( getViewer(), document.getPresentationContext(), oldInput, debugContext, document.getCurrentOffset() ); +// getViewer().refresh( false, true ); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) + */ + public void debugContextChanged( DebugContextEvent event ) { + ISelection selection = event.getContext(); + if ( selection instanceof IStructuredSelection ) { + IStructuredSelection ss = (IStructuredSelection)selection; + Object context = ss.getFirstElement(); + if ( context != null ) { + IDisassemblyContextProvider contextProvider = getDisassemblyContextProvider( context ); + if ( contextProvider != null ) { + Object disassemblyContext = contextProvider.getDisassemblyContext( context ); + if ( disassemblyContext != null ) { + DisassemblyEditorInput oldInput = (DisassemblyEditorInput)getEditorInput(); + if ( oldInput.getDisassemblyContext().equals( disassemblyContext ) ) { + if ( !oldInput.getDebugContext().equals( context ) ) { + setInput( new DisassemblyEditorInput( context, disassemblyContext ) ); + } + } + } + } + } + } + } + + private IDisassemblyContextProvider getDisassemblyContextProvider( Object element ) { + IDisassemblyContextProvider adapter = null; + if ( element instanceof IDisassemblyContextProvider ) { + adapter = (IDisassemblyContextProvider)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IDisassemblyContextProvider)adaptable.getAdapter( IDisassemblyContextProvider.class ); + } + return adapter; + } + + private VirtualSourceViewer getViewer() { + return fDisassemblyPane.getViewer(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#close(boolean) + */ + public void close( boolean save ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#doRevertToSaved() + */ + public void doRevertToSaved() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#getAction(java.lang.String) + */ + public IAction getAction( String actionId ) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#getDocumentProvider() + */ + public IDocumentProvider getDocumentProvider() { + return CDebugUIPlugin.getDefault().getDisassemblyEditorManager().getDocumentProvider(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#getHighlightRange() + */ + public IRegion getHighlightRange() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#getSelectionProvider() + */ + public ISelectionProvider getSelectionProvider() { + VirtualSourceViewer viewer = getViewer(); + return ( viewer != null ) ? viewer.getSelectionProvider() : null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#isEditable() + */ + public boolean isEditable() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#removeActionActivationCode(java.lang.String) + */ + public void removeActionActivationCode( String actionId ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#resetHighlightRange() + */ + public void resetHighlightRange() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#selectAndReveal(int, int) + */ + public void selectAndReveal( int offset, int length ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#setAction(java.lang.String, org.eclipse.jface.action.IAction) + */ + public void setAction( String actionID, IAction action ) { + fDisassemblyPane.setAction( actionID, action ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#setActionActivationCode(java.lang.String, char, int, int) + */ + public void setActionActivationCode( String actionId, char activationCharacter, int activationKeyCode, int activationStateMask ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#setHighlightRange(int, int, boolean) + */ + public void setHighlightRange( int offset, int length, boolean moveCursor ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#showHighlightRangeOnly(boolean) + */ + public void showHighlightRangeOnly( boolean showHighlightRangeOnly ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.ITextEditor#showsHighlightRangeOnly() + */ + public boolean showsHighlightRangeOnly() { + // TODO Auto-generated method stub + return false; + } + + protected void createActions() { + IVerticalRuler ruler = fDisassemblyPane.getVerticalRuler(); + IAction action= new ToggleBreakpointRulerAction( this, ruler ); + setAction( IInternalCDebugUIConstants.ACTION_TOGGLE_BREAKPOINT, action ); + action= new EnableDisableBreakpointRulerAction( this, ruler ); + setAction( IInternalCDebugUIConstants.ACTION_ENABLE_DISABLE_BREAKPOINT, action ); + action= new CBreakpointPropertiesRulerAction( this, ruler ); + setAction( IInternalCDebugUIConstants.ACTION_BREAKPOINT_PROPERTIES, action ); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorInput.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorInput.java new file mode 100644 index 00000000000..f82c41ffdb8 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorInput.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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.editor; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +public class DisassemblyEditorInput implements IEditorInput { + + private Object fDebugContext; + private Object fDisassemblyContext; + + public DisassemblyEditorInput( Object debugContext, Object disassemblyContext ) { + fDisassemblyContext = disassemblyContext; + fDebugContext = debugContext; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#exists() + */ + public boolean exists() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + public ImageDescriptor getImageDescriptor() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + public String getName() { + // TODO Auto-generated method stub + return ""; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + public IPersistableElement getPersistable() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + public String getToolTipText() { + // TODO Auto-generated method stub + return ""; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("unchecked") + public Object getAdapter( Class adapter ) { + // TODO Auto-generated method stub + return null; + } + + public Object getDisassemblyContext() { + return fDisassemblyContext; + } + + public Object getDebugContext() { + return fDebugContext; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorManager.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorManager.java new file mode 100644 index 00000000000..8aa0179866f --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/editor/DisassemblyEditorManager.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * 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.editor; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDebugConstants; +import org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextListener; +import org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextProvider; +import org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextService; +import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; +import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; +import org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DisassemblyDocumentProvider; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.ui.ISourcePresentation; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IWindowListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.progress.UIJob; + +public class DisassemblyEditorManager implements IWindowListener, IDisassemblyContextListener, IPartListener2 { + + private static final String DEFAULT_EDITOR_ID = "com.arm.eclipse.rvd.ui.disassemblyEditor"; //$NON-NLS-1$ + private Map fEditorParts; + private Map fOpenDisassemblyPolicy; + private Map fSteppingModePolicy; + private DisassemblyDocumentProvider fDocumentProvider; + + public DisassemblyEditorManager() { + fDocumentProvider = new DisassemblyDocumentProvider(); + fEditorParts = new HashMap(); + fOpenDisassemblyPolicy = new HashMap(); + fSteppingModePolicy = new HashMap(); + CDebugUIPlugin.getDefault().getWorkbench().addWindowListener( this ); + IWorkbenchWindow window = CDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow(); + if ( window != null ) { + window.getPartService().addPartListener( this ); + } + getDisassemblyManager().addDisassemblyContextListener( this ); + } + + public void dispose() { + getDisassemblyManager().removeDisassemblyContextListener( this ); + CDebugUIPlugin.getDefault().getWorkbench().removeWindowListener( this ); + fSteppingModePolicy.clear(); + fOpenDisassemblyPolicy.clear(); + fEditorParts.clear(); + fDocumentProvider.dispose(); + } + + public DisassemblyDocumentProvider getDocumentProvider() { + return fDocumentProvider; + } + + public void openEditor( IWorkbenchPage page, Object debugContext ) throws DebugException { + Object disassemblyContext = getDiassemblyContext( debugContext ); + if ( disassemblyContext != null ) { + IEditorPart editor = fEditorParts.get( disassemblyContext ); + if ( editor == null ) { + ISourcePresentation sp = getSourcePresentation(); + if ( sp == null ) { + throw new DebugException( new Status( IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), 0, "No disassembly editor found", null ) ); + } + IEditorInput input = sp.getEditorInput( debugContext ); + try { + editor = IDE.openEditor( page, input, sp.getEditorId( input, disassemblyContext ) ); + fEditorParts.put( disassemblyContext, editor ); + ISteppingModeTarget steppingModeTarget = getSteppingModeTarget( debugContext ); + if ( steppingModeTarget != null ) { + if ( ICDebugConstants.PREF_VALUE_STEP_MODE_CONTEXT.equals( + CDebugCorePlugin.getDefault().getPluginPreferences().getString( ICDebugConstants.PREF_STEP_MODE ) ) ) + steppingModeTarget.enableInstructionStepping( true ); + fSteppingModePolicy.put( disassemblyContext, steppingModeTarget ); + } + } + catch( PartInitException e ) { + throw new DebugException( e.getStatus() ); + } + } + page.activate( editor ); + } + } + + public IEditorPart findEditor( IWorkbenchPage page, Object debugContext ) { + Object disassemblyContext = getDiassemblyContext( debugContext ); + return ( disassemblyContext != null ) ? fEditorParts.get( disassemblyContext ) : null; + } + + public String getOpenDisassemblyMode( Object debugContext ) { + String mode = MessageDialogWithToggle.NEVER; + Object disassemblyContext = getDiassemblyContext( debugContext ); + if ( disassemblyContext != null ) { + // shouldn't happen + mode = fOpenDisassemblyPolicy.get( disassemblyContext ); + if ( mode == null ) { + IPreferenceStore prefs = CDebugUIPlugin.getDefault().getPreferenceStore(); + mode = prefs.getString( IInternalCDebugUIConstants.PREF_OPEN_DISASSEMBLY_MODE ); + fOpenDisassemblyPolicy.put( disassemblyContext, mode ); + } + } + return mode; + } + + public void setOpenDisassemblyMode( Object debugContext, String mode ) { + Object disassemblyContext = getDiassemblyContext( debugContext ); + if ( disassemblyContext == null ) + return; + fOpenDisassemblyPolicy.put( disassemblyContext, mode ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partActivated( IWorkbenchPartReference partRef ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partBroughtToTop( IWorkbenchPartReference partRef ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partClosed( IWorkbenchPartReference partRef ) { + if ( isDisassemblyEditorPart( partRef ) ) { + IWorkbenchPart part = partRef.getPart( false ); + if ( part instanceof IEditorPart ) { + IEditorInput input = ((IEditorPart)part).getEditorInput(); + if ( input instanceof DisassemblyEditorInput ) { + Object disassemblyContext = ((DisassemblyEditorInput)input).getDisassemblyContext(); + fEditorParts.remove( disassemblyContext ); + ISteppingModeTarget steppingModeTarget = fSteppingModePolicy.remove( disassemblyContext ); + if ( steppingModeTarget != null + && ICDebugConstants.PREF_VALUE_STEP_MODE_CONTEXT.equals( + CDebugCorePlugin.getDefault().getPluginPreferences().getString( ICDebugConstants.PREF_STEP_MODE ) ) ) + steppingModeTarget.enableInstructionStepping( false ); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partDeactivated( IWorkbenchPartReference partRef ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partHidden( IWorkbenchPartReference partRef ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partInputChanged( IWorkbenchPartReference partRef ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partOpened( IWorkbenchPartReference partRef ) { + if ( isDisassemblyEditorPart( partRef ) ) { + IWorkbenchPart part = partRef.getPart( false ); + if ( part instanceof IEditorPart ) { + IEditorInput input = ((IEditorPart)part).getEditorInput(); + if ( input instanceof DisassemblyEditorInput ) { + Object disassemblyContext = ((DisassemblyEditorInput)input).getDisassemblyContext(); + fEditorParts.put( disassemblyContext, (IEditorPart)part ); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partVisible( IWorkbenchPartReference partRef ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) + */ + public void windowActivated( IWorkbenchWindow window ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) + */ + public void windowClosed( IWorkbenchWindow window ) { + window.getPartService().removePartListener( this ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) + */ + public void windowDeactivated( IWorkbenchWindow window ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) + */ + public void windowOpened( IWorkbenchWindow window ) { + window.getPartService().addPartListener( this ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextListener#contextAdded(java.lang.Object) + */ + public void contextAdded( Object context ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.disassembly.IDisassemblyContextListener#contextRemoved(java.lang.Object) + */ + public void contextRemoved( Object context ) { + final IEditorPart editor = fEditorParts.remove( context ); + if ( editor != null ) { + UIJob job = new UIJob( editor.getSite().getShell().getDisplay(), "Closing disassembly" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + editor.getSite().getPage().closeEditor( editor, false ); + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + } + + private IDisassemblyContextService getDisassemblyManager() { + return CDebugCorePlugin.getDefault().getDisassemblyContextService(); + } + + private boolean isDisassemblyEditorPart( IWorkbenchPartReference partRef ) { + // TODO: check all editors contributed via the extension point + return ( partRef.getId().equals( DEFAULT_EDITOR_ID ) ); + } + + private ISourcePresentation getSourcePresentation() { + + return new ISourcePresentation() { + + public IEditorInput getEditorInput( Object element ) { + Object disassemblyContext = getDiassemblyContext( element ); + return new DisassemblyEditorInput( element, disassemblyContext ); + } + + public String getEditorId( IEditorInput input, Object element ) { + return DEFAULT_EDITOR_ID; + } + }; + } + + protected Object getDiassemblyContext( Object element ) { + IDisassemblyContextProvider adapter = getDisassemblyContextProvider( element ); + return ( adapter != null ) ? adapter.getDisassemblyContext( element ) : null; + } + + private IDisassemblyContextProvider getDisassemblyContextProvider( Object element ) { + IDisassemblyContextProvider adapter = null; + if ( element instanceof IDisassemblyContextProvider ) { + adapter = (IDisassemblyContextProvider)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IDisassemblyContextProvider)adaptable.getAdapter( IDisassemblyContextProvider.class ); + } + return adapter; + } + + private ISteppingModeTarget getSteppingModeTarget( Object debugContext ) { + if ( debugContext instanceof ISteppingModeTarget ) + return (ISteppingModeTarget)debugContext; + if ( debugContext instanceof IAdaptable ) + return (ISteppingModeTarget)((IAdaptable)debugContext).getAdapter( ISteppingModeTarget.class ); + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyDocumentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyDocumentProvider.java new file mode 100644 index 00000000000..894e64e2172 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyDocumentProvider.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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.Map; + +import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorInput; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.IElementStateListener; + +/** + * org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DisassemblyDocumentProvider: + * //TODO Add description. + */ +public class DisassemblyDocumentProvider implements IDocumentProvider { + + class DocumentInfo { + + private VirtualDocument fDocument; + private IAnnotationModel fAnnotationModel; + private IDocumentPresentation fPresentation; + + DocumentInfo( VirtualDocument document, IAnnotationModel annotationModel, IDocumentPresentation presentation ) { + fDocument = document; + fAnnotationModel = annotationModel; + fPresentation = presentation; + } + + VirtualDocument getDocument() { + return fDocument; + } + + IAnnotationModel getAnnotationModel() { + return fAnnotationModel; + } + + IDocumentPresentation getPresentation() { + return fPresentation; + } + + void dispose() { + fPresentation.dispose(); + fPresentation = null; + fAnnotationModel = null; + fDocument.dispose(); + fDocument = null; + } + } + + private Map fDocumentInfos; + + public DisassemblyDocumentProvider() { + fDocumentInfos = new HashMap(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#aboutToChange(java.lang.Object) + */ + public void aboutToChange( Object element ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#addElementStateListener(org.eclipse.ui.texteditor.IElementStateListener) + */ + public void addElementStateListener( IElementStateListener listener ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#canSaveDocument(java.lang.Object) + */ + public boolean canSaveDocument( Object element ) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#changed(java.lang.Object) + */ + public void changed( Object element ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#connect(java.lang.Object) + */ + public synchronized void connect( Object element ) throws CoreException { + Object disassemblyContext = ((DisassemblyEditorInput)element).getDisassemblyContext(); + if ( fDocumentInfos.get( disassemblyContext ) == null ) { + IDocumentPresentation presentation = createDocumentPresentation( disassemblyContext ); + IAnnotationModel annotationModel = createAnnotationModel(); + VirtualDocument document = createDocument( disassemblyContext, presentation, annotationModel ); + fDocumentInfos.put( disassemblyContext, new DocumentInfo( document, annotationModel, presentation ) ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#disconnect(java.lang.Object) + */ + public synchronized void disconnect( Object element ) { + Object disassemblyContext = ((DisassemblyEditorInput)element).getDisassemblyContext(); + DocumentInfo info = fDocumentInfos.remove( disassemblyContext ); + if ( info != null ) { + info.dispose(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getAnnotationModel(java.lang.Object) + */ + public IAnnotationModel getAnnotationModel( Object element ) { + Object disassemblyContext = ((DisassemblyEditorInput)element).getDisassemblyContext(); + DocumentInfo info = fDocumentInfos.get( disassemblyContext ); + return ( info != null ) ? info.getAnnotationModel() : null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getDocument(java.lang.Object) + */ + public IDocument getDocument( Object element ) { + Object disassemblyContext = ((DisassemblyEditorInput)element).getDisassemblyContext(); + DocumentInfo info = fDocumentInfos.get( disassemblyContext ); + return ( info != null ) ? info.getDocument() : null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getModificationStamp(java.lang.Object) + */ + public long getModificationStamp( Object element ) { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getSynchronizationStamp(java.lang.Object) + */ + public long getSynchronizationStamp( Object element ) { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#isDeleted(java.lang.Object) + */ + public boolean isDeleted( Object element ) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#mustSaveDocument(java.lang.Object) + */ + public boolean mustSaveDocument( Object element ) { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#removeElementStateListener(org.eclipse.ui.texteditor.IElementStateListener) + */ + public void removeElementStateListener( IElementStateListener listener ) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#resetDocument(java.lang.Object) + */ + public void resetDocument( Object element ) throws CoreException { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#saveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean) + */ + public void saveDocument( IProgressMonitor monitor, Object element, IDocument document, boolean overwrite ) throws CoreException { + // TODO Auto-generated method stub + + } + + public void dispose() { + for( DocumentInfo info : fDocumentInfos.values() ) { + info.dispose(); + } + fDocumentInfos.clear(); + } + + public IDocumentPresentation getDocumentPresentation( Object element ) { + Object disassemblyContext = ((DisassemblyEditorInput)element).getDisassemblyContext(); + DocumentInfo info = fDocumentInfos.get( disassemblyContext ); + return ( info != null ) ? info.getPresentation() : null; + } + + private IAnnotationModel createAnnotationModel() { + return new AnnotationModel(); + } + + private VirtualDocument createDocument( Object disassemblyContext, IDocumentPresentation presentationContext, IAnnotationModel annotationModel ) { + return null; + } + + private IDocumentPresentation createDocumentPresentation( Object context ) { + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyPane.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyPane.java new file mode 100644 index 00000000000..23c97f44fa2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DisassemblyPane.java @@ -0,0 +1,416 @@ +/******************************************************************************* + * 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 fActions = new HashMap( 10 ); + + public DisassemblyPane() { + fAnnotationPreferences = new MarkerAnnotationPreferences(); + setViewContextMenuId( "#DisassemblyViewContext" ); //$NON-NLS-1$ + setRulerContextMenuId( "#DisassemblyEditorRulerContext" ); //$NON-NLS-1$ + } + + 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() { + + 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(); + } + } + + public void mouseUp( MouseEvent e ) { +// setFocus(); + if ( 1 == e.button && !fDoubleClicked ) + triggerAction( ITextEditorActionConstants.RULER_CLICK ); + fDoubleClicked = false; + } + + public void mouseDoubleClick( MouseEvent e ) { + if ( 1 == e.button ) { + fDoubleClicked = true; + triggerAction( IInternalCDebugUIConstants.ACTION_TOGGLE_BREAKPOINT ); + } + } + + 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) + */ + 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; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationProvider.java new file mode 100644 index 00000000000..212bca7c7d3 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationProvider.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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 org.eclipse.cdt.debug.ui.disassembly.IDocumentElementAnnotationProvider; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.ui.progress.UIJob; + +/** + * org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DocumentAnnotationProvider: + * //TODO Add description. + */ +public class DocumentAnnotationProvider { + + private VirtualDocument fDocument; + + public DocumentAnnotationProvider( VirtualDocument document ) { + fDocument = document; + } + + public void dispose() { + fDocument = null; + } + + public void update( Object parent, Object[] elements, IDocumentPresentation context ) { + IDocumentElementAnnotationProvider annotationProvider = getAnnotationAdapter( parent ); + if ( annotationProvider != null ) { + Object root = getDocument().getContentProvider().getRoot(); + Object base = getDocument().getContentProvider().getBase(); + DocumentAnnotationUpdate[] updates = new DocumentAnnotationUpdate[elements.length]; + for ( int i = 0; i < elements.length; ++i ) { + updates[i] = new DocumentAnnotationUpdate( this, context, root, base, elements[i], i ); + } + annotationProvider.update( updates ); + } + } + + public void update( Object parent, Object element, int index, IDocumentPresentation context ) { + IDocumentElementAnnotationProvider annotationProvider = getAnnotationAdapter( parent ); + if ( annotationProvider != null ) { + Object root = getDocument().getContentProvider().getRoot(); + Object base = getDocument().getContentProvider().getBase(); + annotationProvider.update( new DocumentAnnotationUpdate[] { new DocumentAnnotationUpdate( this, context, root, base, element, index ) } ); + } + } + + public void completed( DocumentAnnotationUpdate update ) { + if ( update.isCanceled() ) + return; + + final int index = update.getIndex(); + final Annotation[] annotations = update.getAnnotations(); + UIJob uiJob = new UIJob( "Add annotations" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + VirtualDocument document = getDocument(); + if ( document != null ) { + getDocument().updateAnnotations( index, annotations ); + } + return Status.OK_STATUS; + } + }; + uiJob.setSystem( true ); + uiJob.schedule(); + } + + protected IDocumentElementAnnotationProvider getAnnotationAdapter( Object element ) { + IDocumentElementAnnotationProvider adapter = null; + if ( element instanceof IDocumentElementAnnotationProvider ) { + adapter = (IDocumentElementAnnotationProvider)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IDocumentElementAnnotationProvider)adaptable.getAdapter( IDocumentElementAnnotationProvider.class ); + } + return adapter; + } + + protected VirtualDocument getDocument() { + return fDocument; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationUpdate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationUpdate.java new file mode 100644 index 00000000000..1b37c40e198 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentAnnotationUpdate.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * 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.ArrayList; +import java.util.List; + +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementAnnotationUpdate; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.jface.text.source.Annotation; + +/** + * org.eclipse.cdt.debug.internal.ui.disassembly.viewer.DocumentAnnotationUpdate: + * //TODO Add description. + */ +public class DocumentAnnotationUpdate extends DocumentUpdate implements IDocumentElementAnnotationUpdate { + private DocumentAnnotationProvider fAnnotationProvider; + private int fIndex = 0; + private List fAnnotations; + + public DocumentAnnotationUpdate( DocumentAnnotationProvider annotationProvider, IDocumentPresentation presentationContext, Object root, Object base, Object element, int index ) { + super( presentationContext, root, base, element ); + fAnnotationProvider = annotationProvider; + fIndex = index; + fAnnotations = new ArrayList(); + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementAnnotationUpdate#addAnnotation(org.eclipse.jface.text.source.Annotation) + */ + public void addAnnotation( Annotation annotation ) { + fAnnotations.add( annotation ); + } + + public int getIndex() { + return fIndex; + } + + public Annotation[] getAnnotations() { + return fAnnotations.toArray( new Annotation[fAnnotations.size()] ); + } + + protected DocumentAnnotationProvider getAnnotationProvider() { + return fAnnotationProvider; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.internal.ui.disassembly.DocumentUpdate#done() + */ + @Override + public void done() { + super.done(); + getAnnotationProvider().completed( this ); + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.internal.ui.disassembly.DocumentUpdate#startRequest() + */ + @Override + void startRequest() { + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentBaseChangeUpdate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentBaseChangeUpdate.java new file mode 100644 index 00000000000..49c01db78b0 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentBaseChangeUpdate.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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 org.eclipse.cdt.debug.ui.disassembly.IDocumentBaseChangeUpdate; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementContentProvider; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; + +public class DocumentBaseChangeUpdate extends DocumentUpdate implements IDocumentBaseChangeUpdate { + + private DocumentContentProvider fContentProvider; + private IDocumentElementContentProvider fElementContentProvider; + private int fOriginalOffset = 0; + private int fOffset = 0; + + public DocumentBaseChangeUpdate( DocumentContentProvider contentProvider, IDocumentElementContentProvider elementContentProvider, IDocumentPresentation presentationContext, Object root, Object base, Object input, int offset ) { + super( presentationContext, root, base, input ); + fContentProvider = contentProvider; + fElementContentProvider = elementContentProvider; + fOriginalOffset = offset; + fOffset = offset; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentBaseChangeUpdate#setBaseElement(java.lang.Object) + */ + @Override + public void setBaseElement( Object base ) { + super.setBaseElement( base ); + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentBaseChangeUpdate#setOffset(int) + */ + public void setOffset( int offset ) { + fOffset = offset; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentBaseChangeUpdate#getOriginalOffset() + */ + public int getOriginalOffset() { + return fOriginalOffset; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.commands.Request#done() + */ + @Override + public void done() { + super.done(); + getContentProvider().inputChanged( this ); + } + + public int getOffset() { + return fOffset; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.internal.ui.disassembly.DocumentUpdate#startRequest() + */ + @Override + void startRequest() { + getElementContentProvider().updateInput( this ); + } + + protected DocumentContentProvider getContentProvider() { + return fContentProvider; + } + + protected IDocumentElementContentProvider getElementContentProvider() { + return fElementContentProvider; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentProvider.java new file mode 100644 index 00000000000..11644655b9e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentProvider.java @@ -0,0 +1,465 @@ +/******************************************************************************* + * 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.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementContentProvider; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * Manages the mapping between the viewer model and the underlying debug model + * through the content, label and annotation adapters. + * Maintains the list of model proxies and reacts to the debug model changes. + */ +public class DocumentContentProvider implements IModelChangedListener { + + private VirtualSourceViewer fViewer; + private VirtualDocument fDocument; + + private Object fRoot; + private Object fBase; + private Object fInput; + + private IModelProxy fRootProxy; + private IModelProxy fBaseProxy; + private List fLineProxies = new ArrayList( 50 ); + private Map fLineElements = new HashMap( 20 ); + + private DocumentUpdate fUpdateInProgress; + + public DocumentContentProvider( VirtualDocument document ) { + super(); + fDocument = document; + } + + protected void init( Object root ) { + fRoot = root; + installRootProxy( fRoot ); + } + + public void update( IDocumentPresentation presentationContext, int lineCount, int offset, boolean reveal ) { + IDocumentElementContentProvider contentAdapter = getContentAdapter( getInput() ); + if ( contentAdapter != null && getRoot() != null && getBase() != null ) { + DocumentContentUpdate update = new DocumentContentUpdate( this, contentAdapter, presentationContext, getRoot(), getBase(), getInput(), lineCount, offset, reveal ); + schedule( update ); + } + else { + updateCompleted( new DocumentContentUpdate( this, contentAdapter, presentationContext, getRoot(), getBase(), getInput(), lineCount, offset, reveal ) ); + } + } + + public synchronized void updateCompleted( DocumentContentUpdate update ) { + if ( fUpdateInProgress == update ) { + fUpdateInProgress = null; + } + if ( !update.isCanceled() ) { + disposeLineProxies(); + getDocument().setCurrentOffset( update.getOffset() ); + Object[] elements = update.getElements(); + for ( int i = 0; i < elements.length; ++i ) { + installLineProxy( i, elements[i] ); + getDocument().updateElement( getInput(), i, elements[i] ); + } + } + // TODO: display error content if status is not OK + } + + protected IDocumentElementContentProvider getContentAdapter( Object element ) { + IDocumentElementContentProvider adapter = null; + if ( element instanceof IDocumentElementContentProvider ) { + adapter = (IDocumentElementContentProvider)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IDocumentElementContentProvider)adaptable.getAdapter( IDocumentElementContentProvider.class ); + } + return adapter; + } + + protected VirtualDocument getDocument() { + return fDocument; + } + + public Object getRoot() { + return fRoot; + } + + public Object getInput() { + return fInput; + } + + public Object getBase() { + return fBase; + } + + public void dispose() { + synchronized( this ) { + if ( fUpdateInProgress != null ) { + fUpdateInProgress.cancel(); + } + } + disposeRootProxy(); + fDocument = null; + fInput = null; + fViewer = null; + } + + public void changeInput( VirtualSourceViewer viewer, IDocumentPresentation presentationContext, Object oldInput, Object newInput, int offset ) { + fViewer = viewer; + if ( newInput != oldInput ) { + fInput = newInput; + IDocumentElementContentProvider contentAdapter = getContentAdapter( getInput() ); + if ( contentAdapter != null ) { + DocumentBaseChangeUpdate update = new DocumentBaseChangeUpdate( this, contentAdapter, presentationContext, getRoot(), getBase(), getInput(), offset ); + schedule( update ); + } + else { + inputChanged( new DocumentBaseChangeUpdate( this, contentAdapter, presentationContext, getRoot(), getBase(), getInput(), offset ) ); + } + } + } + + public synchronized void inputChanged( DocumentBaseChangeUpdate update ) { + if ( fUpdateInProgress == update ) { + fUpdateInProgress = null; + } + Object newBase = update.getBaseElement(); + int newOffset = update.getOffset(); + VirtualDocument document = getDocument(); + boolean needsUpdate = false; + if ( newBase != getBase() ) { + fBase = newBase; + disposeBaseProxy(); + installBaseProxy( fBase ); + needsUpdate = true; + } + if ( newOffset != document.getCurrentOffset() ) { + document.setCurrentOffset( newOffset ); + needsUpdate = true; + } + if ( needsUpdate ) { + WorkbenchJob job = new WorkbenchJob( "refresh content" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + getViewer().refresh( true ); + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta, org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy) + */ + public void modelChanged( final IModelDelta delta, final IModelProxy proxy ) { + WorkbenchJob job = new WorkbenchJob( "process model delta" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + if ( !proxy.isDisposed() ) { + handleModelChanges( delta ); + } + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + + protected void handleModelChanges( IModelDelta delta ) { + updateNodes( new IModelDelta[] { delta } ); + } + + protected void updateNodes( IModelDelta[] nodes ) { + for( int i = 0; i < nodes.length; i++ ) { + IModelDelta node = nodes[i]; + int flags = node.getFlags(); + + if ( (flags & IModelDelta.ADDED) != 0 ) { + handleAdd( node ); + } + if ( (flags & IModelDelta.REMOVED) != 0 ) { + handleRemove( node ); + } + if ( (flags & IModelDelta.CONTENT) != 0 ) { + handleContent( node ); + } + if ( (flags & IModelDelta.SELECT) != 0 ) { + handleSelect( node ); + } + if ( (flags & IModelDelta.STATE) != 0 ) { + handleState( node ); + } + if ( (flags & IModelDelta.INSERTED) != 0 ) { + handleInsert( node ); + } + if ( (flags & IModelDelta.REPLACED) != 0 ) { + handleReplace( node ); + } + if ( (flags & IModelDelta.INSTALL) != 0 ) { + handleInstall( node ); + } + if ( (flags & IModelDelta.UNINSTALL) != 0 ) { + handleUninstall( node ); + } + if ( (flags & IModelDelta.REVEAL) != 0 ) { + handleReveal( node ); + } + updateNodes( node.getChildDeltas() ); + } + } + + protected void handleState( IModelDelta delta ) { + int index = getElementIndex( delta.getElement() ); + if ( index >= 0 ) { + getDocument().updateElement( getInput(), index, delta.getElement() ); + } + } + + protected void handleSelect( IModelDelta delta ) { + + } + + protected void handleContent( IModelDelta delta ) { + if ( delta.getElement().equals( getRoot() ) || delta.getElement().equals( getBase() ) ) { + getViewer().refresh(); + } + } + + protected void handleRemove( IModelDelta delta ) { + + } + + protected void handleAdd( IModelDelta delta ) { + + } + + protected void handleInsert( IModelDelta delta ) { + + } + + protected void handleReplace( IModelDelta delta ) { + + } + + protected void handleReveal( IModelDelta delta ) { + + } + + protected void handleInstall( IModelDelta delta ) { + } + + protected void handleUninstall( IModelDelta delta ) { + } + + protected synchronized void installRootProxy( Object element ) { + if ( element != null && (!element.equals( getRoot()) || fRootProxy == null) ) { + disposeRootProxy(); + IModelProxyFactory modelProxyFactory = getModelProxyFactoryAdapter( element ); + if ( modelProxyFactory != null ) { + final IModelProxy proxy = modelProxyFactory.createModelProxy( element, getPresentationContext() ); + if ( proxy != null ) { + fRootProxy = proxy; + Job job = new Job( "Model Proxy installed notification job" ) {//$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run( IProgressMonitor monitor ) { + if ( !monitor.isCanceled() ) { + proxy.init( getPresentationContext() ); + proxy.addModelChangedListener( DocumentContentProvider.this ); + proxy.installed( getViewer() ); + } + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + } + } + } + + protected synchronized void installBaseProxy( Object element ) { + if ( element != null && (!element.equals( getBase()) || fBaseProxy == null) ) { + IModelProxyFactory modelProxyFactory = getModelProxyFactoryAdapter( element ); + if ( modelProxyFactory != null ) { + final IModelProxy proxy = modelProxyFactory.createModelProxy( element, getPresentationContext() ); + if ( proxy != null ) { + fBaseProxy = proxy; + Job job = new Job( "Model Proxy installed notification job" ) {//$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run( IProgressMonitor monitor ) { + if ( !monitor.isCanceled() ) { + proxy.init( getPresentationContext() ); + proxy.addModelChangedListener( DocumentContentProvider.this ); + proxy.installed( getViewer() ); + } + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + } + } + } + + protected synchronized void installLineProxy( int index, Object element ) { + IModelProxyFactory modelProxyFactory = getModelProxyFactoryAdapter( element ); + if ( modelProxyFactory != null ) { + final IModelProxy proxy = modelProxyFactory.createModelProxy( element, getPresentationContext() ); + if ( proxy != null ) { + fLineProxies.add( index, proxy ); + fLineElements.put( element, Integer.valueOf( index ) ); + Job job = new Job( "Model Proxy installed notification job" ) {//$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + protected IStatus run( IProgressMonitor monitor ) { + if ( !monitor.isCanceled() ) { + proxy.init( getPresentationContext() ); + proxy.addModelChangedListener( DocumentContentProvider.this ); + proxy.installed( getViewer() ); + } + return Status.OK_STATUS; + } + }; + job.setSystem( true ); + job.schedule(); + } + } + } + + protected IModelProxyFactory getModelProxyFactoryAdapter( Object element ) { + IModelProxyFactory adapter = null; + if ( element instanceof IModelProxyFactory ) { + adapter = (IModelProxyFactory)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IModelProxyFactory)adaptable.getAdapter( IModelProxyFactory.class ); + } + return adapter; + } + + protected IPresentationContext getPresentationContext() { + return getDocument().getPresentationContext(); + } + + protected synchronized void disposeRootProxy() { + disposeBaseProxy(); + if ( fRootProxy != null ) { + fRootProxy.dispose(); + } + fRootProxy = null; + } + + protected synchronized void disposeBaseProxy() { + disposeLineProxies(); + if ( fBaseProxy != null ) { + fBaseProxy.dispose(); + } + fBaseProxy = null; + } + + protected synchronized void disposeLineProxies() { + for ( IModelProxy proxy : fLineProxies ) { + proxy.dispose(); + } + fLineProxies.clear(); + fLineElements.clear(); + } + + protected VirtualSourceViewer getViewer() { + return fViewer; + } + + synchronized void schedule( DocumentUpdate update ) { + if ( fUpdateInProgress != null ) { + if ( update instanceof DocumentBaseChangeUpdate ) { + // cancel the earlier update and start the latest + fUpdateInProgress.cancel(); + fUpdateInProgress.done(); + fUpdateInProgress = update; + fUpdateInProgress.start(); + } + else if ( fUpdateInProgress instanceof DocumentBaseChangeUpdate + && update instanceof DocumentContentUpdate ) { + // cancel the content update because the base change update + // will start a new one + update.cancel(); + update.done(); + } + else if ( fUpdateInProgress instanceof DocumentContentUpdate + && update instanceof DocumentBaseChangeUpdate ) { + // cancel the content update and start the base change update + fUpdateInProgress.cancel(); + fUpdateInProgress.done(); + fUpdateInProgress = update; + fUpdateInProgress.start(); + } + } + else { + fUpdateInProgress = update; + fUpdateInProgress.start(); + } + } + + private int getElementIndex( Object element ) { + Integer index = fLineElements.get( element ); + return ( index != null ) ? index.intValue() : -1; + } + + protected Object getElementAtLine( int lineNumber ) { + synchronized( fLineElements ) { + for ( Object element : fLineElements.keySet() ) { + if ( fLineElements.get( element ).intValue() == lineNumber ) { + return element; + } + } + } + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentUpdate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentUpdate.java new file mode 100644 index 00000000000..db73dd044f5 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentContentUpdate.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * 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 org.eclipse.cdt.debug.ui.disassembly.IDocumentElementContentProvider; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementContentUpdate; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; + +public class DocumentContentUpdate extends DocumentUpdate implements IDocumentElementContentUpdate { + + private DocumentContentProvider fContentProvider; + private IDocumentElementContentProvider fElementContentProvider; + private int fLineCount = 0; + private int fOriginalOffset = 0; + private int fOffset = 0; + private Object[] fElements; + boolean fReveal = true; + + public DocumentContentUpdate( DocumentContentProvider contentProvider, IDocumentElementContentProvider elementContentProvider, IDocumentPresentation presentationContext, Object rootElement, Object baseElement, Object input, int lineCount, int offset, boolean reveal ) { + super( presentationContext, rootElement, baseElement, input ); + fContentProvider = contentProvider; + fElementContentProvider = elementContentProvider; + fLineCount = lineCount; + fOriginalOffset = offset; + fOffset = offset; + fElements = new Object[lineCount]; + fReveal = reveal; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#setLineCount(int) + */ + public void setLineCount( int lineCount ) { + fElements = new Object[lineCount]; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#addElement(int, java.lang.Object) + */ + public void addElement( int line, Object element ) throws IndexOutOfBoundsException { + if ( line < 0 || line >= fElements.length ) + throw new IndexOutOfBoundsException( Integer.toString( line ) ); + fElements[line] = element; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#getOriginalOffset() + */ + public int getOriginalOffset() { + return fOriginalOffset; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#getRequestedLineCount() + */ + public int getRequestedLineCount() { + return fLineCount; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#setOffset(int) + */ + public void setOffset( int offset ) { + fOffset = offset; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementContentUpdate#reveal() + */ + public boolean reveal() { + return fReveal; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.commands.Request#done() + */ + @Override + public void done() { + super.done(); + getContentProvider().updateCompleted( this ); + } + + protected Object[] getElements() { + return fElements; + } + + protected int getLineCount() { + return fElements.length; + } + + protected int getOffset() { + return fOffset; + } + + protected DocumentContentProvider getContentProvider() { + return fContentProvider; + } + + protected IDocumentElementContentProvider getElementContentProvider() { + return fElementContentProvider; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.internal.ui.disassembly.DocumentUpdate#startRequest() + */ + @Override + void startRequest() { + getElementContentProvider().updateContent( this ); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelProvider.java new file mode 100644 index 00000000000..f7401d2efa6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelProvider.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * 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.List; +import java.util.Map; +import java.util.Properties; + +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelProvider; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.ui.progress.UIJob; + +public class DocumentLabelProvider extends BaseLabelProvider { + + private VirtualDocument fDocument; + + public DocumentLabelProvider( VirtualDocument document ) { + super(); + fDocument = document; + } + + public void update( Object parent, Object[] elements, IDocumentPresentation context ) { + IDocumentElementLabelProvider labelProvider = getLabelAdapter( parent ); + if ( labelProvider != null ) { + Object root = getDocument().getContentProvider().getRoot(); + Object base = getDocument().getContentProvider().getBase(); + DocumentLabelUpdate[] updates = new DocumentLabelUpdate[elements.length]; + for ( int i = 0; i < elements.length; ++i ) { + updates[i] = new DocumentLabelUpdate( this, context, root, base, elements[i], i ); + } + labelProvider.update( updates ); + } + } + + public void update( Object parent, Object element, int index, IDocumentPresentation context ) { + IDocumentElementLabelProvider labelProvider = getLabelAdapter( parent ); + if ( labelProvider != null ) { + Object root = getDocument().getContentProvider().getRoot(); + Object base = getDocument().getContentProvider().getBase(); + labelProvider.update( new DocumentLabelUpdate[] { new DocumentLabelUpdate( this, context, root, base, element, index ) } ); + } + } + + public void completed( DocumentLabelUpdate update ) { + if ( update.isCanceled() ) + return; + + UIJob uiJob = null; + final int index = update.getIndex(); + if ( update.getElement() != null ) { + final Object element = update.getElement(); + final Properties labels = update.getLabels(); + + uiJob = new UIJob( "Replace line" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + getDocument().labelDone( element, index, labels ); + return Status.OK_STATUS; + } + }; + } + else { + uiJob = new UIJob( "Remove line" ) { //$NON-NLS-1$ + + /* (non-Javadoc) + * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public IStatus runInUIThread( IProgressMonitor monitor ) { + getDocument().removeLine( index ); + return Status.OK_STATUS; + } + }; + } + uiJob.setSystem( true ); + uiJob.schedule(); + } + + protected VirtualDocument getDocument() { + return fDocument; + } + + protected IDocumentElementLabelProvider getLabelAdapter( Object element ) { + IDocumentElementLabelProvider adapter = null; + if ( element instanceof IDocumentElementLabelProvider ) { + adapter = (IDocumentElementLabelProvider)element; + } + else if ( element instanceof IAdaptable ) { + IAdaptable adaptable = (IAdaptable)element; + adapter = (IDocumentElementLabelProvider)adaptable.getAdapter( IDocumentElementLabelProvider.class ); + } + return adapter; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelUpdate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelUpdate.java new file mode 100644 index 00000000000..98ca24458e9 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentLabelUpdate.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.Properties; + +import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelUpdate; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; + +public class DocumentLabelUpdate extends DocumentUpdate implements IDocumentElementLabelUpdate { + private DocumentLabelProvider fLabelProvider; + private int fIndex = 0; + private Properties fLabels; + + public DocumentLabelUpdate( DocumentLabelProvider labelProvider, IDocumentPresentation presentationContext, Object root, Object base, Object element, int index ) { + super( presentationContext, root, base, element ); + fLabelProvider = labelProvider; + fIndex = index; + fLabels = new Properties(); + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentElementLabelUpdate#setLabel(java.lang.String, java.lang.String) + */ + public void setLabel( String attribute, String text ) { + fLabels.put( attribute, text ); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.commands.Request#done() + */ + @Override + public void done() { + super.done(); + getLabelProvider().completed( this ); + } + + public int getIndex() { + return fIndex; + } + + protected DocumentLabelProvider getLabelProvider() { + return fLabelProvider; + } + + protected Properties getLabels() { + return fLabels; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.internal.ui.disassembly.DocumentUpdate#startRequest() + */ + @Override + void startRequest() { + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentUpdate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentUpdate.java new file mode 100644 index 00000000000..a99d6ecf5a1 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/DocumentUpdate.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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 org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.cdt.debug.ui.disassembly.IDocumentUpdate; +import org.eclipse.debug.internal.core.commands.Request; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.TreePath; + +public abstract class DocumentUpdate extends Request implements IDocumentUpdate { + + private Object fRootElement; + private Object fBaseElement; + private Object fElement; + private IDocumentPresentation fPresentationContext; + + private boolean fDone = false; + private boolean fStarted = false; + + public DocumentUpdate( IDocumentPresentation presentationContext, Object rootElement, Object baseElement, Object element ) { + super(); + fRootElement = rootElement; + fBaseElement = baseElement; + fElement = element; + fPresentationContext = presentationContext; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentUpdate#getBaseElement() + */ + public Object getBaseElement() { + return fBaseElement; + } + + /* (non-Javadoc) + * @see com.arm.eclipse.rvd.ui.disassembly.IDocumentUpdate#getRootElement() + */ + public Object getRootElement() { + return fRootElement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getElement() + */ + public Object getElement() { + return fElement; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getElementPath() + */ + public TreePath getElementPath() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getPresentationContext() + */ + public IPresentationContext getPresentationContext() { + return fPresentationContext; + } + + /** + * Starts this request. Subclasses must override startRequest(). + */ + final void start() { + synchronized( this ) { + if ( fStarted ) { + return; + } + fStarted = true; + } + if ( !isCanceled() ) { + startRequest(); + } + else { + done(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.core.commands.Request#done() + */ + @Override + public void done() { + synchronized( this ) { + if ( isDone() ) { + return; + } + fDone = true; + } + } + + void setRootElement( Object rootElement ) { + fRootElement = rootElement; + } + + void setBaseElement( Object baseElement ) { + fBaseElement = baseElement; + } + + protected synchronized boolean isDone() { + return fDone; + } + + /** + * Subclasses must override to initiate specific request types. + */ + abstract void startRequest(); + + /* (non-Javadoc) + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate#getViewerInput() + */ + public Object getViewerInput() { + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualDocument.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualDocument.java new file mode 100644 index 00000000000..ab1f129788b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualDocument.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * 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.Properties; + +import org.eclipse.cdt.debug.ui.disassembly.IDocumentPresentation; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; + +/** + * Converts the model elements into the text content + */ +abstract public class VirtualDocument extends Document { + + private Object fRoot; + private int fCurrentOffset = 0; + + private IDocumentPresentation fPresentationContext; + private AnnotationModel fAnnotationModel; + private DocumentContentProvider fContentProvider; + + public VirtualDocument( AnnotationModel annotationModel, IDocumentPresentation presentationContext, Object root ) { + super(); + fRoot = root; + fPresentationContext = presentationContext; + fAnnotationModel = annotationModel; + fContentProvider = new DocumentContentProvider( this ); + } + + public void dispose() { + getContentProvider().dispose(); + fRoot = null; + } + + public IDocumentPresentation getPresentationContext() { + return fPresentationContext; + } + + public AnnotationModel getAnnotationModel() { + return fAnnotationModel; + } + + public DocumentContentProvider getContentProvider() { + return fContentProvider; + } + + public int getCurrentOffset() { + return fCurrentOffset; + } + + public void setCurrentOffset( int offset ) { + fCurrentOffset = offset; + } + + public void updateContent( int lineCount, int offset, boolean revealInput ) { + } + + protected void updateElement( Object input, int index, Object element ) { + } + + final void labelDone( Object element, int lineNumber, Properties labels ) { + } + + protected void removeLine( int lineNumber ) { + } + + protected void updateAnnotations( int lineNumber, Annotation[] annotations ) { + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualSourceViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualSourceViewer.java new file mode 100644 index 00000000000..5667b89e2e2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/viewer/VirtualSourceViewer.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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 org.eclipse.jface.text.source.IOverviewRuler; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.ScrollBar; + +/** + * Notifies the associated document when the viewer is refreshed, scrolled or resized. + */ +public class VirtualSourceViewer extends SourceViewer { + + private SelectionListener fScrollSelectionListener; + + public VirtualSourceViewer( Composite parent, IVerticalRuler ruler, int styles ) { + this( parent, ruler, null, false, styles ); + } + + public VirtualSourceViewer( Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean showAnnotationsOverview, int styles ) { + super( parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles ); + initScrollBarListener(); + initControlListener(); + } + + public VirtualDocument getVirtualDocument() { + return (VirtualDocument)getDocument(); + } + + private void initControlListener() { + getTextWidget().addControlListener( new ControlListener() { + + public void controlMoved( ControlEvent e ) { + } + + public void controlResized( ControlEvent e ) { + handleControlResized(); + } + } ); + } + + private void initScrollBarListener() { + ScrollBar scroll = getTextWidget().getVerticalBar(); + fScrollSelectionListener = new SelectionAdapter() { + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected( SelectionEvent e ) { + handleScrollBarSelection( e ); + } + }; + scroll.addSelectionListener( fScrollSelectionListener ); + } + + public int getNumberOfVisibleLines() { + StyledText widget = getTextWidget(); + if ( widget != null ) { + Rectangle clArea = widget.getClientArea(); + if ( !clArea.isEmpty() ) { + return (clArea.height / widget.getLineHeight()) + 1; + } + } + return 0; + } + + protected void handleScrollBarSelection( SelectionEvent e ) { + int offset = getVirtualDocument().getCurrentOffset(); + int lines = getNumberOfVisibleLines(); + if ( e.detail == SWT.ARROW_UP ) { + --offset; + } + else if ( e.detail == SWT.ARROW_DOWN ) { + ++offset; + } + else if ( e.detail == SWT.PAGE_UP ) { + offset -= lines; + } + else if ( e.detail == SWT.PAGE_DOWN ) { + offset += lines; + } + else if ( e.detail == SWT.HOME ) { + } + else if ( e.detail == SWT.END ) { + } + getVirtualDocument().updateContent( lines, offset, false ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.TextViewer#refresh() + */ + @Override + public void refresh() { + refresh( false ); + } + + public void refresh( boolean revealInput ) { + VirtualDocument document = getVirtualDocument(); + document.updateContent( getNumberOfVisibleLines(), getVirtualDocument().getCurrentOffset(), revealInput ); + } + + protected void handleControlResized() { + getVirtualDocument().updateContent( getNumberOfVisibleLines(), getVirtualDocument().getCurrentOffset(), false ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.source.SourceViewer#handleDispose() + */ + @Override + protected void handleDispose() { + getVirtualDocument().dispose(); + super.handleDispose(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java index 4b378853e1f..bec4b02cb35 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java @@ -23,9 +23,9 @@ import org.eclipse.cdt.debug.internal.ui.CDebuggerPageAdapter; import org.eclipse.cdt.debug.internal.ui.ColorManager; import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; +import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; -import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -64,10 +64,12 @@ public class CDebugUIPlugin extends AbstractUIPlugin { //The shared instance. private static CDebugUIPlugin plugin; - protected Map fDebuggerPageMap; + protected Map fDebuggerPageMap; private CDebugImageDescriptorRegistry fImageDescriptorRegistry; + private DisassemblyEditorManager fDisassemblyEditorManager; + /** * The constructor. */ @@ -143,7 +145,7 @@ public class CDebugUIPlugin extends AbstractUIPlugin { if ( fDebuggerPageMap == null ) { initializeDebuggerPageMap(); } - IConfigurationElement configElement = (IConfigurationElement)fDebuggerPageMap.get( debuggerID ); + IConfigurationElement configElement = fDebuggerPageMap.get( debuggerID ); ICDebuggerPage tab = null; if ( configElement != null ) { Object o = configElement.createExecutableExtension( "class" ); //$NON-NLS-1$ @@ -160,7 +162,7 @@ public class CDebugUIPlugin extends AbstractUIPlugin { } protected void initializeDebuggerPageMap() { - fDebuggerPageMap = new HashMap( 10 ); + fDebuggerPageMap = new HashMap( 10 ); IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint( PLUGIN_ID, CDEBUGGER_PAGE_EXTENSION_POINT_ID ); IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); for( int i = 0; i < infos.length; i++ ) { @@ -263,8 +265,10 @@ public class CDebugUIPlugin extends AbstractUIPlugin { * * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ - public void start( BundleContext context ) throws Exception { + @Override + public void start( BundleContext context ) throws Exception { super.start( context ); + fDisassemblyEditorManager = new DisassemblyEditorManager(); EvaluationContextManager.startup(); CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() ); } @@ -274,8 +278,10 @@ public class CDebugUIPlugin extends AbstractUIPlugin { * * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ - public void stop( BundleContext context ) throws Exception { + @Override + public void stop( BundleContext context ) throws Exception { CDebugCorePlugin.getDefault().removeCBreakpointListener( CBreakpointUpdater.getInstance() ); + fDisassemblyEditorManager.dispose(); if ( fImageDescriptorRegistry != null ) { fImageDescriptorRegistry.dispose(); } @@ -291,4 +297,8 @@ public class CDebugUIPlugin extends AbstractUIPlugin { public ISharedTextColors getSharedTextColors() { return EditorsUI.getSharedTextColors(); } + + public DisassemblyEditorManager getDisassemblyEditorManager() { + return fDisassemblyEditorManager; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/IDocumentPresentation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/IDocumentPresentation.java new file mode 100644 index 00000000000..e2a69415925 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/IDocumentPresentation.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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.ui.disassembly; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; + +/** + * Virtual document specific presentation context. + *

+ * Clients may implement and extend this interface to provide + * special contexts. Implementations must subclass {@link PresentationContext}. + *

+ * + * This interface is experimental. + */ +public interface IDocumentPresentation extends IPresentationContext { + +}