diff options
author | Darin Wright | 2004-11-26 03:33:46 +0000 |
---|---|---|
committer | Darin Wright | 2004-11-26 03:33:46 +0000 |
commit | e6ca5895d79a2335d6b6f2a2094821baed8685e3 (patch) | |
tree | 74187a438c6d856daaaaeb863d8783c25da2ef53 /org.eclipse.debug.ui | |
parent | 17357ae869f7c573c022371cd0754c2291a1caab (diff) | |
download | eclipse.platform.debug-e6ca5895d79a2335d6b6f2a2094821baed8685e3.tar.gz eclipse.platform.debug-e6ca5895d79a2335d6b6f2a2094821baed8685e3.tar.xz eclipse.platform.debug-e6ca5895d79a2335d6b6f2a2094821baed8685e3.zip |
Bug 35400 - new Debugger view can't get to associated text editor
Diffstat (limited to 'org.eclipse.debug.ui')
5 files changed, 744 insertions, 364 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java new file mode 100644 index 000000000..591051610 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java @@ -0,0 +1,470 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.sourcelookup; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.DelegatingModelPresentation; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.InstructionPointerManager; +import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages; +import org.eclipse.debug.internal.ui.views.launch.Decoration; +import org.eclipse.debug.internal.ui.views.launch.DecorationManager; +import org.eclipse.debug.internal.ui.views.launch.SourceNotFoundEditorInput; +import org.eclipse.debug.internal.ui.views.launch.StandardDecoration; +import org.eclipse.debug.ui.IDebugEditorPresentation; +import org.eclipse.debug.ui.IDebugModelPresentation; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.ISourcePresentation; +import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IPageListener; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IReusableEditor; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Utility methods for looking up and displaying source. + * + * @since 3.1 + */ +public class SourceLookupFacility implements IPageListener, IPartListener2, IPropertyChangeListener { + + /** + * Singleton source lookup facility + */ + private static SourceLookupFacility fgDefault; + + /** + * Contains a map of the editor to use for each workbench + * page, when the 'resuse editor' preference is on. + */ + private Map fEditorsByPage; + + /** + * Whether to re-use editors when displaying source. + */ + private boolean fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR); + + /** + * Returns the source lookup facility + * @return + */ + public static SourceLookupFacility getDefault() { + if (fgDefault == null) { + fgDefault = new SourceLookupFacility(); + } + return fgDefault; + } + + /** + * Constructs a source lookup facility. + */ + private SourceLookupFacility() { + fEditorsByPage = new HashMap(); + } + + /** + * Performs source lookup for the given artifact and returns the result. + * + * @param artifact object for which source is to be resolved + * @param locator the source locator to use, or <code>null</code>. When <code>null</code> + * a source locator is determined from the artifact, if possible. If the artifact + * is a debug element, the source locator from its associated launch is used. + * @return a source lookup result + */ + public SourceLookupResult lookup(Object artifact, ISourceLocator locator) { + SourceLookupResult result = new SourceLookupResult(artifact, null, null, null); + IDebugElement debugElement = null; + if (artifact instanceof IDebugElement) { + debugElement = (IDebugElement)artifact; + } + if (locator == null) { + ILaunch launch = null; + if (debugElement != null) { + launch = debugElement.getLaunch(); + } + if (launch != null) { + locator = launch.getSourceLocator(); + } + } + if (locator != null) { + String editorId =null; + IEditorInput editorInput = null; + Object sourceElement = null; + if (locator instanceof ISourceLookupDirector) { + ISourceLookupDirector director = (ISourceLookupDirector)locator; + sourceElement = director.getSourceElement(artifact); + } else { + if (artifact instanceof IStackFrame) { + sourceElement = locator.getSourceElement((IStackFrame)artifact); + } + } + if (sourceElement == null) { + if (locator instanceof AbstractSourceLookupDirector) { + editorInput = new CommonSourceNotFoundEditorInput(artifact); + editorId = IInternalDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR; + } else { + if (artifact instanceof IStackFrame) { + IStackFrame frame = (IStackFrame)artifact; + editorInput = new SourceNotFoundEditorInput(frame); + editorId = IInternalDebugUIConstants.ID_SOURCE_NOT_FOUND_EDITOR; + } + } + } else { + ISourcePresentation presentation= null; + if (locator instanceof ISourcePresentation) { + presentation= (ISourcePresentation) locator; + } else { + if (debugElement != null) { + presentation= getPresentation(debugElement.getModelIdentifier()); + } + } + if (presentation != null) { + editorInput= presentation.getEditorInput(sourceElement); + } + if (editorInput != null) { + editorId= presentation.getEditorId(editorInput, sourceElement); + } + result.setEditorInput(editorInput); + result.setEditorId(editorId); + result.setSourceElement(sourceElement); + } + } + return result; + } + + /** + * Rerturns the model presentation for the given debug model, or <code>null</code> + * if none. + * + * @param id debug model id + * @return presentation for the model, or <code>null</code> if none. + */ + protected IDebugModelPresentation getPresentation(String id) { + return ((DelegatingModelPresentation)DebugUIPlugin.getModelPresentation()).getPresentation(id); + } + + /** + * Returns an editor presentation. + * + * @return an editor presentation + */ + protected IDebugEditorPresentation getEditorPresentation() { + return (DelegatingModelPresentation)DebugUIPlugin.getModelPresentation(); + } + + /** + * Opens an editor in the given workbench page for the given source lookup + * result. Has no effect if the result has an unknown editor id or editor input. + * The editor is opened, positioned, and annotated. + * <p> + * Honors the user preference of whether to re-use editors when displaying source. + * </p> + * @param result source lookup result to display + * @param page the page to display the result in + */ + public void display(ISourceLookupResult result, IWorkbenchPage page) { + IEditorPart editor= openEditor(result, page); + if (editor == null) { + return; + } + IStackFrame frame = null; + if (result.getArtifact() instanceof IStackFrame) { + frame = (IStackFrame) result.getArtifact(); + } + // position and annotate editor for stack frame + if (frame != null) { + IDebugEditorPresentation editorPresentation = getEditorPresentation(); + if (editorPresentation.addAnnotations(editor, frame)) { + Decoration decoration = new StandardDecoration(editorPresentation, editor, frame.getThread()); + DecorationManager.addDecoration(decoration); + } else { + // perform standard positioning and annotations + ITextEditor textEditor = null; + if (editor instanceof ITextEditor) { + textEditor = (ITextEditor)editor; + } else { + textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class); + } + if (textEditor != null) { + positionEditor(textEditor, frame); + InstructionPointerManager.getDefault().addAnnotation(textEditor, frame); + } + } + } + } + + /** + * Opens the editor used to display the source for an element selected in + * this view and returns the editor that was opened or <code>null</code> if + * no editor could be opened. + */ + private IEditorPart openEditor(ISourceLookupResult result, IWorkbenchPage page) { + IEditorPart editor = null; + IEditorInput input= result.getEditorInput(); + String id= result.getEditorId(); + if (input == null || id == null) { + return null; + } + + // TODO: persist/restore the editor to use per page + + if (fReuseEditor) { + editor = page.getActiveEditor(); + if (editor != null) { + // The active editor is the one we want to reuse + if (!editor.getEditorInput().equals(input)) { + editor = null; + } + } + if (editor == null) { + // Try to find the editor we want to reuse and activate it + IEditorReference[] refs = page.getEditorReferences(); + for (int i = 0; i < refs.length; i++) { + IEditorPart refEditor= refs[i].getEditor(false); + if (refEditor != null && input.equals(refEditor.getEditorInput())) { + editor = refEditor; + page.bringToTop(editor); + break; + } + } + } + if (editor == null) { + IEditorPart editorForPage = getEditor(page); + if (editorForPage == null || editorForPage.isDirty() || page.isEditorPinned(editorForPage)) { + // open a new editor + editor = openEditor(page, input, id); + editorForPage = editor; + } else if (editorForPage instanceof IReusableEditor && editorForPage.getSite().getId().equals(id)) { + // re-use editor + ((IReusableEditor)editorForPage).setInput(input); + editor = editorForPage; + page.bringToTop(editor); + } else { + // close editor, open a new one + editor = openEditor(page, input, id); + page.closeEditor(editorForPage, false); + editorForPage = editor; + } + setEditor(page, editorForPage); + } + } else { + // Open a new editor + editor = openEditor(page, input, id); + } + return editor; + } + + /** + * Positions the text editor for the given stack frame + */ + private void positionEditor(ITextEditor editor, IStackFrame frame) { + try { + int charStart = frame.getCharStart(); + if (charStart > 0) { + editor.selectAndReveal(charStart, 0); + return; + } + int lineNumber = frame.getLineNumber(); + lineNumber--; // Document line numbers are 0-based. Debug line numbers are 1-based. + IRegion region= getLineInformation(editor, lineNumber); + if (region != null) { + editor.selectAndReveal(region.getOffset(), 0); + } + } catch (DebugException e) { + } + } + + /** + * Returns the line information for the given line in the given editor + */ + private IRegion getLineInformation(ITextEditor editor, int lineNumber) { + IDocumentProvider provider= editor.getDocumentProvider(); + IEditorInput input= editor.getEditorInput(); + try { + provider.connect(input); + } catch (CoreException e) { + return null; + } + try { + IDocument document= provider.getDocument(input); + if (document != null) + return document.getLineInformation(lineNumber); + } catch (BadLocationException e) { + } finally { + provider.disconnect(input); + } + return null; + } + /** + * Opens an editor in the workbench and returns the editor that was opened + * or <code>null</code> if an error occurred while attempting to open the + * editor. + */ + private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) { + final IEditorPart[] editor = new IEditorPart[] {null}; + Runnable r = new Runnable() { + public void run() { + try { + editor[0] = page.openEditor(input, id, false); + } catch (PartInitException e) { + DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), + DebugUIViewsMessages.getString("LaunchView.Error_1"), //$NON-NLS-1$ + DebugUIViewsMessages.getString("LaunchView.Exception_occurred_opening_editor_for_debugger._2"), //$NON-NLS-1$ + e); + } + } + }; + BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), r); + return editor[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPageListener#pageActivated(org.eclipse.ui.IWorkbenchPage) + */ + public void pageActivated(IWorkbenchPage page) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPageListener#pageClosed(org.eclipse.ui.IWorkbenchPage) + */ + public void pageClosed(IWorkbenchPage page) { + fEditorsByPage.remove(page); + page.removePartListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPageListener#pageOpened(org.eclipse.ui.IWorkbenchPage) + */ + public void pageOpened(IWorkbenchPage page) { + page.addPartListener(this); + } + + /* (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) { + // clear the cached editor for the page if it has been closed + IWorkbenchPage page = partRef.getPage(); + IEditorPart editor = getEditor(page); + IWorkbenchPart part = partRef.getPart(false); + if (part != null && part.equals(editor)) { + fEditorsByPage.remove(page); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partDeactivated(IWorkbenchPartReference partRef) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partOpened(IWorkbenchPartReference partRef) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partHidden(IWorkbenchPartReference partRef) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partVisible(IWorkbenchPartReference partRef) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference) + */ + public void partInputChanged(IWorkbenchPartReference partRef) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String property = event.getProperty(); + if (property.equals(IDebugUIConstants.PREF_REUSE_EDITOR)) { + fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR); + } + } + + /** + * Returns the editor to use to display source in the given page, or + * <code>null</code> if a new editor should be opened. + * + * @param page workbench page + * @return the editor to use to display source in the given page, or + * <code>null</code> if a new editor should be opened + */ + protected IEditorPart getEditor(IWorkbenchPage page) { + return (IEditorPart) fEditorsByPage.get(page); + } + + /** + * Sets the editor to use to display source in the given page, or + * <code>null</code> if a new editor should be opened. + * + * @param page workbench page + * @return the editor to use to display source in the given page, or + * <code>null</code> if a new editor should be opened + */ + protected void setEditor(IWorkbenchPage page, IEditorPart editorPart) { + if (editorPart == null) { + fEditorsByPage.remove(page); + } else { + fEditorsByPage.put(page, editorPart); + } + page.addPartListener(this); + page.getWorkbenchWindow().addPageListener(this); + } + +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java new file mode 100644 index 000000000..2a64d3717 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.sourcelookup; + +import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; +import org.eclipse.ui.IEditorInput; + +/** + * The result of a source lookup contains the source element, editor id, and + * editor input resolved for a debug artifact. + * + * @since 3.1 + */ +public class SourceLookupResult implements ISourceLookupResult { + + /** + * Element that source was resolved for. + */ + private Object fArtifact; + /** + * Corresponding source element, or <code>null</code> + * if unknown. + */ + private Object fSourceElement; + /** + * Associated editor id, used to display the source element, + * or <code>null</code> if unknown. + */ + private String fEditorId; + /** + * Associatd editor input, used to display the source element, + * or <code>null</code> if unknown. + */ + private IEditorInput fEditorInput; + + /** + * Creates a source lookup result on the given artifact, source element, + * editor id, and editor input. + */ + public SourceLookupResult(Object artifact, Object sourceElement, String editorId, IEditorInput editorInput) { + fArtifact = artifact; + setSourceElement(sourceElement); + setEditorId(editorId); + setEditorInput(editorInput); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getArtifact() + */ + public Object getArtifact() { + return fArtifact; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getSourceElement() + */ + public Object getSourceElement() { + return fSourceElement; + } + + /** + * Sets the source element resolved for the artifact that source + * lookup was performed for, or <code>null</code> if a source element + * was not resolved. + * + * @param element resolved source element or <code>null</code> if unknown + */ + protected void setSourceElement(Object element) { + fSourceElement = element; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorId() + */ + public String getEditorId() { + return fEditorId; + } + + /** + * Sets the identifier of the editor used to display this source + * lookup result's source element, or <code>null</code> if unknown. + * + * @param id the identifier of the editor used to display this source + * lookup result's source element, or <code>null</code> if unknown + */ + protected void setEditorId(String id) { + fEditorId = id; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.sourcelookup.ISourceLookupResult#getEditorInput() + */ + public IEditorInput getEditorInput() { + return fEditorInput; + } + + /** + * Sets the editor input used to display this source lookup + * result's source element, or <code>null</code> if unknown. + * + * @param input the editor input used to display this source lookup + * result's source element, or <code>null</code> if unknown + */ + protected void setEditorInput(IEditorInput input) { + fEditorInput = input; + } +} diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java index 06fa6c7c1..31608e073 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/LaunchView.java @@ -31,11 +31,9 @@ import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.ITerminate; import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DelegatingModelPresentation; import org.eclipse.debug.internal.ui.IDebugHelpContextIds; @@ -43,7 +41,6 @@ import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.InstructionPointerManager; import org.eclipse.debug.internal.ui.actions.AddToFavoritesAction; import org.eclipse.debug.internal.ui.actions.EditLaunchConfigurationAction; -import org.eclipse.debug.internal.ui.sourcelookup.CommonSourceNotFoundEditorInput; import org.eclipse.debug.internal.ui.sourcelookup.EditSourceLookupPathAction; import org.eclipse.debug.internal.ui.sourcelookup.LookupSourceAction; import org.eclipse.debug.internal.ui.views.AbstractDebugEventHandlerView; @@ -52,18 +49,16 @@ import org.eclipse.debug.internal.ui.views.DebugViewDecoratingLabelProvider; import org.eclipse.debug.internal.ui.views.DebugViewInterimLabelProvider; import org.eclipse.debug.internal.ui.views.DebugViewLabelDecorator; import org.eclipse.debug.internal.ui.views.RemoteTreeViewer; +import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugEditorPresentation; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.debug.ui.ISourcePresentation; +import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.DoubleClickEvent; @@ -75,21 +70,17 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPageListener; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveListener2; -import org.eclipse.ui.IReusableEditor; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; @@ -103,8 +94,6 @@ import org.eclipse.ui.part.IShowInSource; import org.eclipse.ui.part.IShowInTarget; import org.eclipse.ui.part.IShowInTargetList; import org.eclipse.ui.part.ShowInContext; -import org.eclipse.ui.texteditor.IDocumentProvider; -import org.eclipse.ui.texteditor.ITextEditor; public class LaunchView extends AbstractDebugEventHandlerView implements ISelectionChangedListener, IPerspectiveListener2, IPageListener, IPropertyChangeListener, IResourceChangeListener, IShowInTarget, IShowInSource, IShowInTargetList, IPartListener2 { @@ -119,41 +108,16 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect private IStackFrame fStackFrame = null; /** - * Cache of the editor input used to display source + * Result of last source lookup */ - private IEditorInput fEditorInput = null; - - /** - * Cache of the editor id used to display source - */ - private String fEditorId = null; - + private ISourceLookupResult fResult = null; + /** * Whether this view is in the active page of a perspective. */ private boolean fIsActive = true; /** - * Editor to reuse - */ - private IEditorPart fEditor = null; - - /** - * The source element corresponding to the selected stack frame - */ - private Object fSourceElement = null; - - /** - * The restored editor index of the editor to re-use - */ - private int fEditorIndex = -1; - - /** - * Whether to re-use editors - */ - private boolean fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR); - - /** * Resource delta visitor */ private IResourceDeltaVisitor fVisitor = null; @@ -397,16 +361,17 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect if (memento == null) { return; } - if (fReuseEditor) { - String index = memento.getString(IDebugUIConstants.PREF_REUSE_EDITOR); - if (index != null) { - try { - fEditorIndex = Integer.parseInt(index); - } catch (NumberFormatException e) { - DebugUIPlugin.log(e); - } - } - } + // TODO: persist editor to re-use +// if (fReuseEditor) { +// String index = memento.getString(IDebugUIConstants.PREF_REUSE_EDITOR); +// if (index != null) { +// try { +// fEditorIndex = Integer.parseInt(index); +// } catch (NumberFormatException e) { +// DebugUIPlugin.log(e); +// } +// } +// } } /* (non-Javadoc) @@ -451,11 +416,18 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect * Disposes of cached information */ protected void cleanup() { - setEditorId(null); - setEditorInput(null); + setSourceLookupResult(null); setStackFrame(null); } + private void setSourceLookupResult(ISourceLookupResult result) { + fResult = result; + } + + private ISourceLookupResult getSourceLookupResult() { + return fResult; + } + /** * The selection has changed in the viewer. Show the * associated source code if it is a stack frame. @@ -596,51 +568,6 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect openEditorForStackFrame((IStackFrame) obj); } - /** - * Translate to an editor input using the source presentation - * provided by the source locator, or the default debug model - * presentation. - */ - private void lookupEditorInput(IStackFrame stackFrame) { - setEditorId(null); - setEditorInput(null); - setSourceElement(null); - Object sourceElement= null; - ILaunch launch= stackFrame.getLaunch(); - if (launch == null) { - return; - } - ISourceLocator locator= launch.getSourceLocator(); - if (locator == null) { - return; - } - sourceElement= locator.getSourceElement(stackFrame); - if (sourceElement == null) { - if (locator instanceof AbstractSourceLookupDirector) - commonSourceNotFound(stackFrame); - else - sourceNotFound(stackFrame); - return; - } - ISourcePresentation presentation= null; - if (locator instanceof ISourcePresentation) { - presentation= (ISourcePresentation) locator; - } else { - presentation= getPresentation(stackFrame.getModelIdentifier()); - } - IEditorInput editorInput= null; - String editorId= null; - if (presentation != null) { - editorInput= presentation.getEditorInput(sourceElement); - } - if (editorInput != null) { - editorId= presentation.getEditorId(editorInput, sourceElement); - } - setEditorInput(editorInput); - setEditorId(editorId); - setSourceElement(sourceElement); - } - /* (non-Javadoc) * @see org.eclipse.debug.ui.IDebugView#getPresentation(java.lang.String) */ @@ -649,22 +576,6 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect } /** - * Sets editor id and input for the "source not found" editor. - */ - private void sourceNotFound(IStackFrame frame) { - setEditorInput(new SourceNotFoundEditorInput(frame)); - setEditorId(IInternalDebugUIConstants.ID_SOURCE_NOT_FOUND_EDITOR); - } - - /** - * Sets editor id and input for the "common source not found" editor. - */ - private void commonSourceNotFound(IStackFrame frame) { - setEditorInput(new CommonSourceNotFoundEditorInput(frame)); - setEditorId(IInternalDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR); - } - - /** * Get the active window and open/bring to the front an editor on the stack * frame. Selection is based on the line number OR the char start and end. */ @@ -679,181 +590,31 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect return; } - if (stackFrame.equals(getStackFrame())) { - if (getEditorInput() == null || getEditorId() == null) { - lookupEditorInput(stackFrame); - } - } else { - setStackFrame(stackFrame); - lookupEditorInput(stackFrame); - } - if (getEditorInput() == null || getEditorId() == null) { - return; - } - IEditorPart editor= openEditor(); - if (editor == null) { - return; - } - // position and annotate editor for stack frame - if (fEditorPresentation.addAnnotations(editor, stackFrame)) { - Decoration decoration = new StandardDecoration(fEditorPresentation, editor, stackFrame.getThread()); - DecorationManager.addDecoration(decoration); - } else { - // perform standard positioning and annotations - ITextEditor textEditor = null; - if (editor instanceof ITextEditor) { - textEditor = (ITextEditor)editor; - } else { - textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class); - } - if (textEditor != null) { - positionEditor(textEditor, stackFrame); - InstructionPointerManager.getDefault().addAnnotation(textEditor, stackFrame); - } + if (!stackFrame.equals(getStackFrame()) || (getEditorInput() == null || getEditorId() == null)) { + setSourceLookupResult(DebugUITools.lookupSource(stackFrame, null)); } + setStackFrame(stackFrame); + DebugUITools.displaySource(getSourceLookupResult(), getSite().getPage()); } finally { fShowingEditor= false; } } - /** - * Positions the text editor for the given stack frame - */ - private void positionEditor(ITextEditor editor, IStackFrame frame) { - try { - int charStart = frame.getCharStart(); - if (charStart > 0) { - editor.selectAndReveal(charStart, 0); - return; - } - int lineNumber = frame.getLineNumber(); - lineNumber--; // Document line numbers are 0-based. Debug line numbers are 1-based. - IRegion region= getLineInformation(editor, lineNumber); - if (region != null) { - editor.selectAndReveal(region.getOffset(), 0); - } - } catch (DebugException e) { + private IEditorInput getEditorInput() { + if (fResult != null) { + return fResult.getEditorInput(); } + return null; } - /** - * Returns the line information for the given line in the given editor - */ - private IRegion getLineInformation(ITextEditor editor, int lineNumber) { - IDocumentProvider provider= editor.getDocumentProvider(); - IEditorInput input= editor.getEditorInput(); - try { - provider.connect(input); - } catch (CoreException e) { - return null; - } - try { - IDocument document= provider.getDocument(input); - if (document != null) - return document.getLineInformation(lineNumber); - } catch (BadLocationException e) { - } finally { - provider.disconnect(input); + private String getEditorId() { + if (fResult != null) { + return fResult.getEditorId(); } return null; } - - - /** - * Opens the editor used to display the source for an element selected in - * this view and returns the editor that was opened or <code>null</code> if - * no editor could be opened. - */ - private IEditorPart openEditor() { - IWorkbenchWindow window= getSite().getWorkbenchWindow(); - if (window == null) { - return null; - } - IWorkbenchPage page= window.getActivePage(); - if (page == null) { - return null; - } - - if (fEditorIndex >= 0) { - // first restoration of editor re-use - IEditorReference[] refs = page.getEditorReferences(); - if (fEditorIndex < refs.length) { - fEditor = refs[fEditorIndex].getEditor(false); - } - fEditorIndex = -1; - } - - IEditorPart editor = null; - IEditorInput input= getEditorInput(); - String id= getEditorId(); - if (input == null || id == null) { - return null; - } - if (fReuseEditor) { - editor = page.getActiveEditor(); - if (editor != null) { - // The active editor is the one we want to reuse - if (!editor.getEditorInput().equals(input)) { - editor = null; - } - } - if (editor == null) { - // Try to find the editor we want to reuse and activate it - IEditorReference[] refs = page.getEditorReferences(); - for (int i = 0; i < refs.length; i++) { - IEditorPart refEditor= refs[i].getEditor(false); - if (refEditor != null && input.equals(refEditor.getEditorInput())) { - editor = refEditor; - page.bringToTop(editor); - break; - } - } - } - if (editor == null) { - if (fEditor == null || fEditor.isDirty() || page.isEditorPinned(fEditor)) { - editor = openEditor(page, input, id); - fEditor = editor; - } else if (fEditor instanceof IReusableEditor && fEditor.getSite().getId().equals(id)) { - ((IReusableEditor)fEditor).setInput(input); - editor = fEditor; - page.bringToTop(editor); - } else { - editor = openEditor(page, input, id); - page.closeEditor(fEditor, false); - fEditor = editor; - } - } - } else { - // Open a new editor - editor = openEditor(page, input, id); - } - return editor; - } /** - * Opens an editor in the workbench and returns the editor that was opened - * or <code>null</code> if an error occurred while attempting to open the - * editor. - */ - private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) { - final IEditorPart[] editor = new IEditorPart[] {null}; - Runnable r = new Runnable() { - public void run() { - try { - editor[0] = page.openEditor(input, id, false); - } catch (PartInitException e) { - DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), - DebugUIViewsMessages.getString("LaunchView.Error_1"), //$NON-NLS-1$ - DebugUIViewsMessages.getString("LaunchView.Exception_occurred_opening_editor_for_debugger._2"), //$NON-NLS-1$ - e); - } - } - }; - BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), r); - return editor[0]; - } - - /** * Deselects any source decorations associated with the given thread or * debug target. * @@ -1011,65 +772,7 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect protected void setStackFrame(IStackFrame frame) { fStackFrame= frame; } - - /** - * Sets the editor input that was resolved for the - * source display. - * - * @param editorInput editor input - */ - private void setEditorInput(IEditorInput editorInput) { - fEditorInput = editorInput; - } - - /** - * Returns the editor input that was resolved for the - * source display. - * - * @return editor input - */ - protected IEditorInput getEditorInput() { - return fEditorInput; - } - - /** - * Sets the id of the editor opened when displaying - * source. - * - * @param editorId editor id - */ - private void setEditorId(String editorId) { - fEditorId = editorId; - } - - /** - * Returns the id of the editor opened when displaying - * source. - * - * @return editor id - */ - protected String getEditorId() { - return fEditorId; - } - - /** - * Sets the current source element, possibly <code>null</code> - * - * @param sourceElement - */ - private void setSourceElement(Object sourceElement) { - fSourceElement = sourceElement; - } - - /** - * Returns the current source element, possibly <code>null</code> - * - * @return Object - */ - protected Object getSourceElement() { - return fSourceElement; - } - + /** * Sets whether this view is in the active page of a * perspective. Since a page can have more than one @@ -1099,9 +802,7 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect */ public void propertyChange(PropertyChangeEvent event) { String property = event.getProperty(); - if (property.equals(IDebugUIConstants.PREF_REUSE_EDITOR)) { - fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR); - } else if (property.equals(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES)) { + if (property.equals(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES)) { fContextListener.reloadAutoManagePerspectives(((IStructuredSelection) getViewer().getSelection()).getFirstElement()); } else if (property.equals(LaunchViewContextListener.PREF_OPENED_VIEWS) && fContextListener != null) { fContextListener.loadOpenedViews(); @@ -1117,27 +818,28 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect */ public void saveState(IMemento memento) { super.saveState(memento); - if (fReuseEditor && fEditor != null) { - IWorkbenchWindow dwindow= getSite().getWorkbenchWindow(); - if (dwindow == null) { - return; - } - IWorkbenchPage page= dwindow.getActivePage(); - if (page == null) { - return; - } - IEditorReference[] refs = page.getEditorReferences(); - int index = -1; - for (int i = 0; i < refs.length; i++) { - if (fEditor.equals(refs[i].getEditor(false))) { - index = i; - break; - } - } - if (index >= 0) { - memento.putString(IDebugUIConstants.PREF_REUSE_EDITOR, Integer.toString(index)); - } - } + // TODO: persist editor to re-use +// if (fReuseEditor && fEditor != null) { +// IWorkbenchWindow dwindow= getSite().getWorkbenchWindow(); +// if (dwindow == null) { +// return; +// } +// IWorkbenchPage page= dwindow.getActivePage(); +// if (page == null) { +// return; +// } +// IEditorReference[] refs = page.getEditorReferences(); +// int index = -1; +// for (int i = 0; i < refs.length; i++) { +// if (fEditor.equals(refs[i].getEditor(false))) { +// index = i; +// break; +// } +// } +// if (index >= 0) { +// memento.putString(IDebugUIConstants.PREF_REUSE_EDITOR, Integer.toString(index)); +// } +// } } /** @@ -1235,10 +937,13 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect if (isActive()) { IStructuredSelection selection = (IStructuredSelection)getViewer().getSelection(); if (!selection.isEmpty()) { - Object sourceElement = getSourceElement(); + Object sourceElement = null; + if (fResult != null) { + sourceElement = fResult.getSourceElement(); + } if (sourceElement instanceof IAdaptable) { if (((IAdaptable)sourceElement).getAdapter(IResource.class) != null) { - return new ShowInContext(null, new StructuredSelection(getSourceElement())); + return new ShowInContext(null, new StructuredSelection(sourceElement)); } } } @@ -1257,10 +962,6 @@ public class LaunchView extends AbstractDebugEventHandlerView implements ISelect * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference) */ public void partClosed(IWorkbenchPartReference partRef) { - IWorkbenchPart part = partRef.getPart(false); - if (part != null && part.equals(fEditor)) { - fEditor = null; - } } /* (non-Javadoc) diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java index 8621370e8..0f408f349 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java @@ -27,6 +27,7 @@ import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.internal.ui.DebugPluginImages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.DefaultLabelProvider; @@ -37,7 +38,9 @@ import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationMan import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPropertiesDialog; import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog; import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupExtension; +import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility; import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager; +import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; @@ -45,6 +48,7 @@ import org.eclipse.jface.window.Window; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.console.IConsole; /** @@ -631,9 +635,39 @@ public class DebugUITools { * @param mode * @return the launch group the given launch configuration belongs to, for * the specified mode, or <code>null</code> if none + * @since 3.0 */ public static ILaunchGroup getLaunchGroup(ILaunchConfiguration configuration, String mode) { return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(configuration, mode); } + /** + * Performs source lookup on the given artifact and returns the result. + * Optionally, a source locator may be specified. + * + * @param artifact object for which source is to be resolved + * @param locator the source locator to use, or <code>null</code>. When <code>null</code> + * a source locator is determined from the artifact, if possible. If the artifact + * is a debug element, the source locator from its associated launch is used. + * @return a source lookup result + * @since 3.1 + */ + public static ISourceLookupResult lookupSource(Object artifact, ISourceLocator locator) { + return SourceLookupFacility.getDefault().lookup(artifact, locator); + } + + /** + * Displays the given source lookup result in an editor in the given workbench + * page. Has no effect if the result has an unknown editor id or editor input. + * The editor is opened, positioned, and annotated. + * <p> + * Honors user preference for editors re-use. + * </p> + * @param result source lookup result to display + * @param page the page to display the result in + * @since 3.1 + */ + public static void displaySource(ISourceLookupResult result, IWorkbenchPage page) { + SourceLookupFacility.getDefault().display(result, page); + } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/sourcelookup/ISourceLookupResult.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/sourcelookup/ISourceLookupResult.java new file mode 100644 index 000000000..f96bb3e29 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/sourcelookup/ISourceLookupResult.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.ui.sourcelookup; + +import org.eclipse.ui.IEditorInput; + +/** + * The result of performing source lookup on a debug artifact. + * The result contains the resolved source element and description + * of an editor (editor id, and editor input) in which to display + * the result. + * + * @see org.eclipse.debug.ui.DebugUITools#lookupSource(Object, ISourceLocator) + * @see org.eclipse.debug.ui.DebugUITools#displaySource(ISourceLookupResult, IWorkbenchPage) + * @since 3.1 + */ +public interface ISourceLookupResult { + + /** + * Returns the artifact for which source lookup was performed, + * such as a stack frame. + * + * @return the artifact for which source lookup was performed + */ + public Object getArtifact(); + + /** + * Returns the source element resolved during source lookup, + * or <code>null</code> if a source element was not resolved. + * + * @return resolved source element or <code>null</code> if unknown + */ + public Object getSourceElement(); + + /** + * Returns the identifier of an editor used to display this result, + * or <code>null</code> if unknown. + * + * @return the identifier of an editor used to display this result, + * or <code>null</code> if unknown + */ + public String getEditorId(); + + /** + * Returns the editor input used to display result, + * or <code>null</code> if unknown. + * + * @return the editor input used to display result, + * or <code>null</code> if unknown + */ + public IEditorInput getEditorInput(); +} |