1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Bug 338472 - [Pin&Clone] Pinned view should blank out when session terminated

This commit is contained in:
Patrick Chuong 2011-03-04 16:45:10 +00:00
parent c57cf3cce3
commit 38f65aca63
4 changed files with 135 additions and 31 deletions

View file

@ -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<IPinElementHandle, IPinProvider>();
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<IPinElementHandle> pin(IWorkbenchPart part, ISelection selection) {
private Set<IPinElementHandle> pin(IWorkbenchPart part, ISelection selection, IPinModelListener listener) {
Set<IPinElementHandle> handles = new HashSet<IPinElementHandle>();
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);
}
});
}
}

View file

@ -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();

View file

@ -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.
* <br><br>
* 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 <code>pin</code> method with the selected debug context.
* If more than one debug context is selected, than <code>pin</code> is called multiple times.
* The <code>pin</code> method should returns a handle for the pinned debug context and when
* If more than one debug context is selected, the <code>pin</code> method is called multiple times.
* The <code>pin</code> 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,
* <code>isPinnedTo</code> will be call by the DebugEventFilterService to determine whether the
* debug context in question is pinned to the handle returned by the <code>pin</code> 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 <code>null</code>.
* If <code>null</code>, than the default image description will be use.
* If <code>null</code>, 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

View file

@ -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<IPinElementHandle> gsPinnedHandles = Collections.synchronizedSet(new HashSet<IPinElementHandle>());
private static Map<IPinElementHandle, IPinModelListener> gsPinnedHandles =
Collections.synchronizedMap(new HashMap<IPinElementHandle, IPinModelListener>());
/**
* Dsf session.
@ -106,7 +113,7 @@ public class GdbPinProvider implements IPinProvider {
* @return the element handles.
*/
public static Set<IPinElementHandle> 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<Entry<IPinElementHandle, IPinModelListener>> entries = gsPinnedHandles.entrySet();
for (final Entry<IPinElementHandle, IPinModelListener> 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();
}
}