mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 09:16:02 +02:00
[302628] - [breakpoints][cdi] Implement linking of active debug context with selection in Breakpoints view.
This commit is contained in:
parent
a0dce915c6
commit
aa07b8ae87
9 changed files with 721 additions and 372 deletions
|
@ -57,7 +57,7 @@ public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
||||||
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
|
} else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
|
||||||
return new ModulesVMProvider(this, context, getSession());
|
return new ModulesVMProvider(this, context, getSession());
|
||||||
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
} else if (IDebugUIConstants.ID_BREAKPOINT_VIEW.equals(context.getId()) ) {
|
||||||
return new GdbBreakpointVMProvider(this, context);
|
return new GdbBreakpointVMProvider(this, context, getSession());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,29 +12,59 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
|
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.BreakpointVMProvider;
|
import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.BreakpointVMProvider;
|
||||||
|
import org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints.RawBreakpointVMNode;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.debug.core.DebugPlugin;
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
import org.eclipse.debug.core.model.IBreakpoint;
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class GdbBreakpointVMProvider extends BreakpointVMProvider {
|
public class GdbBreakpointVMProvider extends BreakpointVMProvider {
|
||||||
|
|
||||||
public GdbBreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext) {
|
final private DsfSession fSession;
|
||||||
|
|
||||||
|
final private DsfServicesTracker fServicesTracker;
|
||||||
|
|
||||||
|
public GdbBreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) {
|
||||||
super(adapter, presentationContext);
|
super(adapter, presentationContext);
|
||||||
|
fSession = session;
|
||||||
|
fServicesTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
fServicesTracker.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void calcFileteredBreakpoints(DataRequestMonitor<IBreakpoint[]> rm) {
|
protected void calcFileteredBreakpoints(DataRequestMonitor<IBreakpoint[]> rm) {
|
||||||
if (getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION) != null) {
|
if (Boolean.TRUE.equals(getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION))) {
|
||||||
IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
|
IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
|
||||||
List<IBreakpoint> filteredBPs = new ArrayList<IBreakpoint>(allBreakpoints.length);
|
List<IBreakpoint> filteredBPs = new ArrayList<IBreakpoint>(allBreakpoints.length);
|
||||||
for (IBreakpoint bp : allBreakpoints) {
|
for (IBreakpoint bp : allBreakpoints) {
|
||||||
|
@ -48,4 +78,71 @@ public class GdbBreakpointVMProvider extends BreakpointVMProvider {
|
||||||
super.calcFileteredBreakpoints(rm);
|
super.calcFileteredBreakpoints(rm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IVMNode createBreakpointVMNode() {
|
||||||
|
return new RawBreakpointVMNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getBreakpointsForDebugContext(ISelection debugContext, final DataRequestMonitor<IBreakpoint[]> rm) {
|
||||||
|
IExecutionDMContext _execCtx = null;
|
||||||
|
if (debugContext instanceof IStructuredSelection) {
|
||||||
|
Object element = ((IStructuredSelection)debugContext).getFirstElement();
|
||||||
|
if (element instanceof IDMVMContext) {
|
||||||
|
_execCtx = DMContexts.getAncestorOfType( ((IDMVMContext)element).getDMContext(), IExecutionDMContext.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_execCtx == null || !fSession.getId().equals(_execCtx.getSessionId())) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Debug context doesn't contain a thread", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final IExecutionDMContext execCtx = _execCtx;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fSession.getExecutor().execute(new DsfRunnable() {
|
||||||
|
public void run() {
|
||||||
|
IBreakpointsExtension bpService = fServicesTracker.getService(IBreakpointsExtension.class);
|
||||||
|
if (bpService == null) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Breakpoints service not available", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bpService.getExecutionContextBreakpoints(
|
||||||
|
execCtx,
|
||||||
|
new DataRequestMonitor<IBreakpoints.IBreakpointDMContext[]>(fSession.getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
MIBreakpointsManager bpManager = fServicesTracker.getService(MIBreakpointsManager.class);
|
||||||
|
if (bpManager == null) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Breakpoints service not available", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBreakpoint bp = null;
|
||||||
|
|
||||||
|
|
||||||
|
if (getData().length > 0) {
|
||||||
|
bp = bpManager.findPlatformBreakpoint(getData()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp != null) {
|
||||||
|
rm.setData(new IBreakpoint[] { bp });
|
||||||
|
} else {
|
||||||
|
rm.setData(new IBreakpoint[0]);
|
||||||
|
}
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e)); //$NON-NLS-1$ //$NON-NLS-2$);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,299 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.ModelProxyInstalledEvent;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||||
|
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
|
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||||
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||||
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||||
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
||||||
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||||
|
import org.eclipse.debug.ui.DebugUITools;
|
||||||
|
import org.eclipse.debug.ui.contexts.DebugContextEvent;
|
||||||
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.ui.IWorkbenchWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for breakpoint VM Nodes. Concrete implementations must
|
||||||
|
* implement the breakpoint object to be populated into the view.
|
||||||
|
* Also this node only implements the content provider so sub-classes
|
||||||
|
* must also implement a label provider, element editor, etc.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public abstract class AbstractBreakpointVMNode extends AbstractVMNode {
|
||||||
|
|
||||||
|
public AbstractBreakpointVMNode(BreakpointVMProvider provider) {
|
||||||
|
super(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that creates the element object for the corresponding breakpoints.
|
||||||
|
* This element object will be populated in the breakpoitns view to represent
|
||||||
|
* the given breakpoint.
|
||||||
|
*/
|
||||||
|
abstract protected Object createBreakpiontElement(IBreakpoint bp);
|
||||||
|
|
||||||
|
public void update(final IHasChildrenUpdate[] updates) {
|
||||||
|
for (final IHasChildrenUpdate update : updates) {
|
||||||
|
if (!checkUpdate(update)) continue;
|
||||||
|
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||||
|
update.getElementPath(),
|
||||||
|
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (isSuccess()) {
|
||||||
|
update.setHasChilren(getData().length != 0);
|
||||||
|
} else {
|
||||||
|
update.setHasChilren(false);
|
||||||
|
}
|
||||||
|
update.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(final IChildrenCountUpdate[] updates) {
|
||||||
|
for (final IChildrenCountUpdate update : updates) {
|
||||||
|
if (!checkUpdate(update)) continue;
|
||||||
|
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||||
|
update.getElementPath(),
|
||||||
|
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (isSuccess()) {
|
||||||
|
update.setChildCount(getData().length);
|
||||||
|
} else {
|
||||||
|
update.setChildCount(0);
|
||||||
|
}
|
||||||
|
update.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(IChildrenUpdate[] updates) {
|
||||||
|
for (final IChildrenUpdate update : updates) {
|
||||||
|
if (!checkUpdate(update)) continue;
|
||||||
|
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
||||||
|
update.getElementPath(),
|
||||||
|
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (isSuccess()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Comparator<Object> comparator =
|
||||||
|
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
|
||||||
|
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
||||||
|
if (comparator != null) {
|
||||||
|
Arrays.sort(getData(), comparator);
|
||||||
|
}
|
||||||
|
fillUpdateWithBreakpointElements(update, getData());
|
||||||
|
}
|
||||||
|
update.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillUpdateWithBreakpointElements(IChildrenUpdate update, IBreakpoint[] bps) {
|
||||||
|
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
||||||
|
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
|
||||||
|
while (updateIdx < endIdx && updateIdx < bps.length) {
|
||||||
|
update.setChild(createBreakpiontElement(bps[updateIdx]), updateIdx);
|
||||||
|
updateIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDeltaFlags(Object event) {
|
||||||
|
if (event instanceof BreakpointsChangedEvent) {
|
||||||
|
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||||
|
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||||
|
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||||
|
}
|
||||||
|
return IModelDelta.CONTENT;
|
||||||
|
}
|
||||||
|
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||||
|
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||||
|
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||||
|
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||||
|
{
|
||||||
|
return IModelDelta.CONTENT;
|
||||||
|
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||||
|
return IModelDelta.EXPAND | IModelDelta.CONTENT;
|
||||||
|
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION.equals(propertyEvent.getProperty()) &&
|
||||||
|
Boolean.TRUE.equals(propertyEvent.getNewValue()) )
|
||||||
|
{
|
||||||
|
return IModelDelta.EXPAND | IModelDelta.SELECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event instanceof DebugContextEvent && (((DebugContextEvent)event).getFlags() | DebugContextEvent.ACTIVATED) != 0) {
|
||||||
|
int flags = IModelDelta.NO_CHANGE;
|
||||||
|
if ( Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
|
||||||
|
flags |= IModelDelta.CONTENT;
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
|
||||||
|
flags |= IModelDelta.EXPAND | IModelDelta.SELECT;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
} else if (event instanceof ModelProxyInstalledEvent) {
|
||||||
|
// Upon model proxy installed, check whether we need to select a
|
||||||
|
// breakpoint in linking with Debug view
|
||||||
|
if (Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
|
||||||
|
return IModelDelta.EXPAND | IModelDelta.SELECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
|
||||||
|
if (event instanceof BreakpointsChangedEvent) {
|
||||||
|
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
||||||
|
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
||||||
|
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
|
||||||
|
// Do not call rm.done() in this method!
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
||||||
|
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||||
|
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
||||||
|
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
||||||
|
{
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||||
|
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
|
||||||
|
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION.equals(propertyEvent.getProperty()) &&
|
||||||
|
Boolean.TRUE.equals(propertyEvent.getNewValue()) )
|
||||||
|
{
|
||||||
|
IWorkbenchWindow window = getVMProvider().getPresentationContext().getWindow();
|
||||||
|
if (window != null) {
|
||||||
|
ISelection activeContext = DebugUITools.getDebugContextManager().getContextService(window).getActiveContext();
|
||||||
|
buildTrackSelectionDelta(activeContext, parent, nodeOffset, rm);
|
||||||
|
// Do not call rm.done() in this method!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event instanceof DebugContextEvent && (((DebugContextEvent)event).getFlags() | DebugContextEvent.ACTIVATED) != 0) {
|
||||||
|
if ( Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION)) ) {
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
|
||||||
|
buildTrackSelectionDelta(((DebugContextEvent)event).getContext(), parent, nodeOffset, rm);
|
||||||
|
// Do not call rm.done() in this method!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (event instanceof ModelProxyInstalledEvent) {
|
||||||
|
if (Boolean.TRUE.equals(getVMProvider().getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_TRACK_SELECTION)) ) {
|
||||||
|
IWorkbenchWindow window = getVMProvider().getPresentationContext().getWindow();
|
||||||
|
if (window != null) {
|
||||||
|
ISelection activeContext = DebugUITools.getDebugContextManager().getContextService(window).getActiveContext();
|
||||||
|
buildTrackSelectionDelta(activeContext, parent, nodeOffset, rm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
||||||
|
getVMProvider().updateNode(this, new VMChildrenUpdate(
|
||||||
|
parent, getVMProvider().getPresentationContext(), -1, -1,
|
||||||
|
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
for (int i = 0; i < event.getBreakpoints().length; i++) {
|
||||||
|
IBreakpoint eventBp = event.getBreakpoints()[i];
|
||||||
|
int bpIndex = findBreakpointIndex(eventBp, getData());
|
||||||
|
if (bpIndex >= 0) {
|
||||||
|
// Select only the first breakpoint that was added
|
||||||
|
if (i == 0) {
|
||||||
|
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
||||||
|
}
|
||||||
|
// For all other added breakpoints, expand the parent.
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void buildTrackSelectionDelta(ISelection debugContext, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
||||||
|
assert getVMProvider() instanceof BreakpointVMProvider;
|
||||||
|
|
||||||
|
((BreakpointVMProvider)getVMProvider()).getBreakpointsForDebugContext(
|
||||||
|
debugContext,
|
||||||
|
new DataRequestMonitor<IBreakpoint[]>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
if (getData().length == 0) {
|
||||||
|
// No breakpoints to select, we're done.
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final IBreakpoint[] bpsToSelect = getData();
|
||||||
|
|
||||||
|
getVMProvider().updateNode(AbstractBreakpointVMNode.this, new VMChildrenUpdate(
|
||||||
|
parent, getVMProvider().getPresentationContext(), -1, -1,
|
||||||
|
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
for (int i = 0; i < bpsToSelect.length; i++) {
|
||||||
|
int bpIndex = findBreakpointIndex(bpsToSelect[i], getData());
|
||||||
|
if (bpIndex >= 0) {
|
||||||
|
// Select only the first breakpoint that was added
|
||||||
|
if (i == 0) {
|
||||||
|
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
||||||
|
}
|
||||||
|
// For all other added breakpoints, expand the parent.
|
||||||
|
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleErrorOrWarning() {
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findBreakpointIndex(IBreakpoint bp, List<Object> bpElements) {
|
||||||
|
for (int j = 0; j < bpElements.size(); j++) {
|
||||||
|
IBreakpoint elementBp = (IBreakpoint)DebugPlugin.getAdapter(bpElements.get(j), IBreakpoint.class);
|
||||||
|
if (elementBp != null && elementBp.equals(bp)) {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,11 +11,9 @@
|
||||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMAdapter;
|
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||||
import org.eclipse.core.runtime.Platform;
|
|
||||||
import org.eclipse.core.runtime.PlatformObject;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||||
|
@ -23,12 +21,17 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRe
|
||||||
/**
|
/**
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public class BreakpointVMInput extends PlatformObject implements IElementMementoProvider {
|
public class BreakpointVMInput extends AbstractVMContext implements IElementMementoProvider, IDMVMContext {
|
||||||
|
|
||||||
private IVMNode fVMNode;
|
final private IDMContext fDMContext;
|
||||||
|
|
||||||
public BreakpointVMInput(IVMNode node, IDMContext activeDMContext) {
|
public BreakpointVMInput(IVMNode node, IDMContext dmc) {
|
||||||
fVMNode = node;
|
super(node);
|
||||||
|
fDMContext = dmc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDMContext getDMContext() {
|
||||||
|
return fDMContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encodeElements(IElementMementoRequest[] requests) {
|
public void encodeElements(IElementMementoRequest[] requests) {
|
||||||
|
@ -45,34 +48,13 @@ public class BreakpointVMInput extends PlatformObject implements IElementMemento
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings({"rawtypes" })
|
|
||||||
public Object getAdapter(Class adapter) {
|
|
||||||
// If the context implements the given adapter directly, it always takes
|
|
||||||
// precedence.
|
|
||||||
if (adapter.isInstance(this)) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
IVMProvider vmProvider = fVMNode.getVMProvider();
|
|
||||||
IVMAdapter vmAdapter = vmProvider.getVMAdapter();
|
|
||||||
if (adapter.isInstance(vmAdapter)) {
|
|
||||||
return vmAdapter;
|
|
||||||
} else if (adapter.isInstance(vmProvider)) {
|
|
||||||
return vmProvider;
|
|
||||||
} else if (adapter.isInstance(fVMNode)) {
|
|
||||||
return fVMNode;
|
|
||||||
}
|
|
||||||
return Platform.getAdapterManager().getAdapter(this, adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return obj instanceof BreakpointVMInput;
|
return obj instanceof BreakpointVMInput && ((BreakpointVMInput)obj).getDMContext().equals(fDMContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return getClass().hashCode();
|
return fDMContext.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,123 +11,41 @@
|
||||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.debug.core.model.IBreakpoint;
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
|
||||||
import org.eclipse.jface.viewers.TreePath;
|
import org.eclipse.jface.viewers.TreePath;
|
||||||
import org.eclipse.swt.graphics.FontData;
|
import org.eclipse.swt.graphics.FontData;
|
||||||
import org.eclipse.swt.graphics.RGB;
|
import org.eclipse.swt.graphics.RGB;
|
||||||
import org.eclipse.ui.IMemento;
|
import org.eclipse.ui.IMemento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Breakpiont VM Node which uses VM Contexts to populate breakpoint elements
|
||||||
|
* in the view. Any actions or other selection listeners which depend on the
|
||||||
|
* breakpoint object will not work with these elements unless they use the
|
||||||
|
* adapter mechanism to obtain the breakpoints.
|
||||||
*
|
*
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public class BreakpointVMNode extends AbstractVMNode implements IElementLabelProvider, IElementMementoProvider {
|
public class BreakpointVMNode extends AbstractBreakpointVMNode implements IElementLabelProvider, IElementMementoProvider {
|
||||||
|
|
||||||
public BreakpointVMNode(IVMProvider provider) {
|
public BreakpointVMNode(BreakpointVMProvider provider) {
|
||||||
super(provider);
|
super(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final IHasChildrenUpdate[] updates) {
|
|
||||||
for (final IHasChildrenUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected Object createBreakpiontElement(IBreakpoint bp) {
|
||||||
if (isSuccess()) {
|
|
||||||
update.setHasChilren(getData().length != 0);
|
|
||||||
} else {
|
|
||||||
update.setHasChilren(false);
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(final IChildrenCountUpdate[] updates) {
|
|
||||||
for (final IChildrenCountUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
|
||||||
protected void handleCompleted() {
|
|
||||||
if (isSuccess()) {
|
|
||||||
update.setChildCount(getData().length);
|
|
||||||
} else {
|
|
||||||
update.setChildCount(0);
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(IChildrenUpdate[] updates) {
|
|
||||||
for (final IChildrenUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
|
||||||
protected void handleCompleted() {
|
|
||||||
if (isSuccess()) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Comparator<Object> comparator =
|
|
||||||
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
|
||||||
if (comparator != null) {
|
|
||||||
Arrays.sort(getData(), comparator);
|
|
||||||
}
|
|
||||||
fillUpdateWithBreakpointVMCs(update, getData());
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillUpdateWithBreakpointVMCs(IChildrenUpdate update, IBreakpoint[] bps) {
|
|
||||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
|
||||||
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
|
|
||||||
while (updateIdx < endIdx && updateIdx < bps.length) {
|
|
||||||
update.setChild(createVMContext(bps[updateIdx]), updateIdx);
|
|
||||||
updateIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BreakpointVMContext createVMContext(IBreakpoint bp) {
|
|
||||||
return new BreakpointVMContext(this, bp);
|
return new BreakpointVMContext(this, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,71 +170,4 @@ public class BreakpointVMNode extends AbstractVMNode implements IElementLabelPro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDeltaFlags(Object event) {
|
|
||||||
if (event instanceof BreakpointsChangedEvent) {
|
|
||||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
|
||||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
|
||||||
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
|
|
||||||
}
|
|
||||||
return IModelDelta.CONTENT;
|
|
||||||
}
|
|
||||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
|
||||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
|
||||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
|
||||||
{
|
|
||||||
return IModelDelta.CONTENT;
|
|
||||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
|
||||||
return IModelDelta.EXPAND | IModelDelta.CONTENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
|
|
||||||
if (event instanceof BreakpointsChangedEvent) {
|
|
||||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
|
||||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
|
||||||
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
|
|
||||||
// Do not call rm.done() in this method!
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
|
||||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
|
||||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
|
||||||
{
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
|
||||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
|
||||||
getVMProvider().updateNode(this, new VMChildrenUpdate(
|
|
||||||
parent, getVMProvider().getPresentationContext(), -1, -1,
|
|
||||||
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
|
||||||
@Override
|
|
||||||
protected void handleSuccess() {
|
|
||||||
for (int i = 0; i < event.getBreakpoints().length; i++) {
|
|
||||||
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
|
|
||||||
if (bpIndex >= 0) {
|
|
||||||
// Select only the first breakpoint that was added
|
|
||||||
if (i == 0) {
|
|
||||||
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
|
||||||
}
|
|
||||||
// For all other added breakpoints, expand the parent.
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,17 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataCache;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode;
|
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode;
|
||||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
|
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
|
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||||
|
@ -42,15 +42,20 @@ import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
|
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory;
|
import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory;
|
||||||
|
import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
|
||||||
|
import org.eclipse.debug.ui.DebugUITools;
|
||||||
import org.eclipse.debug.ui.IBreakpointOrganizerDelegate;
|
import org.eclipse.debug.ui.IBreakpointOrganizerDelegate;
|
||||||
|
import org.eclipse.debug.ui.contexts.DebugContextEvent;
|
||||||
|
import org.eclipse.debug.ui.contexts.IDebugContextListener;
|
||||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
import org.eclipse.jface.viewers.TreePath;
|
import org.eclipse.jface.viewers.TreePath;
|
||||||
|
import org.eclipse.ui.IWorkbenchWindow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expression provider is used to populate the contents of the expressions
|
* The expression provider is used to populate the contents of the expressions
|
||||||
|
@ -88,6 +93,12 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private IDebugContextListener fDebugContextListener = new IDebugContextListener() {
|
||||||
|
public void debugContextChanged(final DebugContextEvent event) {
|
||||||
|
handleEventInExecThread(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private class ContainerBreakpointsCache extends DataCache<List<BreakpointOrganizerVMContext>> {
|
private class ContainerBreakpointsCache extends DataCache<List<BreakpointOrganizerVMContext>> {
|
||||||
|
|
||||||
private BreakpointOrganizerVMNode fOrganizerVMNode;
|
private BreakpointOrganizerVMNode fOrganizerVMNode;
|
||||||
|
@ -169,9 +180,21 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) {
|
public BreakpointVMProvider(AbstractVMAdapter adapter, IPresentationContext context) {
|
||||||
super(adapter, context);
|
super(adapter, context);
|
||||||
|
|
||||||
|
// Create the top level node which provides the anchor starting point.
|
||||||
|
// This node is referenced by the BreakpointVMInput element so it
|
||||||
|
// should not change when the view layout is updated.
|
||||||
|
setRootNode(new RootDMVMNode(this));
|
||||||
|
// Configure the rest of the layout nodes.
|
||||||
configureLayout();
|
configureLayout();
|
||||||
|
|
||||||
context.addPropertyChangeListener(fPresentationContextListener);
|
context.addPropertyChangeListener(fPresentationContextListener);
|
||||||
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener);
|
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(fBreakpointsListener);
|
||||||
|
IWorkbenchWindow window = context.getWindow();
|
||||||
|
if (window != null) {
|
||||||
|
DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener(
|
||||||
|
fDebugContextListener);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -188,15 +211,10 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
* sub classes to create an alternate configuration in this provider.
|
* sub classes to create an alternate configuration in this provider.
|
||||||
*/
|
*/
|
||||||
protected void configureLayout() {
|
protected void configureLayout() {
|
||||||
/*
|
|
||||||
* Create the top level node which provides the anchor starting point.
|
|
||||||
*/
|
|
||||||
IRootVMNode rootNode = new RootDMVMNode(this);
|
|
||||||
|
|
||||||
IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])
|
IBreakpointOrganizer[] organizers = (IBreakpointOrganizer[])
|
||||||
getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
|
getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS);
|
||||||
|
|
||||||
IVMNode parentNode = rootNode;
|
IVMNode parentNode = getRootVMNode();
|
||||||
if (organizers != null) {
|
if (organizers != null) {
|
||||||
for (IBreakpointOrganizer organizer : organizers) {
|
for (IBreakpointOrganizer organizer : organizers) {
|
||||||
IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer);
|
IVMNode organizerNode = new BreakpointOrganizerVMNode(this, organizer);
|
||||||
|
@ -207,11 +225,6 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
|
|
||||||
IVMNode bpsNode = createBreakpointVMNode();
|
IVMNode bpsNode = createBreakpointVMNode();
|
||||||
addChildNodes(parentNode, new IVMNode[] {bpsNode});
|
addChildNodes(parentNode, new IVMNode[] {bpsNode});
|
||||||
|
|
||||||
/*
|
|
||||||
* Let the work know which is the top level node.
|
|
||||||
*/
|
|
||||||
setRootNode(rootNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,6 +232,11 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
|
getPresentationContext().removePropertyChangeListener(fPresentationContextListener);
|
||||||
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener);
|
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(fBreakpointsListener);
|
||||||
|
IWorkbenchWindow window = getPresentationContext().getWindow();
|
||||||
|
if (window != null) {
|
||||||
|
DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener(
|
||||||
|
fDebugContextListener);
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,15 +252,18 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(IViewerInputUpdate update) {
|
public void update(IViewerInputUpdate update) {
|
||||||
IStructuredSelection filterSelection = (IStructuredSelection)
|
|
||||||
update.getPresentationContext().getProperty(IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION);
|
|
||||||
IDMContext activeDMContext = null;
|
IDMContext activeDMContext = null;
|
||||||
if (filterSelection != null) {
|
|
||||||
if (update.getElement() instanceof IDMVMContext) {
|
if (update.getElement() instanceof IDMVMContext) {
|
||||||
activeDMContext = ((IDMVMContext)update.getElement()).getDMContext();
|
activeDMContext = ((IDMVMContext)update.getElement()).getDMContext();
|
||||||
|
activeDMContext = DMContexts.getAncestorOfType(activeDMContext, IBreakpointsTargetDMContext.class);
|
||||||
}
|
}
|
||||||
}
|
if (activeDMContext != null) {
|
||||||
update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext));
|
update.setInputElement(new BreakpointVMInput(getRootVMNode(), activeDMContext));
|
||||||
|
} else {
|
||||||
|
// If no breakpoints target found in active context, delegate the breakpoint
|
||||||
|
// presentation to the default: breakpoint manager.
|
||||||
|
update.setInputElement(new DefaultBreakpointsViewInput(update.getPresentationContext()));
|
||||||
|
}
|
||||||
update.done();
|
update.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,6 +327,11 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getBreakpointsForDebugContext(ISelection debugContext, DataRequestMonitor<IBreakpoint[]> rm) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
public void handleEventInExecThread(final Object event) {
|
public void handleEventInExecThread(final Object event) {
|
||||||
getExecutor().execute(new DsfRunnable() {
|
getExecutor().execute(new DsfRunnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -320,7 +346,7 @@ public class BreakpointVMProvider extends AbstractVMProvider
|
||||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
||||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
|
if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty()))
|
||||||
{
|
{
|
||||||
clearNodes();
|
clearNodes(false);
|
||||||
configureLayout();
|
configureLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
|
import org.eclipse.cdt.dsf.internal.DsfPlugin;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A general purpose cache, which caches the result of a single request.
|
||||||
|
* Sub classes need to implement {@link #retrieve(DataRequestMonitor)} to fetch
|
||||||
|
* data from the data source. Clients are responsible for calling
|
||||||
|
* {@link #disable()} and {@link #reset()} to manage the state of the cache in
|
||||||
|
* response to events from the data source.
|
||||||
|
* <p>
|
||||||
|
* This cache requires an executor to use. The executor is used to synchronize
|
||||||
|
* access to the cache state and data.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* This class is intended as a general utility, but it's not quite ready for
|
||||||
|
* API, so it's just private class for now.
|
||||||
|
* </p>
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
@ConfinedToDsfExecutor("fExecutor")
|
||||||
|
abstract class DataCache<V> {
|
||||||
|
|
||||||
|
final private Executor fExecutor;
|
||||||
|
|
||||||
|
private boolean fValid;
|
||||||
|
|
||||||
|
protected DataRequestMonitor<V> fRm;
|
||||||
|
private V fData;
|
||||||
|
private IStatus fStatus;
|
||||||
|
|
||||||
|
private List<DataRequestMonitor<V>> fWaitingList = new LinkedList<DataRequestMonitor<V>>();
|
||||||
|
|
||||||
|
public DataCache(Executor executor) {
|
||||||
|
fExecutor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sub-classes should override this method to retrieve the cache data
|
||||||
|
* from its source.
|
||||||
|
*
|
||||||
|
* @param rm Request monitor for completion of data retrieval.
|
||||||
|
*/
|
||||||
|
protected abstract void retrieve(DataRequestMonitor<V> rm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the cache is currently valid. I.e.
|
||||||
|
* whether the cache can return a value immediately without first
|
||||||
|
* retrieving it from the data source.
|
||||||
|
*/
|
||||||
|
public boolean isValid() {
|
||||||
|
return fValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the cache is currently waiting for data
|
||||||
|
* from the data source.
|
||||||
|
*/
|
||||||
|
public boolean isPending() {
|
||||||
|
return fRm != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current data value held by this cache. Clients should first
|
||||||
|
* call isValid() to determine if the data is up to date.
|
||||||
|
*/
|
||||||
|
public V getData() {
|
||||||
|
return fData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the status of the source request held by this cache. Clients
|
||||||
|
* should first call isValid() to determine if the data is up to date.
|
||||||
|
*/
|
||||||
|
public IStatus getStatus() {
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request data from the cache. The cache is valid, it will complete the
|
||||||
|
* request immediately, otherwise data will first be retrieved from the
|
||||||
|
* source.
|
||||||
|
* @param req
|
||||||
|
*/
|
||||||
|
public void request(final DataRequestMonitor<V> rm) {
|
||||||
|
if (!fValid) {
|
||||||
|
boolean first = fWaitingList.isEmpty();
|
||||||
|
fWaitingList.add(rm);
|
||||||
|
if(first) {
|
||||||
|
fRm = new DataRequestMonitor<V>(fExecutor, null) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (!isCanceled()) {
|
||||||
|
fValid = true;
|
||||||
|
fRm = null;
|
||||||
|
set(getData(), getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
retrieve(fRm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rm.setData(fData);
|
||||||
|
rm.setStatus(fStatus);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void set(V data, IStatus status) {
|
||||||
|
fData = data;
|
||||||
|
fStatus = status;
|
||||||
|
List<DataRequestMonitor<V>> waitingList = fWaitingList;
|
||||||
|
fWaitingList = new LinkedList<DataRequestMonitor<V>>();
|
||||||
|
|
||||||
|
for (DataRequestMonitor<V> rm : waitingList) {
|
||||||
|
rm.setData(data);
|
||||||
|
rm.setStatus(status);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the cache with a data value <code>null</code> and an error
|
||||||
|
* status with code {@link IDsfStatusConstants#INVALID_STATE}.
|
||||||
|
*
|
||||||
|
* @see #reset(Object, IStatus)
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
reset(null, new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache reset", null)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the cache with given data and status. Resetting the cache
|
||||||
|
* forces the cache to be invalid and cancels any current pending requests
|
||||||
|
* from data source.
|
||||||
|
* <p>
|
||||||
|
* This method should be called when the data source has issued an event
|
||||||
|
* indicating that the source data has changed but data may still be
|
||||||
|
* retrieved. Clients may need to re-request data following cache reset.
|
||||||
|
* </p>
|
||||||
|
* @param data The data that should be returned to any clients currently
|
||||||
|
* waiting for cache data.
|
||||||
|
* @status The status that should be returned to any clients currently
|
||||||
|
* waiting for cache data.
|
||||||
|
*/
|
||||||
|
public void reset(V data, IStatus status) {
|
||||||
|
fValid = false;
|
||||||
|
if (fRm != null) {
|
||||||
|
fRm.cancel();
|
||||||
|
fRm = null;
|
||||||
|
}
|
||||||
|
set(data, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the cache from retrieving data from the source. If the cache
|
||||||
|
* is already valid the data and status is retained. If the cache is not
|
||||||
|
* valid, then data value <code>null</code> and an error status with code
|
||||||
|
* {@link IDsfStatusConstants#INVALID_STATE} are set.
|
||||||
|
*
|
||||||
|
* @see #disable(Object, IStatus)
|
||||||
|
*/
|
||||||
|
public void disable() {
|
||||||
|
//TODO: better.
|
||||||
|
|
||||||
|
V data;
|
||||||
|
IStatus status;
|
||||||
|
if (fValid) {
|
||||||
|
data = getData();
|
||||||
|
status = getStatus();
|
||||||
|
} else {
|
||||||
|
data = null;
|
||||||
|
status = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Cache disable", null); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
disable(data, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the cache then disables it. When a cache is disabled it means
|
||||||
|
* that it is valid and requests to the data source will not be sent.
|
||||||
|
* <p>
|
||||||
|
* This method should be called when the data source has issued an event
|
||||||
|
* indicating that the source data has changed and future requests for
|
||||||
|
* data will return the given data and status. Once the source data
|
||||||
|
* becomes available again, clients should call {@link #reset()}.
|
||||||
|
* </p>
|
||||||
|
* @param data The data that should be returned to any clients waiting for
|
||||||
|
* cache data and for clients requesting data until the cache is reset again.
|
||||||
|
* @status The status that should be returned to any clients waiting for
|
||||||
|
* cache data and for clients requesting data until the cache is reset again.
|
||||||
|
*
|
||||||
|
* @see #reset(Object, IStatus)
|
||||||
|
*/
|
||||||
|
public void disable(V data, IStatus status) {
|
||||||
|
reset(data, status);
|
||||||
|
fValid = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,172 +10,24 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
package org.eclipse.cdt.dsf.debug.ui.viewmodel.breakpoints;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
|
||||||
import org.eclipse.debug.core.model.IBreakpoint;
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Breakpoint node which uses raw breakpiont objects (without a wrapper) as
|
||||||
|
* elements which are populated into the view. The breakpoint objects are
|
||||||
|
* responsible for supplying their own label and memento providers, as well
|
||||||
|
* as content provider for any children.
|
||||||
*
|
*
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public class RawBreakpointVMNode extends AbstractVMNode {
|
public class RawBreakpointVMNode extends AbstractBreakpointVMNode {
|
||||||
|
|
||||||
public RawBreakpointVMNode(IVMProvider provider) {
|
public RawBreakpointVMNode(BreakpointVMProvider provider) {
|
||||||
super(provider);
|
super(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final IHasChildrenUpdate[] updates) {
|
|
||||||
for (final IHasChildrenUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected Object createBreakpiontElement(IBreakpoint bp) {
|
||||||
if (isSuccess()) {
|
return bp;
|
||||||
update.setHasChilren(getData().length != 0);
|
|
||||||
} else {
|
|
||||||
update.setHasChilren(false);
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(final IChildrenCountUpdate[] updates) {
|
|
||||||
for (final IChildrenCountUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
|
||||||
protected void handleCompleted() {
|
|
||||||
if (isSuccess()) {
|
|
||||||
update.setChildCount(getData().length);
|
|
||||||
} else {
|
|
||||||
update.setChildCount(0);
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(IChildrenUpdate[] updates) {
|
|
||||||
for (final IChildrenUpdate update : updates) {
|
|
||||||
if (!checkUpdate(update)) continue;
|
|
||||||
((BreakpointVMProvider)getVMProvider()).getNestingCategoryBreakpoints(
|
|
||||||
update.getElementPath(),
|
|
||||||
new ViewerDataRequestMonitor<IBreakpoint[]>(getExecutor(), update) {
|
|
||||||
@Override
|
|
||||||
protected void handleCompleted() {
|
|
||||||
if (isSuccess()) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Comparator<Object> comparator =
|
|
||||||
(Comparator<Object>)getVMProvider().getPresentationContext().getProperty(
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR);
|
|
||||||
if (comparator != null) {
|
|
||||||
Arrays.sort(getData(), comparator);
|
|
||||||
}
|
|
||||||
fillUpdateWithBreakpoints(update, getData());
|
|
||||||
}
|
|
||||||
update.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillUpdateWithBreakpoints(IChildrenUpdate update, IBreakpoint[] bps) {
|
|
||||||
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
|
|
||||||
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : bps.length);
|
|
||||||
while (updateIdx < endIdx && updateIdx < bps.length) {
|
|
||||||
update.setChild(bps[updateIdx], updateIdx);
|
|
||||||
updateIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDeltaFlags(Object event) {
|
|
||||||
if (event instanceof BreakpointsChangedEvent) {
|
|
||||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
|
||||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
|
||||||
return IModelDelta.CONTENT | IModelDelta.SELECT | IModelDelta.EXPAND;
|
|
||||||
}
|
|
||||||
return IModelDelta.CONTENT;
|
|
||||||
}
|
|
||||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
|
||||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
|
||||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
|
||||||
{
|
|
||||||
return IModelDelta.CONTENT;
|
|
||||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
|
||||||
return IModelDelta.EXPAND | IModelDelta.CONTENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
|
|
||||||
if (event instanceof BreakpointsChangedEvent) {
|
|
||||||
BreakpointsChangedEvent bpChangedEvent = ((BreakpointsChangedEvent)event);
|
|
||||||
if (BreakpointsChangedEvent.Type.ADDED.equals(bpChangedEvent.getType())) {
|
|
||||||
buildBreakpointAddedDelta(bpChangedEvent, parent, nodeOffset, rm);
|
|
||||||
// Do not call rm.done() in this method!
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (BreakpointVMProvider.isPresentationContextEvent(event)) {
|
|
||||||
PropertyChangeEvent propertyEvent = (PropertyChangeEvent)event;
|
|
||||||
if (IBreakpointUIConstants.PROP_BREAKPOINTS_FILTER_SELECTION.equals(propertyEvent.getProperty()) ||
|
|
||||||
IBreakpointUIConstants.PROP_BREAKPOINTS_ELEMENT_COMPARATOR.equals(propertyEvent.getProperty()))
|
|
||||||
{
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
|
|
||||||
} else if (IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS.equals(propertyEvent.getProperty())) {
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.EXPAND | IModelDelta.CONTENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildBreakpointAddedDelta(final BreakpointsChangedEvent event, final VMDelta parent, final int nodeOffset, final RequestMonitor rm) {
|
|
||||||
getVMProvider().updateNode(this, new VMChildrenUpdate(
|
|
||||||
parent, getVMProvider().getPresentationContext(), -1, -1,
|
|
||||||
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
|
||||||
@Override
|
|
||||||
protected void handleSuccess() {
|
|
||||||
for (int i = 0; i < event.getBreakpoints().length; i++) {
|
|
||||||
int bpIndex = getData().indexOf(event.getBreakpoints()[i]);
|
|
||||||
if (bpIndex >= 0) {
|
|
||||||
// Select only the first breakpoint that was added
|
|
||||||
if (i == 0) {
|
|
||||||
parent.addNode(getData().get(bpIndex), bpIndex, IModelDelta.SELECT);
|
|
||||||
}
|
|
||||||
// For all other added breakpoints, expand the parent.
|
|
||||||
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT | IModelDelta.EXPAND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,10 +484,11 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all configured nodes. This allows a subclass to reset and
|
* Clears all configured nodes, including the root node. This allows a
|
||||||
* reconfigure its nodes.
|
* subclass to reset and reconfigure its nodes.
|
||||||
*/
|
*/
|
||||||
protected void clearNodes() {
|
protected void clearNodes() {
|
||||||
|
clearNodes(true);
|
||||||
for (IVMNode node : fChildNodesMap.keySet()) {
|
for (IVMNode node : fChildNodesMap.keySet()) {
|
||||||
node.dispose();
|
node.dispose();
|
||||||
}
|
}
|
||||||
|
@ -495,6 +496,27 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
||||||
fRootNode = null;
|
fRootNode = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all configured nodes. This allows a subclass to reset and
|
||||||
|
* reconfigure its nodes.
|
||||||
|
*
|
||||||
|
* @param clearRootNode Flag indicating whether to also clear the root node.
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected void clearNodes(boolean clearRootNode) {
|
||||||
|
for (IVMNode node : fChildNodesMap.keySet()) {
|
||||||
|
if ( !clearRootNode || !node.equals(getRootVMNode()) ) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fChildNodesMap.clear();
|
||||||
|
if (clearRootNode) {
|
||||||
|
fRootNode = null;
|
||||||
|
} else {
|
||||||
|
fChildNodesMap.put(getRootVMNode(), EMPTY_NODES_ARRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the root node for this provider.
|
* Sets the root node for this provider.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue