From 9689b69ba1847876fcb90869739d604cbd284e47 Mon Sep 17 00:00:00 2001 From: raghucssit Date: Tue, 21 Jan 2025 15:27:11 +0100 Subject: [PATCH] Restrict Pin View and Open View to active CPP debug context. That is if any CPP application is under debug. Because Pin View is never enabled other than CPP application debug session. This also includes Action to Command migration. Fixes https://github.com/eclipse-cdt/cdt/issues/1048 --- debug/org.eclipse.cdt.debug.ui/plugin.xml | 182 ++++++++----- .../ui/actions/OpenNewViewActionDelegate.java | 41 --- .../ui/actions/OpenNewViewHandler.java | 41 +++ ...ctionDelegate.java => PinViewHandler.java} | 251 +++++++----------- dsf/org.eclipse.cdt.dsf.ui/plugin.xml | 55 ++-- .../layout/PinCommandEnablementTester.java | 58 ++++ .../plugin.xml | 54 ++-- 7 files changed, 372 insertions(+), 310 deletions(-) delete mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewActionDelegate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewHandler.java rename debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/{PinDebugContextActionDelegate.java => PinViewHandler.java} (55%) create mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/PinCommandEnablementTester.java diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index ab3d5286c13..5b6a2fa3287 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -718,76 +718,6 @@ helpContextId="add_line_breakpoint_action_context" tooltip="%AddLineBreakpoint.tooltip"/> - - - - - - - - - - - - - - - - - - - - - - - - @@ -1402,6 +1332,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1771,6 +1805,14 @@ class="org.eclipse.cdt.debug.internal.ui.commands.ToggleInstructionStepModeHandler" commandId="org.eclipse.cdt.debug.internal.ui.actions.ToggleInstructionStepModeCommand"> + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewActionDelegate.java deleted file mode 100644 index c1401f9ffe4..00000000000 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewActionDelegate.java +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************** - * Copyright (c) 2010, 2014 Texas Instruments 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: - * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) - * Marc Dumais (Ericsson) - Bug 437692 - *****************************************************************/ -package org.eclipse.cdt.debug.internal.ui.actions; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.IViewActionDelegate; -import org.eclipse.ui.IViewPart; - -/** - * Opens a new view of the same type. - */ -public class OpenNewViewActionDelegate implements IViewActionDelegate { - private OpenNewViewAction fOpenNewViewAction = new OpenNewViewAction(); - - @Override - public void run(IAction action) { - fOpenNewViewAction.run(); - } - - @Override - public void selectionChanged(IAction action, ISelection selection) { - } - - @Override - public void init(IViewPart view) { - fOpenNewViewAction.init(view); - } -} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewHandler.java new file mode 100644 index 00000000000..2828dd37d63 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewHandler.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Texas Instruments 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: + * Patrick Chuong (Texas Instruments) - Initial implementation of run() + * Marc Dumais (Ericsson) - Bug 437692 + * Raghunandana Murthappa(Advantest Europe GmbH) - Issue 1048 + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Handler that opens the new View of the view type selected. This is used by + * the OpenNewViewCommand which is contributed to debug related views. + */ +public class OpenNewViewHandler extends AbstractHandler { + private OpenNewViewAction fOpenNewViewAction = new OpenNewViewAction(); + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IViewPart viewPart = (IViewPart) HandlerUtil.getActivePart(event); + fOpenNewViewAction.init(viewPart); + fOpenNewViewAction.run(); + + return IStatus.OK; + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinDebugContextActionDelegate.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinViewHandler.java similarity index 55% rename from debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinDebugContextActionDelegate.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinViewHandler.java index 632cbe2c941..e2fad90b8f4 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinDebugContextActionDelegate.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinViewHandler.java @@ -1,4 +1,4 @@ -/***************************************************************** +/******************************************************************************* * Copyright (c) 2010, 2012 Texas Instruments and others * * This program and the accompanying materials @@ -9,9 +9,10 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) - * Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566) - *****************************************************************/ + * Patrick Chuong (Texas Instruments) - Initial implementation of run() + * Marc Dumais (Ericsson) - Bug 437692 + * Raghunandana Murthappa(Advantest Europe GmbH) - Issue 1048 + *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.actions; import java.util.HashSet; @@ -25,123 +26,41 @@ import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementColorDescriptor; import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle; import org.eclipse.cdt.ui.CDTSharedImages; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.contexts.DebugContextEvent; -import org.eclipse.debug.ui.contexts.IDebugContextListener; import org.eclipse.debug.ui.contexts.IDebugContextService; -import org.eclipse.jface.action.IAction; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IActionDelegate2; +import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.IPartListener2; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartConstants; import org.eclipse.ui.IWorkbenchPartReference; -import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.part.WorkbenchPart; /** - * Pin the selected debug context for the view. + * A Handler which handles the Pin View Command contributed to all the debug + * related views. */ -public class PinDebugContextActionDelegate implements IViewActionDelegate, IActionDelegate2, IDebugContextListener { - private IViewPart fPart; - private String fPinnedContextLabel = ""; //$NON-NLS-1$ +public class PinViewHandler extends AbstractHandler { + private DebugContextPinProvider fProvider; private String fLastKnownDescription = ""; //$NON-NLS-1$ - private IAction fAction; + private String fPinnedContextLabel = ""; //$NON-NLS-1$ private IPartListener2 fPartListener; - private DebugContextPinProvider fProvider; - - public PinDebugContextActionDelegate() { - } - - /* (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); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) - */ - @Override - public void run(IAction action) { - if (action.isChecked()) { - fProvider = DebugEventFilterService.getInstance().addDebugEventFilter(fPart, getActiveDebugContext()); - if (fProvider != null) { - fLastKnownDescription = ((WorkbenchPart) fPart).getContentDescription(); - fPinnedContextLabel = getPinContextLabel(fProvider); - PinCloneUtils.setPartContentDescription(fPart, fPinnedContextLabel); - updatePinContextColor(fProvider); - } - } else { - fProvider = null; - DebugEventFilterService.getInstance().removeDebugEventFilter(fPart); - updatePinContextColor(fProvider); - PinCloneUtils.setPartContentDescription(fPart, fLastKnownDescription); - } - } + private static final Set pinned = new HashSet<>(); + private Image image; - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) - */ - @Override - public void selectionChanged(IAction action, ISelection selection) { - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction) - */ - @Override - public void init(IAction action) { - fAction = action; + public PinViewHandler() { + createPartListener(); } - /* (non-Javadoc) - * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) - */ - @Override - public void init(IViewPart view) { - fPart = view; - - if (fAction != null && !fAction.isChecked()) { - IDebugContextService service = DebugUITools.getDebugContextManager() - .getContextService(fPart.getViewSite().getWorkbenchWindow()); - boolean pinnable = PinCloneUtils.isPinnable(fPart, service.getActiveContext()); - fAction.setEnabled(pinnable); - } - - fPart.addPropertyListener(new IPropertyListener() { - @Override - public void propertyChanged(Object source, int propId) { - if (IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION == propId) { - // if the content description is not the pinned context label, - // then cache it so that we can set it back when the action is unchecked. - String desc = ((WorkbenchPart) fPart).getContentDescription(); - if (!fPinnedContextLabel.equals(desc)) { - fLastKnownDescription = desc; - } - - // if action is checked, than set it back to the pinned context label. - if (fAction != null && fAction.isChecked()) { - PinCloneUtils.setPartContentDescription(fPart, fPinnedContextLabel); - } - } else if (IWorkbenchPartConstants.PROP_PART_NAME == propId) { - PinCloneUtils.setPartTitle(fPart); - } - } - }); - - DebugUITools.addPartDebugContextListener(fPart.getSite(), this); - - // Platform AbstractDebugView saves action check state, - // in our case, we don't want this behavior. - // Listens to part close and set the check state off. + private void createPartListener() { fPartListener = new IPartListener2() { @Override public void partBroughtToTop(IWorkbenchPartReference partRef) { @@ -150,9 +69,10 @@ public void partBroughtToTop(IWorkbenchPartReference partRef) { @Override public void partClosed(IWorkbenchPartReference partRef) { IWorkbenchPart part = partRef.getPart(false); - if (part.equals(fPart)) { - unpinPart(); - } + if (pinned == null || !pinned.contains(part)) + return; + pinned.remove(part); + DebugEventFilterService.getInstance().removeDebugEventFilter(part); } @Override @@ -179,29 +99,49 @@ public void partInputChanged(IWorkbenchPartReference partRef) { public void partActivated(IWorkbenchPartReference partRef) { } }; - fPart.getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); } - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate2#dispose() - */ @Override - public void dispose() { - DebugUITools.removePartDebugContextListener(fPart.getSite(), this); - fPart.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); - unpinPart(); + public Object execute(ExecutionEvent event) throws ExecutionException { + Event trigger = (org.eclipse.swt.widgets.Event) event.getTrigger(); + ToolItem toolItem = (ToolItem) trigger.widget; + boolean selection = toolItem.getSelection(); + + IViewPart viewPart = (IViewPart) HandlerUtil.getActivePart(event); + if (selection) { + fProvider = DebugEventFilterService.getInstance().addDebugEventFilter(viewPart, + getActiveDebugContext(viewPart)); + if (fProvider != null) { + fLastKnownDescription = ((WorkbenchPart) viewPart).getContentDescription(); + fPinnedContextLabel = getPinContextLabel(fProvider); + PinCloneUtils.setPartContentDescription(viewPart, fPinnedContextLabel); + disposeImage(); + updatePinContextColor(fProvider, toolItem); + pinned.add(viewPart); + viewPart.getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); + } + } else { + fProvider = null; + DebugEventFilterService.getInstance().removeDebugEventFilter(viewPart); + disposeImage(); + updatePinContextColor(fProvider, toolItem); + PinCloneUtils.setPartContentDescription(viewPart, fLastKnownDescription); + pinned.remove(viewPart); + viewPart.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); + } + + return IStatus.OK; } - protected void unpinPart() { - if (fAction.isChecked()) { - DebugEventFilterService.getInstance().removeDebugEventFilter(fPart); - fAction.setChecked(false); + private void disposeImage() { + if (image != null) { + image.dispose(); } } - protected ISelection getActiveDebugContext() { + protected ISelection getActiveDebugContext(IViewPart viewPart) { IDebugContextService contextService = DebugUITools.getDebugContextManager() - .getContextService(fPart.getSite().getWorkbenchWindow()); + .getContextService(viewPart.getSite().getWorkbenchWindow()); return contextService.getActiveContext(); } @@ -238,36 +178,13 @@ private String getLabel(IPinElementHandle handle) { return label; } - private boolean useMultiPinImage(Set handles) { - if (handles.size() <= 1) - return false; - - int overlayColor = IPinElementColorDescriptor.UNDEFINED; - ImageDescriptor imageDesc = null; - for (IPinElementHandle handle : handles) { - IPinElementColorDescriptor colorDesc = handle.getPinElementColorDescriptor(); - if (colorDesc != null) { - ImageDescriptor descImageDesc = colorDesc.getToolbarIconDescriptor(); - if (imageDesc != null && !imageDesc.equals(descImageDesc)) - return true; - imageDesc = descImageDesc; - - int descOverlayColor = colorDesc.getOverlayColor(); - if (overlayColor != IPinElementColorDescriptor.UNDEFINED && descOverlayColor != overlayColor) - return true; - overlayColor = descOverlayColor; - } - } - - return false; - } - - private void updatePinContextColor(DebugContextPinProvider provider) { + private void updatePinContextColor(DebugContextPinProvider provider, ToolItem toolItem) { ImageDescriptor imageDesc = null; if (provider != null) { Set handles = provider.getPinHandles(); - // if handles have different toolbar icon descriptor or different pin color, than use a + // if handles have different toolbar icon descriptor or different pin color, + // than use a // multi-pin toolbar icon if (useMultiPinImage(handles)) imageDesc = CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_VIEW_PIN_ACTION_MULTI); @@ -301,19 +218,41 @@ private void updatePinContextColor(DebugContextPinProvider provider) { if (imageDesc == null) imageDesc = CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_VIEW_PIN_ACTION); - fAction.setImageDescriptor(imageDesc); + image = imageDesc.createImage(); + toolItem.setImage(image); } - /* (non-Javadoc) - * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) - */ - @Override - public void debugContextChanged(DebugContextEvent event) { - if (fAction != null && !fAction.isChecked()) { - final boolean pinnable = PinCloneUtils.isPinnable(fPart, event.getContext()); - if (pinnable != fAction.isEnabled()) { - PlatformUI.getWorkbench().getDisplay().syncExec(() -> fAction.setEnabled(pinnable)); + private boolean useMultiPinImage(Set handles) { + if (handles.size() <= 1) + return false; + + int overlayColor = IPinElementColorDescriptor.UNDEFINED; + ImageDescriptor imageDesc = null; + for (IPinElementHandle handle : handles) { + IPinElementColorDescriptor colorDesc = handle.getPinElementColorDescriptor(); + if (colorDesc != null) { + ImageDescriptor descImageDesc = colorDesc.getToolbarIconDescriptor(); + if (imageDesc != null && !imageDesc.equals(descImageDesc)) + return true; + imageDesc = descImageDesc; + + int descOverlayColor = colorDesc.getOverlayColor(); + if (overlayColor != IPinElementColorDescriptor.UNDEFINED && descOverlayColor != overlayColor) + return true; + overlayColor = descOverlayColor; } } + + return false; + } + + @Override + public void dispose() { + pinned.clear(); + disposeImage(); + } + + public static Set getPinnedViews() { + return pinned; } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml index 8845c655b5f..17346638a2e 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml @@ -76,26 +76,6 @@ toolbarPath="additions"> - - - - - - + + + + + + + + + + + + + + @@ -572,6 +580,13 @@ properties="isDisassemblyViewSupportsCBreakpoint" type="org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart"> + + diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/PinCommandEnablementTester.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/PinCommandEnablementTester.java new file mode 100644 index 00000000000..5aa995a1987 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/PinCommandEnablementTester.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2025 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.dsf.debug.internal.ui.debugview.layout; + +import org.eclipse.cdt.debug.internal.ui.actions.PinViewHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Adapters; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.ui.DebugUITools; + +/** + * Tests if 'Pin to Debug Context' and 'Open New View' commands can be enabled. + * This is tested in 2 steps. + *

+ * 1. If any view is already pinned then command must be enabled in all the + * views where it is contributed. + *

+ *

+ * 2. A valid {@link DsfSession} is active. + *

+ * + * + * @author Raghunandana Murthappa + */ +public class PinCommandEnablementTester extends PropertyTester { + + private static final String PIN_VIEW_COMMAND_PROP_TEST_NAME = "canPinViewEnabled"; //$NON-NLS-1$ + + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + + if (PIN_VIEW_COMMAND_PROP_TEST_NAME.equals(property)) { + + // We enable Pin Command on all views if it is pinned in any View. + if (!PinViewHandler.getPinnedViews().isEmpty()) { + return true; + } + + IAdaptable debugContext = DebugUITools.getDebugContext(); + IDMVMContext dmvmContext = Adapters.adapt(debugContext, IDMVMContext.class); + return dmvmContext != null && DsfSession.isSessionActive(dmvmContext.getDMContext().getSessionId()); + } + return false; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/plugin.xml index 831162bb9ec..3274d323bde 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/plugin.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/plugin.xml @@ -40,29 +40,6 @@ point="org.eclipse.core.runtime.preferences">
- - - - - - - - + + + + + + + + + + + + + + + +