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 index 054c68e64a1..f0483b110a3 100644 --- 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 @@ -1,5 +1,5 @@ /***************************************************************** - * Copyright (c) 2010 Texas Instruments and others + * Copyright (c) 2010, 2011 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 @@ -19,6 +19,7 @@ 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.IPinProvider.IPinModelListener; import org.eclipse.cdt.debug.ui.PinElementHandle; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider; @@ -26,11 +27,13 @@ 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.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPart; /** * Pin debug context provider. - * It takes a debug context and translate to a handle for pinning purpose. + * It takes a debug context and translates it to a handle for pinning purpose. */ public class DebugContextPinProvider extends AbstractDebugContextProvider implements IDebugContextProvider2 { private ISelection fActiveContext; @@ -50,7 +53,17 @@ public class DebugContextPinProvider extends AbstractDebugContextProvider implem fPinProvider = new HashMap(); fActiveContext = activeContext; - fPinHandles = pin(part, activeContext); + fPinHandles = pin(part, activeContext, new IPinModelListener() { + public void modelChanged(int eventType) { + // send a change notification for the view to update + switch (eventType) { + case IPinModelListener.EXITED: + case IPinModelListener.RESUMED: + delegateEvent(new DebugContextEvent(DebugContextPinProvider.this, new StructuredSelection(), DebugContextEvent.ACTIVATED)); + break; + } + } + }); } /** @@ -102,9 +115,10 @@ public class DebugContextPinProvider extends AbstractDebugContextProvider implem * * @param part the workbench part where the pin action is requested * @param selection the debug context selection + * @param listener pin model listener * @return a set of pinned handle */ - private Set pin(IWorkbenchPart part, ISelection selection) { + private Set pin(IWorkbenchPart part, ISelection selection, IPinModelListener listener) { Set handles = new HashSet(); if (selection instanceof IStructuredSelection) { @@ -115,7 +129,7 @@ public class DebugContextPinProvider extends AbstractDebugContextProvider implem } if (pinProvider != null) { - IPinElementHandle handle = pinProvider.pin(fWorkbenchPart, element); + IPinElementHandle handle = pinProvider.pin(fWorkbenchPart, element, listener); handles.add(handle); fPinProvider.put(handle, pinProvider); } else @@ -132,7 +146,11 @@ public class DebugContextPinProvider extends AbstractDebugContextProvider implem * @param event debug event */ public void delegateEvent(final DebugContextEvent event) { - fActiveContext = event.getContext(); - fire(event); + Display.getDefault().syncExec(new Runnable() { + public void run() { + fActiveContext = event.getContext(); + fire(event); + } + }); } } 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 index 248a46fd9c5..77f191329e5 100644 --- 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 @@ -1,5 +1,5 @@ /***************************************************************** - * Copyright (c) 2010 Texas Instruments and others + * Copyright (c) 2010, 2011 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 @@ -67,7 +67,8 @@ public final class ViewIDCounterManager { if (fInitialized) return; fInitialized = true; - new WorkbenchJob("Initializing pinnable view") { //$NON-NLS-1$ + new WorkbenchJob("Initializing pinnable view") { //$NON-NLS-1$ + { setSystem(true); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); 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 index efa8c76d55c..e89f52fa222 100644 --- 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 @@ -1,5 +1,5 @@ /***************************************************************** - * Copyright (c) 2010 Texas Instruments and others + * Copyright (c) 2010, 2011 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 @@ -16,13 +16,11 @@ 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 + * When the user presses 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 + * If more than one debug context is selected, the pin method is called multiple times. + * The pin method should return 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. @@ -60,16 +58,16 @@ public interface IPinProvider { int BLUE = 2; /** - * Returns the overlay pin color. The overlay pin will be used to decorate the debug view for element that + * Returns the overlay pin color. The overlay pin will be used to decorate the debug view for an element that * is pinned to a view. * - * @return one of the overlay color + * @return one of the overlay colors */ int getOverlayColor(); /** * Returns the toolbar pin action image description to use when the view is pinned, can be null. - * If null, than the default image description will be use. + * If null, then the default image description will be used. * * @return the icon descriptor */ @@ -88,8 +86,7 @@ public interface IPinProvider { Object getDebugContext(); /** - * Returns the label the label will be used to display - * in the pinned view's descriptor. + * Returns the label that will be used in the pinned view's description. * * @return the handle label */ @@ -103,6 +100,25 @@ public interface IPinProvider { IPinElementColorDescriptor getPinElementColorDescriptor(); } + /** + * A callback interface that can be used by an IPinProvider to indicate + * that the model has changed for a pinned view and that the view must be + * refreshed. + * + * @noimplement This interface is not intended to be implemented by clients. + */ + public interface IPinModelListener { + static final int RESUMED = 0; + static final int EXITED = 1; + + /** + * Model changed handler that will cause the view to update. + * + * @param eventType one of the event type. + */ + void modelChanged(int eventType); + } + /** * Returns whether the debug context is pinnable. * @@ -120,7 +136,7 @@ public interface IPinProvider { * @return a handle for the pinned debug context */ - IPinElementHandle pin(IWorkbenchPart part, Object debugContext); + IPinElementHandle pin(IWorkbenchPart part, Object debugContext, IPinModelListener listener); /** * Unpin the debug context for the given pin handle. @@ -133,7 +149,7 @@ public interface IPinProvider { /** * 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. + * then the debug context change event will be delegated to the view. * * @param debugContext the debug context in question * @param handle an existing pinned debug context handle 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 index c2722643e69..a864326cd9c 100644 --- 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 @@ -1,5 +1,5 @@ /***************************************************************** - * Copyright (c) 2010 Texas Instruments and others + * Copyright (c) 2010, 2011 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 @@ -12,7 +12,9 @@ package org.eclipse.cdt.dsf.gdb.internal.ui; import java.util.Collections; -import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; @@ -24,12 +26,16 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor; 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.datamodel.IDMEvent; 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.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StateChangedEvent; +import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServicesTracker; @@ -61,9 +67,10 @@ public class GdbPinProvider implements IPinProvider { } /** - * A set of pinned element handles. + * A set of pinned element handles and their callback. */ - static private Set gsPinnedHandles = Collections.synchronizedSet(new HashSet()); + private static Map gsPinnedHandles = + Collections.synchronizedMap(new HashMap()); /** * Dsf session. @@ -106,7 +113,7 @@ public class GdbPinProvider implements IPinProvider { * @return the element handles. */ public static Set getPinnedHandles() { - return gsPinnedHandles; + return gsPinnedHandles.keySet(); } private static IMIExecutionDMContext getExecutionDmc(IDMContext dmc) { @@ -189,9 +196,9 @@ public class GdbPinProvider implements IPinProvider { /* * (non-Javadoc) - * @see org.eclipse.cdt.debug.ui.IPinProvider#pin(org.eclipse.ui.IWorkbenchPart, java.lang.Object) + * @see org.eclipse.cdt.debug.ui.IPinProvider#pin(org.eclipse.ui.IWorkbenchPart, java.lang.Object, org.eclipse.cdt.debug.ui.IPinModelListener) */ - public IPinElementHandle pin(IWorkbenchPart part, Object debugContext) { + public IPinElementHandle pin(IWorkbenchPart part, Object debugContext, IPinModelListener listener) { Object pinContext = debugContext; String label = ""; //$NON-NLS-1$ String sessionId = ""; //$NON-NLS-1$ @@ -222,7 +229,7 @@ public class GdbPinProvider implements IPinProvider { IPinElementColorDescriptor colorDesc = new GdbPinElementColorDescriptor(GdbPinColorTracker.INSTANCE.addRef(sessionId + label)); PinElementHandle handle = new PinElementHandle(pinContext, label, colorDesc); - gsPinnedHandles.add(handle); + gsPinnedHandles.put(handle, listener); dispatchChangedEvent(dmc); return handle; @@ -299,7 +306,7 @@ public class GdbPinProvider implements IPinProvider { final IProcessDMContext eventProcessDmc = getProcessDmc(eventDmc); if (eventProcessDmc != null) { - for (final IPinElementHandle h : gsPinnedHandles) { + for (final IPinElementHandle h : getPinnedHandles()) { new Job("Updating pin handler debug context") { //$NON-NLS-1$ {setPriority(INTERACTIVE);} @Override @@ -329,4 +336,66 @@ public class GdbPinProvider implements IPinProvider { } } } + + @DsfServiceEventHandler + public void handleEvent(final IExitedDMEvent event) { + doHandleEvent(event, IPinModelListener.EXITED); + } + + @DsfServiceEventHandler + public void handleEvent(final IResumedDMEvent event) { + doHandleEvent(event, IPinModelListener.RESUMED); + } + + private void doHandleEvent(IDMEvent event, final int notificationId) { + Set> entries = gsPinnedHandles.entrySet(); + for (final Entry e : entries) { + final IPinModelListener listener = e.getValue(); + if (listener != null) { + IPinElementHandle handle = e.getKey(); + + Object handleObject = handle.getDebugContext(); + if (handleObject instanceof IDMContext) { + IDMContext handleDmc = (IDMContext)handleObject; + IDMContext eventDmc = event.getDMContext(); + + // First check if we have a thread. We must use IMIExecutionDMContext and not + // IExecutionDMContext because IExecutionDMContext also represents a process + IMIExecutionDMContext execEventDmc = DMContexts.getAncestorOfType(eventDmc, IMIExecutionDMContext.class); + IMIExecutionDMContext execHandleDmc = DMContexts.getAncestorOfType(handleDmc, IMIExecutionDMContext.class); + + // Make sure both dmcs are not null to know if we should compare thread dmcs or container dmcs + if (execEventDmc != null && execHandleDmc != null) { + // It is a thread event, but is it the same as the pin handle? + if (execEventDmc.equals(execHandleDmc)) { + fireModleChangeEvent(listener, notificationId); + } + continue; + } + + // If we weren't dealing with a thread for either the event or the handle, + // let's check for IMIContainerDMContext + IMIContainerDMContext procEventDmc = DMContexts.getAncestorOfType(eventDmc, IMIContainerDMContext.class); + IMIContainerDMContext procHandleDmc = DMContexts.getAncestorOfType(handleDmc, IMIContainerDMContext.class); + if (procEventDmc != null && procHandleDmc != null) { + if (procEventDmc.equals(procHandleDmc)) { + fireModleChangeEvent(listener, notificationId); + } + continue; + } + } + } + } + } + + private void fireModleChangeEvent(final IPinModelListener listener, final int notificationId) { + new Job("Model Changed") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor arg0) { + listener.modelChanged(notificationId); + return Status.OK_STATUS; + } + }.schedule(); + } }