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 00000000000..7aea894d0b6
Binary files /dev/null and b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/open_new.gif differ
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 00000000000..0f13a0ec5b3
Binary files /dev/null and b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/pin.gif differ
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties
index 7a78f0bc7bc..d10c308b012 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties
@@ -8,6 +8,7 @@
# Contributors:
# QNX Software Systems - Initial API and implementation
# IBM Corporation
+# Patrick Chuong (Texas Instruments) - Pin and Clone Supports (Bug 331781)
###############################################################################
pluginName=C/C++ Development Tools Debugger UI
@@ -211,3 +212,7 @@ SaveTraceData.name=Save Trace Data
sourceNotFoundEditor.name = C/C++ Source Not Found Editor
CastingCategory.description = Set of commands for displaying variables and expressions as other types or arrays.
CastingCategory.name = Cast to Type or Array
+
+# Pin & Clone
+PinView.name = Pin to Debug Context
+OpenNewView.name = Open New View
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml
index 1c255cecb8f..75e66a86276 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml
@@ -1044,6 +1044,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 00000000000..7aea894d0b6
Binary files /dev/null and b/dsf/org.eclipse.cdt.dsf.ui/icons/open_new.gif differ
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 00000000000..0f13a0ec5b3
Binary files /dev/null and b/dsf/org.eclipse.cdt.dsf.ui/icons/pin.gif differ
diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties
index 37f942defc9..b88d2ccf30c 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties
+++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties
@@ -8,6 +8,7 @@
# Contributors:
# Wind River Systems - initial API and implementation
# IBM Corporation
+# Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781)
###############################################################################
pluginName=Debugger Services Framework UI
providerName=Eclipse CDT
@@ -63,3 +64,6 @@ StaleData.background.description=This color is used to indicate that a given ele
debugUpdateModes.label = Debug Update Modes
+# Pin & Clone
+PinView.name = Pin to Debug Context
+OpenNewView.name = Open New View
\ No newline at end of file
diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
index 59494256de4..a612d7a107b 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
+++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml
@@ -63,6 +63,26 @@
toolbarPath="additions">
+
+
+
+
+
+
+ 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();
}