diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF index b0afcc0dfd3..9c3016797f3 100644 --- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.ui; singleton:=true -Bundle-Version: 8.5.500.qualifier +Bundle-Version: 8.5.600.qualifier Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 58e7bc1fc42..3e7f020eaa3 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -280,17 +280,6 @@ helpContextId="move_to_line_action_context" label="%GlobalMoveToLineAction.label" menubarPath="org.eclipse.ui.run/stepGroup"/> - - - - - - - - - - @@ -675,28 +643,6 @@ - - - - - - - - @@ -1379,9 +1325,85 @@ id="org.eclipse.debug.ui.actions.BreakpointTypesContribution" class="org.eclipse.debug.ui.actions.BreakpointTypesContribution"> - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1660,6 +1682,14 @@ id="org.eclipse.cdt.debug.ui.command.loadAllSymbols" name="%LoadSymbolsForAllAction.label"> + + + + @@ -1737,7 +1767,11 @@ - + + + @@ -2564,6 +2598,13 @@ properties="createBreakpointAdapt" type="org.eclipse.cdt.debug.ui.breakpoints.ICBreakpointContext"> + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CDTDebugPropertyTester.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CDTDebugPropertyTester.java new file mode 100644 index 00000000000..cd50b9fd146 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CDTDebugPropertyTester.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2024 Advantest Europe GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Raghunandana Murthappa + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +/** + * Tests whether an active C/C++ application is debugging. And selection inside Debug View is present on it. + * + * @author Raghunandana Murthappa + */ +public class CDTDebugPropertyTester extends PropertyTester { + + private static final String IS_CDT_DEBUGGING = "isCDTDebugging"; //$NON-NLS-1$ + + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + if (IS_CDT_DEBUGGING.equals(property)) { + return isCdtLaunchConfigDebugMode(); + } + return false; + } + + private boolean isCdtLaunchConfigDebugMode() { + ISteppingModeTarget gdbTarget = getSteppingModeTarget(); + return gdbTarget != null && gdbTarget.supportsInstructionStepping(); + } + + /** + * Debug View can contain many targets at given point of time. This will check if {@code ISteppingModeTarget} present and it is selected. If yes returns it. + * + * @return Instruction stepping mode target. + */ + public static ISteppingModeTarget getSteppingModeTarget() { + IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (workbenchWindow == null) { + return null; + } + + IWorkbenchPage workbenchPage = workbenchWindow.getActivePage(); + if (workbenchPage == null) { + return null; + } + + IViewPart debugView = workbenchPage.findView(IDebugUIConstants.ID_DEBUG_VIEW); + if (debugView == null) { + return null; + } + + IDebugView debugViewClazz = debugView.getAdapter(IDebugView.class); + ISelection selection = debugViewClazz.getViewer().getSelection(); + if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) { + return null; + } + + Object element = ((IStructuredSelection) selection).getFirstElement(); + + return getTargetFromSelection(element); + } + + public static ISteppingModeTarget getTargetFromSelection(Object element) { + ISteppingModeTarget target = null; + if (element instanceof IDebugElement) { + IDebugTarget debugTarget = ((IDebugElement) element).getDebugTarget(); + if (debugTarget instanceof ISteppingModeTarget) { + target = (ISteppingModeTarget) debugTarget; + } + } + if (target == null) { + if (element instanceof IAdaptable) { + target = ((IAdaptable) element).getAdapter(ISteppingModeTarget.class); + } + } + return target; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleInstructionStepModeActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleInstructionStepModeActionDelegate.java deleted file mode 100644 index 2598d93f247..00000000000 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleInstructionStepModeActionDelegate.java +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2015 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - Initial API and implementation - * Pawel Piech (WindRiver) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=228063 - *******************************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions; - -import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; -import org.eclipse.cdt.debug.core.model.ITargetProperties; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; -import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; -import org.eclipse.debug.core.model.IDebugElement; -import org.eclipse.debug.core.model.IDebugTarget; -import org.eclipse.debug.core.model.IDisconnect; -import org.eclipse.debug.core.model.ITerminate; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.contexts.DebugContextEvent; -import org.eclipse.debug.ui.contexts.IDebugContextListener; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.actions.ActionDelegate; - -/** - * Turns instruction step mode on/off for selected target. - */ -public class ToggleInstructionStepModeActionDelegate extends ActionDelegate - implements IViewActionDelegate, IWorkbenchWindowActionDelegate, IPropertyChangeListener, IDebugContextListener { - - private ISteppingModeTarget fTarget = null; - - private IAction fAction = null; - - private IWorkbenchWindow fWindow = null; - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent) - */ - @Override - public void propertyChange(PropertyChangeEvent event) { - IAction action = getAction(); - if (action != null) { - if (event.getNewValue() instanceof Boolean) { - boolean value = ((Boolean) event.getNewValue()).booleanValue(); - if (value != action.isChecked()) - action.setChecked(value); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) - */ - @Override - public void init(IViewPart view) { - fWindow = view.getSite().getWorkbenchWindow(); - DebugUITools.getDebugContextManager().getContextService(fWindow).addDebugContextListener(this); - } - - @Override - public void init(IWorkbenchWindow window) { - fWindow = window; - DebugUITools.getDebugContextManager().getContextService(fWindow).addDebugContextListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate2#dispose() - */ - @Override - public void dispose() { - DebugUITools.getDebugContextManager().getContextService(fWindow).removeDebugContextListener(this); - ISteppingModeTarget target = getTarget(); - if (target != null && target instanceof ITargetProperties) { - ((ITargetProperties) target).removePropertyChangeListener(this); - } - setTarget(null); - setAction(null); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction) - */ - @Override - public void init(IAction action) { - setAction(action); - action.setChecked(false); - action.setEnabled(false); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) - */ - @Override - public void run(IAction action) { - boolean enabled = getAction().isChecked(); - ISteppingModeTarget target = getTarget(); - if (target != null) { - target.enableInstructionStepping(enabled); - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event) - */ - @Override - public void runWithEvent(IAction action, Event event) { - run(action); - } - - @Override - public void debugContextChanged(DebugContextEvent event) { - if (fAction == null) - return; - - ISelection selection = event.getContext(); - ISteppingModeTarget newTarget = null; - if (selection instanceof IStructuredSelection) { - newTarget = getTargetFromSelection(((IStructuredSelection) selection).getFirstElement()); - } - ISteppingModeTarget oldTarget = getTarget(); - if (oldTarget != null && !oldTarget.equals(newTarget)) { - if (oldTarget instanceof ITargetProperties) { - ((ITargetProperties) oldTarget).removePropertyChangeListener(this); - } - setTarget(null); - fAction.setChecked(false); - } - if (newTarget != null && !isTerminated(newTarget)) { - setTarget(newTarget); - if (newTarget instanceof ITargetProperties) { - ((ITargetProperties) newTarget).addPropertyChangeListener(this); - } - fAction.setChecked(newTarget.isInstructionSteppingEnabled()); - } - fAction.setEnabled(newTarget != null && newTarget.supportsInstructionStepping() && !isTerminated(newTarget)); - } - - private boolean isTerminated(ISteppingModeTarget target) { - return ((target instanceof ITerminate && ((ITerminate) target).isTerminated()) - || (target instanceof IDisconnect && ((IDisconnect) target).isDisconnected())); - } - - private ISteppingModeTarget getTarget() { - return this.fTarget; - } - - private void setTarget(ISteppingModeTarget target) { - this.fTarget = target; - } - - private IAction getAction() { - return this.fAction; - } - - private void setAction(IAction action) { - this.fAction = action; - } - - private ISteppingModeTarget getTargetFromSelection(Object element) { - ISteppingModeTarget target = null; - if (element instanceof IDebugElement) { - IDebugTarget debugTarget = ((IDebugElement) element).getDebugTarget(); - if (debugTarget instanceof ISteppingModeTarget) { - target = (ISteppingModeTarget) debugTarget; - } - } - if (target == null) { - if (element instanceof IAdaptable) { - target = ((IAdaptable) element).getAdapter(ISteppingModeTarget.class); - } - } - return target; - } - -} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.java index c707c790739..9259c20c305 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.java @@ -18,6 +18,7 @@ public class Messages extends NLS { public static String ReverseDebugging_ToggleHardwareTrace; public static String ReverseDebugging_ToggleSoftwareTrace; public static String ReverseDebugging_ToggleReverseDebugging; + public static String ToogleCommand_State_Not_found; static { // initialize resource bundle diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.properties index 09820542446..225f8a8b1e6 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/Messages.properties @@ -14,3 +14,5 @@ ReverseDebugging_UndefinedTraceMethod=Undefined trace method for Reverse Debuggi ReverseDebugging_ToggleHardwareTrace=Toggle Hardware Trace ReverseDebugging_ToggleSoftwareTrace=Toggle Software Trace ReverseDebugging_ToggleReverseDebugging=Toggle Reverse Debugging +# {0} - command id. Example: ToggleInstructionStepMode commannd. +ToogleCommand_State_Not_found=Toggle state not found for command: {0} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ToggleInstructionStepModeHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ToggleInstructionStepModeHandler.java new file mode 100644 index 00000000000..157d2ac64f9 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ToggleInstructionStepModeHandler.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2024 Advantest Europe GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Raghunandana Murthappa + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.commands; + +import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; +import org.eclipse.cdt.debug.core.model.ITargetProperties; +import org.eclipse.cdt.debug.internal.ui.actions.CDTDebugPropertyTester; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; +import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; +import org.eclipse.debug.core.model.IDisconnect; +import org.eclipse.debug.core.model.ITerminate; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.RegistryToggleState; + +/** + * Handles the command org.eclipse.cdt.debug.internal.ui.actions.ToggleInstructionStepModeCommand + * Turns instruction step mode on/off for selected target. + * @author Raghunandana Murthappa + */ +public class ToggleInstructionStepModeHandler extends AbstractHandler + implements IPropertyChangeListener, IDebugContextListener { + + private static final String TISM_COMMAND_ID = "org.eclipse.cdt.debug.internal.ui.actions.ToggleInstructionStepModeCommand"; //$NON-NLS-1$ + + private Command fCommand = null; + + private ISteppingModeTarget fTarget = null; + + private IWorkbenchWindow fWorkbenchWindow = null; + + public ToggleInstructionStepModeHandler() { + fWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + DebugUITools.getDebugContextManager().getContextService(fWorkbenchWindow).addDebugContextListener(this); + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + if (fCommand != null && event.getNewValue() instanceof Boolean) { + boolean prefState = ((Boolean) event.getNewValue()).booleanValue(); + try { + State state = fCommand.getState(RegistryToggleState.STATE_ID); + boolean currentState = (Boolean) state.getValue(); + if (currentState != prefState) { + HandlerUtil.toggleCommandState(fCommand); + } + } catch (ExecutionException e) { + CDebugUIPlugin.log(e); + } + } + } + + @Override + public void setEnabled(Object evaluationContext) { + ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class); + if (commandService != null) { + fCommand = commandService.getCommand(TISM_COMMAND_ID); + + } + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + State state = fCommand.getState(RegistryToggleState.STATE_ID); + if (state == null) { + throw new ExecutionException(NLS.bind(Messages.ToogleCommand_State_Not_found, fCommand.getId())); + } + + boolean currentState = (Boolean) state.getValue(); + HandlerUtil.toggleCommandState(fCommand); + + ISteppingModeTarget target = getTarget(); + if (target != null) { + target.enableInstructionStepping(!currentState); + } + + return IStatus.OK; + } + + private boolean isTerminated(ISteppingModeTarget target) { + return ((target instanceof ITerminate && ((ITerminate) target).isTerminated()) + || (target instanceof IDisconnect && ((IDisconnect) target).isDisconnected())); + } + + @Override + public void dispose() { + if (fWorkbenchWindow != null) { + DebugUITools.getDebugContextManager().getContextService(fWorkbenchWindow).removeDebugContextListener(this); + } + ISteppingModeTarget target = getTarget(); + if (target != null && target instanceof ITargetProperties) { + ((ITargetProperties) target).removePropertyChangeListener(this); + } + setTarget(null); + super.dispose(); + } + + @Override + public void debugContextChanged(DebugContextEvent event) { + ISelection selection = event.getContext(); + ISteppingModeTarget newTarget = null; + if (selection instanceof IStructuredSelection) { + newTarget = CDTDebugPropertyTester + .getTargetFromSelection(((IStructuredSelection) selection).getFirstElement()); + } + + if (newTarget == null) { + return; + } + + ISteppingModeTarget oldTarget = getTarget(); + if (newTarget.equals(oldTarget)) { + return; + } + + if (oldTarget != null) { + if (oldTarget instanceof ITargetProperties) { + ((ITargetProperties) oldTarget).removePropertyChangeListener(this); + } + } + + setTarget(newTarget); + if (newTarget instanceof ITargetProperties) { + ((ITargetProperties) newTarget).addPropertyChangeListener(this); + } + + try { + boolean prefState = !isTerminated(newTarget) && newTarget.isInstructionSteppingEnabled(); + if (fCommand != null) { + State state = fCommand.getState(RegistryToggleState.STATE_ID); + boolean currentState = (Boolean) state.getValue(); + if (currentState != prefState) { + HandlerUtil.toggleCommandState(fCommand); + } + } + } catch (ExecutionException e) { + CDebugUIPlugin.log(e); + } + } + + private ISteppingModeTarget getTarget() { + return fTarget; + } + + private void setTarget(ISteppingModeTarget target) { + fTarget = target; + } +}