blob: 87e72850d9a494f97949bd60acea50a7d91a9967 [file] [log] [blame]
package org.eclipse.debug.internal.ui.views.launch;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.views.AbstractDebugEventHandlerView;
import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ISourcePresentation;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.SubContributionItem;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ApplicationWindow;
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.IPageListener;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.texteditor.ITextEditor;
public class LaunchView extends AbstractDebugEventHandlerView implements ISelectionChangedListener, IPerspectiveListener, IPageListener, IPropertyChangeListener {
/**
* A marker for the source selection and icon for an
* instruction pointer. This marker is transient.
*/
private IMarker fInstructionPointer;
private boolean fShowingMarker = false;
// marker attributes
private final static String[] fgStartEnd =
new String[] {IMarker.CHAR_START, IMarker.CHAR_END};
private final static String[] fgLineStartEnd =
new String[] {IMarker.LINE_NUMBER, IMarker.CHAR_START, IMarker.CHAR_END};
/**
* Cache of the stack frame that source was displayed
* for.
*/
private IStackFrame fStackFrame = null;
/**
* Cache of the editor input used to display source
*/
private IEditorInput fEditorInput = null;
/**
* Cache of the editor id used to display source
*/
private String fEditorId = null;
/**
* Whether this view is in the active page of a perspective.
*/
private boolean fIsActive = true;
/**
* Editor to reuse
*/
private IEditorPart fEditor = 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);
/**
* Creates a launch view and an instruction pointer marker for the view
*/
public LaunchView() {
try {
fInstructionPointer = ResourcesPlugin.getWorkspace().getRoot().createMarker(IInternalDebugUIConstants.INSTRUCTION_POINTER);
DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
} catch (CoreException e) {
DebugUIPlugin.log(e);
}
}
/**
* @see AbstractDebugView#getHelpContextId()
*/
protected String getHelpContextId() {
return IDebugHelpContextIds.DEBUG_VIEW;
}
/**
* @see AbstractDebugView#createActions()
*/
protected void createActions() {
setAction("Properties", new PropertyDialogAction(getSite().getWorkbenchWindow().getShell(), getSite().getSelectionProvider())); //$NON-NLS-1$
// submit an async exec to update the selection once the
// view has been created - i.e. auto-expand and select the
// suspended thread on creation. (Done here, because the
// viewer needs to be set).
Runnable r = new Runnable() {
public void run() {
initializeSelection();
}
};
asyncExec(r);
}
/**
* @see AbstractDebugView#createViewer(Composite)
*/
protected Viewer createViewer(Composite parent) {
LaunchViewer lv = new LaunchViewer(parent);
lv.addSelectionChangedListener(this);
lv.setContentProvider(createContentProvider());
lv.setLabelProvider(new DelegatingModelPresentation());
lv.setUseHashlookup(true);
// add my viewer as a selection provider, so selective re-launch works
getSite().setSelectionProvider(lv);
lv.setInput(DebugPlugin.getDefault().getLaunchManager());
setEventHandler(new LaunchViewEventHandler(this));
// determine if active
setActive(getSite().getPage().findView(getSite().getId()) != null);
return lv;
}
/**
* Select the first stack frame in a suspended thread,
* if any.
*/
protected void initializeSelection() {
if (!isAvailable()) {
return;
}
TreeViewer tv = (TreeViewer)getViewer();
tv.expandToLevel(2);
Object[] elements = tv.getExpandedElements();
for (int i = 0; i < elements.length; i++) {
if (elements[i] instanceof ILaunch) {
IStackFrame frame = findFrame((ILaunch)elements[i]);
if (frame != null) {
autoExpand(frame, false, true);
}
}
}
}
/**
* Returns the first stack frame in the first suspended
* thread of the given launch, or <code>null</code> if
* none.
*
* @param launch a launch in this view
* @return stack frame or <code>null</code>
*/
protected IStackFrame findFrame(ILaunch launch) {
IDebugTarget target = launch.getDebugTarget();
if (target != null) {
try {
IThread[] threads = target.getThreads();
for (int i = 0; i < threads.length; i++) {
if (threads[i].isSuspended()) {
return threads[i].getTopStackFrame();
}
}
} catch (DebugException e) {
DebugUIPlugin.log(e);
}
}
return null;
}
/**
* @see IViewPart#init(IViewSite)
*/
public void init(IViewSite site) throws PartInitException {
super.init(site);
site.getPage().addPartListener(this);
site.getWorkbenchWindow().addPageListener(this);
site.getWorkbenchWindow().addPerspectiveListener(this);
}
/**
* @see IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
*/
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
site.getPage().addPartListener(this);
site.getWorkbenchWindow().addPageListener(this);
site.getWorkbenchWindow().addPerspectiveListener(this);
if (fReuseEditor && memento != null) {
String index = memento.getString(IDebugUIConstants.PREF_REUSE_EDITOR);
if (index != null) {
try {
fEditorIndex = Integer.parseInt(index);
} catch (NumberFormatException e) {
DebugUIPlugin.log(e);
}
}
}
}
/**
* @see AbstractDebugView#configureToolBar(IToolBarManager)
*/
protected void configureToolBar(IToolBarManager tbm) {
tbm.add(new Separator(IDebugUIConstants.THREAD_GROUP));
tbm.add(new Separator(IDebugUIConstants.STEP_GROUP));
tbm.add(new GroupMarker(IDebugUIConstants.STEP_INTO_GROUP));
tbm.add(new GroupMarker(IDebugUIConstants.STEP_OVER_GROUP));
tbm.add(new GroupMarker(IDebugUIConstants.STEP_RETURN_GROUP));
tbm.add(new GroupMarker(IDebugUIConstants.EMPTY_STEP_GROUP));
tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP));
}
/**
* @see IWorkbenchPart#dispose()
*/
public void dispose() {
if (getViewer() != null) {
getViewer().removeSelectionChangedListener(this);
}
getSite().getPage().removePartListener(this);
getSite().getWorkbenchWindow().removePerspectiveListener(this);
getSite().getWorkbenchWindow().removePageListener(this);
setEditorId(null);
setEditorInput(null);
setStackFrame(null);
DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
super.dispose();
}
/**
* Creates and returns the content provider to use for
* the viewer of this view.
*/
protected IStructuredContentProvider createContentProvider() {
return new LaunchViewContentProvider();
}
/**
* The selection has changed in the viewer. Show the
* associated source code if it is a stack frame.
*
* @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
*/
public void selectionChanged(SelectionChangedEvent event) {
updateObjects();
showMarkerForCurrentSelection();
}
/**
* @see IDoubleClickListener#doubleClick(DoubleClickEvent)
*/
public void doubleClick(DoubleClickEvent event) {
ISelection selection= event.getSelection();
if (!(selection instanceof IStructuredSelection)) {
return;
}
IStructuredSelection ss= (IStructuredSelection)selection;
Object o= ss.getFirstElement();
if (o instanceof IStackFrame) {
return;
}
TreeViewer tViewer= (TreeViewer)getViewer();
boolean expanded= tViewer.getExpandedState(o);
tViewer.setExpandedState(o, !expanded);
}
/**
* @see IPerspectiveListener#perspectiveActivated(IWorkbenchPage, IPerspectiveDescriptor)
*/
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
setActive(page.findView(getSite().getId()) != null);
updateObjects();
showMarkerForCurrentSelection();
if (isActive()) {
asyncExec(new Runnable() {
public void run() {
updateDebugActionSetAccelerators();
}
});
}
}
/**
* @see IPerspectiveListener#perspectiveChanged(IWorkbenchPage, IPerspectiveDescriptor, String)
*/
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
setActive(page.findView(getSite().getId()) != null);
}
/**
* @see IPageListener#pageActivated(IWorkbenchPage)
*/
public void pageActivated(IWorkbenchPage page) {
if (getSite().getPage().equals(page)) {
setActive(true);
updateObjects();
showMarkerForCurrentSelection();
}
}
/**
* @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
*/
public void partClosed(IWorkbenchPart part) {
if (part.equals(fEditor)) {
fEditor = null;
}
}
/**
* Workaround for bug 9082
*/
protected void updateDebugActionSetAccelerators() {
IWorkbenchWindow window= DebugUIPlugin.getActiveWorkbenchWindow();
if (window instanceof ApplicationWindow) {
ApplicationWindow appWindow= (ApplicationWindow)window;
IMenuManager manager= appWindow.getMenuBarManager();
IContributionItem actionSetItem= manager.findUsingPath("org.eclipse.ui.run"); //$NON-NLS-1$
if (actionSetItem instanceof SubContributionItem) {
IContributionItem item= ((SubContributionItem)actionSetItem).getInnerItem();
if (item instanceof IMenuManager) {
//force the accelerators to be updated
((IMenuManager)item).update(true);
}
}
}
}
/**
* @see IPageListener#pageClosed(IWorkbenchPage)
*/
public void pageClosed(IWorkbenchPage page) {
}
/**
* @see IPageListener#pageOpened(IWorkbenchPage)
*/
public void pageOpened(IWorkbenchPage page) {
}
/**
* Returns the configured instruction pointer.
* Selection is based on the line number OR char start and char end.
*/
protected IMarker getInstructionPointer(final int lineNumber, final int charStart, final int charEnd) {
IWorkspace workspace= ResourcesPlugin.getWorkspace();
IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
if (lineNumber == -1) {
fInstructionPointer.setAttributes(fgStartEnd,
new Object[] {new Integer(charStart), new Integer(charEnd)});
} else {
fInstructionPointer.setAttributes(fgLineStartEnd,
new Object[] {new Integer(lineNumber), new Integer(charStart), new Integer(charEnd)});
}
}
};
try {
workspace.run(runnable, null);
} catch (CoreException ce) {
DebugUIPlugin.log(ce);
}
return fInstructionPointer;
}
/**
* Opens a marker for the current selection if it is a stack frame.
* If the current selection is a thread, deselection occurs.
* Otherwise, nothing will happen.
*/
protected void showMarkerForCurrentSelection() {
// ensure this view is visible in the active page
if (!isActive()) {
return;
}
if (!fShowingMarker) {
try {
fShowingMarker = true;
ISelection selection= getViewer().getSelection();
Object obj= null;
if (selection instanceof IStructuredSelection) {
obj= ((IStructuredSelection) selection).getFirstElement();
}
if (!(obj instanceof IStackFrame)) {
return;
}
IStackFrame stackFrame= (IStackFrame) obj;
if (!stackFrame.equals(getStackFrame())) {
setStackFrame(stackFrame);
lookupEditorInput();
}
if (getEditorInput() != null && getEditorId() != null) {
int lineNumber= 0;
int start = -1;
int end = -1;
try {
lineNumber= stackFrame.getLineNumber();
start= stackFrame.getCharStart();
end= stackFrame.getCharEnd();
} catch (DebugException de) {
DebugUIPlugin.log(de);
}
openEditorAndSetMarker(getEditorInput(), getEditorId(), lineNumber, start, end);
}
} finally {
fShowingMarker= false;
}
}
}
/**
* Translate to an editor input using the source presentation
* provided by the source locator, or the default debug model
* presentation.
*/
private void lookupEditorInput() {
setEditorId(null);
setEditorInput(null);
Object sourceElement= null;
IStackFrame stackFrame= getStackFrame();
ILaunch launch = stackFrame.getLaunch();
if (launch == null) {
return;
}
ISourceLocator locator= launch.getSourceLocator();
if (locator == null) {
return;
}
sourceElement = locator.getSourceElement(stackFrame);
if (sourceElement == null) {
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);
}
/**
* Get the active window and open/bring to the front an editor on the source element.
* Selection is based on the line number OR the char start and end.
*/
protected void openEditorAndSetMarker(IEditorInput input, String editorId, int lineNumber, int charStart, int charEnd) {
IWorkbenchWindow dwindow= getSite().getWorkbenchWindow();
if (dwindow == null) {
return;
}
IWorkbenchPage page= dwindow.getActivePage();
if (page == null) {
return;
}
if (fEditorIndex >= 0) {
// first restoration of editor re-use
IEditorReference[] refs = page.getEditorReferences();
if (fEditorIndex < refs.length) {
fEditor = refs[fEditorIndex].getEditor(false);
}
fEditorIndex = -1;
}
// if there is an editor in the debug page with the newInput
// page bringToTop(editorAlreadyOpened)
// else if editorToBeReused is null or
// if editorToBeReused is pinned or
// if editorToBeReused is dirty or
// if keep editors opened (debug preference)
// editorToBeReused = page openEditor
// else if editorToBeReused is instance of IReusableEditor
// editorToBeReused.setInput(newInput)
// else
// page close editorToBeReused
// editorToBeReused = page openEditor
IEditorPart editor = null;
if (fReuseEditor) {
editor = page.getActiveEditor();
if (editor != null) {
if (!editor.getEditorInput().equals(input)) {
editor = null;
}
}
if (editor == null) {
IEditorReference[] refs = page.getEditorReferences();
for (int i = 0; i < refs.length; i++) {
IEditorPart refEditor= refs[i].getEditor(false);
if (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, editorId, false);
fEditor = editor;
} else if (fEditor instanceof IReusableEditor && editorId.equals(fEditor.getSite().getId())) {
((IReusableEditor)fEditor).setInput(input);
editor = fEditor;
} else {
page.closeEditor(fEditor, false);
editor = openEditor(page, input, editorId, false);
fEditor = editor;
}
}
} else {
editor = openEditor(page, input, editorId, false);
}
if (editor != null && (lineNumber >= 0 || charStart >= 0)) {
//have an editor and either a lineNumber or a starting character
IMarker marker= getInstructionPointer(lineNumber, charStart, charEnd);
editor.gotoMarker(marker);
}
}
protected IEditorPart openEditor(IWorkbenchPage page, IEditorInput input, String id, boolean activate) {
try {
return page.openEditor(input, id, false);
} catch (PartInitException e) {
DebugUIPlugin.errorDialog(DebugUIPlugin.getDefault().getShell(),
DebugUIViewsMessages.getString("LaunchView.Error_1"), //$NON-NLS-1$
DebugUIViewsMessages.getString("LaunchView.Exception_occurred_opening_editor_for_debugger._2"), //$NON-NLS-1$
e);
}
return null;
}
/**
* Deselects any source in the active editor that was 'programmatically' selected by
* the debugger.
*/
public void clearSourceSelection() {
// Get the active editor
IEditorPart editor= getSite().getPage().getActiveEditor();
if (!(editor instanceof ITextEditor)) {
return;
}
ITextEditor textEditor= (ITextEditor)editor;
// Get the current text selection in the editor. If there is none,
// then there's nothing to do
ITextSelection textSelection= (ITextSelection)textEditor.getSelectionProvider().getSelection();
if (textSelection.isEmpty()) {
return;
}
int startChar= textSelection.getOffset();
int endChar= startChar + textSelection.getLength() - 1;
int startLine= textSelection.getStartLine();
// Check to see if the current selection looks the same as the last 'programmatic'
// selection in fInstructionPointer. If not, it must be a user selection, which
// we leave alone. In practice, we can leave alone any user selections on other lines,
// but if the user makes a selection on the same line as the last programmatic selection,
// it will get cleared.
int lastCharStart= fInstructionPointer.getAttribute(IMarker.CHAR_START, -1);
if (lastCharStart == -1) {
// subtract 1 since editor is 0-based
if (fInstructionPointer.getAttribute(IMarker.LINE_NUMBER, -1) - 1 != startLine) {
return;
}
} else {
int lastCharEnd= fInstructionPointer.getAttribute(IMarker.CHAR_END, -1);
if ((lastCharStart != startChar) || (lastCharEnd != endChar)) {
return;
}
}
ITextSelection nullSelection= getNullSelection(startLine, startChar);
textEditor.getSelectionProvider().setSelection(nullSelection);
}
/**
* Creates and returns an ITextSelection that is a zero-length selection located at the
* start line and start char.
*/
protected ITextSelection getNullSelection(final int startLine, final int startChar) {
return new ITextSelection() {
public int getStartLine() {
return startLine;
}
public int getEndLine() {
return startLine;
}
public int getOffset() {
return startChar;
}
public String getText() {
return ""; //$NON-NLS-1$
}
public int getLength() {
return 0;
}
public boolean isEmpty() {
return true;
}
};
}
/**
* @see AbstractDebugView#fillContextMenu(IMenuManager)
*/
protected void fillContextMenu(IMenuManager menu) {
menu.add(new Separator(IDebugUIConstants.EMPTY_EDIT_GROUP));
menu.add(new Separator(IDebugUIConstants.EDIT_GROUP));
menu.add(new Separator(IDebugUIConstants.EMPTY_STEP_GROUP));
menu.add(new Separator(IDebugUIConstants.STEP_GROUP));
menu.add(new GroupMarker(IDebugUIConstants.STEP_INTO_GROUP));
menu.add(new GroupMarker(IDebugUIConstants.STEP_OVER_GROUP));
menu.add(new GroupMarker(IDebugUIConstants.STEP_RETURN_GROUP));
menu.add(new Separator(IDebugUIConstants.EMPTY_THREAD_GROUP));
menu.add(new Separator(IDebugUIConstants.THREAD_GROUP));
menu.add(new Separator(IDebugUIConstants.EMPTY_LAUNCH_GROUP));
menu.add(new Separator(IDebugUIConstants.LAUNCH_GROUP));
menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP));
menu.add(new Separator(IDebugUIConstants.RENDER_GROUP));
menu.add(new Separator(IDebugUIConstants.PROPERTY_GROUP));
PropertyDialogAction action = (PropertyDialogAction)getAction("Properties"); //$NON-NLS-1$
action.setEnabled(action.isApplicableForSelection());
menu.add(action);
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
/**
* Auto-expand and select the given element - must be called in UI thread.
* This is used to implement auto-expansion-and-select on a SUSPEND event.
*/
public void autoExpand(Object element, boolean refreshNeeded, boolean selectNeeded) {
Object selectee = element;
Object[] children= null;
if (element instanceof IThread) {
if (!refreshNeeded) {
refreshNeeded= threadRefreshNeeded((IThread)element);
}
// try the top stack frame
try {
selectee = ((IThread)element).getTopStackFrame();
} catch (DebugException de) {
}
if (selectee == null) {
selectee = element;
}
} else if (element instanceof ILaunch) {
IDebugTarget dt = ((ILaunch)element).getDebugTarget();
if (dt != null) {
selectee= dt;
try {
children= dt.getThreads();
} catch (DebugException de) {
DebugUIPlugin.log(de);
}
}
}
if (refreshNeeded) {
//ensures that the child item exists in the viewer widget
//set selection only works if the child exists
getStructuredViewer().refresh(element);
}
if (selectNeeded) {
getViewer().setSelection(new StructuredSelection(selectee), true);
}
if (children != null && children.length > 0) {
//reveal the thread children of a debug target
getStructuredViewer().reveal(children[0]);
}
}
/**
* Returns whether the given thread needs to
* be refreshed in the tree.
*
* The tree needs to be refreshed if the
* underlying model objects (IStackFrame) under the given thread
* differ from those currently displayed in the tree.
*/
protected boolean threadRefreshNeeded(IThread thread) {
LaunchViewer viewer= (LaunchViewer)getStructuredViewer();
ILaunch launch= thread.getLaunch();
TreeItem[] launches= viewer.getTree().getItems();
for (int i = 0; i < launches.length; i++) {
if (launches[i].getData() == launch) {
IDebugTarget target= thread.getDebugTarget();
TreeItem[] targets= launches[i].getItems();
for (int j = 0; j < targets.length; j++) {
if (targets[j].getData() == target) {
TreeItem[] threads= targets[j].getItems();
for (int k = 0; k < threads.length; k++) {
if (threads[k].getData() == thread) {
IStackFrame[] frames= null;
try {
frames = thread.getStackFrames();
} catch (DebugException exception) {
return true;
}
TreeItem[] treeFrames= threads[k].getItems();
for (int l= 0, numFrames= treeFrames.length; l < numFrames; l++) {
if (treeFrames[l].getData() != frames[l]) {
return true;
}
}
break;
}
}
break;
}
}
break;
}
}
return false;
}
/**
* Returns the last stack frame that source was retrieved
* for. Used to avoid source lookups for the same stack
* frame when stepping.
*
* @return stack frame, or <code>null</code>
*/
protected IStackFrame getStackFrame() {
return fStackFrame;
}
/**
* Sets the last stack frame that source was retrieved
* for. Used to avoid source lookups for the same stack
* frame when stepping. Setting the stack frame to <code>null</code>
* effectively forces a source lookup.
*
* @param frame The stack frame or <code>null</code>
*/
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 whether this view is in the active page of a
* perspective. Since a page can have more than one
* perspective, this view only show's source when in
* the active perspective/page.
*
* @param active whether this view is in the active page of a
* perspective
*/
protected void setActive(boolean active) {
fIsActive = active;
}
/**
* Returns whether this view is in the active page of
* the active perspective and has been fully created.
*
* @return whether this view is in the active page of
* the active perspective and has been fully created.
*/
protected boolean isActive() {
return fIsActive && getViewer() != null;
}
/**
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty() == IDebugUIConstants.PREF_REUSE_EDITOR) {
fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);
}
}
/**
* @see IViewPart#saveState(IMemento)
*/
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));
}
}
}
}