From 0d4ca399d00621f5b0c94340764fd6c19feaf73f Mon Sep 17 00:00:00 2001 From: Patrick Chuong Date: Mon, 17 Jan 2011 18:17:43 +0000 Subject: [PATCH] Bug 331781 - Pin and Clone support --- .../META-INF/MANIFEST.MF | 4 +- .../icons/elcl16/open_new.gif | Bin 0 -> 612 bytes .../icons/elcl16/pin.gif | Bin 0 -> 358 bytes .../plugin.properties | 5 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 60 ++++++ .../ui/actions/OpenNewViewActionDelegate.java | 79 +++++++ .../PinDebugContextActionDelegate.java | 204 ++++++++++++++++++ .../ui/pinclone/DebugContextPinProvider.java | 150 +++++++++++++ .../ui/pinclone/DebugEventFilterService.java | 138 ++++++++++++ .../internal/ui/pinclone/PinCloneUtils.java | 171 +++++++++++++++ .../ui/pinclone/ViewIDCounterManager.java | 198 +++++++++++++++++ .../eclipse/cdt/debug/ui/CDebugUIPlugin.java | 2 + .../eclipse/cdt/debug/ui/IPinProvider.java | 94 ++++++++ .../cdt/debug/ui/PinElementHandle.java | 60 ++++++ .../gdb/internal/ui/GdbAdapterFactory.java | 9 +- .../dsf/gdb/internal/ui/GdbPinProvider.java | 168 +++++++++++++++ dsf/org.eclipse.cdt.dsf.ui/icons/open_new.gif | Bin 0 -> 612 bytes dsf/org.eclipse.cdt.dsf.ui/icons/pin.gif | Bin 0 -> 358 bytes dsf/org.eclipse.cdt.dsf.ui/plugin.properties | 4 + dsf/org.eclipse.cdt.dsf.ui/plugin.xml | 20 ++ .../ui/disassembly/DisassemblyPart.java | 22 +- .../icons/open_new.gif | Bin 0 -> 612 bytes .../icons/pin.gif | Bin 0 -> 358 bytes .../plugin.properties | 7 +- .../plugin.xml | 31 ++- .../memory/memorybrowser/MemoryBrowser.java | 7 +- 26 files changed, 1411 insertions(+), 22 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/elcl16/open_new.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/elcl16/pin.gif create 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/PinDebugContextActionDelegate.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugContextPinProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugEventFilterService.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/PinCloneUtils.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/ViewIDCounterManager.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/IPinProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/PinElementHandle.java create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbPinProvider.java create mode 100644 dsf/org.eclipse.cdt.dsf.ui/icons/open_new.gif create mode 100644 dsf/org.eclipse.cdt.dsf.ui/icons/pin.gif create mode 100644 memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/icons/open_new.gif create mode 100644 memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/icons/pin.gif 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 7cb7f39b33a..f57ad9dd1d7 100644 --- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.ui; singleton:=true -Bundle-Version: 7.0.0.qualifier +Bundle-Version: 7.1.0.qualifier Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.cdt.debug.internal.ui;x-internal:=true, - org.eclipse.cdt.debug.internal.ui.actions;x-friends:="org.eclipse.cdt.dsf.ui", + org.eclipse.cdt.debug.internal.ui.actions;x-friends:="org.eclipse.cdt.dsf.ui,org.eclipse.cdt.debug.ui.memory.memorybrowser", org.eclipse.cdt.debug.internal.ui.commands;x-internal:=true, org.eclipse.cdt.debug.internal.ui.dialogfields;x-internal:=true, org.eclipse.cdt.debug.internal.ui.dialogs;x-internal:=true, diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/open_new.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/open_new.gif new file mode 100644 index 0000000000000000000000000000000000000000..7aea894d0b603a02aed2a7f706bcb3170988774d GIT binary patch literal 612 zcmZ{h>q}E%9Dt8G)5LOgQI2^@7e=H}5t7*jq~=si${U5|rU_+M-j`oOU#sb&i!)6! zQj1L2<%^C`(3Frs!zQH!M$LxHZR)0;HP3s_`~J#5py%WBe0&lT<%eQbQbx*H7)D;+ zC9mj8tL`~bsh6u?DXLzlp`Oc4!$r+QwcX=`U*-e?sC#^9(mL|ZR{74{H@%DrT- zV)#}6;rDanLRp{LGx3fOqC^RS3vNq|)X-(A$o!#sus3{C+!5o{Rj7~JHa zq?m$3AWMR=N;c$n#X>#8pgrH*sO=7AfY*vOt}fICx=Rq;>*}tJq5D zJOzs&S}52kF^hQm&roD!pv_wX{I_nC2C7b_o=HnlsqcF+ z>%ILpZc-}G=AK7a*@3|wd!lmkaw^a@Hhgq+cl5#IStlz|F}po7cvo=5fta}bq!M(A z4UvV+$@aw_y%1lD%Gl7ITxjV2!wCgP%26SkA9VL}>?w1J7eN*3kUXk(DEU6m(EdKjHN)jkv7c;{Jb4a3C!1>qfFng9R* literal 0 HcmV?d00001 diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/pin.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/pin.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f13a0ec5b3c8f5bc4094ecdaa9d2e10dcc8e4c8 GIT binary patch literal 358 zcmZ?wbhEHb6krfwSZcx0F?F4|QS8K7D<{laVNkNmrEHa3`D(X{)po5%>{<@T&OW#5 z)RWbxo*cdZC3eoamMynhw%$7X>;K2!|G)nE|Ksof*T4S1`~Cm@@BbhF{Qval|JT3&fBgIZ{ont&3m42? zw1A<=j3H5vAxNEJs-5ZVh@x$twOa!hpK6@HJa5&i>8n>x-@dVL|F(|*IDq0$7DfgJ zdj=f_AOQJ^fvx$#`~nXhseX?ouT{N;!Z$=*e%a(0f2gUkp}(JdYNg z%m~wum=R$iAjHMNe64D0o{Kqea|>gQaf5S{qKu*7ZYA- vRTVi^ISEx&Qx`2>HTex2 + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 00000000000..49d651fe840 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/OpenNewViewActionDelegate.java @@ -0,0 +1,79 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils; +import org.eclipse.cdt.debug.internal.ui.pinclone.ViewIDCounterManager; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; + +/** + * Opens a new view of the same type. + */ +public class OpenNewViewActionDelegate implements IViewActionDelegate { + private IViewPart fView; + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + IViewSite site = fView.getViewSite(); + String viewId = site.getId(); + IWorkbenchWindow ww = fView.getViewSite().getWorkbenchWindow(); + if (ww != null) { + Integer secondaryId = null; + boolean assignSecondaryId = false; + + // if there is a view without a secondary id, than get the next available id. + IViewReference[] viewRefs = ww.getActivePage().getViewReferences(); + for (IViewReference viewRef : viewRefs) { + if (viewId.equals(viewRef.getId()) && (viewRef.getSecondaryId() == null)) { + assignSecondaryId = true; + break; + } + } + if (assignSecondaryId) + secondaryId = ViewIDCounterManager.getInstance().getNextCounter(viewId); + + try { + ww.getActivePage().showView(viewId, + secondaryId != null ? PinCloneUtils.encodeClonedPartSecondaryId(secondaryId.toString()) : null, + IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + CDebugUIPlugin.log(e); + } + } + } + + /* + * (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) { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + fView = view; + } +} 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/PinDebugContextActionDelegate.java new file mode 100644 index 00000000000..7adbb600e3a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/PinDebugContextActionDelegate.java @@ -0,0 +1,204 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.actions; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.cdt.debug.internal.ui.pinclone.DebugContextPinProvider; +import org.eclipse.cdt.debug.internal.ui.pinclone.DebugEventFilterService; +import org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils; +import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle; +import org.eclipse.cdt.debug.ui.IPinProvider.IPinHandleLabelProvider; +import org.eclipse.core.runtime.IAdaptable; +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.viewers.ISelection; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IActionDelegate2; +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; + +/** + * Pin the selected debug context for the view. + */ +public class PinDebugContextActionDelegate implements IViewActionDelegate, IActionDelegate2, IDebugContextListener { + IViewPart fPart; + IAction fAction; + IPartListener2 fPartListener; + DebugContextPinProvider fProvider; + + public PinDebugContextActionDelegate() {} + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event) + */ + public void runWithEvent(IAction action, Event event) { + run(action); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + if (action.isChecked()) { + fProvider = DebugEventFilterService.getInstance().addDebugEventFilter(fPart, getActiveDebugContext()); + if (fProvider != null) { + // TODO: set image descriptor + updatePinContextLabel(fProvider); + } + } else { + fProvider = null; + DebugEventFilterService.getInstance().removeDebugEventFilter(fPart); + // TODO: remove image descriptor + updatePinContextLabel(fProvider); + } + } + + /* (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) { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction) + */ + public void init(IAction action) { + fAction = action; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + 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() { + public void propertyChanged(Object source, int propId) { + if (IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION == propId) { + updatePinContextLabel(fProvider); + } 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. + fPartListener = new IPartListener2() { + public void partBroughtToTop(IWorkbenchPartReference partRef) {} + public void partClosed(IWorkbenchPartReference partRef) { + IWorkbenchPart part = partRef.getPart(false); + if (part.equals(fPart)) { + if (fAction.isChecked()) { + DebugEventFilterService.getInstance().removeDebugEventFilter(fPart); + fAction.setChecked(false); + } + } + } + public void partDeactivated(IWorkbenchPartReference partRef) {} + public void partOpened(IWorkbenchPartReference partRef) {} + public void partHidden(IWorkbenchPartReference partRef) {} + public void partVisible(IWorkbenchPartReference partRef) {} + public void partInputChanged(IWorkbenchPartReference partRef) {} + public void partActivated(IWorkbenchPartReference partRef) {} + }; + fPart.getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate2#dispose() + */ + public void dispose() { + DebugUITools.removePartDebugContextListener(fPart.getSite(), this); + fPart.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); + } + + protected ISelection getActiveDebugContext() { + IDebugContextService contextService = + DebugUITools.getDebugContextManager().getContextService(fPart.getSite().getWorkbenchWindow()); + return contextService.getActiveContext(); + } + + private void updatePinContextLabel(DebugContextPinProvider provider) { + String description = ""; //$NON-NLS-1$ + + if (provider != null) { + Set labels = new HashSet(); + Set handles = provider.getPinHandles(); + for (IPinElementHandle handle : handles) { + String tmp = getLabel(handle); + if (tmp != null && tmp.trim().length() != 0) + labels.add(tmp); + } + + for (String label : labels) { + if (label != null) { + if (description.length() > 0) { + description += "," + label; //$NON-NLS-1$ + } else { + description = label; + } + } + } + } + + PinCloneUtils.setPartContentDescription(fPart, description); + } + + private String getLabel(IPinElementHandle handle) { + String label = ""; //$NON-NLS-1$ + + if (handle instanceof IAdaptable) { + IPinHandleLabelProvider provider = + (IPinHandleLabelProvider) ((IAdaptable) handle).getAdapter(IPinHandleLabelProvider.class); + if (provider != null) + label = provider.getLabel(); + } + + return label; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) + */ + 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(new Runnable() { + public void run() { + fAction.setEnabled(pinnable); + } + }); + } + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugContextPinProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugContextPinProvider.java new file mode 100644 index 00000000000..b6af12d62f7 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugContextPinProvider.java @@ -0,0 +1,150 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.pinclone; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.cdt.debug.ui.IPinProvider; +import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle; +import org.eclipse.cdt.debug.ui.PinElementHandle; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider; +import org.eclipse.debug.ui.contexts.DebugContextEvent; +import org.eclipse.debug.ui.contexts.IDebugContextProvider2; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Pin debug context provider. + * It takes a debug context and translate to a handle for pinning purpose. + */ +public class DebugContextPinProvider extends AbstractDebugContextProvider implements IDebugContextProvider2 { + private ISelection fActiveContext; + private final Set fPinHandles; + private final IWorkbenchPart fWorkbenchPart; + private final Map fPinProvider; + + /** + * Constructor. + * + * @param part the workbench part of where the pin action takes place + * @param activeContext the debug context selection + */ + public DebugContextPinProvider(IWorkbenchPart part, ISelection activeContext) { + super(part); + fWorkbenchPart = part; + fPinProvider = new HashMap(); + + fActiveContext = activeContext; + fPinHandles = pin(part, activeContext); + } + + /** + * Dispose the provider. + */ + public void dispose() { + for (Entry entry : fPinProvider.entrySet()) { + entry.getValue().unpin(fWorkbenchPart, entry.getKey()); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextProvider2#isWindowContextProvider() + */ + public boolean isWindowContextProvider() { + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextProvider#getActiveContext() + */ + public ISelection getActiveContext() { + return fActiveContext; + } + + /** + * Returns the pinned debug context handles. + * + * @return the handle set + */ + public Set getPinHandles() { + return fPinHandles; + } + + /** + * Returns whether the current pinned handles are pinned to the given debug context. + * + * @param debugContext the debug context in question + * @return true if the pinned handles are pinned to the debug context + */ + public boolean isPinnedTo(Object debugContext) { + IPinProvider pinProvider = null; + if (debugContext instanceof IAdaptable) { + pinProvider = (IPinProvider) ((IAdaptable)debugContext).getAdapter(IPinProvider.class); + } + + for (IPinElementHandle handle : fPinHandles) { + if (pinProvider != null && pinProvider.isPinnedTo(debugContext, handle)) { + return true; + + } else if (handle.getDebugContext().equals(debugContext)) { + return true; + } + } + return false; + } + + /** + * Pin the given debug context selection. + * + * @param part the workbench part where the pin action is requested + * @param selection the debug context selection + * @return a set of pinned handle + */ + private Set pin(IWorkbenchPart part, ISelection selection) { + Set handles = new HashSet(); + + if (selection instanceof IStructuredSelection) { + for (Object element : ((IStructuredSelection)selection).toList()) { + IPinProvider pinProvider = null; + if (element instanceof IAdaptable) { + pinProvider = (IPinProvider) ((IAdaptable)element).getAdapter(IPinProvider.class); + } + + if (pinProvider != null) { + IPinElementHandle handle = pinProvider.pin(fWorkbenchPart, element); + handles.add(handle); + fPinProvider.put(handle, pinProvider); + } else + handles.add(new PinElementHandle(element, null)); + } + } + + return handles; + } + + /** + * Delegates debug event to the listener. + * + * @param event debug event + */ + public void delegateEvent(final DebugContextEvent event) { + fActiveContext = event.getContext(); + fire(event); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugEventFilterService.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugEventFilterService.java new file mode 100644 index 00000000000..1e7a4f20ad6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/DebugEventFilterService.java @@ -0,0 +1,138 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.pinclone; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPart; + +/** + * This class provides debug event filtering service for the pin-able views. + */ +public class DebugEventFilterService { + + /** + * A debug context event listen that provides filter support + * for the pinned debug context. + */ + private class DebugEventFilter implements IDebugContextListener { + private final DebugContextPinProvider fProvider; + + private DebugEventFilter(DebugContextPinProvider provider) { + fProvider = provider; + } + + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent) + */ + public void debugContextChanged(DebugContextEvent event) { + ISelection eventContext = event.getContext(); + if (eventContext instanceof IStructuredSelection) { + + List eventContextList = ((IStructuredSelection)eventContext).toList(); + for (Object o : eventContextList) { + if (fProvider.isPinnedTo(o)) { + if (fProvider != event.getDebugContextProvider()) { + fProvider.delegateEvent(new DebugContextEvent(fProvider, event.getContext(), event.getFlags())); + } + return; + } + } + } + } + + public DebugContextPinProvider getTranslator() { + return fProvider; + } + } + + private static DebugEventFilterService INSTANCE; + private Map fFilterMap = new HashMap(); + + private DebugEventFilterService() { + } + + public static synchronized DebugEventFilterService getInstance() { + if (INSTANCE == null) + INSTANCE = new DebugEventFilterService(); + return INSTANCE; + } + + /** + * Add debug event filter for the provided part and filter debug context change + * event for the provided debug context. + * + * @param part the part to filter debug context change event. + * @param debugContext the debug context that filter should stick to. + * @return the debug context provider that handles the filtering. + */ + public DebugContextPinProvider addDebugEventFilter(IWorkbenchPart part, ISelection debugContext) { + DebugContextPinProvider contextProvider = null; + DebugEventFilter filter = null; + + synchronized (fFilterMap) { + if (fFilterMap.containsKey(part)) { + return null; + } + + contextProvider = new DebugContextPinProvider(part, debugContext); + filter = new DebugEventFilter(contextProvider); + fFilterMap.put(part, filter); + } + + assert contextProvider != null && filter != null; + + IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(part.getSite().getWorkbenchWindow()); + contextService.addDebugContextProvider(contextProvider); + contextService.addDebugContextListener(filter); + + return contextProvider; + } + + /** + * Remove debug event filter for the provided part. + * + * @param part the workbench part. + */ + public void removeDebugEventFilter(IWorkbenchPart part) { + DebugEventFilter filter = null; + + synchronized (fFilterMap) { + if (!fFilterMap.containsKey(part)) { + return; + } + + filter = fFilterMap.remove(part); + } + + assert filter != null; + + DebugContextPinProvider contextProvider = filter.getTranslator(); + IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(part.getSite().getWorkbenchWindow()); + + // send a change notification to the listener to update with selected context + contextProvider.delegateEvent(new DebugContextEvent(contextProvider, contextService.getActiveContext(), DebugContextEvent.ACTIVATED)); + + // removes the listener and provider + contextService.removeDebugContextListener(filter); + contextService.removeDebugContextProvider(contextProvider); + contextProvider.dispose(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/PinCloneUtils.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/PinCloneUtils.java new file mode 100644 index 00000000000..39e53d4543b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/PinCloneUtils.java @@ -0,0 +1,171 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.pinclone; + +import java.lang.reflect.Method; +import java.util.List; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.debug.ui.IPinProvider; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.WorkbenchPart; + +/** + * A utility class for pin and clone support. + */ +public class PinCloneUtils { + public static String PIN_CLONE_VIEW_TAG = "PIN_CLONE_VIEW_"; //$NON-NLS-1$ + + /** + * Encodes cloned part secondary id. + * + * @param secondaryId the part's secondary id. + * @return an encoded part secondary id, can be null. + */ + public static String encodeClonedPartSecondaryId(String secondaryId) { + return PIN_CLONE_VIEW_TAG + secondaryId; + } + + /** + * Decodes cloned part secondary id. + * + * @param secondaryId the part's secondary id. + * @return a decoded part secondary id. + */ + public static String decodeClonedPartSecondaryId(String secondaryId) { + return secondaryId.replaceFirst(PIN_CLONE_VIEW_TAG, ""); //$NON-NLS-1$ + } + + /** + * Determine whether the view part is a cloned part. + * + * @param part the view part + * @return true if it is a cloned part + */ + public static boolean isClonedPart(IViewPart part) { + String secondaryId = part.getViewSite().getSecondaryId(); + return hasCloneTag(secondaryId); + } + + /** + * Determine whether the view reference is a cloned part. + * + * @param ref the view reference + * @return true if it is a cloned part + */ + public static boolean isClonedPart(IViewReference ref) { + String secondaryId = ref.getSecondaryId(); + return hasCloneTag(secondaryId); + } + + /** + * Returns whether the id has the PIN_CLONE_VIEW_TAG. + * + * @param id view id + * @return true if it has the tag, otherwise false + */ + private static boolean hasCloneTag(String id) { + return id != null && id.startsWith(PIN_CLONE_VIEW_TAG); + } + + /** + * Set the part title to include the secondary id as part of the title. + * + * @param part the view part + */ + public static void setPartTitle(IViewPart part) { + try { + if (!isClonedPart(part)) + return; + + String secondaryId = part.getViewSite().getSecondaryId(); + secondaryId = decodeClonedPartSecondaryId(secondaryId); + + // use reflection to set the part name of the new view + Method method = WorkbenchPart.class.getDeclaredMethod("setPartName", String.class); //$NON-NLS-1$ + if (method != null) { + if (part instanceof WorkbenchPart) { + String name = ((WorkbenchPart) part).getPartName(); + + String tag = " <" + secondaryId + ">"; //$NON-NLS-1$//$NON-NLS-2$ + if (!name.contains(tag)) { + name = name + tag; + + method.setAccessible(true); + method.invoke(part, name); + } + } + } + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } + + /** + * Set the part content description. + * + * @param part the part + * @param description the new description + */ + public static void setPartContentDescription(IViewPart part, String description) { + try { + Method method = WorkbenchPart.class.getDeclaredMethod("setContentDescription", String.class); //$NON-NLS-1$ + if (method != null) { + method.setAccessible(true); + method.invoke(part, description); + } + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } + + /** + * Returns whether the debug context selection is pinnable. + * + * @param part the workbench part were the pin action is triggered + * @param selection the debug context selection + * @return true if all elements are pinnable, otherwise false + */ + public static boolean isPinnable(IWorkbenchPart part, ISelection selection) { + boolean pinnable = false; + + if (selection instanceof IStructuredSelection) { + List list = ((IStructuredSelection) selection).toList(); + for (Object element : list) { + pinnable = false; + + /* IPinProvider */ + if (element instanceof IAdaptable) { + IPinProvider pinProvider = (IPinProvider) ((IAdaptable)element).getAdapter(IPinProvider.class); + if (pinProvider != null) { + if (pinProvider.isPinnable(part, element)) + pinnable = true; + } + } + +// TODO: support for CDI +// /* support CDebugElement */ +// if (!pinnable && (element instanceof ICDebugElement)) { +// pinnable = true; +// } + + if (!pinnable) break; + } + } + + return pinnable; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/ViewIDCounterManager.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/ViewIDCounterManager.java new file mode 100644 index 00000000000..248a46fd9c5 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/pinclone/ViewIDCounterManager.java @@ -0,0 +1,198 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.internal.ui.pinclone; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWindowListener; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.WorkbenchJob; + +/** + * This class provides counter id for view that support multiple instances. + * It is assumed that view will use the counter id for it's secondary id. + */ +public final class ViewIDCounterManager { + private static ViewIDCounterManager INSTANCE; + private static boolean fInitialized = false; + + private boolean fShuttingDown = false; + private final Map> viewIdToNextCounterMap = Collections.synchronizedMap(new HashMap>()); + + private ViewIDCounterManager() { + initListeners(); + } + + /** + * Returns an instance of the view id counter manager. + * + * @return the counter manager. + */ + synchronized public static ViewIDCounterManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new ViewIDCounterManager(); + } + return INSTANCE; + } + + /** + * Initialize this view ID counter manager. Catch up opened view and set the title + * accordingly from the view's secondary id. + */ + synchronized public void init() { + if (fInitialized) return; + fInitialized = true; + + new WorkbenchJob("Initializing pinnable view") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + for (IWorkbenchWindow window : windows) { + IViewReference[] viewRefs = window.getActivePage().getViewReferences(); + for (IViewReference viewRef : viewRefs) { + try { + // initialize the view id counter map + if (PinCloneUtils.isClonedPart(viewRef)) { + String id = viewRef.getId(); + String secondaryId = viewRef.getSecondaryId(); + Set secondaryIdSet = viewIdToNextCounterMap.get(id); + if (secondaryIdSet == null) { + secondaryIdSet = new HashSet(); + viewIdToNextCounterMap.put(id, secondaryIdSet); + } + secondaryId = PinCloneUtils.decodeClonedPartSecondaryId(secondaryId); + secondaryIdSet.add(Integer.valueOf(secondaryId)); + } + + // set the view title + IViewPart part = viewRef.getView(false); + if (part != null && PinCloneUtils.isClonedPart(part)) { + PinCloneUtils.setPartTitle(part); + } + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } + } + return Status.OK_STATUS; + } + }.schedule(); + } + + private void initListeners() { + try { + // add a workbench listener to listen to preShutdown and ignore view part close event + IWorkbench wb = PlatformUI.getWorkbench(); + wb.addWorkbenchListener(new IWorkbenchListener() { + public void postShutdown(IWorkbench workbench) {} + + public boolean preShutdown(IWorkbench workbench, boolean forced) { + fShuttingDown = true; + return true; + } + }); + + final IPartListener2 partListener = new IPartListener2() { + public void partVisible(IWorkbenchPartReference partRef) {} + public void partInputChanged(IWorkbenchPartReference partRef) {} + public void partHidden(IWorkbenchPartReference partRef) {} + public void partDeactivated(IWorkbenchPartReference partRef) {} + public void partBroughtToTop(IWorkbenchPartReference partRef) {} + public void partActivated(IWorkbenchPartReference partRef) {} + + public void partOpened(IWorkbenchPartReference partRef) { + if (partRef instanceof IViewReference) { + IViewPart part = ((IViewReference) partRef).getView(false); + if (part != null && PinCloneUtils.isClonedPart(part)) { + PinCloneUtils.setPartTitle(part); + } + } + } + + public void partClosed(IWorkbenchPartReference partRef) { + if (!fShuttingDown) + recycleCounterId(partRef); + } + }; + + // subscribe to existing workbench window listener + for (IWorkbenchWindow ww : wb.getWorkbenchWindows()) { + ww.getPartService().addPartListener(partListener); + } + + // subscribe to new workbench window listener + wb.addWindowListener(new IWindowListener() { + public void windowDeactivated(IWorkbenchWindow window) {} + public void windowActivated(IWorkbenchWindow window) {} + public void windowClosed(IWorkbenchWindow window) {} + + public void windowOpened(IWorkbenchWindow window) { + window.getPartService().addPartListener(partListener); + } + }); + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } + + private void recycleCounterId(IWorkbenchPartReference partRef) { + if (partRef instanceof IViewReference) { + IViewReference viewRef = ((IViewReference) partRef); + IWorkbenchPart part = viewRef.getPart(false); + if ( !(part instanceof IViewPart) || !PinCloneUtils.isClonedPart((IViewPart) part)) + return; + + String viewId = viewRef.getId(); + String secondaryId = viewRef.getSecondaryId(); + + if (secondaryId != null) { + Set secondaryIdSet = viewIdToNextCounterMap.get(viewId); + if (secondaryIdSet != null) { + secondaryIdSet.remove(new Integer(PinCloneUtils.decodeClonedPartSecondaryId(secondaryId))); + } + } + } + } + + public Integer getNextCounter(String viewId) { + Set secondaryIdSet = viewIdToNextCounterMap.get(viewId); + if (secondaryIdSet == null) { + secondaryIdSet = new HashSet(); + viewIdToNextCounterMap.put(viewId, secondaryIdSet); + } + + for (int i = 1; i < Integer.MAX_VALUE; ++i) { + Integer next = new Integer(i); + if (!secondaryIdSet.contains(next)) { + secondaryIdSet.add(next); + return next; + } + } + + return new Integer(0); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java index dbfb7c92ee5..f6391cf6863 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyBackendCdiFactory; import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager; +import org.eclipse.cdt.debug.internal.ui.pinclone.ViewIDCounterManager; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; import org.eclipse.core.resources.IWorkspace; @@ -288,6 +289,7 @@ public class CDebugUIPlugin extends AbstractUIPlugin { @Override public void start( BundleContext context ) throws Exception { super.start( context ); + ViewIDCounterManager.getInstance().init(); fDisassemblyEditorManager = new DisassemblyEditorManager(); EvaluationContextManager.startup(); CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() ); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/IPinProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/IPinProvider.java new file mode 100644 index 00000000000..c678677a8bd --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/IPinProvider.java @@ -0,0 +1,94 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.ui; + +import org.eclipse.ui.IWorkbenchPart; + +/** + * Debug element that wants to enable pin capability should be adaptable to this interface. + * If the debug element is not adaptable to this interface, than the default implementation + * will be provided. + *

+ * When user press the 'Pin' action in a view that supports debug context pinning, the + * DebugEventFilterService calls the pin method with the selected debug context. + * If more than one debug context is selected, than pin is called multiple times. + * The pin method should returns a handle for the pinned debug context and when + * there is a debug context change event generated by the debug context manager, + * isPinnedTo will be call by the DebugEventFilterService to determine whether the + * debug context in question is pinned to the handle returned by the pin method. + * + * @since 7.1 + */ +public interface IPinProvider { + /** + * An interface that provides label for the pinned handle. Handle that + * wish to provide custom label should implement this interface. + */ + public interface IPinHandleLabelProvider { + /** + * Returns the label the label will be used to display + * in the pinned view's descriptor. + * + * @return the handle label + */ + String getLabel(); + } + + /** + * Pin element handler interface. + */ + public interface IPinElementHandle { + /** + * Returns the debug context for this handle. + * + * @return the debug context + */ + Object getDebugContext(); + } + + /** + * Returns whether the debug context is pinnable. + * + * @param part the workbench part + * @param debugContext the debug context in question + * @return true if the debug context is pinnable + */ + boolean isPinnable(IWorkbenchPart part, Object debugContext); + + /** + * Pin the debug context and returns a handle for the pinned debug context. + * + * @param part the workbench part + * @param debugContext the debug context to pin to + * @return a handle for the pinned debug context + */ + + IPinElementHandle pin(IWorkbenchPart part, Object debugContext); + + /** + * Unpin the debug context for the given pin handle. + * + * @param part the workbench part + * @param handle the handle for the pinned debug context + */ + void unpin(IWorkbenchPart part, IPinElementHandle handle); + + + /** + * Returns true if the debug context belongs to the handle. If returning true, + * than the debug context change event will be delegate to the view. + * + * @param debugContext the debug context in question + * @param handle an existing pinned debug context handle + * @return true to delegate debug context change event to the view + */ + boolean isPinnedTo(Object debugContext, IPinElementHandle handle); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/PinElementHandle.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/PinElementHandle.java new file mode 100644 index 00000000000..43a4f93739e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/PinElementHandle.java @@ -0,0 +1,60 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.debug.ui; + +import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle; +import org.eclipse.cdt.debug.ui.IPinProvider.IPinHandleLabelProvider; +import org.eclipse.core.runtime.PlatformObject; + +/** + * A class that encapsulates the pin element handle and implements IPinHandleLableProvider. + * + * @since 7.1 + */ +public class PinElementHandle extends PlatformObject implements IPinHandleLabelProvider, IPinElementHandle { + private final Object fDebugContext; + private final String fLabel; + + public PinElementHandle(Object debugContext, String label) { + fDebugContext = debugContext; + fLabel = label; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle#getDebugContext() + */ + public Object getDebugContext() { + return fDebugContext; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.core.IPinProvider.IHandleLabelProvider#getLabel() + */ + public String getLabel() { + return fLabel; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof PinElementHandle) { + if (fDebugContext == null) + return ((PinElementHandle) obj).getDebugContext() == null; + else + return fDebugContext.equals(((PinElementHandle) obj).getDebugContext()); + } + return false; + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java index 393e82757d0..4e6a4ad8d41 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.debug.core.model.IStartTracingHandler; import org.eclipse.cdt.debug.core.model.ISteppingModeTarget; import org.eclipse.cdt.debug.core.model.IStopTracingHandler; import org.eclipse.cdt.debug.core.model.IUncallHandler; +import org.eclipse.cdt.debug.ui.IPinProvider; import org.eclipse.cdt.dsf.concurrent.Immutable; import org.eclipse.cdt.dsf.concurrent.ThreadSafe; import org.eclipse.cdt.dsf.debug.ui.actions.DsfResumeCommand; @@ -127,6 +128,7 @@ public class GdbAdapterFactory final GdbSelectNextTraceRecordCommand fSelectNextRecordTarget; final GdbSelectPrevTraceRecordCommand fSelectPrevRecordTarget; final GdbDebugTextHover fDebugTextHover; + final GdbPinProvider fPinProvider; SessionAdapterSet(GdbLaunch launch) { fLaunch = launch; @@ -170,6 +172,7 @@ public class GdbAdapterFactory fSaveTraceDataTarget = new GdbSaveTraceDataCommand(session); fSelectNextRecordTarget = new GdbSelectNextTraceRecordCommand(session); fSelectPrevRecordTarget = new GdbSelectPrevTraceRecordCommand(session); + fPinProvider = new GdbPinProvider(); session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget); session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); @@ -194,6 +197,7 @@ public class GdbAdapterFactory session.registerModelAdapter(ISaveTraceDataHandler.class, fSaveTraceDataTarget); session.registerModelAdapter(ISelectNextTraceRecordHandler.class, fSelectNextRecordTarget); session.registerModelAdapter(ISelectPrevTraceRecordHandler.class, fSelectPrevRecordTarget); + session.registerModelAdapter(IPinProvider.class, fPinProvider); fDebugModelProvider = new IDebugModelProvider() { // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() @@ -252,7 +256,8 @@ public class GdbAdapterFactory session.unregisterModelAdapter(ISaveTraceDataHandler.class); session.unregisterModelAdapter(ISelectNextTraceRecordHandler.class); session.unregisterModelAdapter(ISelectPrevTraceRecordHandler.class); - + session.unregisterModelAdapter(IPinProvider.class); + session.unregisterModelAdapter(IDebugModelProvider.class); session.unregisterModelAdapter(ILaunch.class); @@ -364,7 +369,7 @@ public class GdbAdapterFactory public Class[] getAdapterList() { return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, ISuspendTrigger.class, - IColumnPresentationFactory.class + IColumnPresentationFactory.class, }; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbPinProvider.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbPinProvider.java new file mode 100644 index 00000000000..58259f04239 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbPinProvider.java @@ -0,0 +1,168 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) + *****************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.ui; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.debug.ui.IPinProvider; +import org.eclipse.cdt.debug.ui.PinElementHandle; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; +import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.ui.IWorkbenchPart; + +/** + * GDB pin provider implementation. + */ +public class GdbPinProvider implements IPinProvider { + + private IMIExecutionDMContext getExecutionDmc(IDMContext dmc) { + return DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class); + + } + + private IProcessDMContext getProcessDmc(IDMContext dmc) { + return DMContexts.getAncestorOfType(dmc, IProcessDMContext.class); + } + + private IThreadDMData getData(final IThreadDMContext threadDmc) { + if (threadDmc == null) + return null; + + IThreadDMData data = null; + try { + String sessionId = threadDmc.getSessionId(); + DsfSession session = DsfSession.getSession(sessionId); + final DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), sessionId); + + try { + if (tracker != null) { + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + final IProcesses processes = tracker.getService(IProcesses.class); + if (processes != null) { + processes.getExecutionData(threadDmc, rm); + } + } + }; + + session.getExecutor().execute(query); + data = query.get(1, TimeUnit.SECONDS); + } + } finally { + if (tracker != null) + tracker.dispose(); + } + } catch (Exception e) { + } + + return data; + } + + private String getLabel(IThreadDMData data) { + String label = ""; //$NON-NLS-1$ + if (data != null) { + String name = data.getName(); + String id = data.getId(); + if (name != null && name.length() > 0) + label = name; + else if (id != null && id.length() > 0) + label = id; + } + return label; + } + + private String getCombinedLabels(IThreadDMContext processDmc, IMIExecutionDMContext execDmc) { + // get the process label + IThreadDMData processData = getData(processDmc); + String label = getLabel(processData); + + // get the execution (thread) context label + if (execDmc != null) { + int threadId = execDmc.getThreadId(); + label += label.length() > 0 ? ": " : ""; //$NON-NLS-1$//$NON-NLS-2$ + label += "Thread [" + Integer.toString(threadId) + "]"; //$NON-NLS-1$//$NON-NLS-2$ + } + return label; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.IPinProvider#isPinnable(org.eclipse.ui.IWorkbenchPart, java.lang.Object) + */ + public boolean isPinnable(IWorkbenchPart part, Object debugContext) { + if (debugContext instanceof IAdaptable) { + return ((IAdaptable) debugContext).getAdapter(IDMContext.class) != null; + } + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.IPinProvider#pin(org.eclipse.ui.IWorkbenchPart, java.lang.Object) + */ + public IPinElementHandle pin(IWorkbenchPart part, Object debugContext) { + Object pinContext = debugContext; + String label = ""; //$NON-NLS-1$ + + if (debugContext instanceof IAdaptable) { + IDMContext dmc = (IDMContext) ((IAdaptable) debugContext).getAdapter(IDMContext.class); + if (dmc != null) { + IMIExecutionDMContext execDmc = getExecutionDmc(dmc); + IProcessDMContext processDmc = getProcessDmc(dmc); + + label = getCombinedLabels(processDmc, execDmc); + if (execDmc != null) + pinContext = execDmc; + } + } + return new PinElementHandle(pinContext, label); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.IPinProvider#unpin(org.eclipse.ui.IWorkbenchPart, org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle) + */ + public void unpin(IWorkbenchPart part, IPinElementHandle handle) { + // do nothing for now. + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.debug.ui.IPinProvider#isPinnedTo(java.lang.Object, org.eclipse.cdt.debug.ui.IPinProvider.IPinElementHandle) + */ + public boolean isPinnedTo(Object debugContext, IPinElementHandle handle) { + if (debugContext instanceof IAdaptable) { + IDMContext dmc = (IDMContext) ((IAdaptable) debugContext).getAdapter(IDMContext.class); + if (dmc != null) { + IMIExecutionDMContext execDmc = getExecutionDmc(dmc); + IProcessDMContext processDmc = getProcessDmc(dmc); + + if (execDmc != null && processDmc != null ) { + String label = getCombinedLabels(processDmc, execDmc); + if (handle instanceof IPinHandleLabelProvider) + return label.equals( ((IPinHandleLabelProvider)handle).getLabel() ); + } + } + } + return false; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/icons/open_new.gif b/dsf/org.eclipse.cdt.dsf.ui/icons/open_new.gif new file mode 100644 index 0000000000000000000000000000000000000000..7aea894d0b603a02aed2a7f706bcb3170988774d GIT binary patch literal 612 zcmZ{h>q}E%9Dt8G)5LOgQI2^@7e=H}5t7*jq~=si${U5|rU_+M-j`oOU#sb&i!)6! zQj1L2<%^C`(3Frs!zQH!M$LxHZR)0;HP3s_`~J#5py%WBe0&lT<%eQbQbx*H7)D;+ zC9mj8tL`~bsh6u?DXLzlp`Oc4!$r+QwcX=`U*-e?sC#^9(mL|ZR{74{H@%DrT- zV)#}6;rDanLRp{LGx3fOqC^RS3vNq|)X-(A$o!#sus3{C+!5o{Rj7~JHa zq?m$3AWMR=N;c$n#X>#8pgrH*sO=7AfY*vOt}fICx=Rq;>*}tJq5D zJOzs&S}52kF^hQm&roD!pv_wX{I_nC2C7b_o=HnlsqcF+ z>%ILpZc-}G=AK7a*@3|wd!lmkaw^a@Hhgq+cl5#IStlz|F}po7cvo=5fta}bq!M(A z4UvV+$@aw_y%1lD%Gl7ITxjV2!wCgP%26SkA9VL}>?w1J7eN*3kUXk(DEU6m(EdKjHN)jkv7c;{Jb4a3C!1>qfFng9R* literal 0 HcmV?d00001 diff --git a/dsf/org.eclipse.cdt.dsf.ui/icons/pin.gif b/dsf/org.eclipse.cdt.dsf.ui/icons/pin.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f13a0ec5b3c8f5bc4094ecdaa9d2e10dcc8e4c8 GIT binary patch literal 358 zcmZ?wbhEHb6krfwSZcx0F?F4|QS8K7D<{laVNkNmrEHa3`D(X{)po5%>{<@T&OW#5 z)RWbxo*cdZC3eoamMynhw%$7X>;K2!|G)nE|Ksof*T4S1`~Cm@@BbhF{Qval|JT3&fBgIZ{ont&3m42? zw1A<=j3H5vAxNEJs-5ZVh@x$twOa!hpK6@HJa5&i>8n>x-@dVL|F(|*IDq0$7DfgJ zdj=f_AOQJ^fvx$#`~nXhseX?ouT{N;!Z$=*e%a(0f2gUkp}(JdYNg z%m~wum=R$iAjHMNe64D0o{Kqea|>gQaf5S{qKu*7ZYA- vRTVi^ISEx&Qx`2>HTex2 + + + + + +
q}E%9Dt8G)5LOgQI2^@7e=H}5t7*jq~=si${U5|rU_+M-j`oOU#sb&i!)6! zQj1L2<%^C`(3Frs!zQH!M$LxHZR)0;HP3s_`~J#5py%WBe0&lT<%eQbQbx*H7)D;+ zC9mj8tL`~bsh6u?DXLzlp`Oc4!$r+QwcX=`U*-e?sC#^9(mL|ZR{74{H@%DrT- zV)#}6;rDanLRp{LGx3fOqC^RS3vNq|)X-(A$o!#sus3{C+!5o{Rj7~JHa zq?m$3AWMR=N;c$n#X>#8pgrH*sO=7AfY*vOt}fICx=Rq;>*}tJq5D zJOzs&S}52kF^hQm&roD!pv_wX{I_nC2C7b_o=HnlsqcF+ z>%ILpZc-}G=AK7a*@3|wd!lmkaw^a@Hhgq+cl5#IStlz|F}po7cvo=5fta}bq!M(A z4UvV+$@aw_y%1lD%Gl7ITxjV2!wCgP%26SkA9VL}>?w1J7eN*3kUXk(DEU6m(EdKjHN)jkv7c;{Jb4a3C!1>qfFng9R* literal 0 HcmV?d00001 diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/icons/pin.gif b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/icons/pin.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f13a0ec5b3c8f5bc4094ecdaa9d2e10dcc8e4c8 GIT binary patch literal 358 zcmZ?wbhEHb6krfwSZcx0F?F4|QS8K7D<{laVNkNmrEHa3`D(X{)po5%>{<@T&OW#5 z)RWbxo*cdZC3eoamMynhw%$7X>;K2!|G)nE|Ksof*T4S1`~Cm@@BbhF{Qval|JT3&fBgIZ{ont&3m42? zw1A<=j3H5vAxNEJs-5ZVh@x$twOa!hpK6@HJa5&i>8n>x-@dVL|F(|*IDq0$7DfgJ zdj=f_AOQJ^fvx$#`~nXhseX?ouT{N;!Z$=*e%a(0f2gUkp}(JdYNg z%m~wum=R$iAjHMNe64D0o{Kqea|>gQaf5S{qKu*7ZYA- vRTVi^ISEx&Qx`2>HTex2 + icon="icons/memorybrowser_view.gif" + id="org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser" + name="%view.name.0"> @@ -34,4 +36,27 @@ point="org.eclipse.core.runtime.preferences"> + + + + + + + + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java index fae795178b6..8b684768e52 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java +++ b/memory/org.eclipse.cdt.debug.ui.memory.memorybrowser/src/org/eclipse/cdt/debug/ui/memory/memorybrowser/MemoryBrowser.java @@ -8,6 +8,7 @@ * Contributors: * Ted R Williams (Wind River Systems, Inc.) - initial implementation * Ted R Williams (Mentor Graphics, Inc.) - address space enhancements + * Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781) *******************************************************************************/ package org.eclipse.cdt.debug.ui.memory.memorybrowser; @@ -296,8 +297,8 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM contextService.addDebugContextListener(this, presentationContextId); selection = contextService.getActiveContext(presentationContextId); } else { - contextService.addDebugContextListener(this); - selection = contextService.getActiveContext(); + DebugUITools.addPartDebugContextListener(getSite(), this); + selection = contextService.getActiveContext(getSite().getId(), ((IViewSite)getSite()).getSecondaryId()); } DebugPlugin.getDefault().addDebugEventListener(this); @@ -339,7 +340,7 @@ public class MemoryBrowser extends ViewPart implements IDebugContextListener, IM String presentationContextId = getPresentationContextId(); contextService.removeDebugContextListener(this, presentationContextId); } else { - contextService.removeDebugContextListener(this); + DebugUITools.removePartDebugContextListener(getSite(), this); } super.dispose(); }