diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java index 345f7473d73..befe3d2fee1 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java @@ -588,7 +588,8 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControl fSourceLookupParticipant = new DsfSourceLookupParticipant(session); fSourceLookup.addParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant} ); - fIPManager = new InstructionPointerManager(); + final IInstructionPointerPresentation ipPresentation = (IInstructionPointerPresentation) session.getModelAdapter(IInstructionPointerPresentation.class); + fIPManager = new InstructionPointerManager(ipPresentation); fSession.addServiceEventListener(this, null); @@ -607,7 +608,7 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControl * @since 1.1 */ public void setSelectionChangeDelay(int delay) { - fSelectionChangeDelay = delay; + fSelectionChangeDelay = delay; } public void dispose() { diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/IInstructionPointerPresentation.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/IInstructionPointerPresentation.java new file mode 100644 index 00000000000..29e42557287 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/IInstructionPointerPresentation.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.ui.sourcelookup; + + +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.IEditorPart; + +/** + * Clients may implement this interface to override annotations used to display + * instruction pointers for stack frames. + *

+ * This interface is modeled after the platform interface + * {@link org.eclipse.debug.ui.IInstructionPointerPresentation}. + *

+ *

+ * A client has several options when overriding default instruction pointer + * annotations. The following prioritized order is used to compute an annotation + * for a stack frame. + *

    + *
  1. Specify the annotation object to use. This is done by returning a non- + * null value from getInstructionPointerAnnotation(..) + * .
  2. + *
  3. Specify an annotationType extension to use. This is done by + * returning a non-null value from + * getInstructionPointerAnnotationType(..). When specified, the + * annotation type controls the image displayed via its associated + * markerAnnotationSpecification.
  4. + *
  5. Specify the image to use. This is done by returning a non- + * null value from getInstructionPointerImage(..).
  6. + *
+ * Additionally, when specifying an annotation type or image the text for the + * instruction pointer may be specified by returning a non-null + * value from getInstructionPointerText(..). + *

+ *

+ * These methods are called when the debugger has opened an editor to display + * source for the given stack frame. The image will be positioned based on stack + * frame line number and character ranges. + *

+ * + * @see org.eclipse.debug.ui.IInstructionPointerPresentation + * @since 2.0 + */ +public interface IInstructionPointerPresentation { + /** + * Returns an annotation used for the specified stack frame in the specified + * editor, or null if a default annotation should be used. + * + * @param editorPart the editor the debugger has opened + * @param frame the stack frame for which the debugger is displaying + * source + * @return annotation or null + */ + public Annotation getInstructionPointerAnnotation(IEditorPart editorPart, IFrameDMContext frame); + + /** + * Returns an identifier of a org.eclipse.ui.editors.annotationTypes extension used for + * the specified stack frame in the specified editor, or null if a default annotation + * should be used. + * + * @param editorPart the editor the debugger has opened + * @param frame the stack frame for which the debugger is displaying + * source + * @return annotation type identifier or null + */ + public String getInstructionPointerAnnotationType(IEditorPart editorPart, IFrameDMContext frame); + + /** + * Returns the instruction pointer image used for the specified stack frame in the specified + * editor, or null if a default image should be used. + *

+ * By default, the debug platform uses different images for top stack + * frames and non-top stack frames in a thread. + *

+ * @param editorPart the editor the debugger has opened + * @param frame the stack frame for which the debugger is displaying + * source + * @return image or null + */ + public Image getInstructionPointerImage(IEditorPart editorPart, IFrameDMContext frame); + + /** + * Returns the text to associate with the instruction pointer annotation used for the + * specified stack frame in the specified editor, or null if a default + * message should be used. + *

+ * By default, the debug platform uses different images for top stack + * frames and non-top stack frames in a thread. + *

+ * @param editorPart the editor the debugger has opened + * @param frame the stack frame for which the debugger is displaying + * source + * @return message or null + */ + public String getInstructionPointerText(IEditorPart editorPart, IFrameDMContext frame); +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/InstructionPointerManager.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/InstructionPointerManager.java index 825ec43daf3..b94b7dc3a2a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/InstructionPointerManager.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/sourcelookup/InstructionPointerManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2009 IBM Corporation 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 @@ -11,8 +11,7 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.ui.sourcelookup; - -import java.util.Collections; + import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -22,6 +21,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IStack; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.text.Position; @@ -154,13 +154,30 @@ class InstructionPointerManager { * Mapping of IDebugTarget objects to (mappings of IThread objects to lists of instruction * pointer contexts). */ - private List fAnnotationWrappers; + private final List fAnnotationWrappers; + + /** + * For customized instruction pointer presentation. + */ + private final IInstructionPointerPresentation fPresentation; /** * Clients must not instantiate this class. */ public InstructionPointerManager() { - fAnnotationWrappers = Collections.synchronizedList(new LinkedList()); + this(null); + } + + /** + * Clients must not instantiate this class. + * + * @param presentation + * the custom instruction pointer presentation or + * null to use the default presentation + */ + public InstructionPointerManager(IInstructionPointerPresentation presentation) { + fPresentation = presentation; + fAnnotationWrappers = new LinkedList(); } /** @@ -177,31 +194,58 @@ class InstructionPointerManager { return; } - String id; - String text; - Image image; - if (isTopFrame) { - id = ID_CURRENT_IP; - text = "Debug Current Instruction Pointer"; //$NON-NLS-1$ - image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP); - } else { - id = ID_SECONDARY_IP; - text = "Debug Call Stack"; //$NON-NLS-1$ - image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER); - } - if (isTopFrame) { // remove other top-frame IP annotation(s) for this execution-context removeAnnotations(DMContexts.getAncestorOfType(frame.getParents()[0], IExecutionDMContext.class)); } - Annotation annotation = new IPAnnotation(frame, id, text, image); + Annotation annotation = createAnnotation(textEditor, frame); // Add the annotation at the position to the editor's annotation model. annModel.removeAnnotation(annotation); annModel.addAnnotation(annotation, position); // Add to list of existing wrappers - fAnnotationWrappers.add(new AnnotationWrapper(textEditor, annotation, frame)); + synchronized (fAnnotationWrappers) { + fAnnotationWrappers.add(new AnnotationWrapper(textEditor, annotation, frame)); + } + } + + private Annotation createAnnotation(ITextEditor editorPart, IStack.IFrameDMContext frame) { + String id = null; + String text = null; + Image image = null; + if (fPresentation != null) { + Annotation annotation = fPresentation.getInstructionPointerAnnotation(editorPart, frame); + if (annotation != null) { + return annotation; + } + id = fPresentation.getInstructionPointerAnnotationType(editorPart, frame); + if (id == null) { + image = fPresentation.getInstructionPointerImage(editorPart, frame); + } + text = fPresentation.getInstructionPointerText(editorPart, frame); + } + if (id == null) { + if (frame.getLevel() == 0) { + id = ID_CURRENT_IP; + if (text == null) { + text = "Debug Current Instruction Pointer"; //$NON-NLS-1$ + } + if (image == null) { + image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP); + } + } else { + id = ID_SECONDARY_IP; + if (text == null) { + text = "Debug Call Stack"; //$NON-NLS-1$ + } + if (image == null) { + image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER); + } + } + return new IPAnnotation(frame, id, text, image); + } + return new Annotation(id, false, text); } /** @@ -230,8 +274,8 @@ class InstructionPointerManager { synchronized(fAnnotationWrappers) { for (Iterator wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) { AnnotationWrapper wrapper = wrapperItr.next(); - if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc) - && ID_CURRENT_IP.equals(wrapper.getAnnotation().getType())) { + final IFrameDMContext frameDmc= wrapper.getFrameDMC(); + if (DMContexts.isAncestorOf(frameDmc, execDmc) && frameDmc.getLevel() == 0) { removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation()); wrapperItr.remove(); }