From 95df2620f02bb81e6cebfc81e73cef4ee84208b9 Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Fri, 30 Apr 2004 22:00:57 +0000 Subject: [PATCH] New implementation of the "Resume At Line" global action. --- debug/org.eclipse.cdt.debug.ui/ChangeLog | 7 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 80 ++--- .../ui/actions/ActionMessages.properties | 5 + .../actions/ResumeAtLineActionDelegate.java | 312 ++++++++++++++++++ .../ui/actions/ToggleBreakpointAdapter.java | 7 + 5 files changed, 371 insertions(+), 40 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ResumeAtLineActionDelegate.java diff --git a/debug/org.eclipse.cdt.debug.ui/ChangeLog b/debug/org.eclipse.cdt.debug.ui/ChangeLog index 660800d7eef..17d430a96fe 100644 --- a/debug/org.eclipse.cdt.debug.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.ui/ChangeLog @@ -1,3 +1,10 @@ +2004-04-30 Mikhail Khodjaiants + New implementation of the "Resume At Line" global action. + * plugin.xml + * ActionMessages.properties + * ResumeAtLineActionDelegate.java + * ToggleBreakpointAdapter.java + 2004-04-30 Mikhail Khodjaiants Added ruler breakpoint actions to the Disassembly view. * ICDebugHelpContextIds.java diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index f7dbc68698f..64c492bb211 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -87,8 +87,8 @@ + relationship="stack" + id="org.eclipse.cdt.debug.ui.MemoryView"> @@ -96,8 +96,8 @@ + relationship="stack" + id="org.eclipse.cdt.debug.ui.SharedLibrariesView"> @@ -105,8 +105,8 @@ + relationship="stack" + id="org.eclipse.cdt.debug.ui.SignalsView"> @@ -117,8 +117,8 @@ + relationship="stack" + id="org.eclipse.cdt.debug.ui.DisassemblyView"> @@ -173,7 +173,7 @@ @@ -706,8 +706,8 @@ label="%SignalAction.label" icon="icons/full/clcl16/signal_co.gif" helpContextId="signal_action_context" - tooltip="%SignalAction.tooltip" class="org.eclipse.cdt.debug.internal.ui.actions.SignalActionDelegate" + tooltip="%SignalAction.tooltip" menubarPath="additions" enablesFor="1" id="org.eclipse.cdt.debug.internal.ui.actions.SignalActionDelegate"> @@ -722,8 +722,8 @@ label="%SignalPropertiesAction.label" style="pulldown" helpContextId="signal_properties_action_context" - tooltip="%SignalPropertiesAction.tooltip" class="org.eclipse.cdt.debug.internal.ui.actions.SignalPropertiesActionDelegate" + tooltip="%SignalPropertiesAction.tooltip" enablesFor="1" id="org.eclipse.cdt.debug.ui.SignalPropertiesAction"> @@ -759,8 +759,8 @@ @@ -775,8 +775,8 @@ label="%CastToTypeAction.label" icon="icons/full/clcl16/casttotype_co.gif" helpContextId="cast_to_type_action_context" - class="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionDelegate" tooltip="%CastToTypeAction.tooltip" + class="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionDelegate" menubarPath="additions" enablesFor="1" id="org.eclipse.cdt.debug.internal.ui.actions.CastToTypeActionDelegate"> @@ -791,8 +791,8 @@ label="%CastToArrayAction.label" icon="icons/full/clcl16/showasarray_co.gif" helpContextId="cast_to_array_action_context" - class="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionDelegate" tooltip="%CastToArrayAction.tooltip" + class="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionDelegate" menubarPath="additions" enablesFor="1" id="org.eclipse.cdt.debug.internal.ui.actions.CastToArrayActionDelegate"> @@ -811,8 +811,8 @@ label="%ManageFunctionBreakpointAction.label" icon="icons/full/obj16/funbrkp_obj.gif" helpContextId="manage_function_breakpoint_action_context" - class="org.eclipse.cdt.debug.internal.ui.actions.ManageFunctionBreakpointActionDelegate" tooltip="%ManageFunctionBreakpointAction.tooltip" + class="org.eclipse.cdt.debug.internal.ui.actions.ManageFunctionBreakpointActionDelegate" menubarPath="additions" enablesFor="1" id="org.eclipse.cdt.debug.internal.ui.actions.ManageFunctionBreakpointActionDelegate"> @@ -831,8 +831,8 @@ label="%DisableVariablesAction.label" icon="icons/full/clcl16/disabled_co.gif" helpContextId="disable_variables_action_context" - class="org.eclipse.cdt.debug.internal.ui.actions.DisableVariablesActionDelegate" tooltip="%DisableVariablesAction.tooltip" + class="org.eclipse.cdt.debug.internal.ui.actions.DisableVariablesActionDelegate" menubarPath="variableGroup" enablesFor="2+" id="org.eclipse.cdt.debug.internal.ui.actions.DisableVariablesActionDelegate"> @@ -844,8 +844,8 @@ label="%EnableVariablesAction.label" icon="icons/full/clcl16/enabled_co.gif" helpContextId="enable_variables_action_context" - class="org.eclipse.cdt.debug.internal.ui.actions.EnableVariablesActionDelegate" tooltip="%EnableVariablesAction.tooltip" + class="org.eclipse.cdt.debug.internal.ui.actions.EnableVariablesActionDelegate" menubarPath="variableGroup" enablesFor="2+" id="org.eclipse.cdt.debug.internal.ui.actions.EnableVariablesActionDelegate"> @@ -868,8 +868,8 @@ disabledIcon="icons/full/dlcl16/restart.gif" enablesFor="1" icon="icons/full/elcl16/restart.gif" - label="%RestartAction.label" helpContextId="restart_action_context" + label="%RestartAction.label" tooltip="%RestartAction.tooltip"> @@ -927,11 +927,11 @@ id="org.eclipse.cdt.debug.ui.breakpointView.menu"> @@ -953,8 +953,8 @@ disabledIcon="icons/full/dlcl16/watch_globals.gif" enablesFor="1" icon="icons/full/elcl16/watch_globals.gif" - label="%AddGlobalsAction.label" helpContextId="add_globals_action_context" + label="%AddGlobalsAction.label" tooltip="%AddGlobalsAction.tooltip"> @@ -1064,20 +1064,20 @@ @@ -1134,16 +1134,16 @@ point="org.eclipse.ui.editors"> @@ -1165,8 +1165,8 @@ + parentId="org.eclipse.debug.ui.debugging" + id="org.eclipse.cdt.debug.ui.debugging"> @@ -1244,8 +1244,8 @@ highlightPreferenceValue="true" presentationLayer="6" icon="icons/full/obj16/inst_ptr.gif" - textPreferenceValue="false" label="%DisassemblySecondaryInstructionPointer" + textPreferenceValue="false" textPreferenceKey="secondaryDisassemblyIPIndication" verticalRulerPreferenceKey="secondaryDisassemblyIPVerticalRuler" overviewRulerPreferenceKey="secondaryDisassemblyIPOverviewRuler"> @@ -1274,8 +1274,8 @@ + class="org.eclipse.cdt.debug.internal.ui.actions.RetargettableActionAdapterFactory" + adaptableType="org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyView"> diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties index df41002f518..a035b85dd3d 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ActionMessages.properties @@ -31,3 +31,8 @@ ToggleBreakpointRulerAction.Toggle_Breakpoint_1=Toggle &Breakpoint ToggleBreakpointRulerAction.Error_1=Error ToggleBreakpointRulerAction.Operation_failed_1=Operation failed CBreakpointPropertiesRulerAction.Breakpoint_Properties=Breakpoint &Properties... +ResumeAtLineActionDelegate.Error_1=Error +ResumeAtLineActionDelegate.Operation_failed_1=Operation failed. +ResumeAtLineActionDelegate.Missing_document=Missing document +ResumeAtLineActionDelegate.Empty_editor_1=Empty editor +ResumeAtLineActionDelegate.Operation_is_not_supported_1=Operation is not supported diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ResumeAtLineActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ResumeAtLineActionDelegate.java new file mode 100644 index 00000000000..1700fa9eff7 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ResumeAtLineActionDelegate.java @@ -0,0 +1,312 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.model.IJumpToAddress; +import org.eclipse.cdt.debug.core.model.IJumpToLine; +import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyEditorInput; +import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyView; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.ICDebugUIConstants; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IPartService; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.IUpdate; + +/** + * Global retargettable "Resume at Line" action. + */ +public class ResumeAtLineActionDelegate implements IWorkbenchWindowActionDelegate, IPartListener, IUpdate { + + protected IWorkbenchWindow fWindow = null; + private IWorkbenchPart fActivePart = null; + private IAction fAction = null; + private IDebugElement fTargetElement = null; + + private static final ISelection EMPTY_SELECTION = new EmptySelection(); + + static class EmptySelection implements ISelection { + public boolean isEmpty() { + return true; + } + } + + private ISelectionListener fSelectionListener = new DebugSelectionListener(); + + class DebugSelectionListener implements ISelectionListener { + /* (non-Javadoc) + * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged( IWorkbenchPart part, ISelection selection ) { + setTargetElement( null ); + if ( selection instanceof IStructuredSelection ) { + IStructuredSelection ss = (IStructuredSelection)selection; + if ( ss.size() == 1 ) { + Object object = ss.getFirstElement(); + if ( object instanceof IDebugElement ) { + setTargetElement( (IDebugElement)object ); + } + } + } + update(); + } + } + + /** + * Returns the current selection in the active part, possibly + * and empty selection, but never null. + * + * @return the selection in the active part, possibly empty + */ + private ISelection getTargetSelection() { + if ( fActivePart != null ) { + ISelectionProvider selectionProvider = fActivePart.getSite().getSelectionProvider(); + if ( selectionProvider != null ) { + return selectionProvider.getSelection(); + } + } + return EMPTY_SELECTION; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() + */ + public void dispose() { + fWindow.getSelectionService().removeSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, fSelectionListener ); + fWindow.getPartService().removePartListener( this ); + fActivePart = null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) + */ + public void init( IWorkbenchWindow window ) { + this.fWindow = window; + IPartService partService = window.getPartService(); + partService.addPartListener( this ); + fWindow.getSelectionService().addSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, fSelectionListener ); + IWorkbenchPart part = partService.getActivePart(); + if ( part != null ) { + partActivated( part ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart) + */ + public void partActivated( IWorkbenchPart part ) { + fActivePart = part; + update(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart) + */ + public void partBroughtToTop( IWorkbenchPart part ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart) + */ + public void partClosed( IWorkbenchPart part ) { + clearPart(part); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart) + */ + public void partDeactivated( IWorkbenchPart part ) { + clearPart(part); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart) + */ + public void partOpened( IWorkbenchPart part ) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + if ( fAction == null ) { + return; + } + fAction.setEnabled( canPerformAction( getTargetSelection() ) ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run( IAction action ) { + if ( fTargetElement != null ) { + try { + performAction( getTargetSelection() ); + } catch( CoreException e ) { + DebugUIPlugin.errorDialog( fWindow.getShell(), ActionMessages.getString( "ResumeAtLineActionDelegate.Error_1" ), ActionMessages.getString( "ResumeAtLineActionDelegate.Operation_failed_1" ), e.getStatus() ); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged( IAction action, ISelection selection ) { + this.fAction = action; + update(); + } + + /** + * Clears reference to active part and adapter when a relevant part + * is closed or deactivated. + * + * @param part workbench part that has been closed or deactivated + */ + protected void clearPart( IWorkbenchPart part ) { + if ( part.equals( fActivePart ) ) { + fActivePart = null; + } + } + + protected IDebugElement getTargetElement() { + return this.fTargetElement; + } + + protected void setTargetElement( IDebugElement targetElement ) { + this.fTargetElement = targetElement; + } + + private boolean canPerformAction( ISelection selection ) { + if ( fTargetElement == null || + !fTargetElement.getModelIdentifier().equals( CDIDebugModel.getPluginIdentifier() ) ) + return false; + IDebugTarget debugTarget = fTargetElement.getDebugTarget(); + if ( fActivePart instanceof IEditorPart ) { + IJumpToLine jumpToLine = (IJumpToLine)debugTarget.getAdapter( IJumpToLine.class ); + if ( jumpToLine == null ) + return false; + IEditorPart editorPart = (IEditorPart)fActivePart; + IEditorInput input = editorPart.getEditorInput(); + if ( input == null ) { + return false; + } + ITextEditor textEditor = (ITextEditor)editorPart; + IDocument document = textEditor.getDocumentProvider().getDocument( input ); + if ( document == null ) { + return false; + } + String fileName; + try { + fileName = getFileName( input ); + } + catch( CoreException e ) { + return false; + } + ITextSelection textSelection = (ITextSelection)selection; + int lineNumber = textSelection.getStartLine() + 1; + return jumpToLine.canJumpToLine( fileName, lineNumber ); + } + if ( fActivePart instanceof DisassemblyView ) { + IJumpToAddress jumpToAddress = (IJumpToAddress)debugTarget.getAdapter( IJumpToAddress.class ); + if ( jumpToAddress == null ) + return false; + IEditorInput input = ((DisassemblyView)fActivePart).getInput(); + if ( !(input instanceof DisassemblyEditorInput) ) { + return false; + } + ITextSelection textSelection = (ITextSelection)selection; + int lineNumber = textSelection.getStartLine() + 1; + long address = ((DisassemblyEditorInput)input).getAddress( lineNumber ); + return jumpToAddress.canJumpToAddress( address ); + } + return false; + } + + private void performAction( ISelection selection ) throws CoreException { + IDebugTarget debugTarget = fTargetElement.getDebugTarget(); + String errorMessage = null; + if ( fActivePart instanceof IEditorPart ) { + IEditorPart editorPart = (IEditorPart)fActivePart; + IEditorInput input = editorPart.getEditorInput(); + if ( input == null ) { + errorMessage = ActionMessages.getString( "ResumeAtLineActionDelegate.Empty_editor_1" ); //$NON-NLS-1$ + } + else { + ITextEditor textEditor = (ITextEditor)editorPart; + IDocument document = textEditor.getDocumentProvider().getDocument( input ); + if ( document == null ) { + errorMessage = ActionMessages.getString( "ResumeAtLineActionDelegate.Missing_document" ); //$NON-NLS-1$ + } + else { + String fileName = getFileName( input ); + ITextSelection textSelection = (ITextSelection)selection; + int lineNumber = textSelection.getStartLine() + 1; + IJumpToLine jumpToLine = (IJumpToLine)((IAdaptable)debugTarget).getAdapter( IJumpToLine.class ); + if ( jumpToLine != null ) + jumpToLine.jumpToLine( fileName, lineNumber ); + return; + } + } + } + else if ( fActivePart instanceof DisassemblyView ) { + IEditorInput input = ((DisassemblyView)fActivePart).getInput(); + if ( !(input instanceof DisassemblyEditorInput) ) { + errorMessage = ActionMessages.getString( "ResumeAtLineActionDelegate.Empty_editor_1" ); //$NON-NLS-1$ + } + else { + ITextSelection textSelection = (ITextSelection)selection; + int lineNumber = textSelection.getStartLine() + 1; + long address = ((DisassemblyEditorInput)input).getAddress( lineNumber ); + IJumpToAddress jumpToAddress = (IJumpToAddress)((IAdaptable)debugTarget).getAdapter( IJumpToAddress.class ); + if ( jumpToAddress != null ) + jumpToAddress.jumpToAddress( address ); + return; + } + } + else { + errorMessage = ActionMessages.getString( "ResumeAtLineActionDelegate.Operation_is_not_supported_1" ); //$NON-NLS-1$ + } + throw new CoreException( new Status( IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), ICDebugUIConstants.INTERNAL_ERROR, errorMessage, null ) ); + } + + private String getFileName( IEditorInput input ) throws CoreException { + if ( input instanceof IFileEditorInput ) { + return ((IFileEditorInput)input).getFile().getName(); + } + if ( input instanceof IStorageEditorInput ) { + return ((IStorageEditorInput)input).getStorage().getName(); + } + return null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java index 14439d3295b..4bb8e7561fd 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java @@ -136,6 +136,13 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget { * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ public boolean canToggleLineBreakpoints( IWorkbenchPart part, ISelection selection ) { + if ( part instanceof DisassemblyView ) { + IEditorInput input = ((DisassemblyView)part).getInput(); + if ( !(input instanceof DisassemblyEditorInput) || + ((DisassemblyEditorInput)input).equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ) { + return false; + } + } return ( selection instanceof ITextSelection ); }