1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

[225650] - [view model] Convert debug views' view model implementation to use IElementPropertyProvider.

This commit is contained in:
Pawel Piech 2009-03-10 23:47:17 +00:00
parent 445fc4b23a
commit 081d4ed5ac
85 changed files with 3679 additions and 2847 deletions

View file

@ -16,29 +16,32 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractContainerVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMDelegatingPropertiesUpdate;
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.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.ui.IMemento;
@ -79,50 +82,56 @@ public class ContainerVMNode extends AbstractContainerVMNode
});
}
@Override
protected void updateLabelInSessionThread(final ILabelUpdate update) {
IProcesses processService = getServicesTracker().getService(IProcesses.class);
IRunControl runControl = getServicesTracker().getService(IRunControl.class);
if (processService == null || runControl == null) {
handleFailedUpdate(update);
return;
}
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
final IContainerDMContext contDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IContainerDMContext.class);
String imageKey = null;
if (runControl.isSuspended(contDmc)) {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
} else {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
}
update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
processService.getExecutionData(
procDmc,
new ViewerDataRequestMonitor<IThreadDMData>(getExecutor(), update) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
update.setLabel("<unavailable>", 0); //$NON-NLS-1$
update.done();
return;
}
// Create Labels of type Name[PID] if the pid is available
final StringBuilder builder = new StringBuilder();
builder.append(getData().getName());
if (getData().getId() != null && getData().getId().length() > 0) {
builder.append("[" + getData().getId()+ "]"); //$NON-NLS-1$//$NON-NLS-2$
}
update.setLabel(builder.toString(), 0);
update.done();
}
});
}
@Override
protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
IPropertiesUpdate[] parentUpdates = new IPropertiesUpdate[updates.length];
for (int i = 0; i < updates.length; i++) {
final IPropertiesUpdate update = updates[i];
final ViewerCountingRequestMonitor countringRm =
new ViewerCountingRequestMonitor(ImmediateExecutor.getInstance(), updates[i]);
int count = 0;
// Create a delegating update which will let the super-class fill in the
// standard container properties.
parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
count++;
IProcesses processService = getServicesTracker().getService(IProcesses.class);
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
if (processService == null || procDmc == null) {
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Service or handle invalid", null)); //$NON-NLS-1$
} else {
processService.getExecutionData(
procDmc,
new ViewerDataRequestMonitor<IThreadDMData>(getExecutor(), update) {
@Override
public void handleCompleted() {
if (isSuccess()) {
fillThreadDataProperties(update, getData());
} else {
update.setStatus(getStatus());
}
countringRm.done();
}
});
count++;
}
countringRm.setDoneCount(count);
}
super.updatePropertiesInSessionThread(parentUpdates);
}
protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(ILaunchVMConstants.PROP_ID, data.getId());
}
@Override
public int getDeltaFlags(Object e) {
if (e instanceof ICommandControlShutdownDMEvent) {

View file

@ -11,26 +11,27 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractThreadVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMDelegatingPropertiesUpdate;
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.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.ui.IMemento;
@ -48,84 +49,57 @@ public class ThreadVMNode extends AbstractThreadVMNode
}
@Override
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
if (runControl == null) {
handleFailedUpdate(update);
continue;
}
protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
IPropertiesUpdate[] parentUpdates = new IPropertiesUpdate[updates.length];
for (int i = 0; i < updates.length; i++) {
final IPropertiesUpdate update = updates[i];
final IMIExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class);
String imageKey = null;
final boolean threadSuspended;
if (runControl.isSuspended(execDmc)) {
threadSuspended = true;
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
final ViewerCountingRequestMonitor countringRm =
new ViewerCountingRequestMonitor(ImmediateExecutor.getInstance(), updates[i]);
int count = 0;
// Create a delegating update which will let the super-class fill in the
// standard container properties.
parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
count++;
IProcesses processService = getServicesTracker().getService(IProcesses.class);
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
if (processService == null || procDmc == null) {
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Service or handle invalid", null)); //$NON-NLS-1$
} else {
threadSuspended = false;
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
}
update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
// Find the Reason for the State
runControl.getExecutionData(execDmc,
new ViewerDataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), update) {
@Override
public void handleCompleted(){
if (!isSuccess()) {
update.setLabel("<unavailable>", 0); //$NON-NLS-1$
update.done();
return;
}
final IProcesses procService = getServicesTracker().getService(IProcesses.class);
if ( procService == null ) {
handleFailedUpdate(update);
return;
}
final StateChangeReason reason = getData().getStateChangeReason();
// Retrieve the rest of the thread information
final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class);
procService.getExecutionData(
threadDmc,
new ViewerDataRequestMonitor<IThreadDMData>(getSession().getExecutor(), update) {
@Override
public void handleCompleted() {
// We can still generate a good enough label even if this call fails
// so continue and check if we should use getData() or not.
// Create Labels of type Thread[GDBthreadId]RealThreadID/Name (State: Reason)
// Thread[1] 3457 (Suspended:BREAKPOINT)
final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$
builder.append(execDmc.getThreadId());
builder.append("] "); //$NON-NLS-1$
if (isSuccess()) {
builder.append(getData().getId());
builder.append(getData().getName());
processService.getExecutionData(
procDmc,
new ViewerDataRequestMonitor<IThreadDMData>(getExecutor(), update) {
@Override
public void handleCompleted() {
if (isSuccess()) {
fillThreadDataProperties(update, getData());
} else {
final IMIExecutionDMContext execDmc = findDmcInPath(
update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class);
if (execDmc != null) {
update.setProperty(ILaunchVMConstants.PROP_ID, Integer.toString(execDmc.getThreadId()));
} else {
update.setStatus(getStatus());
}
if(threadSuspended)
builder.append(" (Suspended"); //$NON-NLS-1$
else
builder.append(" (Running"); //$NON-NLS-1$
// Reason will be null before ContainerSuspendEvent is fired
if(reason != null) {
builder.append(" : "); //$NON-NLS-1$
builder.append(reason);
}
builder.append(")"); //$NON-NLS-1$
update.setLabel(builder.toString(), 0);
update.done();
}
});
}
});
countringRm.done();
}
});
count++;
}
countringRm.setDoneCount(count);
}
super.updatePropertiesInSessionThread(parentUpdates);
}
protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(ILaunchVMConstants.PROP_ID, data.getId());
}
private String produceThreadElementName(String viewName, IMIExecutionDMContext execCtx) {

View file

@ -469,26 +469,6 @@ public class GDBProcesses_7_0 extends AbstractDsfService
return execDmcList.toArray(new IMIExecutionDMContext[0]);
}
/**
* This method obtains the model data for a given IThreadDMContext object
* which can represent a thread or a process.
*
* @param dmc
* The context for which we are requesting the data
* @param rm
* The request monitor that will contain the requested data
*/
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IThreadDMContext) {
getExecutionData((IThreadDMContext) dmc,
(DataRequestMonitor<IThreadDMData>) rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
if (dmc instanceof IMIProcessDMContext) {
final String id = ((IMIProcessDMContext)dmc).getProcId();

View file

@ -244,20 +244,6 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IRunCont
return GdbPlugin.getBundleContext();
}
///////////////////////////////////////////////////////////////////////////
// IDMService
///////////////////////////////////////////////////////////////////////////
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IExecutionDMContext) {
getExecutionData((IExecutionDMContext) dmc, (DataRequestMonitor<IExecutionDMData>) rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
///////////////////////////////////////////////////////////////////////////
// IRunControl
///////////////////////////////////////////////////////////////////////////

View file

@ -562,29 +562,6 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
IFormattedValues.OCTAL_FORMAT, IFormattedValues.DECIMAL_FORMAT });
rm.done();
}
/**
* This method obtains the model data for a given ExpressionDMC object or
* for a FormattedValueDMC, or for this DSF service.
*
* @param dmc
* The context for which we are requesting the data
* @param rm
* The request monitor that will contain the requested data
*/
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof MIExpressionDMC) {
getExpressionData((MIExpressionDMC) dmc,
(DataRequestMonitor<IExpressionDMData>) rm);
} else if (dmc instanceof FormattedValueDMContext) {
getFormattedExpressionValue((FormattedValueDMContext) dmc,
(DataRequestMonitor<FormattedValueDMData>) rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
/**
* Obtains the static data of an expression represented

View file

@ -399,26 +399,6 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses, ICa
return createContainerContext(processDmc, groupId);
}
/**
* This method obtains the model data for a given IThreadDMContext object
* which can represent a thread or a process.
*
* @param dmc
* The context for which we are requesting the data
* @param rm
* The request monitor that will contain the requested data
*/
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IThreadDMContext) {
getExecutionData((IThreadDMContext) dmc,
(DataRequestMonitor<IThreadDMData>) rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
if (dmc instanceof MIProcessDMC) {
rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getProcId())); //$NON-NLS-1$

View file

@ -202,27 +202,6 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
public boolean isValid() { return true; }
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
/*
* This is the method which is called when actual results need to be returned. We
* can be called either with a service DMC for which we return ourselves or we can
* be called with the DMC's we have handed out. If the latter is the case then we
* data mine by talking to the Debug Engine.
*/
if (dmc instanceof MIRegisterGroupDMC) {
getRegisterGroupData((MIRegisterGroupDMC)dmc, (DataRequestMonitor<IRegisterGroupDMData>)rm);
} else if (dmc instanceof MIRegisterDMC) {
getRegisterData((MIRegisterDMC)dmc, (DataRequestMonitor<IRegisterDMData>)rm);
} else if (dmc instanceof FormattedValueDMContext) {
getFormattedExpressionValue((FormattedValueDMContext)dmc, (DataRequestMonitor<FormattedValueDMData>)rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor<FormattedValueDMData> rm) {
if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIRegisterDMC) {
getRegisterDataValue( (MIRegisterDMC) dmc.getParents()[0], dmc.getFormatID(), rm);
@ -534,12 +513,12 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
final MIExpressions exprService = getServicesTracker().getService(MIExpressions.class);
String regName = regDmc.getName();
final IExpressionDMContext exprCtxt = exprService.createExpression(regCtx, "$" + regName); //$NON-NLS-1$
exprService.getModelData(exprCtxt, new DataRequestMonitor<IExpressionDMData>(getExecutor(), rm) {
exprService.getExpressionData(exprCtxt, new DataRequestMonitor<IExpressionDMData>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Evaluate the expression - request HEX since it works in every case
final FormattedValueDMContext valueDmc = exprService.getFormattedValueContext(exprCtxt, formatId);
exprService.getModelData(
exprService.getFormattedExpressionValue(
valueDmc,
new DataRequestMonitor<FormattedValueDMData>(getExecutor(), rm) {
@Override

View file

@ -314,16 +314,6 @@ public class MIRunControl extends AbstractDsfService implements IRunControl, ICa
/** @since 2.0 */
protected void setTerminated(boolean terminated) { fTerminated = terminated; }
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof IExecutionDMContext) {
getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
public CommandCache getCache() { return fMICommandCache; }
/** @since 2.0 */
protected ICommandControlService getConnection() { return fConnection; }

View file

@ -208,20 +208,6 @@ public class MIStack extends AbstractDsfService
super.shutdown(rm);
}
@SuppressWarnings("unchecked")
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
if (dmc instanceof MIFrameDMC) {
getFrameData((MIFrameDMC)dmc, (DataRequestMonitor<IFrameDMData>)rm);
// getFrameData invokes rm
} else if (dmc instanceof MIVariableDMC) {
getVariableData((MIVariableDMC)dmc, (DataRequestMonitor<IVariableDMData>)rm);
// getVariablesData invokes rm
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
/**
* Creates a frame context. This method is intended to be used by other MI
* services and sub-classes which need to create a frame context directly.

View file

@ -20,13 +20,7 @@ public class MessagesForNumberFormatDetailPane extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.numberformat.detail.messages"; //$NON-NLS-1$
public static String NumberFormatDetailPane_Natural_label;
public static String NumberFormatDetailPane_Decimal_label;
public static String NumberFormatDetailPane_Hex_label;
public static String NumberFormatDetailPane_Octal_label;
public static String NumberFormatDetailPane_Binary_label;
public static String NumberFormatDetailPane_String_label;
public static String NumberFormatDetailPane_Other_label;
public static String NumberFormatDetailPane_format_separator__label;
public static String NumberFormatDetailPane_Name_label;
public static String NumberFormatDetailPane_Spaces_label;
public static String NumberFormatDetailPane_CarriageReturn_label;

View file

@ -12,44 +12,38 @@
package org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.numberformat.detail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.detailsupport.DetailPaneMaxLengthAction;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.detailsupport.DetailPaneWordWrapAction;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.detailsupport.MessagesForDetailPane;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.detailsupport.TextViewerAction;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.update.AbstractCachingVMProvider;
import org.eclipse.cdt.dsf.ui.concurrent.SimpleDisplayExecutor;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMPropertiesUpdate;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IDebugModelProvider;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
@ -249,35 +243,12 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert
/**
* Useful shortened names for the internationalized strings.
*/
public static String HEX = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Hex_label;
public static String NATURAL = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Natural_label;
public static String DECIMAL = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Decimal_label;
public static String OCTAL = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Octal_label;
public static String BINARY = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Binary_label;
public static String STRING = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_String_label;
public static String OTHER = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_String_label;
public static String FORMAT_SEPARATOR = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_format_separator__label;
public static String NAME = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Name_label;
public static String SPACES = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_Spaces_label;
public static String CRLF = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_CarriageReturn_label;
public static String DOTS = MessagesForNumberFormatDetailPane.NumberFormatDetailPane_DotDotDot_label;
/*
* Returns a formatted combination of format label and its corresponding value.
*/
private String formatNumericResult(String format, String value) {
/*
* Select the proper string format and create the total value to be displayed.
*/
if ( format == IFormattedValues.HEX_FORMAT) { return(HEX + value); }
else if ( format == IFormattedValues.OCTAL_FORMAT) { return(OCTAL + value); }
else if ( format == IFormattedValues.NATURAL_FORMAT) { return(NATURAL + value); }
else if ( format == IFormattedValues.BINARY_FORMAT) { return(BINARY + value); }
else if ( format == IFormattedValues.DECIMAL_FORMAT) { return(DECIMAL + value); }
else if ( format == IFormattedValues.STRING_FORMAT) { return(STRING + value); }
else { return(OTHER + value); }
}
/**
* Job to compute the details for a selection
*/
@ -299,142 +270,11 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert
fElements = elements;
}
/*
* This is the routine which will actually process the various format requests
* for a given element. It is expected and required that this routine will be
* called from within a DSF executor.
*/
private void putInformationIntoDetailPane( final AbstractCachingVMProvider provider,
final IVMNode node,
final TreePath path,
final IFormattedDataDMContext finalDmc ,
final IFormattedValues service,
final IProgressMonitor monitor,
final String name ) {
/*
* Now that we can process this one. Find out how many formats we can
* show this in. We will choose to show all of the supported formats.
* Since we are doing this in the background and the debug engines do
* typically cache the results so producing multiple formats will not
* typically be a burden. We should probably consider perhaps doing a
* preference where they can select what formats they want to show.
*/
final DataRequestMonitor<String[]> getAvailableFormatsDone =
new DataRequestMonitor<String[]>(service.getExecutor(), null) {
@Override
protected void handleSuccess() {
if (monitor.isCanceled()) {
notifyAll();
return;
}
/*
* Now we have a set of formats for each one fire up an independent
* asynchronous request to get the data in that format. We do not
* go through the cache manager here because when the values are
* edited and written the cache is bypassed.
*/
String[] formats = getData();
final List<String> completedFormatStrings = new ArrayList<String>();
final CountingRequestMonitor countingRm = new CountingRequestMonitor(service.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (monitor.isCanceled()) {
notifyAll();
return;
}
/*
* We sort the array to make the strings appear always in the same order.
*/
java.util.Collections.sort( completedFormatStrings );
int len = completedFormatStrings.size() ;
if ( len == 0 ) {
detailComputed(null,""); //$NON-NLS-1$
}
else {
/*
* Add the HEADER which identifies what is being represented. When there
* are multiple selections in the view the detail pane contains multiple
* entries. They would be all compressed together and even though the
* order of the entries is the order of the selections in the view and
* it is very hard to know what goes with what. This makes it easy.
*/
String finalResult = NAME + name + CRLF;
int cnt = 0 ;
for (String str : completedFormatStrings) {
finalResult += SPACES + str ;
if ( ( ++ cnt ) < len ) {
finalResult += CRLF;
}
}
detailComputed(null,finalResult);
}
}
};
countingRm.setDoneCount(formats.length);
for ( final String str : formats ) {
/*
* Format has been validated. Get the formatted value.
*/
final FormattedValueDMContext valueDmc = service.getFormattedValueContext(finalDmc, str);
provider.getModelData(
node,
new IViewerUpdate() {
public void cancel() {}
public void done() {}
public Object getViewerInput() { return fViewerInput; }
public TreePath getElementPath() { return path; }
public Object getElement() { return path.getLastSegment(); }
public IPresentationContext getPresentationContext() { return fPresentationContext; }
public boolean isCanceled() { return monitor.isCanceled(); }
public void setStatus(IStatus status) {}
public IStatus getStatus() { return null; }
},
service, valueDmc,
new DataRequestMonitor<FormattedValueDMData>(service.getExecutor(), null) {
@Override
public void handleCompleted() {
if (getStatus().isOK()) {
/*
* Show the information indicating the format.
*/
completedFormatStrings.add( formatNumericResult( str, getData().getFormattedValue() ) );
}
countingRm.done();
}
},
provider.getExecutor());
}
}
};
/*
* Get the supported formats.
*/
service.getAvailableFormats(finalDmc, getAvailableFormatsDone);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected IStatus run(final IProgressMonitor monitor) {
String message = null;
if ( fMonitor != null && ! fMonitor.isCanceled() ) {
fMonitor.setCanceled(true);
}
@ -447,158 +287,62 @@ public class NumberFormatDetailPane implements IDetailPane, IAdaptable, IPropert
final TreePath path = paths[i];
Object element = paths[i].getLastSegment();
/*
* Make sure this is an element we want to deal with.
*/
if ( element instanceof IDMVMContext) {
IDMVMContext vmc = (IDMVMContext)element;
/*
* We are specifically looking to support the following Data Model Contexts
*
* IRegisterDMContext
* IBitFieldDMContext
* IExpressionDMContext
*
* At first you might think that we should just use the service which is
* associated with the dmc. But there are implementations where the data
* model contexts are extended but the services do not extend each other
* ( this is the case with the WindRiver OCD extensions for example ).
*
* So here we specifically look for the service which knows how to deal
* with the formatted data.
*
* Please note that the order or searching for the ancestor is important.
* A BitField Data Model Context will have a Register Data Model Context
* as its parent so if we search for a Register DMC first when we actually
* have a BitField DMC we will get the register and show the value of the
* register not the bit field.
*/
DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), vmc.getDMContext().getSessionId());
final AbstractCachingVMProvider provider = (AbstractCachingVMProvider)vmc.getAdapter(AbstractCachingVMProvider.class);
final IVMNode node = (IVMNode)vmc.getAdapter(IVMNode.class);
final IBitFieldDMContext bitfieldDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IBitFieldDMContext.class);
if ( bitfieldDmc != null ) {
/*
* Get the name so we can construct the header which identifies the detail
* set of values.
*/
final IRegisters regService = tracker.getService(IRegisters.class);
regService.getExecutor().submit(
new Runnable() {
public void run() {
regService.getBitFieldData(
bitfieldDmc,
new DataRequestMonitor<IBitFieldDMData>(regService.getExecutor(), null) {
@Override
public void handleCompleted() {
if (getStatus().isOK()) {
putInformationIntoDetailPane(provider, node, path, bitfieldDmc , regService, monitor, getData().getName());
}
}
}
);
}
}
);
}
else {
final IRegisterDMContext regDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IRegisterDMContext.class);
if ( regDmc != null ) {
/*
* Get the name so we can construct the header which identifies the detail
* set of values.
*/
final IRegisters regService = tracker.getService(IRegisters.class);
regService.getExecutor().submit(
new Runnable() {
public void run() {
regService.getRegisterData(
regDmc,
new DataRequestMonitor<IRegisterDMData>(regService.getExecutor(), null) {
@Override
public void handleCompleted() {
if (getStatus().isOK()) {
putInformationIntoDetailPane(provider, node, path, regDmc , regService, monitor, getData().getName());
}
}
}
);
}
}
);
}
else {
final IExpressionDMContext exprDmc = DMContexts.getAncestorOfType(((IDMVMContext) element).getDMContext(), IExpressionDMContext.class);
if ( exprDmc != null ) {
final IExpressions exprService = tracker.getService(IExpressions.class);;
exprService.getExecutor().submit(
new Runnable() {
public void run() {
putInformationIntoDetailPane(provider, node, path, exprDmc , exprService, monitor, exprDmc.getExpression());
}
}
);
}
else {
/*
* For whatever reason we are seeing some form of context we do not handle. So we
* will skip this one and try and process any remaining ones. At least this way
* we can fill the detail pane with those we do understand.
*/
continue;
}
}
}
tracker.dispose();
/*
* We need to wait until all the values are in. This causes the work
* to in effect be synchronous, but if we do not wait then when we
* are stepping fast if we exit before the job is finished then we
* will enter and start to update the pane before the previous work
* is actually done. This causes the data to be screwed up in an
* overlapped way. It should be the case that most of the jobs that
* occur in the middle will be cancelled, so there is not a lot of
* waste actually going on.
*/
synchronized (this) {
try {
// wait for a max of 30 seconds for result, then cancel
wait(30000);
if (!fComputed) {
fMonitor.setCanceled(true);
}
} catch (InterruptedException e) {
break;
}
}
}
else {
if (element instanceof String) { message = (String) element; }
else { message = element.toString(); }
fComputed = true;
}
final IElementPropertiesProvider propertiesProvider =
(IElementPropertiesProvider)DebugPlugin.getAdapter(element, IElementPropertiesProvider.class);
/*
* If no details were computed for the selected variable, clear the pane
* or use the message.
*/
if (!fComputed){
if (message == null) {
detailComputed(null,""); //$NON-NLS-1$
} else {
detailComputed(null, message);
}
}
final Executor executor = SimpleDisplayExecutor.getSimpleDisplayExecutor(
fWorkbenchPartSite.getShell().getDisplay());
Set<String> properties = new HashSet<String>(1);
properties.add(IDebugVMConstants.PROP_FORMATTED_VALUE_AVAILABLE_FORMATS);
propertiesProvider.update(new IPropertiesUpdate[] { new VMPropertiesUpdate(
properties, path, fViewerInput, fPresentationContext,
new DataRequestMonitor<Map<String,Object>>(executor, null) {
@Override
protected void handleCompleted() {
Set<String> properties = new HashSet<String>(1);
properties.add(IElementPropertiesProvider.PROP_NAME);
final String[] formats = (String[])getData().get(
IDebugVMConstants.PROP_FORMATTED_VALUE_AVAILABLE_FORMATS);
if (formats != null) {
for (String format : formats) {
properties.add(FormattedValueVMUtil.getPropertyForFormatId(format));
}
}
propertiesProvider.update(new IPropertiesUpdate[] { new VMPropertiesUpdate(
properties, path, fViewerInput, fPresentationContext,
new DataRequestMonitor<Map<String,Object>>(executor, null) {
@Override
protected void handleSuccess() {
StringBuffer finalResult = new StringBuffer();
finalResult.append(NAME).append(getData().get(IElementPropertiesProvider.PROP_NAME)).append(CRLF);
List<String> formatsList = new ArrayList<String>(Arrays.asList(formats));
Collections.sort(formatsList);
for (int i = 0; i < formatsList.size(); i++) {
String formatId = formatsList.get(i);
finalResult.append(SPACES);
finalResult.append( FormattedValueVMUtil.getFormatLabel(formatId) );
finalResult.append(FORMAT_SEPARATOR);
finalResult.append( getData().get(FormattedValueVMUtil.getPropertyForFormatId(formatId)) );
if ( i < formatsList.size() + 1 ) {
finalResult.append(CRLF);
}
}
detailComputed(null, finalResult.toString());
}
@Override
protected void handleErrorOrWarning() {
detailComputed(null, getStatus().getMessage());
};
})
});
}
})
});
continue;
}
return Status.OK_STATUS;

View file

@ -9,13 +9,7 @@
# Wind River Systems Inc - copied for non-restricted version for DSDP/DD/DSF
###############################################################################
NumberFormatDetailPane_Natural_label=Default :
NumberFormatDetailPane_Decimal_label=Decimal :
NumberFormatDetailPane_Hex_label=Hex.... :
NumberFormatDetailPane_Octal_label=Octal.. :
NumberFormatDetailPane_Binary_label=Binary. :
NumberFormatDetailPane_String_label=String :
NumberFormatDetailPane_Other_label=Other.. :
NumberFormatDetailPane_format_separator__label= :
NumberFormatDetailPane_Name_label=Name :
NumberFormatDetailPane_Spaces_label=\t
NumberFormatDetailPane_CarriageReturn_label=\n

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* 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;
import java.util.Map;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.core.runtime.IStatus;
/**
* @since 2.0
*/
public class ErrorLabelText extends LabelText {
protected final static String PROP_ERROR_MESSAGE = "error_message"; //$NON-NLS-1$
public ErrorLabelText() {
this(
MessagesForDebugVM.ErrorLabelText__text_format,
new String[] { PROP_ERROR_MESSAGE });
}
public ErrorLabelText(String formatPattern, String[] propertyNames) {
super(formatPattern, addActiveFormatPropertyNames(propertyNames));
}
private static String[] addActiveFormatPropertyNames(String[] propertyNames) {
String[] newPropertyNames = new String[propertyNames.length + 1];
System.arraycopy(propertyNames, 0, newPropertyNames, 0, propertyNames.length);
newPropertyNames[propertyNames.length + 0] = PROP_ERROR_MESSAGE;
return newPropertyNames;
}
@Override
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
if (PROP_ERROR_MESSAGE.equals(propertyName)) {
return status.getMessage().replaceAll(
"\n", MessagesForDebugVM.ErrorLabelText_Error_message__text_page_break_delimiter); //$NON-NLS-1$
}
return super.getPropertyValue(propertyName, status, properties);
}
@Override
public boolean checkProperty(String propertyName, IStatus status, Map<String,Object> properties) {
if (PROP_ERROR_MESSAGE.equals(propertyName)) {
return !status.isOK();
}
return super.checkProperty(propertyName, status, properties);
};
}

View file

@ -10,7 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.ui.viewmodel.update.ICachingVMProvider;
/**
*
@ -30,6 +33,38 @@ public interface IDebugVMConstants {
/**
* Location of the current format in the IPresentationContext data store.
*
* @since 2.0
*/
public final static String CURRENT_FORMAT_STORAGE = "CurrentNumericStyle" ; //$NON-NLS-1$
public final static String PROP_FORMATTED_VALUE_FORMAT_PREFERENCE = "CurrentNumericStyle" ; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE = "formatted_value_active_format_value"; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_FORMATTED_VALUE_AVAILABLE_FORMATS = "formatted_value_available_formats"; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_FORMATTED_VALUE_ACTIVE_FORMAT = "formatted_value_active_format"; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_FORMATTED_VALUE_BASE = "formatted_value_base"; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_IS_STRING_FORMAT_VALUE_CHANGED = ICachingVMProvider.PROP_IS_CHANGED_PREFIX + FormattedValueVMUtil.getPropertyForFormatId(IFormattedValues.STRING_FORMAT);
/**
* @since 2.0
*/
public static final String PROP_IS_ACTIVE_FORMATTED_VALUE_CHANGED = ICachingVMProvider.PROP_IS_CHANGED_PREFIX + FormattedValueVMUtil.getPropertyForFormatId(IFormattedValues.NATURAL_FORMAT);
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 IBM Corporation 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, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel;
import org.eclipse.osgi.util.NLS;
/**
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class MessagesForDebugVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.messages"; //$NON-NLS-1$
public static String ErrorLabelText__text_format;
public static String ErrorLabelText_Error_message__text_page_break_delimiter;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForDebugVM.class);
}
private MessagesForDebugVM() {}
}

View file

@ -43,6 +43,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
public abstract class AbstractExpressionVMNode extends AbstractDMVMNode
implements IExpressionVMNode
{
/**
* @since 2.0
*/
protected static final String PROP_ELEMENT_EXPRESSION = "element_expression"; //$NON-NLS-1$
public AbstractExpressionVMNode(AbstractDMVMProvider provider, DsfSession session, Class<? extends IDMContext> dmcClassType) {
super(provider, session, dmcClassType);
}

View file

@ -22,8 +22,6 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterBitFieldVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterGroupVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMNode;
@ -198,8 +196,6 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
*/
protected void configureLayout() {
IFormattedValuePreferenceStore prefStore = FormattedValuePreferenceStore.getDefault();
/*
* Allocate the synchronous data providers.
*/
@ -222,13 +218,13 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
*/
IExpressionVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), syncRegDataAccess);
IExpressionVMNode registerNode = new RegisterVMNode(prefStore, this, getSession(), syncRegDataAccess);
IExpressionVMNode registerNode = new RegisterVMNode(this, getSession(), syncRegDataAccess);
addChildNodes(registerGroupNode, new IExpressionVMNode[] {registerNode});
/*
* Create the next level which is the bit-field level.
*/
IVMNode bitFieldNode = new RegisterBitFieldVMNode(prefStore, this, getSession(), syncRegDataAccess);
IVMNode bitFieldNode = new RegisterBitFieldVMNode(this, getSession(), syncRegDataAccess);
addChildNodes(registerNode, new IVMNode[] { bitFieldNode });
/*
@ -236,7 +232,7 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
* view comes in as a fully qualified expression so we go directly to the SubExpression layout
* node.
*/
IExpressionVMNode variableNode = new VariableVMNode(prefStore, this, getSession(), syncvarDataAccess);
IExpressionVMNode variableNode = new VariableVMNode(this, getSession(), syncvarDataAccess);
addChildNodes(variableNode, new IExpressionVMNode[] {variableNode});
/*

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
@ -22,17 +23,30 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
/**
* Abstract implementation of a container view model node.
@ -40,35 +54,118 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public abstract class AbstractContainerVMNode extends AbstractDMVMNode implements IElementLabelProvider {
public abstract class AbstractContainerVMNode extends AbstractDMVMNode
implements IElementLabelProvider, IElementPropertiesProvider
{
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public AbstractContainerVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session, IRunControl.IContainerDMContext.class);
}
public void update(final ILabelUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
for (final ILabelUpdate update : updates) {
updateLabelInSessionThread(update);
}
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
handleFailedUpdate(update);
}
}
fLabelProvider = createLabelProvider();
}
/**
* Perform the given label updates in the session executor thread.
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new ExecutionContextLabelText(
MessagesForLaunchVM.AbstractContainerVMNode_No_columns__text_format,
new String[] {
ExecutionContextLabelText.PROP_NAME_KNOWN,
PROP_NAME,
ExecutionContextLabelText.PROP_ID_KNOWN,
ILaunchVMConstants.PROP_ID }),
new LabelText(MessagesForLaunchVM.AbstractContainerVMNode_No_columns__Error__label, new String[0]),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_SUSPENDED)) {
{ setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); }
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
return !Boolean.TRUE.equals(properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED));
};
},
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET)),
}));
return provider;
}
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @param updates the pending label updates
* @see {@link #update(ILabelUpdate[])
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
/**
* @since 2.0
*/
protected abstract void updateLabelInSessionThread(ILabelUpdate update);
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IRunControl service = getServicesTracker().getService(IRunControl.class);
for (final IPropertiesUpdate update : updates) {
if (service == null) {
handleFailedUpdate(update);
continue;
}
IExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
if (dmc == null) {
handleFailedUpdate(update);
continue;
}
update.setProperty(ILaunchVMConstants.PROP_IS_SUSPENDED, service.isSuspended(dmc));
update.setProperty(ILaunchVMConstants.PROP_IS_STEPPING, service.isStepping(dmc));
service.getExecutionData(
dmc,
new ViewerDataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), update) {
@Override
protected void handleSuccess() {
fillExecutionDataProperties(update, getData());
update.done();
}
});
}
}
protected void fillExecutionDataProperties(IPropertiesUpdate update, IExecutionDMData data) {
update.setProperty(ILaunchVMConstants.PROP_STATE_CHANGE_REASON, data.getStateChangeReason().name());
}
@Override
public void getContextsForEvent(VMDelta parentDelta, Object e, final DataRequestMonitor<IVMContext[]> rm) {

View file

@ -12,8 +12,10 @@
package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
@ -26,8 +28,10 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
@ -39,12 +43,21 @@ import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
/**
@ -53,14 +66,78 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public abstract class AbstractThreadVMNode extends AbstractDMVMNode
implements IElementLabelProvider
implements IElementLabelProvider, IElementPropertiesProvider
{
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public AbstractThreadVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session, IExecutionDMContext.class);
fLabelProvider = createLabelProvider();
}
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
// Text is made of the thread name followed by its state and state change reason.
new ExecutionContextLabelText(
MessagesForLaunchVM.AbstractThreadVMNode_No_columns__text_format,
new String[] {
ExecutionContextLabelText.PROP_NAME_KNOWN,
PROP_NAME,
ExecutionContextLabelText.PROP_ID_KNOWN,
ILaunchVMConstants.PROP_ID,
ILaunchVMConstants.PROP_IS_SUSPENDED,
ILaunchVMConstants.PROP_STATE_CHANGE_REASON })
{
@Override
public boolean isEnabled(IStatus status, Map<String, Object> properties) {
String reason = (String)properties.get(ILaunchVMConstants.PROP_STATE_CHANGE_REASON);
return
reason != null && reason.length() != 0 &&
!StateChangeReason.UNKNOWN.equals(reason);
}
},
// If no state change reason is available compose a string without it.
new ExecutionContextLabelText(
MessagesForLaunchVM.AbstractThreadVMNode_No_columns__No_reason__text_format,
new String[] {
ExecutionContextLabelText.PROP_NAME_KNOWN,
PROP_NAME,
ExecutionContextLabelText.PROP_ID_KNOWN,
ILaunchVMConstants.PROP_ID}),
new LabelText(MessagesForLaunchVM.AbstractThreadVMNode_No_columns__Error__label, new String[0]),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING)) {
{ setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); }
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
return !((Boolean)properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED)).booleanValue();
};
},
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED)),
}));
return provider;
}
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
IRunControl runControl = getServicesTracker().getService(IRunControl.class);
@ -85,19 +162,67 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
}
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IRunControl service = getServicesTracker().getService(IRunControl.class);
for (final IPropertiesUpdate update : updates) {
if (service == null) {
handleFailedUpdate(update);
continue;
}
IExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
if (dmc == null) {
handleFailedUpdate(update);
continue;
}
update.setProperty(ILaunchVMConstants.PROP_IS_SUSPENDED, service.isSuspended(dmc));
update.setProperty(ILaunchVMConstants.PROP_IS_STEPPING, service.isStepping(dmc));
service.getExecutionData(
dmc,
new ViewerDataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), update) {
@Override
protected void handleSuccess() {
fillExecutionDataProperties(update, getData());
update.done();
}
});
}
}
protected void fillExecutionDataProperties(IPropertiesUpdate update, IExecutionDMData data) {
update.setProperty(ILaunchVMConstants.PROP_STATE_CHANGE_REASON, data.getStateChangeReason().name());
}
@Override
public void getContextsForEvent(VMDelta parentDelta, Object e, final DataRequestMonitor<IVMContext[]> rm) {
if(e instanceof IContainerResumedDMEvent) {
@ -212,14 +337,6 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
}));
}
/**
* Perform the given label updates in the session executor thread.
*
* @param updates the pending label updates
* @see {@link #update(ILabelUpdate[])
*/
protected abstract void updateLabelInSessionThread(ILabelUpdate[] updates);
public int getDeltaFlags(Object e) {
IDMContext dmc = e instanceof IDMEvent<?> ? ((IDMEvent<?>)e).getDMContext() : null;

View file

@ -0,0 +1,91 @@
/*******************************************************************************
* 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.launch;
import java.util.Map;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.core.runtime.IStatus;
class ExecutionContextLabelText extends LabelText {
/**
* Value <code>0</code> means it's not known. Value <code>1</code>, means it's known.
*/
public static final String PROP_ID_KNOWN = "id_known"; //$NON-NLS-1$
/**
* Value <code>0</code> means it's not known. Value <code>1</code>, means it's known.
*/
public static final String PROP_NAME_KNOWN = "name_known"; //$NON-NLS-1$
protected ExecutionContextLabelText(String formatPattern, String[] propertyNames) {
super(formatPattern, propertyNames);
}
@Override
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
if ( ILaunchVMConstants.PROP_STATE_CHANGE_REASON.equals(propertyName) ) {
String reason = (String)properties.get(propertyName);
String reasonLabel = "invalid reason"; //$NON-NLS-1$
if (StateChangeReason.BREAKPOINT.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Breakpoint__label;
} else if (StateChangeReason.CONTAINER.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Container__label;
} else if (StateChangeReason.ERROR.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Error__label;
} else if (StateChangeReason.EVALUATION.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Evaluation__label;
} else if (StateChangeReason.EXCEPTION.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Exception__label;
} else if (StateChangeReason.SHAREDLIB.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Shared_lib__label;
} else if (StateChangeReason.SIGNAL.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Signal__label;
} else if (StateChangeReason.STEP.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Step__label;
} else if (StateChangeReason.USER_REQUEST.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__User_request__label;
} else if (StateChangeReason.WATCHPOINT.name().equals(reason)) {
reasonLabel = MessagesForLaunchVM.State_change_reason__Watchpoint__label;
}
return reasonLabel;
} else if ( ILaunchVMConstants.PROP_IS_SUSPENDED.equals(propertyName) ) {
Boolean suspended = (Boolean)properties.get(propertyName);
return suspended ? 1 : 0;
} else if (PROP_NAME_KNOWN.equals(propertyName)) {
return properties.get(IElementPropertiesProvider.PROP_NAME) != null ? 1 : 0;
} else if (IElementPropertiesProvider.PROP_NAME.equals(propertyName)) {
Object val = properties.get(IElementPropertiesProvider.PROP_NAME);
return val != null ? val : ""; //$NON-NLS-1$
} else if (PROP_ID_KNOWN.equals(propertyName)) {
return properties.get(ILaunchVMConstants.PROP_ID) != null ? 1 : 0;
} else if (ILaunchVMConstants.PROP_ID.equals(propertyName)) {
Object val = properties.get(ILaunchVMConstants.PROP_ID);
return val != null ? val : ""; //$NON-NLS-1$
}
return super.getPropertyValue(propertyName, status, properties);
}
@Override
protected boolean checkProperty(String propertyName, IStatus status, Map<String, Object> properties) {
if (PROP_NAME_KNOWN.equals(propertyName) ||
IElementPropertiesProvider.PROP_NAME.equals(propertyName) ||
PROP_ID_KNOWN.equals(propertyName) ||
ILaunchVMConstants.PROP_ID.equals(propertyName))
{
return true;
}
return super.checkProperty(propertyName, status, properties);
}
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* 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.launch;
/**
* @since 2.0
*/
public interface ILaunchVMConstants {
public static final String PROP_ID = "id"; //$NON-NLS-1$
public static final String PROP_IS_SUSPENDED = "is_suspended"; //$NON-NLS-1$
public static final String PROP_IS_STEPPING = "is_stepping"; //$NON-NLS-1$
public static final String PROP_FRAME_ADDRESS = "frame_address"; //$NON-NLS-1$
public static final String PROP_FRAME_FUNCTION = "frame_function"; //$NON-NLS-1$
public static final String PROP_FRAME_FILE = "frame_file"; //$NON-NLS-1$
public static final String PROP_FRAME_LINE = "frame_line"; //$NON-NLS-1$
public static final String PROP_FRAME_COLUMN = "frame_column"; //$NON-NLS-1$
public static final String PROP_FRAME_MODULE = "frame_module"; //$NON-NLS-1$
public static final String PROP_STATE_CHANGE_REASON = "state_change_reason"; //$NON-NLS-1$
}

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* 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.launch;
import org.eclipse.osgi.util.NLS;
/**
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class MessagesForLaunchVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.messages"; //$NON-NLS-1$
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForLaunchVM.class);
}
private MessagesForLaunchVM() {
}
public static String StackFramesVMNode_No_columns__Incomplete_stack_marker__text_format;
public static String StackFramesVMNode_No_columns__text_format;
public static String StackFramesVMNode_No_columns__No_line__text_format;
public static String StackFramesVMNode_No_columns__No_function__text_format;
public static String StackFramesVMNode_No_columns__No_module__text_format;
public static String StackFramesVMNode_No_columns__Address_only__text_format;
public static String AbstractContainerVMNode_No_columns__text_format;
public static String AbstractContainerVMNode_No_columns__Error__label;
public static String AbstractThreadVMNode_No_columns__text_format;
public static String AbstractThreadVMNode_No_columns__No_reason__text_format;
public static String AbstractThreadVMNode_No_columns__Error__label;
public static String State_change_reason__Unknown__label;
public static String State_change_reason__User_request__label;
public static String State_change_reason__Step__label;
public static String State_change_reason__Breakpoint__label;
public static String State_change_reason__Exception__label;
public static String State_change_reason__Container__label;
public static String State_change_reason__Watchpoint__label;
public static String State_change_reason__Signal__label;
public static String State_change_reason__Shared_lib__label;
public static String State_change_reason__Error__label;
public static String State_change_reason__Evaluation__label;
}

View file

@ -16,6 +16,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
@ -34,6 +36,7 @@ import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
@ -44,6 +47,14 @@ import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.core.runtime.IStatus;
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;
@ -58,10 +69,13 @@ import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IMemento;
@SuppressWarnings("restriction")
public class StackFramesVMNode extends AbstractDMVMNode
implements IElementLabelProvider, IElementMementoProvider
implements IElementLabelProvider, IElementMementoProvider, IElementPropertiesProvider
{
/**
* @since 2.0
*/
public static final String PROP_IS_INCOMPLETE_STACK_MARKER = "is_incomplete_stack_marker"; //$NON-NLS-1$
/**
* View model context representing the end of an incomplete stack.
@ -100,8 +114,17 @@ public class StackFramesVMNode extends AbstractDMVMNode
*/
private Map<IExecutionDMContext, Integer> fTemporaryLimits = new HashMap<IExecutionDMContext, Integer>();
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public StackFramesVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session, IStack.IFrameDMContext.class);
fLabelProvider = createLabelProvider();
}
@Override
@ -109,6 +132,102 @@ public class StackFramesVMNode extends AbstractDMVMNode
return "StackFramesVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__Incomplete_stack_marker__text_format,
new String[] { PROP_NAME })
{
@Override
public boolean isEnabled(IStatus status, Map<String, Object> properties) {
return Boolean.TRUE.equals(properties.get(PROP_IS_INCOMPLETE_STACK_MARKER));
}
},
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__text_format,
new String[] {
ILaunchVMConstants.PROP_FRAME_ADDRESS,
ILaunchVMConstants.PROP_FRAME_FUNCTION,
ILaunchVMConstants.PROP_FRAME_FILE,
ILaunchVMConstants.PROP_FRAME_LINE,
ILaunchVMConstants.PROP_FRAME_COLUMN,
ILaunchVMConstants.PROP_FRAME_MODULE})
{
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
Integer line = (Integer)properties.get(ILaunchVMConstants.PROP_FRAME_LINE);
String file = (String)properties.get(ILaunchVMConstants.PROP_FRAME_FILE);
return line != null && line >= 0 && file != null && file.length() > 0;
};
},
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__No_line__text_format,
new String[] {
ILaunchVMConstants.PROP_FRAME_ADDRESS,
ILaunchVMConstants.PROP_FRAME_FUNCTION,
ILaunchVMConstants.PROP_FRAME_MODULE})
{
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
String function = (String)properties.get(ILaunchVMConstants.PROP_FRAME_FUNCTION);
String module = (String)properties.get(ILaunchVMConstants.PROP_FRAME_MODULE);
return function != null && function.length() > 0 && module != null && module.length() > 0;
};
},
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__No_function__text_format,
new String[] {
ILaunchVMConstants.PROP_FRAME_ADDRESS,
ILaunchVMConstants.PROP_FRAME_MODULE})
{
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
String module = (String)properties.get(ILaunchVMConstants.PROP_FRAME_MODULE);
return module != null && module.length() > 0;
};
},
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__No_module__text_format,
new String[] {
ILaunchVMConstants.PROP_FRAME_ADDRESS,
ILaunchVMConstants.PROP_FRAME_FUNCTION})
{
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
String function = (String)properties.get(ILaunchVMConstants.PROP_FRAME_FUNCTION);
return function != null && function.length() > 0;
};
},
new LabelText(
MessagesForLaunchVM.StackFramesVMNode_No_columns__Address_only__text_format,
new String[] { ILaunchVMConstants.PROP_FRAME_ADDRESS }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_STACKFRAME_RUNNING)) {
{ setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); }
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
return Boolean.FALSE.equals( properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED) );
};
},
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_STACKFRAME))
}));
return provider;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode#updateHasElementsInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate)
@ -239,83 +358,86 @@ public class StackFramesVMNode extends AbstractDMVMNode
}
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[])
*/
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IStack service = getServicesTracker().getService(IStack.class);
for (final IPropertiesUpdate update : updates) {
if (service == null) {
handleFailedUpdate(update);
continue;
}
if (update.getElement() instanceof IncompleteStackVMContext) {
update.setLabel("<...more frames...>", 0); //$NON-NLS-1$
update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_STACKFRAME), 0);
update.setProperty(PROP_IS_INCOMPLETE_STACK_MARKER, Boolean.TRUE);
update.done();
continue;
}
final IFrameDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class);
IFrameDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IFrameDMContext.class);
if (dmc == null) {
handleFailedUpdate(update);
continue;
}
getDMVMProvider().getModelData(
this, update,
getServicesTracker().getService(IStack.class, null),
IRunControl runControlService = getServicesTracker().getService(IRunControl.class);
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
if (execDmc != null && runControlService != null) {
update.setProperty(ILaunchVMConstants.PROP_IS_SUSPENDED, runControlService.isSuspended(execDmc));
update.setProperty(ILaunchVMConstants.PROP_IS_STEPPING, runControlService.isStepping(execDmc));
} else {
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Invalid context or service not available", null)); //$NON-NLS-1$
}
service.getFrameData(
dmc,
new ViewerDataRequestMonitor<IFrameDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
/*
* Check that the request was evaluated and data is still
* valid. The request could fail if the state of the
* service changed during the request, but the view model
* has not been updated yet.
*/
if (!isSuccess()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR ||
getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED;
handleFailedUpdate(update);
return;
}
/*
* If columns are configured, call the protected methods to
* fill in column values.
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null) localColumns = new String[] { null };
for (int i = 0; i < localColumns.length; i++) {
fillColumnLabel(dmc, getData(), localColumns[i], i, update);
}
protected void handleSuccess() {
fillFrameDataProperties(update, getData());
update.done();
}
},
getExecutor());
});
}
}
protected void fillFrameDataProperties(IPropertiesUpdate update, IFrameDMData data) {
IAddress address = data.getAddress();
if (address != null) {
update.setProperty(ILaunchVMConstants.PROP_FRAME_ADDRESS, "0x" + address.toString(16)); //$NON-NLS-1$
}
update.setProperty(ILaunchVMConstants.PROP_FRAME_FILE, data.getFile());
update.setProperty(ILaunchVMConstants.PROP_FRAME_FUNCTION, data.getFunction());
update.setProperty(ILaunchVMConstants.PROP_FRAME_LINE, data.getLine());
update.setProperty(ILaunchVMConstants.PROP_FRAME_COLUMN, data.getColumn());
update.setProperty(ILaunchVMConstants.PROP_FRAME_MODULE, data.getModule());
}
protected void fillColumnLabel(IFrameDMContext dmContext, IFrameDMData dmData, String columnId, int idx, ILabelUpdate update)
{
if (idx != 0) return;

View file

@ -0,0 +1,73 @@
###############################################################################
# Copyright (c) 2007, 2009 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
###############################################################################
StackFramesVMNode_No_columns__Incomplete_stack_marker__text_format=<...more frames...>
# {0} - address,
# {1} - function,
# {2} - file (path or just name, depending on preference)
# {3} - line
# {4} - column
# {5} - module
StackFramesVMNode_No_columns__text_format={1}() at {2}:{3}{4,choice,0#|1#:{4}}
# {0} - address
# {1} - function
# {2} - module
StackFramesVMNode_No_columns__No_line__text_format={1}() [{2}] at {0}
# {0} - address
# {1} - module
StackFramesVMNode_No_columns__No_function__text_format=[{2}] at {0}
# {0} - address
# {1} - function
StackFramesVMNode_No_columns__No_module__text_format={1}() at {0}
# {0} - address
StackFramesVMNode_No_columns__Address_only__text_format={0}
# {0} - name
# {1} - name available, 0=not available/1=available
# {2} - ID
# {3} - ID available, 0=not available/1=available
AbstractContainerVMNode_No_columns__text_format={0,choice,0#Process|1#{1}}{2,choice,0#|1# [{3}]}
AbstractContainerVMNode_No_columns__Error__label=<unavailable>
# {0} - name
# {1} - name available, 0=not available/1=available
# {2} - ID
# {3} - ID available, 0=not available/1=available
# {4} - 0=running/1=suspended
# {5} - state change reason
AbstractThreadVMNode_No_columns__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]} ({4,choice,0#Running|1#Suspended} : {5})
# {0} - name
# {1} - name available, 0=not available/1=available
# {2} - ID
# {3} - ID available, 0=not available/1=available
# {4} - 0=running/1=suspended
AbstractThreadVMNode_No_columns__No_reason__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]} ({4,choice,0#Running|1#Suspended})
AbstractThreadVMNode_No_columns__Error__label=<unavailable>
State_change_reason__Unknown__label = Unknown
State_change_reason__User_request__label = User Request
State_change_reason__Step__label = Step
State_change_reason__Breakpoint__label = Breakpoint
State_change_reason__Exception__label = Exception
State_change_reason__Container__label = Container
State_change_reason__Watchpoint__label = Watchpoint
State_change_reason__Signal__label = Signal
State_change_reason__Shared_lib__label = Shared Library
State_change_reason__Error__label = Error
State_change_reason__Evaluation__label = Evaluation

View file

@ -0,0 +1,17 @@
###############################################################################
# Copyright (c) 2009 Wind River Corporation 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 Inc - Initial API and implementation
###############################################################################
# {0} - Error message
ErrorLabelText__text_format=Error: {0}
# If multiple errors are shown in the combined error message, this
# string is used as a separator between them.
ErrorLabelText_Error_message__text_page_break_delimiter= \

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* 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.modules;
import org.eclipse.osgi.util.NLS;
/**
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class MessagesForModulesVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.modules.messages"; //$NON-NLS-1$
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForModulesVM.class);
}
private MessagesForModulesVM() {
}
public static String ModulesVMNode_No_columns__text_format;
}

View file

@ -11,10 +11,11 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.modules;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules;
@ -23,21 +24,33 @@ import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMData;
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.internal.ui.DsfUILabelImage;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelFont;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.jface.resource.JFaceResources;
@SuppressWarnings("restriction")
/**
* @since 1.0
*/
public class ModulesVMNode extends AbstractDMVMNode
implements IElementLabelProvider
implements IElementLabelProvider, IElementPropertiesProvider
{
/**
* Marker type for the modules VM context. It allows action enablement
@ -49,9 +62,57 @@ public class ModulesVMNode extends AbstractDMVMNode
}
}
/**
* @since 2.0
*/
public static final String PROP_IS_LOADED = "is_loaded"; //$NON-NLS-1$
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(MessagesForModulesVM.ModulesVMNode_No_columns__text_format, new String[] { PROP_NAME }),
new DsfUILabelImage(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED) {
{ setPropertyNames(new String[] { PROP_IS_LOADED }); }
@Override
public boolean checkProperty(String propertyName, IStatus status, Map<String,Object> properties) {
if (PROP_IS_LOADED.equals(propertyName)) {
return Boolean.TRUE.equals( properties.get(propertyName) );
}
return super.checkProperty(propertyName, status, properties);
};
},
new DsfUILabelImage(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_UNLOADED),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
return provider;
}
public ModulesVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session, IModuleDMContext.class);
fLabelProvider = createLabelProvider();
}
@Override
@ -88,80 +149,60 @@ public class ModulesVMNode extends AbstractDMVMNode
return new ModuleVMContext(dmc);
}
public void update(final ILabelUpdate[] updates) {
/*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
IModules modulesService = getServicesTracker().getService(IModules.class);
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IModules modulesService = getServicesTracker().getService(IModules.class);
for (final IPropertiesUpdate update : updates) {
final IModuleDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IModuleDMContext.class);
// If either update or service are not valid, fail the update and exit.
if ( modulesService == null || dmc == null ) {
handleFailedUpdate(update);
continue;
return;
}
// Use different image for loaded and unloaded symbols when event to report loading of symbols is implemented.
update.setImageDescriptor(DsfUIPlugin.getImageDescriptor(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED), 0);
modulesService.getModuleData(
dmc,
new ViewerDataRequestMonitor<IModuleDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
/*
* The request could fail if the state of the service
* changed during the request, but the view model
* has not been updated yet.
*/
if (!isSuccess()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR ||
getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED;
handleFailedUpdate(update);
return;
}
/*
* If columns are configured, call the protected methods to
* fill in column values.
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null) localColumns = new String[] { null };
for (int i = 0; i < localColumns.length; i++) {
fillColumnLabel(dmc, getData(), localColumns[i], i, update);
}
protected void handleSuccess() {
fillModuleDataProperties(update, getData());
update.done();
}
});
}
}
protected void fillColumnLabel(IModuleDMContext dmContext, IModuleDMData dmData,
String columnId, int idx, ILabelUpdate update)
{
if ( columnId == null ) {
/*
* If the Column ID comes in as "null" then this is the case where the user has decided
* to not have any columns. So we need a default action which makes the most sense and
* is doable. In this case we elect to simply display the name.
*/
update.setLabel(dmData.getName(), idx);
}
}
/**
* @since 2.0
*/
protected void fillModuleDataProperties(IPropertiesUpdate update, IModuleDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(PROP_IS_LOADED, data.isSymbolsLoaded());
}
public int getDeltaFlags(Object e) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
return IModelDelta.CONTENT;

View file

@ -27,9 +27,8 @@ import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public class ModulesVMProvider extends AbstractDMVMProvider {
/*
* Current default for register formatting.

View file

@ -0,0 +1,13 @@
###############################################################################
# Copyright (c) 2007, 2009 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
# Wind River Systems - added Address
###############################################################################
ModulesVMNode_No_columns__text_format={0}

View file

@ -0,0 +1,77 @@
/*******************************************************************************
* 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.numberformat;
import java.text.MessageFormat;
import java.util.Map;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.core.runtime.IStatus;
/**
*
*
* @since 2.0
*/
public class FormattedValueLabelText extends LabelText {
public FormattedValueLabelText() {
this(
MessagesForNumberFormat.FormattedValueLabelText__text_format,
new String[] { IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE });
}
public FormattedValueLabelText(String formatPattern, String[] propertyNames) {
super(formatPattern, addActiveFormatPropertyNames(propertyNames));
}
private static String[] addActiveFormatPropertyNames(String[] propertyNames) {
String[] newPropertyNames = new String[propertyNames.length + 2];
System.arraycopy(propertyNames, 0, newPropertyNames, 0, propertyNames.length);
newPropertyNames[propertyNames.length + 0] = IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT;
newPropertyNames[propertyNames.length + 1] = IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE;
return newPropertyNames;
}
@Override
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
// If the format is not the same as the preferred format, include it in the value string.
if ( IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE.equals(propertyName) ) {
Object activeFormat = properties.get(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
Object preferredFormat = properties.get(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
Object value = properties.get(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
if (value != null && activeFormat != null && !activeFormat.equals(preferredFormat)) {
return MessageFormat.format(
MessagesForNumberFormat.FormattedValueLabelText__Value__text_format,
new Object[] {
value,
FormattedValueVMUtil.getFormatLabel((String)activeFormat) });
}
}
return properties.get(propertyName);
}
@Override
public boolean isEnabled(IStatus status, Map<String, Object> properties) {
for (String property : getPropertyNames()) {
if ( IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT.equals(property) ||
IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE.equals(property) )
{
continue;
}
if (properties.get(property) == null) {
return false;
}
}
return true;
}
}

View file

@ -1,43 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006, 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.numberformat;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
* Provides default implementation of preference storage.
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public class FormattedValuePreferenceStore implements IFormattedValuePreferenceStore {
private static IFormattedValuePreferenceStore fgSingletonReference;
public static IFormattedValuePreferenceStore getDefault() {
if (fgSingletonReference == null) {
fgSingletonReference = new FormattedValuePreferenceStore();
}
return fgSingletonReference;
}
public String getCurrentNumericFormat( IPresentationContext context ) {
Object prop = context.getProperty( IDebugVMConstants.CURRENT_FORMAT_STORAGE );
if ( prop != null ) {
return (String) prop;
}
return IFormattedValues.NATURAL_FORMAT;
}
}

View file

@ -0,0 +1,255 @@
/*******************************************************************************
* 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.numberformat;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
* @since 2.0
*/
public class FormattedValueVMUtil {
/**
* Common map of user-readable labels for format IDs. UI components for
*/
private static Map<String, String> fFormatLabels = new HashMap<String, String>(8);
static {
setFormatLabel(IFormattedValues.NATURAL_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_Natural_format__label);
setFormatLabel(IFormattedValues.HEX_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_Hex_format__label);
setFormatLabel(IFormattedValues.DECIMAL_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_Decimal_format__label);
setFormatLabel(IFormattedValues.OCTAL_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_Octal_format__label);
setFormatLabel(IFormattedValues.BINARY_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_Binary_format__label);
setFormatLabel(IFormattedValues.STRING_FORMAT, MessagesForNumberFormat.FormattedValueVMUtil_String_format__label);
}
public static void setFormatLabel(String formatId, String label) {
fFormatLabels.put(formatId, label);
}
public static String getFormatLabel(String formatId) {
String label = fFormatLabels.get(formatId);
if (label != null) {
return label;
} else {
return MessageFormat.format(
MessagesForNumberFormat.FormattedValueVMUtil_Other_format__format_text, new Object[] { formatId });
}
}
public static String getPropertyForFormatId(String formatId) {
if (formatId == null) {
return null;
}
return IDebugVMConstants.PROP_FORMATTED_VALUE_BASE + "." + formatId; //$NON-NLS-1$
}
public static String getFormatFromProperty(String property) {
return property.substring(IDebugVMConstants.PROP_FORMATTED_VALUE_BASE.length() + 1);
}
public static String getPreferredFormat(IPresentationContext context) {
Object prop = context.getProperty( IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE );
if ( prop != null ) {
return (String) prop;
}
return IFormattedValues.NATURAL_FORMAT;
}
@ConfinedToDsfExecutor("service.getExecutor()")
public static void updateFormattedValues(
final IPropertiesUpdate updates[],
final IFormattedValues service,
final Class<? extends IFormattedDataDMContext> dmcType,
final RequestMonitor monitor)
{
// First retrieve the available formats for all the updates, and store it in a map (as well as the updates).
// After that is completed call another method to retrieve the formatted values.
final Map<IPropertiesUpdate, String[]> availableFormats = new HashMap<IPropertiesUpdate, String[]>(updates.length * 4/3);
final CountingRequestMonitor countingRm = new CountingRequestMonitor(
service.getExecutor(),
new RequestMonitor(service.getExecutor(), monitor) {
@Override
protected void handleCompleted() {
updateFormattedValuesWithAvailableFormats(updates, service, dmcType, availableFormats, monitor);
}
});
int count = 0;
for (final IPropertiesUpdate update : updates) {
if (!update.getProperties().contains(IDebugVMConstants.PROP_FORMATTED_VALUE_AVAILABLE_FORMATS) &&
!update.getProperties().contains(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT) &&
!update.getProperties().contains(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE))
{
// Update is not requesting any formatted value information, so just skip it. If specitic formats were
// requested for this update, they will still be retrieved by updateFormattedValuesWithAvailableFormats.
continue;
}
IFormattedDataDMContext dmc = null;
if (update.getElement() instanceof IDMVMContext) {
dmc = DMContexts.getAncestorOfType(((IDMVMContext)update.getElement()).getDMContext(), dmcType);
}
if (dmc == null) {
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Update element did not contain a valid context: " + dmcType, null)); //$NON-NLS-1$
continue;
}
service.getAvailableFormats(
dmc,
// Use the ViewerDataRequestMonitor in order to propagate the update's cancel request. But this means that
// we have to override the handleRequestedExecutionException() to guarantee that the caller's RM gets
// completed even when the service session has been shut down.
new ViewerDataRequestMonitor<String[]>(service.getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
update.setProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_AVAILABLE_FORMATS, getData());
availableFormats.put(update, getData());
} else {
update.setStatus(getStatus());
}
countingRm.done();
}
@Override
protected void handleRejectedExecutionException() {
countingRm.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_STATE, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null)); //$NON-NLS-1$//$NON-NLS-2$
countingRm.done();
}
});
count++;
}
countingRm.setDoneCount(count);
}
@ConfinedToDsfExecutor("service.getExecutor()")
private static void updateFormattedValuesWithAvailableFormats(
IPropertiesUpdate updates[],
IFormattedValues service,
Class<? extends IFormattedDataDMContext> dmcType,
Map<IPropertiesUpdate, String[]> availableFormatsMap,
final RequestMonitor monitor)
{
// Use a single counting RM for all the requested formats for each update.
final CountingRequestMonitor countingRm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), monitor);
int count = 0;
for (final IPropertiesUpdate update : updates) {
IFormattedDataDMContext dmc = null;
if (update.getElement() instanceof IDMVMContext) {
dmc = DMContexts.getAncestorOfType(((IDMVMContext)update.getElement()).getDMContext(), dmcType);
}
if (dmc == null) {
// The error status should already be set by the calling method.
continue;
}
// Calculate the active value format based on view preference and available formats.
String[] availableFormats = availableFormatsMap.get(update);
String _activeFormat = null;
if (availableFormats != null && availableFormats.length != 0) {
_activeFormat = getPreferredFormat(update.getPresentationContext());
update.setProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, _activeFormat);
if (!isFormatAvailable(_activeFormat, availableFormats)) {
_activeFormat = availableFormats[0];
}
}
final String activeFormat = _activeFormat;
update.setProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT, activeFormat);
// Loop through all the requested properties and check if any of them are for the formatted value. In the
// same loop, try to see if the active format is already requested and if it's not request it at the end.
boolean activeFormatRequested = activeFormat == null;
for (Iterator<String> itr = update.getProperties().iterator(); itr.hasNext() || !activeFormatRequested;) {
String nextFormat;
if (itr.hasNext()) {
String propertyName = itr.next();
if (propertyName.startsWith(IDebugVMConstants.PROP_FORMATTED_VALUE_BASE)) {
nextFormat = FormattedValueVMUtil.getFormatFromProperty(propertyName);
if (nextFormat.equals(activeFormat)) {
activeFormatRequested = true;
}
if (availableFormats != null && !isFormatAvailable(nextFormat, availableFormats)) {
continue;
}
} else {
continue;
}
} else {
nextFormat = activeFormat;
activeFormatRequested = true;
}
final FormattedValueDMContext formattedValueDmc = service.getFormattedValueContext(dmc, nextFormat);
service.getFormattedExpressionValue(
formattedValueDmc,
// Here also use the ViewerDataRequestMonitor in order to propagate the update's cancel request.
// Use an immediate executor to avoid the possibility of a rejected execution exception.
new ViewerDataRequestMonitor<FormattedValueDMData>(ImmediateExecutor.getInstance(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
String format = formattedValueDmc.getFormatID();
update.setProperty(
FormattedValueVMUtil.getPropertyForFormatId(format),
getData().getFormattedValue());
if (format.equals(activeFormat)) {
update.setProperty(
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
getData().getFormattedValue());
}
} else {
update.setStatus(getStatus());
}
countingRm.done();
};
});
count++;
}
}
countingRm.setDoneCount(count);
}
private static boolean isFormatAvailable(String format, String[] availableFormats) {
for (String availableFormat : availableFormats) {
if (availableFormat.equals(format)) {
return true;
}
}
return false;
}
}

View file

@ -1,28 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006, 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.numberformat;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public interface IFormattedValuePreferenceStore {
/*
* Retrieves for the specified Presentation Context the configured format.
*
* @param context Specified Presentation Context
* @return Format ID.
*/
public String getCurrentNumericFormat( IPresentationContext context );
}

View file

@ -16,5 +16,4 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
* @since 1.0
*/
public interface IFormattedValueVMContext extends IVMContext {
IFormattedValuePreferenceStore getPreferenceStore();
}

View file

@ -20,15 +20,19 @@ public class MessagesForNumberFormat extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.messages"; //$NON-NLS-1$
public static String NumberFormatContribution_Natural_label;
public static String NumberFormatContribution_Decimal_label;
public static String NumberFormatContribution_Hex_label;
public static String NumberFormatContribution_Octal_label;
public static String NumberFormatContribution_Binary_label;
public static String NumberFormatContribution_String_label;
public static String FormattedValueVMUtil_Natural_format__label;
public static String FormattedValueVMUtil_Decimal_format__label;
public static String FormattedValueVMUtil_Hex_format__label;
public static String FormattedValueVMUtil_Octal_format__label;
public static String FormattedValueVMUtil_Binary_format__label;
public static String FormattedValueVMUtil_String_format__label;
public static String FormattedValueVMUtil_Other_format__format_text;
public static String NumberFormatContribution_EmptyFormatsList_label;
public static String FormattedValueLabelText__Value__text_format;
public static String FormattedValueLabelText__text_format;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForNumberFormat.class);

View file

@ -11,9 +11,8 @@
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
@ -37,24 +36,23 @@ import org.eclipse.ui.services.IServiceLocator;
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public class NumberFormatsContribution extends CompoundContributionItem implements IWorkbenchContribution {
private static final Map<String, String> FORMATS = new LinkedHashMap<String, String>();
private static final List<String> FORMATS = new LinkedList<String>();
static {
FORMATS.put(IFormattedValues.NATURAL_FORMAT, MessagesForNumberFormat.NumberFormatContribution_Natural_label);
FORMATS.put(IFormattedValues.HEX_FORMAT, MessagesForNumberFormat.NumberFormatContribution_Hex_label);
FORMATS.put(IFormattedValues.DECIMAL_FORMAT, MessagesForNumberFormat.NumberFormatContribution_Decimal_label);
FORMATS.put(IFormattedValues.OCTAL_FORMAT, MessagesForNumberFormat.NumberFormatContribution_Octal_label);
FORMATS.put(IFormattedValues.BINARY_FORMAT, MessagesForNumberFormat.NumberFormatContribution_Binary_label);
FORMATS.put(IFormattedValues.STRING_FORMAT, MessagesForNumberFormat.NumberFormatContribution_String_label);
FORMATS.add(IFormattedValues.NATURAL_FORMAT);
FORMATS.add(IFormattedValues.HEX_FORMAT);
FORMATS.add(IFormattedValues.DECIMAL_FORMAT);
FORMATS.add(IFormattedValues.OCTAL_FORMAT);
FORMATS.add(IFormattedValues.BINARY_FORMAT);
FORMATS.add(IFormattedValues.STRING_FORMAT);
}
private class SelectNumberFormatAction extends Action {
private final IPresentationContext fContext;
private final String fFormatId;
SelectNumberFormatAction(IPresentationContext context, String formatId) {
super(FORMATS.get(formatId), AS_RADIO_BUTTON);
super(FormattedValueVMUtil.getFormatLabel(formatId), AS_RADIO_BUTTON);
fContext = context;
fFormatId = formatId;
}
@ -62,7 +60,7 @@ public class NumberFormatsContribution extends CompoundContributionItem implemen
@Override
public void run() {
if (isChecked()) {
fContext.setProperty(IDebugVMConstants.CURRENT_FORMAT_STORAGE, fFormatId);
fContext.setProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, fFormatId);
}
}
}
@ -95,13 +93,13 @@ public class NumberFormatsContribution extends CompoundContributionItem implemen
}
IPresentationContext context = provider.getPresentationContext();
Object activeId = context.getProperty(IDebugVMConstants.CURRENT_FORMAT_STORAGE);
Object activeId = context.getProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
if (activeId == null) {
activeId = IFormattedValues.NATURAL_FORMAT;
}
List<Action> actions = new ArrayList<Action>(FORMATS.size());
for (String formatId : FORMATS.keySet()) {
for (String formatId : FORMATS) {
Action action = new SelectNumberFormatAction(context, formatId);
if (formatId.equals(activeId)) {
action.setChecked(true);

View file

@ -81,7 +81,7 @@ public class NumberFormatsPropertyTester extends PropertyTester {
} else if (AVAILABLE.equals(property)) {
return AVAILABLE_FORMATS.contains(expectedValue);
} else if (ACTIVE.equals(property)) {
Object activeId = provider.getPresentationContext().getProperty(IDebugVMConstants.CURRENT_FORMAT_STORAGE);
Object activeId = provider.getPresentationContext().getProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
return expectedValue != null && expectedValue.equals(activeId);
}
return false;

View file

@ -9,11 +9,21 @@
# Wind River Systems Inc - copied for non-restricted version for DSDP/DD/DSF
###############################################################################
NumberFormatContribution_Natural_label=Default
NumberFormatContribution_Decimal_label=Decimal
NumberFormatContribution_Hex_label=Hex
NumberFormatContribution_Octal_label=Octal
NumberFormatContribution_Binary_label=Binary
NumberFormatContribution_String_label=String
FormattedValueVMUtil_Natural_format__label=Default
FormattedValueVMUtil_Decimal_format__label=Decimal
FormattedValueVMUtil_Hex_format__label=Hex
FormattedValueVMUtil_Octal_format__label=Octal
FormattedValueVMUtil_Binary_format__label=Binary
FormattedValueVMUtil_String_format__label=String
FormattedValueVMUtil_Other_format__format_text=Other ({0})
NumberFormatContribution_EmptyFormatsList_label=Number formats not available
NumberFormatContribution_EmptyFormatsList_label=Number formats not available
# Message format used for cases where the value is formatted in a format that
# is not configured as the preferred format for the view or item.
# {0} - formatted value
# {1} - name of the format used to format the value
FormattedValueLabelText__Value__text_format={0} ({1})
# {0} - Value string as formatted by ValueLabelText__Value__text_format.
FormattedValueLabelText__text_format={0}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* 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.register;
/**
* @since 2.0
*/
public interface IRegisterVMConstants {
public static final String PROP_DESCRIPTION = "description"; //$NON-NLS-1$
public static final String PROP_IS_FLOAT = "is_float"; //$NON-NLS-1$
public static final String PROP_IS_READABLE = "is_readable"; //$NON-NLS-1$
public static final String PROP_IS_READONCE = "is_readonce"; //$NON-NLS-1$
public static final String PROP_IS_WRITEABLE = "is_writeable"; //$NON-NLS-1$
public static final String PROP_IS_WRITEONCE = "is_writeonce"; //$NON-NLS-1$
public static final String PROP_HAS_SIDE_EFFECTS = "has_side_effects"; //$NON-NLS-1$
public static final String PROP_IS_ZERO_BASED_NUMBERING = "is_zero_based_numbering"; //$NON-NLS-1$
public static final String PROP_IS_ZERO_BIT_LEFT_MOST = "is_zero_bit_left_most"; //$NON-NLS-1$
public static final String PROP_CURRENT_MNEMONIC_LONG_NAME = "mnemonic_long_name"; //$NON-NLS-1$
public static final String PROP_CURRENT_MNEMONIC_SHORT_NAME = "mnemonic_short_name"; //$NON-NLS-1$
}

View file

@ -19,12 +19,34 @@ public class MessagesForRegisterVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.register.messages"; //$NON-NLS-1$
public static String RegisterColumnPresentation_description;
public static String RegisterColumnPresentation_name;
public static String RegisterColumnPresentation_type;
public static String RegisterColumnPresentation_value;
public static String RegisterGroupVMNode_Name_column__text_format;
public static String RegisterGroupVMNode_Description_column__text_format;
public static String RegisterGroupVMNode_Expression_column__text_format;
public static String RegisterGroupVMNode_No_columns__text_format;
public static String RegisterGroupVMNode_No_columns__Error__text_format;
public static String RegisterVMNode_Description_column__text_format;
public static String RegisterVMNode_Name_column__text_format;
public static String RegisterVMNode_Expression_column__text_format;
public static String RegisterVMNode_Type_column__text_format;
public static String RegisterVMNode_No_columns__text_format;
public static String RegisterVMNode_No_columns__Error__text_format;
public static String RegisterBitFieldVMNode_Name_column__text_format;
public static String RegisterBitFieldVMNode_Description_column__text_format;
public static String RegisterBitFieldVMNode_Type_column__text_format;
public static String RegisterBitFieldVMNode_Value_column__With_mnemonic__text_format;
public static String RegisterBitFieldVMNode_Expression_column__text_format;
public static String RegisterBitFieldVMNode_No_columns__text_format;
public static String RegisterBitFieldVMNode_No_columns__With_mnemonic__text_format;
public static String RegisterBitFieldVMNode_No_columns__Error__text_format;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForRegisterVM.class);

View file

@ -18,7 +18,7 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IMnemonic;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.update.AbstractCachingVMProvider;
@ -35,15 +35,16 @@ public class RegisterBitFieldCellModifier extends WatchExpressionCellModifier {
private IBitFieldDMData fBitFieldData = null;
private Object fElement = null;
private SyncRegisterDataAccess fDataAccess = null;
private IFormattedValuePreferenceStore fFormatPrefStore;
/**
* @since 2.0
*/
public RegisterBitFieldCellModifier(AbstractCachingVMProvider provider,
IFormattedValuePreferenceStore formatPrefStore, BitFieldEditorStyle style, SyncRegisterDataAccess access )
BitFieldEditorStyle style, SyncRegisterDataAccess access )
{
fProvider = provider;
fStyle = style;
fDataAccess = access;
fFormatPrefStore = formatPrefStore;
}
/*
@ -109,8 +110,7 @@ public class RegisterBitFieldCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;
@ -167,8 +167,7 @@ public class RegisterBitFieldCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fFormatPrefStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;

View file

@ -10,8 +10,11 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.register;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
@ -19,10 +22,7 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
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.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldChangedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMContext;
@ -33,24 +33,34 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.ErrorLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterBitFieldCellModifier.BitFieldEditorStyle;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColor;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelFont;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.update.ICachingVMProvider;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
@ -61,6 +71,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRe
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.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
import org.eclipse.jface.resource.JFaceResources;
@ -70,11 +81,11 @@ import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
implements IElementEditor, IElementLabelProvider, IElementMementoProvider
implements IElementEditor, IElementLabelProvider, IElementMementoProvider, IElementPropertiesProvider
{
protected class BitFieldVMC extends DMVMContext
implements IFormattedValueVMContext
@ -84,10 +95,6 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
super(dmc);
}
public IFormattedValuePreferenceStore getPreferenceStore() {
return fFormattedPrefStore;
}
public void setExpression(IExpression expression) {
fExpression = expression;
}
@ -150,12 +157,19 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
private SyncRegisterDataAccess fSyncRegisterDataAccess = null;
protected IWatchExpressionFactoryAdapter2 fBitFieldExpressionFactory = null;
private final IFormattedValuePreferenceStore fFormattedPrefStore;
public RegisterBitFieldVMNode(IFormattedValuePreferenceStore prefStore, AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess access) {
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public RegisterBitFieldVMNode(AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess access) {
super(provider, session, IBitFieldDMContext.class);
fSyncRegisterDataAccess = access;
fFormattedPrefStore = prefStore;
fLabelProvider = createLabelProvider();
}
@ -164,10 +178,185 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
return "RegisterBitFieldVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
public IFormattedValuePreferenceStore getPreferenceStore() {
return fFormattedPrefStore;
}
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
// The name column consists of the bit field name.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__NAME,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_Name_column__text_format,
new String[] { PROP_NAME }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// The description column contains a brief description of the bit field.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__DESCRIPTION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_Description_column__text_format,
new String[] { IRegisterVMConstants.PROP_DESCRIPTION }),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// In the type column add information about bit field read/write/fload flags.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__TYPE,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_Type_column__text_format,
new String[] {
IRegisterVMConstants.PROP_IS_READABLE, IRegisterVMConstants.PROP_IS_READONCE,
IRegisterVMConstants.PROP_IS_WRITEABLE, IRegisterVMConstants.PROP_IS_WRITEONCE
})
{
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
int readAttr = 0;
if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_READABLE)) ) {
readAttr = 1;
} else if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_READONCE)) ) {
readAttr = 2;
}
int writeAttr = 0;
if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_WRITEABLE)) ) {
writeAttr = 1;
} else if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_WRITEONCE)) ) {
writeAttr = 2;
}
Object[] messageAttrs = new Object[] { readAttr, writeAttr };
try {
update.setLabel(getMessageFormat().format(
messageAttrs, new StringBuffer(), null).toString(), columnIndex);
} catch (IllegalArgumentException e) {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, 0, "Failed formatting a message for column " + columnIndex + ", for update " + update, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// Value column shows the value in the active value format, followed by the active mnemonic if one is
// available.
//
// In case of error, show the error message in the value column (instead of the usual "...". This is needed
// for the expressions view, where an invalid expression entered by the user is a normal use case.
//
// For changed value high-lighting check the value in the active format. But if the format itself has changed,
// ignore the value change.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__VALUE,
new LabelColumnInfo(new LabelAttribute[] {
new FormattedValueLabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_Value_column__With_mnemonic__text_format,
new String[] {
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IRegisterVMConstants.PROP_CURRENT_MNEMONIC_LONG_NAME}),
new FormattedValueLabelText(),
new ErrorLabelText(),
new LabelColor(new RGB(255, 0, 0), null) // TODO: replace with preference error color
{
{ setPropertyNames(new String[] { PROP_NAME }); }
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
return !status.isOK();
}
},
new LabelColor(
null,
DebugUITools.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB())
{
{
setPropertyNames(new String[] {
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT});
}
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
Boolean activeFormatChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
Boolean activeChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
return Boolean.TRUE.equals(activeChanged) && !Boolean.TRUE.equals(activeFormatChanged);
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// Expression column is visible only in the expressions view. It shows the expression string that the user
// entered. Expression column images are the same as for the name column.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__EXPRESSION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_Expression_column__text_format,
new String[] { PROP_ELEMENT_EXPRESSION }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new FormattedValueLabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_No_columns__With_mnemonic__text_format,
new String[] {
PROP_NAME,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IRegisterVMConstants.PROP_CURRENT_MNEMONIC_LONG_NAME}),
new FormattedValueLabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_No_columns__With_mnemonic__text_format,
new String[] {
PROP_NAME,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE}),
new ErrorLabelText(
MessagesForRegisterVM.RegisterBitFieldVMNode_No_columns__Error__text_format,
new String[] { PROP_NAME }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelColor(
DebugUITools.getPreferenceColor(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR).getRGB(),
null)
{
{
setPropertyNames(new String[] {
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT});
}
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
Boolean activeFormatChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
Boolean activeChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
return Boolean.TRUE.equals(activeChanged) && !Boolean.TRUE.equals(activeFormatChanged);
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
return provider;
}
/**
* @since 1.1
*/
@ -185,286 +374,103 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
return fBitFieldExpressionFactory;
}
/**
* Private data access routine which performs the extra level of data access needed to
* get the formatted data value for a specific register.
*/
private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IBitFieldDMContext dmc, final IBitFieldDMData data)
{
final IRegisters regService = getServicesTracker().getService(IRegisters.class);
/*
* First select the format to be used. This involves checking so see that the preference
* page format is supported by the register service. If the format is not supported then
* we will pick the first available format.
*/
final IPresentationContext context = update.getPresentationContext();
final String preferencePageFormatId = fFormattedPrefStore.getCurrentNumericFormat(context) ;
regService.getAvailableFormats(
dmc,
new ViewerDataRequestMonitor<String[]>(getSession().getExecutor(), update) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
handleFailedUpdate(update);
return;
}
/*
* See if the desired format is supported.
*/
String[] formatIds = getData();
String finalFormatId = IFormattedValues.HEX_FORMAT;
boolean requestedFormatIsSupported = false;
for ( String fId : formatIds ) {
if ( preferencePageFormatId.equals(fId) ) {
/*
* Desired format is supported.
*/
finalFormatId = preferencePageFormatId;
requestedFormatIsSupported = true;
break;
}
}
if ( ! requestedFormatIsSupported ) {
/*
* Desired format is not supported. If there are any formats supported
* then use the first available.
*/
if ( formatIds.length != 0 ) {
finalFormatId = formatIds[0];
}
else {
/*
* Register service does not support any format.
*/
handleFailedUpdate(update);
return;
}
}
/*
* Format has been validated. Get the formatted value.
*/
final FormattedValueDMContext valueDmc = regService.getFormattedValueContext(dmc, finalFormatId);
getDMVMProvider().getModelData(
RegisterBitFieldVMNode.this, update, regService, valueDmc,
new ViewerDataRequestMonitor<FormattedValueDMData>(getSession().getExecutor(), update) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) {
update.setLabel("...", labelIndex); //$NON-NLS-1$
} else {
update.setLabel("Error: " + getStatus().getMessage(), labelIndex); //$NON-NLS-1$
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex);
update.done();
return;
}
/*
* Fill the label/column with the properly formatted data value.
*/
IMnemonic mnemonic = data.getCurrentMnemonicValue();
if ( mnemonic != null ) {
String mnemstr = mnemonic.getLongName() + " - " + getData().getFormattedValue(); //$NON-NLS-1$
update.setLabel(mnemstr , labelIndex);
}
else {
update.setLabel(getData().getFormattedValue() , labelIndex);
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], labelIndex);
// color based on change history
FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData(
RegisterBitFieldVMNode.this, update, valueDmc);
if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) {
update.setBackground(
DebugUIPlugin.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), labelIndex);
}
update.done();
}
},
getExecutor()
);
}
}
);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[])
*/
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
/*
* Updates the requested label based on the specified column.
/**
* @since 2.0
*/
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
final IRegisters regService = getServicesTracker().getService(IRegisters.class);
if ( regService == null ) {
handleFailedUpdate(update);
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IRegisters service = getServicesTracker().getService(IRegisters.class, null);
final CountingRequestMonitor countingRm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
for (final IPropertiesUpdate update : updates) {
update.done();
}
};
};
int count = 0;
if (service != null) {
FormattedValueVMUtil.updateFormattedValues(updates, service, IBitFieldDMContext.class, countingRm);
count++;
}
for (final IPropertiesUpdate update : updates) {
IExpression expression = (IExpression)DebugPlugin.getAdapter(update.getElement(), IExpression.class);
if (expression != null) {
update.setProperty(AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION, expression.getExpressionText());
}
IBitFieldDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IBitFieldDMContext.class);
if (dmc == null || service == null) {
handleFailedUpdate(update);
continue;
}
final IBitFieldDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IBitFieldDMContext.class);
getDMVMProvider().getModelData(
this,
update,
regService,
dmc,
service.getBitFieldData(
dmc,
// Use the ViewerDataRequestMonitor in order to propagate the update's cancel request. Use an immediate
// executor to avoid the possibility of a rejected execution exception.
new ViewerDataRequestMonitor<IBitFieldDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
/*
* Check that the request was evaluated and data is still
* valid. The request could fail if the state of the
* service changed during the request, but the view model
* has not been updated yet.
*/
if (!isSuccess()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR ||
getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED;
/*
* Instead of just failing this outright we are going to attempt to do more here.
* Failing it outright causes the view to display ... for all columns in the line
* and this is uninformative about what is happening. We may be trying to show a
* register whos retrieval has been cancelled by the lower level. Perhaps because
* we are stepping extremely fast and state changes cause the register service to
* return these requests without ever sending them to the debug engine.
*
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null)
localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
for (int idx = 0; idx < localColumns.length; idx++) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
/*
* This used to be easy in that the DMC contained the name. Which allowed us
* to display the register name and an error message across from it. Now that
* name must come from the data and we could not retrieve the data we do not
* have anything intelligent to show here. I think this is going to look very
* ugly and will need to be worked on. We know the service has the name with
* it, it is just the dynamic part which cannot be obtained ( as explained in
* comments above ).
*/
update.setLabel("Unknown name", idx); //$NON-NLS-1$
update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx);
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) {
update.setLabel("", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) {
update.setLabel("...", idx); //$NON-NLS-1$
} else {
update.setLabel("Error: " + getStatus().getMessage(), idx); //$NON-NLS-1$
}
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
update.setLabel("...", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
update.setLabel("", idx); //$NON-NLS-1$
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
}
update.done();
return;
}
/*
* If columns are configured, extract the selected values for each
* understood column. First we fill all of those columns which can
* be filled without the extra data mining. We also note if we do
* have to datamine. Any columns need to set the processing flag
* so we know we have further work to do. If there are more columns
* which need data extraction they need to be added in both "for"
* loops.
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
boolean weAreExtractingFormattedData = false;
for (int idx = 0; idx < localColumns.length; idx++) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
update.setLabel(getData().getName(), idx);
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
weAreExtractingFormattedData = true;
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) {
IBitFieldDMData data = getData();
String typeStr = "Unsigned"; //$NON-NLS-1$
String ReadAttrStr = "ReadNone"; //$NON-NLS-1$
String WriteAddrStr = "WriteNone"; //$NON-NLS-1$
if ( data.isReadOnce() ) { ReadAttrStr = "ReadOnce"; } //$NON-NLS-1$
else if ( data.isReadable() ) { ReadAttrStr = "Readable"; } //$NON-NLS-1$
if ( data.isReadOnce() ) { WriteAddrStr = "WriteOnce"; } //$NON-NLS-1$
else if ( data.isReadable() ) { WriteAddrStr = "Writeable"; } //$NON-NLS-1$
typeStr += " - " + ReadAttrStr + "/" + WriteAddrStr; //$NON-NLS-1$ //$NON-NLS-2$
update.setLabel(typeStr, idx);
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
update.setLabel(getData().getDescription(), idx);
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
IVMContext vmc = (IVMContext)update.getElement();
IExpression expression = (IExpression)vmc.getAdapter(IExpression.class);
if (expression != null) {
update.setLabel(expression.getExpressionText(), idx);
} else {
update.setLabel(getData().getName(), idx);
}
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
}
if ( ! weAreExtractingFormattedData ) {
update.done();
if (isSuccess()) {
fillBitFieldDataProperties(update, getData());
} else {
for (int idx = 0; idx < localColumns.length; idx++) {
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
updateFormattedRegisterValue(update, idx, dmc, getData() );
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
}
update.setStatus(getStatus());
}
countingRm.done();
}
},
getExecutor()
);
});
count++;
}
countingRm.setDoneCount(count);
}
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void fillBitFieldDataProperties(IPropertiesUpdate update, IBitFieldDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(IRegisterVMConstants.PROP_DESCRIPTION, data.getDescription());
update.setProperty(IRegisterVMConstants.PROP_IS_READABLE, data.isReadable());
update.setProperty(IRegisterVMConstants.PROP_IS_READONCE, data.isReadOnce());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEABLE, data.isWriteable());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEONCE, data.isWriteOnce());
update.setProperty(IRegisterVMConstants.PROP_HAS_SIDE_EFFECTS, data.hasSideEffects());
update.setProperty(IRegisterVMConstants.PROP_IS_ZERO_BIT_LEFT_MOST, data.isZeroBitLeftMost());
update.setProperty(IRegisterVMConstants.PROP_IS_ZERO_BASED_NUMBERING, data.isZeroBasedNumbering());
IMnemonic mnemonic = data.getCurrentMnemonicValue();
if (mnemonic != null) {
update.setProperty(IRegisterVMConstants.PROP_CURRENT_MNEMONIC_LONG_NAME, mnemonic.getLongName());
update.setProperty(IRegisterVMConstants.PROP_CURRENT_MNEMONIC_SHORT_NAME, mnemonic.getShortName());
}
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode#updateElementsInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate)
*/
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
final IRegisterDMContext regDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterDMContext.class);
@ -516,7 +522,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
e instanceof IMemoryChangedEvent ||
e instanceof IRegisterChangedDMEvent ||
(e instanceof PropertyChangeEvent &&
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
return IModelDelta.CONTENT;
}
@ -539,7 +545,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
e instanceof IMemoryChangedEvent ||
e instanceof IRegisterChangedDMEvent ||
(e instanceof PropertyChangeEvent &&
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
}
@ -623,14 +629,14 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
* Note we are complex COMBO and return the right editor.
*/
return new RegisterBitFieldCellModifier(
getDMVMProvider(), fFormattedPrefStore, BitFieldEditorStyle.BITFIELDCOMBO, getSyncRegisterDataAccess() );
getDMVMProvider(), BitFieldEditorStyle.BITFIELDCOMBO, getSyncRegisterDataAccess() );
}
else {
/*
* Text editor even if we need to clamp the value entered.
*/
return new RegisterBitFieldCellModifier(
getDMVMProvider(), fFormattedPrefStore, BitFieldEditorStyle.BITFIELDTEXT, getSyncRegisterDataAccess() );
getDMVMProvider(), BitFieldEditorStyle.BITFIELDTEXT, getSyncRegisterDataAccess() );
}
}
else {
@ -769,7 +775,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
}
if (event instanceof PropertyChangeEvent &&
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) {
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) {
return IModelDelta.CONTENT;
}
@ -805,7 +811,7 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode
if ( event instanceof IRegisterChangedDMEvent ||
event instanceof IMemoryChangedEvent ||
(event instanceof PropertyChangeEvent &&
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
parentDelta.addNode(element, IModelDelta.STATE);
}

View file

@ -17,7 +17,7 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.update.AbstractCachingVMProvider;
@ -29,23 +29,17 @@ public class RegisterCellModifier extends WatchExpressionCellModifier {
private AbstractCachingVMProvider fProvider;
private SyncRegisterDataAccess fDataAccess = null;
private IFormattedValuePreferenceStore fFormattedValuePreferenceStore;
public RegisterCellModifier(AbstractCachingVMProvider provider,
IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncRegisterDataAccess access)
public RegisterCellModifier(AbstractCachingVMProvider provider, SyncRegisterDataAccess access)
{
fProvider = provider;
fDataAccess = access;
fFormattedValuePreferenceStore = formattedValuePreferenceStore;
}
public SyncRegisterDataAccess getRegisterDataAccess() {
return fDataAccess;
}
public IFormattedValuePreferenceStore getPreferenceStore() {
return fFormattedValuePreferenceStore;
}
/*
* Used to make sure we are dealing with a valid register.
*/
@ -102,8 +96,7 @@ public class RegisterCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;
@ -141,8 +134,7 @@ public class RegisterCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fFormattedValuePreferenceStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.register;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
@ -31,15 +32,22 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModi
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelFont;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
@ -50,6 +58,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRe
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.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
import org.eclipse.jface.resource.JFaceResources;
@ -59,10 +68,14 @@ import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
public class RegisterGroupVMNode extends AbstractExpressionVMNode
implements IElementEditor, IElementLabelProvider, IElementMementoProvider
implements IElementEditor, IElementLabelProvider, IElementMementoProvider, IElementPropertiesProvider
{
/**
* @since 2.0
*/
private static final String PROP_REGISTER_GROUP_DESCRIPTION = "register_group_description"; //$NON-NLS-1$
protected class RegisterGroupVMC extends DMVMContext
{
private IExpression fExpression;
@ -129,8 +142,17 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode
private IWatchExpressionFactoryAdapter2 fRegisterGroupExpressionFactory = null;
private WatchExpressionCellModifier fWatchExpressionCellModifier = new WatchExpressionCellModifier();
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public RegisterGroupVMNode(AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) {
super(provider, session, IRegisterGroupDMContext.class);
fLabelProvider = createLabelProvider();
fSyncRegisterDataAccess = syncDataAccess;
}
@ -152,11 +174,7 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode
}
return fRegisterGroupExpressionFactory;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode#updateElementsInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate)
*/
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
@ -180,131 +198,131 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode
update.done();
}});
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode#createVMContext(org.eclipse.cdt.dsf.datamodel.IDMContext)
*/
@Override
protected IDMVMContext createVMContext(IDMContext dmc) {
return new RegisterGroupVMC(dmc);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[])
*/
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
// The name column consists of the group name.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__NAME,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterGroupVMNode_Name_column__text_format,
new String[] { PROP_NAME }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// The description column contains a brief description of the register group.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__DESCRIPTION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(MessagesForRegisterVM.RegisterGroupVMNode_Description_column__text_format,
new String[] { PROP_REGISTER_GROUP_DESCRIPTION }),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// Expression column is visible only in the expressions view. It shows the expression string that the user
// entered. Expression column images are the same as for the name column.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__EXPRESSION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterGroupVMNode_Expression_column__text_format,
new String[] { PROP_ELEMENT_EXPRESSION }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(MessagesForRegisterVM.RegisterGroupVMNode_No_columns__text_format,
new String[] { PROP_NAME, PROP_REGISTER_GROUP_DESCRIPTION}),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
return provider;
}
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
/*
* Updates the labels with the required information for each visible column.
/**
* @since 2.0
*/
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
final IRegisterGroupDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterGroupDMContext.class);
if ( dmc == null ) {
handleFailedUpdate(update);
continue;
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
IRegisters service = getServicesTracker().getService(IRegisters.class, null);
for (final IPropertiesUpdate update : updates) {
IExpression expression = (IExpression)DebugPlugin.getAdapter(update.getElement(), IExpression.class);
if (expression != null) {
update.setProperty(AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION, expression.getExpressionText());
}
IRegisterGroupDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterGroupDMContext.class);
IRegisters regService = getServicesTracker().getService(IRegisters.class);
if ( regService == null ) {
if ( dmc == null || regService == null) {
handleFailedUpdate(update);
continue;
return;
}
getDMVMProvider().getModelData(
this,
update,
regService,
service.getRegisterGroupData(
dmc,
new ViewerDataRequestMonitor<IRegisterGroupDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
/*
* Check that the request was evaluated and data is still
* valid. The request could fail if the state of the
* service changed during the request, but the view model
* has not been updated yet.
*/
if (!isSuccess()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR ||
getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED;
handleFailedUpdate(update);
return;
}
/*
* If columns are configured, call the protected methods to
* fill in column values.
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null) localColumns = new String[] { null };
for (int i = 0; i < localColumns.length; i++) {
fillColumnLabel(dmc, getData(), localColumns[i], i, update);
}
protected void handleSuccess() {
fillRegisterGroupDataProperties(update, getData());
update.done();
}
},
getExecutor());
});
}
}
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void fillRegisterGroupDataProperties(IPropertiesUpdate update, IRegisterGroupDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(PROP_REGISTER_GROUP_DESCRIPTION, data.getName());
}
/*
* Based on the specified visible column, provide the appropriate value/label.
*/
protected void fillColumnLabel(IRegisterGroupDMContext dmContext, IRegisterGroupDMData dmData,
String columnId, int idx, ILabelUpdate update)
{
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) {
update.setLabel(dmData.getName(), idx);
update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP), idx);
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
update.setLabel("", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(columnId)) {
update.setLabel(dmData.getDescription(), idx);
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(columnId)) {
update.setLabel("", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) {
IVMContext vmc = (IVMContext)update.getElement();
IExpression expression = (IExpression)vmc.getAdapter(IExpression.class);
if (expression != null) {
update.setLabel(expression.getExpressionText(), idx);
} else {
update.setLabel(dmData.getName(), idx);
}
}
else if ( columnId == null ) {
/*
* If the Column ID comes in as "null" then this is the case where the user has decided
* to not have any columns. So we need a default action which makes the most sense and
* is doable. In this case we elect to simply display the name.
*/
update.setLabel(dmData.getName(), idx);
update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER_GROUP), idx);
}
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.IVMNode#getDeltaFlags(java.lang.Object)
*/
public int getDeltaFlags(Object e) {
if (e instanceof ISuspendedDMEvent) {
return IModelDelta.CONTENT;
@ -318,10 +336,6 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode
return IModelDelta.NO_CHANGE;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.ui.viewmodel.IVMNode#buildDelta(java.lang.Object, org.eclipse.cdt.dsf.ui.viewmodel.VMDelta, int, org.eclipse.cdt.dsf.concurrent.RequestMonitor)
*/
public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
// Although the register groups themselves are not affected by the
// suspended event, typically all the registers are. Add a CONTENT changed
@ -341,10 +355,6 @@ public class RegisterGroupVMNode extends AbstractExpressionVMNode
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.IExpressionVMNode#canParseExpression(org.eclipse.debug.core.model.IExpression)
*/
public boolean canParseExpression(IExpression expression) {
return parseExpressionForGroupName(expression.getExpressionText()) != null;
}

View file

@ -10,22 +10,19 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.register;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
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.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterChangedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
@ -33,23 +30,33 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegistersChangedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.ErrorLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValueVMContext;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColor;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelFont;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.update.ICachingVMProvider;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
@ -61,6 +68,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat
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.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
import org.eclipse.jface.resource.JFaceResources;
@ -69,11 +77,14 @@ import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
@SuppressWarnings("restriction")
/**
* @since 1.0
*/
public class RegisterVMNode extends AbstractExpressionVMNode
implements IElementEditor, IElementLabelProvider, IElementMementoProvider
implements IElementEditor, IElementLabelProvider, IElementMementoProvider, IElementPropertiesProvider
{
protected class RegisterVMC extends DMVMContext
implements IFormattedValueVMContext
@ -113,10 +124,6 @@ public class RegisterVMNode extends AbstractExpressionVMNode
public int hashCode() {
return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0);
}
public IFormattedValuePreferenceStore getPreferenceStore() {
return fFormattedPrefStore;
}
}
protected class RegisterExpressionFactory implements IWatchExpressionFactoryAdapter2 {
@ -147,14 +154,192 @@ public class RegisterVMNode extends AbstractExpressionVMNode
private IWatchExpressionFactoryAdapter2 fRegisterExpressionFactory = null;
final private SyncRegisterDataAccess fSyncRegisterDataAccess;
private final IFormattedValuePreferenceStore fFormattedPrefStore;
public RegisterVMNode(IFormattedValuePreferenceStore prefStore, AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) {
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
public RegisterVMNode(AbstractDMVMProvider provider, DsfSession session, SyncRegisterDataAccess syncDataAccess) {
super(provider, session, IRegisterDMContext.class);
fSyncRegisterDataAccess = syncDataAccess;
fFormattedPrefStore = prefStore;
fLabelProvider = createLabelProvider();
}
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
// The name column consists of the register name.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__NAME,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterVMNode_Name_column__text_format,
new String[] { PROP_NAME }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// The description column contains a brief description of the register.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__DESCRIPTION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterVMNode_Description_column__text_format,
new String[] { IRegisterVMConstants.PROP_DESCRIPTION }),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// In the type column add information about register read/write/fload flags.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__TYPE,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterVMNode_Type_column__text_format,
new String[] {
IRegisterVMConstants.PROP_IS_FLOAT, IRegisterVMConstants.PROP_IS_READABLE, IRegisterVMConstants.PROP_IS_READONCE,
IRegisterVMConstants.PROP_IS_WRITEABLE, IRegisterVMConstants.PROP_IS_WRITEONCE
})
{
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
int type = 0;
if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_FLOAT)) ) {
type = 1;
}
int readAttr = 0;
if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_READABLE)) ) {
readAttr = 1;
} else if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_READONCE)) ) {
readAttr = 2;
}
int writeAttr = 0;
if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_WRITEABLE)) ) {
writeAttr = 1;
} else if ( Boolean.TRUE.equals(properties.get(IRegisterVMConstants.PROP_IS_WRITEONCE)) ) {
writeAttr = 2;
}
Object[] messageAttrs = new Object[] { type, readAttr, writeAttr };
try {
update.setLabel(getMessageFormat().format(
messageAttrs, new StringBuffer(), null).toString(), columnIndex);
} catch (IllegalArgumentException e) {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, 0, "Failed formatting a message for column " + columnIndex + ", for update " + update, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// Value column shows the value in the active value format.
//
// In case of error, show the error message in the value column (instead of the usual "...". This is needed
// for the expressions view, where an invalid expression entered by the user is a normal use case.
//
// For changed value high-lighting check the value in the active format. But if the format itself has changed,
// ignore the value change.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__VALUE,
new LabelColumnInfo(new LabelAttribute[] {
new FormattedValueLabelText(),
new ErrorLabelText(),
new LabelColor(new RGB(255, 0, 0), null) // TODO: replace with preference error color
{
{ setPropertyNames(new String[] { PROP_NAME }); }
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
return !status.isOK();
}
},
new LabelColor(
null,
DebugUITools.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB())
{
{
setPropertyNames(new String[] {
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT});
}
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
Boolean activeFormatChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
Boolean activeChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
return Boolean.TRUE.equals(activeChanged) && !Boolean.TRUE.equals(activeFormatChanged);
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
// Expression column is visible only in the expressions view. It shows the expression string that the user
// entered. Expression column images are the same as for the name column.
provider.setColumnInfo(
IDebugVMConstants.COLUMN_ID__EXPRESSION,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(
MessagesForRegisterVM.RegisterVMNode_Expression_column__text_format,
new String[] { PROP_ELEMENT_EXPRESSION }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new FormattedValueLabelText(
MessagesForRegisterVM.RegisterVMNode_No_columns__text_format,
new String[] { PROP_NAME, IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE }),
new ErrorLabelText(
MessagesForRegisterVM.RegisterVMNode_No_columns__Error__text_format,
new String[] { PROP_NAME }),
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER)),
new LabelColor(
DebugUITools.getPreferenceColor(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR).getRGB(),
null)
{
{
setPropertyNames(new String[] {
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE,
IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT,
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT});
}
@Override
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
Boolean activeFormatChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
Boolean activeChanged = (Boolean)properties.get(
ICachingVMProvider.PROP_IS_CHANGED_PREFIX + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
return Boolean.TRUE.equals(activeChanged) && !Boolean.TRUE.equals(activeFormatChanged);
}
},
new LabelFont(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0])
}));
return provider;
}
@Override
public String toString() {
return "RegisterVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
@ -164,10 +349,6 @@ public class RegisterVMNode extends AbstractExpressionVMNode
return fSyncRegisterDataAccess;
}
public IFormattedValuePreferenceStore getPreferenceStore() {
return fFormattedPrefStore;
}
/**
* @since 1.1
*/
@ -177,398 +358,105 @@ public class RegisterVMNode extends AbstractExpressionVMNode
}
return fRegisterExpressionFactory;
}
/*
* This class is used to hold the associated information needed to finally get the
* formatted value for a register DMC. It starts out with the basic set sans the
* actual formatted register DMC. Once found this is added to the information.
*/
private class QueuedValueUpdate {
ILabelUpdate fUpdate;
int fIndex ;
IRegisterDMContext fDmc;
FormattedValueDMContext fValueDmc = null;
public QueuedValueUpdate( ILabelUpdate update, int index , IRegisterDMContext dmc ) {
fUpdate = update;
fIndex = index;
fDmc = dmc;
}
public ILabelUpdate getUpdate() { return fUpdate; }
public int getIndex() { return fIndex; }
public IRegisterDMContext getDmc() { return fDmc; }
public void setValueDmc( FormattedValueDMContext dmc ) { fValueDmc = dmc; }
public FormattedValueDMContext getValueDmc() { return fValueDmc; }
}
private void retrieveAllFormattedDataValues( final ArrayList<QueuedValueUpdate> updates ) {
final IRegisters regService = getServicesTracker().getService(IRegisters.class);
if ( regService == null ) {
for ( final QueuedValueUpdate up : updates ) {
handleFailedUpdate(up.getUpdate());
}
return;
}
for ( final QueuedValueUpdate up : updates ) {
final ILabelUpdate update = up.getUpdate();
final FormattedValueDMContext valueDmc = up.getValueDmc();
/*
* It is possible that we could not get a formatted DMC. In this case the setup
* logic puts a null as the value. So in this case we just complete this one
* with nothing.
*/
if ( valueDmc == null ) {
update.done();
continue;
}
final int idx = up.getIndex();
getDMVMProvider().getModelData(
RegisterVMNode.this,
update,
regService,
valueDmc,
new ViewerDataRequestMonitor<FormattedValueDMData>(getSession().getExecutor(), update) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) {
update.setLabel("...", idx); //$NON-NLS-1$
} else {
update.setLabel("Error: " + getStatus().getMessage(), idx); //$NON-NLS-1$
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
update.done();
return;
}
/*
* Fill the label/column with the properly formatted data value.
*/
update.setLabel(getData().getFormattedValue(), idx);
// color based on change history
FormattedValueDMData oldData = (FormattedValueDMData) getDMVMProvider().getArchivedModelData(RegisterVMNode.this, update, valueDmc);
if(oldData != null && !oldData.getFormattedValue().equals(getData().getFormattedValue())) {
update.setBackground(DebugUIPlugin.getPreferenceColor(IInternalDebugUIConstants.PREF_CHANGED_VALUE_BACKGROUND).getRGB(), idx);
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
update.done();
}
},
getSession().getExecutor()
);
}
}
/**
* Private data access routine which performs the extra level of data access needed to
* get the formatted data value for a specific register.
*/
private void getFormattedDmcForReqister( final ILabelUpdate update, final IRegisterDMContext dmc, final DataRequestMonitor<FormattedValueDMContext> rm)
{
final IRegisters regService = getServicesTracker().getService(IRegisters.class);
if ( regService == null ) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$
rm.done();
return;
}
/*
* First select the format to be used. This involves checking so see that the preference
* page format is supported by the register service. If the format is not supported then
* we will pick the first available format.
*/
final IPresentationContext context = update.getPresentationContext();
final String preferencePageFormatId = getPreferenceStore().getCurrentNumericFormat(context) ;
regService.getAvailableFormats(
dmc,
new DataRequestMonitor<String[]>(getSession().getExecutor(), rm) {
@Override
public void handleSuccess() {
/*
* See if the desired format is supported.
*/
String[] formatIds = getData();
String finalFormatId = IFormattedValues.NATURAL_FORMAT;
boolean requestedFormatIsSupported = false;
for ( String fId : formatIds ) {
if ( preferencePageFormatId.equals(fId) ) {
/*
* Desired format is supported.
*/
finalFormatId = preferencePageFormatId;
requestedFormatIsSupported = true;
break;
}
}
if ( ! requestedFormatIsSupported ) {
/*
* Desired format is not supported. If there are any formats supported
* then use the first available.
*/
if ( formatIds.length != 0 ) {
finalFormatId = formatIds[0];
}
else {
/*
* Register service does not support any format.
*/
handleFailure();
return;
}
}
/*
* Format has been validated. Return it.
*/
rm.setData(regService.getFormattedValueContext(dmc, finalFormatId));
rm.done();
}
}
);
}
/*
* (non-Javadoc)
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider#update(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[])
*/
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @see IElementPropertiesProvider#update(IPropertiesUpdate[])
*
* @since 2.0
*/
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
public void run() {
updateLabelInSessionThread(updates);
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (ILabelUpdate update : updates) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
/*
* Updates the labels which are controlled by the column being requested.
/**
* @since 2.0
*/
protected void updateLabelInSessionThread(final ILabelUpdate[] updates) {
/*
* This list represents all the QUEUED requests for formatted DMCs. This allows us to issue the
* requests for the data in the same dispatch cycle. Thus the lower level services is given its
* best chance to coalesce the registers in to a single request.
*/
final ArrayList<QueuedValueUpdate> valueUpdatesToProcess = new ArrayList<QueuedValueUpdate>();
final DsfExecutor dsfExecutor = getSession().getExecutor();
final CountingRequestMonitor crm =
new CountingRequestMonitor(dsfExecutor, null) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
for ( ILabelUpdate up : updates ) {
handleFailedUpdate(up);
}
return;
}
/*
* We have all of the formatted DMCs. Go issue the requests for the formatted data
* in a single dispatch cycle.
*/
retrieveAllFormattedDataValues( valueUpdatesToProcess );
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IRegisters service = getServicesTracker().getService(IRegisters.class, null);
final CountingRequestMonitor countingRm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), null) {
@Override
protected void handleCompleted() {
for (final IPropertiesUpdate update : updates) {
update.done();
}
};
crm.setDoneCount( calculateTheNumberOfRowsWithValueColumns(updates) );
};
int count = 0;
/*
* Process each update request, creating a QUEUE of requests which need further processing
* for the formatted values.
*/
for (final ILabelUpdate update : updates) {
final IRegisterDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterDMContext.class);
if ( dmc == null ) {
handleFailedUpdate(update);
continue;
}
IRegisters regService = getServicesTracker().getService(IRegisters.class);
if ( regService == null ) {
handleFailedUpdate(update);
continue;
}
getDMVMProvider().getModelData(
this,
update,
regService,
dmc,
new ViewerDataRequestMonitor<IRegisterDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
/*
* Check that the request was evaluated and data is still
* valid. The request could fail if the state of the
* service changed during the request, but the view model
* has not been updated yet.
*/
if (!isSuccess()) {
assert getStatus().isOK() ||
getStatus().getCode() != IDsfStatusConstants.INTERNAL_ERROR ||
getStatus().getCode() != IDsfStatusConstants.NOT_SUPPORTED;
/*
* Instead of just failing this outright we are going to attempt to do more here.
* Failing it outright causes the view to display ... for all columns in the line
* and this is uninformative about what is happening. We may be trying to show a
* register whos retrieval has been cancelled by the lower level. Perhaps because
* we are stepping extremely fast and state changes cause the register service to
* return these requests without ever sending them to the debug engine.
*
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null)
localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
for (int idx = 0; idx < localColumns.length; idx++) {
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
/*
* This used to be easy in that the DMC contained the name. Which allowed us
* to display the register name and an error message across from it. Now that
* name must come from the data and we could not retrieve the data we do not
* have anything intelligent to show here. I think this is going to look very
* ugly and will need to be worked on. We know the service has the name with
* it, it is just the dynamic part which cannot be obtained ( as explained in
* comments above ).
*/
update.setLabel("Unknown name", idx); //$NON-NLS-1$
update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx);
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) {
update.setLabel("", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
if (getStatus().getCode() == IDsfStatusConstants.INVALID_STATE) {
update.setLabel("...", idx); //$NON-NLS-1$
} else {
update.setLabel("Error: " + getStatus().getMessage(), idx); //$NON-NLS-1$
}
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
update.setLabel("...", idx); //$NON-NLS-1$
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
update.setLabel("", idx); //$NON-NLS-1$
}
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
}
update.done();
return;
}
/*
* If columns are configured, extract the selected values for each understood column. First we fill all
* of those columns which can be filled without the extra data mining. We also note, if we do have to
* datamine. Any columns need to set the processing flag so we know we have further work to do. If there
* are more columns which need data extraction they need to be added in both "for" loops.
*/
String[] localColumns = update.getColumnIds();
if (localColumns == null) localColumns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
boolean allFieldsProcessed = true;
for (int idx = 0; idx < localColumns.length; idx++) {
update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], idx);
if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
update.setLabel(getData().getName(), idx);
update.setImageDescriptor(DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_OBJS_REGISTER), idx);
} else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
allFieldsProcessed = false;
/*
* Create an entry which holds all related data and add it to the list to process
* when all the formatted DMCs are gathered.
*/
final QueuedValueUpdate valueUpdate = new QueuedValueUpdate(update,idx,dmc);
valueUpdatesToProcess.add(valueUpdate);
/*
* Fetch the associated formatted DMC for this field. Note that every time we
* complete the request for a Formatted DMC we tell the Counting Request Monitor
* we have completed one in the list.
*/
getFormattedDmcForReqister(
update, dmc,
new ViewerDataRequestMonitor<FormattedValueDMContext>(dsfExecutor, update) {
@Override
public void handleCompleted() {
if ( getStatus().isOK() ) {
valueUpdate.setValueDmc(getData());
}
else {
valueUpdate.setValueDmc(null);
}
crm.done();
}
});
} else if (IDebugVMConstants.COLUMN_ID__TYPE.equals(localColumns[idx])) {
IRegisterDMData data = getData();
String typeStr = "Unsigned"; //$NON-NLS-1$
String ReadAttrStr = "ReadNone"; //$NON-NLS-1$
String WriteAddrStr = "WriteNone"; //$NON-NLS-1$
if ( data.isFloat() ) { typeStr = "Floating Point"; } //$NON-NLS-1$
if ( data.isReadOnce() ) { ReadAttrStr = "ReadOnce"; } //$NON-NLS-1$
else if ( data.isReadable() ) { ReadAttrStr = "Readable"; } //$NON-NLS-1$
if ( data.isReadOnce() ) { WriteAddrStr = "WriteOnce"; } //$NON-NLS-1$
else if ( data.isReadable() ) { WriteAddrStr = "Writeable"; } //$NON-NLS-1$
typeStr += " - " + ReadAttrStr + "/" + WriteAddrStr; //$NON-NLS-1$ //$NON-NLS-2$
update.setLabel(typeStr, idx);
} else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
update.setLabel(getData().getDescription(), idx);
} else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) {
IVMContext vmc = (IVMContext)update.getElement();
IExpression expression = (IExpression)vmc.getAdapter(IExpression.class);
if (expression != null) {
update.setLabel(expression.getExpressionText(), idx);
} else {
update.setLabel(getData().getName(), idx);
}
}
}
if ( allFieldsProcessed ) {
update.done();
}
}
},
getSession().getExecutor());
if (service != null) {
FormattedValueVMUtil.updateFormattedValues(updates, service, IRegisterDMContext.class, countingRm);
count++;
}
for (final IPropertiesUpdate update : updates) {
IExpression expression = (IExpression)DebugPlugin.getAdapter(update.getElement(), IExpression.class);
if (expression != null) {
update.setProperty(AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION, expression.getExpressionText());
}
final IRegisterDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IRegisterDMContext.class);
if (dmc == null || service == null) {
handleFailedUpdate(update);
continue;
}
service.getRegisterData(
dmc,
// Use the ViewerDataRequestMonitor in order to propagate the update's cancel request. Use an immediate
// executor to avoid the possibility of a rejected execution exception.
new ViewerDataRequestMonitor<IRegisterDMData>(getSession().getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
fillRegisterDataProperties(update, getData());
update.setProperty(PROP_NAME, getData().getName());
update.setProperty(IRegisterVMConstants.PROP_DESCRIPTION, getData().getDescription());
update.setProperty(IRegisterVMConstants.PROP_IS_FLOAT, getData().isFloat());
update.setProperty(IRegisterVMConstants.PROP_IS_READABLE, getData().isReadable());
update.setProperty(IRegisterVMConstants.PROP_IS_READONCE, getData().isReadOnce());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEABLE, getData().isWriteable());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEONCE, getData().isWriteOnce());
} else {
update.setStatus(getStatus());
}
countingRm.done();
}
});
count++;
}
countingRm.setDoneCount(count);
}
private int calculateTheNumberOfRowsWithValueColumns( ILabelUpdate updates[] ) {
int count = 0;
for (final ILabelUpdate update : updates) {
String[] columns = update.getColumnIds();
if (columns == null) columns = new String[] { IDebugVMConstants.COLUMN_ID__NAME };
for (int idx = 0; idx < columns.length; idx++) {
if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columns[idx])) {
count ++;
}
}
}
return count;
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void fillRegisterDataProperties(IPropertiesUpdate update, IRegisterDMData data)
{
update.setProperty(PROP_NAME, data.getName());
update.setProperty(IRegisterVMConstants.PROP_DESCRIPTION, data.getDescription());
update.setProperty(IRegisterVMConstants.PROP_IS_FLOAT, data.isFloat());
update.setProperty(IRegisterVMConstants.PROP_IS_READABLE, data.isReadable());
update.setProperty(IRegisterVMConstants.PROP_IS_READONCE, data.isReadOnce());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEABLE, data.isWriteable());
update.setProperty(IRegisterVMConstants.PROP_IS_WRITEONCE, data.isWriteOnce());
}
/*
* (non-Javadoc)
@ -631,7 +519,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
e instanceof IMemoryChangedEvent ||
e instanceof IRegistersChangedDMEvent ||
(e instanceof PropertyChangeEvent &&
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
return IModelDelta.CONTENT;
}
@ -654,7 +542,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
e instanceof IMemoryChangedEvent ||
e instanceof IRegistersChangedDMEvent ||
(e instanceof PropertyChangeEvent &&
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
// Create a delta that the whole register group has changed.
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
@ -786,7 +674,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
if ( event instanceof IRegisterChangedDMEvent ||
event instanceof IMemoryChangedEvent ||
(event instanceof PropertyChangeEvent &&
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
return IModelDelta.STATE;
}
@ -834,7 +722,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
if ( event instanceof IRegisterChangedDMEvent ||
event instanceof IMemoryChangedEvent ||
(event instanceof PropertyChangeEvent &&
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) )
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) )
{
parentDelta.addNode(element, IModelDelta.STATE);
}
@ -869,8 +757,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
* @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor#getCellModifier(org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, java.lang.Object)
*/
public ICellModifier getCellModifier(IPresentationContext context, Object element) {
return new RegisterCellModifier(
getDMVMProvider(), fFormattedPrefStore, getSyncRegisterDataAccess() );
return new RegisterCellModifier( getDMVMProvider(), getSyncRegisterDataAccess() );
}
/*

View file

@ -21,7 +21,6 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -95,13 +94,13 @@ public class RegisterVMProvider extends AbstractDMVMProvider
/*
* Create the next level which is the registers themselves.
*/
IVMNode registerNode = new RegisterVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess);
IVMNode registerNode = new RegisterVMNode(this, getSession(), regAccess);
addChildNodes(registerGroupNode, new IVMNode[] { registerNode });
/*
* Create the next level which is the bitfield level.
*/
IVMNode bitFieldNode = new RegisterBitFieldVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess);
IVMNode bitFieldNode = new RegisterBitFieldVMNode(this, getSession(), regAccess);
addChildNodes(registerNode, new IVMNode[] { bitFieldNode });
/*

View file

@ -13,3 +13,74 @@ RegisterColumnPresentation_name=Name
RegisterColumnPresentation_type=Type
RegisterColumnPresentation_value=Value
RegisterColumnPresentation_description=Description
# Message format used for cases where the value is formatted in a format that
# is not configured as the preferred format for the view or item.
# {0} - formatted value
# {1} - name of the format used to format the value
Value_column__Value__text_format={0} ({1})
RegisterGroupVMNode_Name_column__text_format={0}
RegisterGroupVMNode_Description_column__text_format={0}
RegisterGroupVMNode_Expression_column__text_format={0}
RegisterGroupVMNode_No_columns__text_format={0} - {1}
# {0} - register group name
# {1} - error message
RegisterGroupVMNode_No_columns__Error__text_format={0} - Error:{1}
RegisterVMNode_Name_column__text_format={0}
RegisterVMNode_Description_column__text_format={0}
# {0} floating point, 0=integer/1=float
# {1} readability, 0=not readable/1=readable/2=readonce
# {2} write-ability, 0=not write-able/1=write-able/2=write once
RegisterVMNode_Type_column__text_format={0,choice,0#Unsigned|1#Floating Point} / {1,choice,0#ReadNone|1#Readable|2#ReadOnce},{2,choice,0#WriteNone|1#Writeable|2#WriteOnce}
RegisterVMNode_Expression_column__text_format={0}
# {0} - register name
# {1} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by the FormattedValueLabelText.
RegisterVMNode_No_columns__text_format={0} = {1}
# {0} - register name
# {1} - error message
RegisterVMNode_No_columns__Error__text_format={0} - Error:{1}
RegisterBitFieldVMNode_Name_column__text_format={0}
RegisterBitFieldVMNode_Description_column__text_format={0}
# {0} readability, 0=not readable/1=readable/2=readonce
# {1} write-ability, 0=not write-able/1=write-able/2=write once
RegisterBitFieldVMNode_Type_column__text_format={0,choice,0#ReadNone|1#Readable|2#ReadOnce},{1,choice,0#WriteNone|1#Writeable|2#WriteOnce}
# Message format for the value column text
# {0} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by FormattedValueLabelText.
# {1} - bit field mnemonic
RegisterBitFieldVMNode_Value_column__With_mnemonic__text_format={0} - {1}
RegisterBitFieldVMNode_Expression_column__text_format={0}
# {0} - bit field name
# {1} - error message
RegisterBitFieldVMNode_No_columns__text_format={0} = {1}
# {0} - bit field name
# {1} - error message
RegisterBitFieldVMNode_No_columns__text_format={0} = {1}
# {0} - bit field name
# {1} - error message
# {2} - bit field mnemonic
RegisterBitFieldVMNode_No_columns__With_mnemonic__text_format={0} = {1} - {2}
# {0} - bit field name
# {1} - error message
RegisterBitFieldVMNode_No_columns__Error__text_format={0} - Error:{1}

View file

@ -20,13 +20,24 @@ public class MessagesForVariablesVM extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.messages"; //$NON-NLS-1$
public static String VariableColumnPresentation_name;
public static String VariableColumnPresentation_type;
public static String VariableColumnPresentation_value;
public static String VariableColumnPresentation_address;
public static String VariableVMNode_Address_column__Error__text_format;
public static String VariableVMNode_Address_column__text_format;
public static String VariableVMNode_Description_column__text_format;
public static String VariableVMNode_Expression_column__text_format;
public static String VariableVMNode_Name_column__text_format;
public static String VariableVMNode_NoColumns_column__Error__text_format;
public static String VariableVMNode_NoColumns_column__text_format;
public static String VariableVMNode_NoColumns_column__No_string__text_format;
public static String VariableVMNode_Type_column__Error__text_format;
public static String VariableVMNode_Type_column__text_format;
public static String VariableVMNode_Value_column__text_format;
public static String VariableVMNode_Value_column___No_string__text_format;
public static String VariableVMNode_Value_column___No_string__Value__text_format;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForVariablesVM.class);

View file

@ -14,7 +14,7 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IFormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.update.AbstractCachingVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.update.UserEditEvent;
@ -26,14 +26,11 @@ public class VariableCellModifier extends WatchExpressionCellModifier {
private AbstractCachingVMProvider fProvider;
private SyncVariableDataAccess fDataAccess = null;
private IFormattedValuePreferenceStore fPrefStore;
public VariableCellModifier(AbstractCachingVMProvider provider,
IFormattedValuePreferenceStore formattedValuePreferenceStore, SyncVariableDataAccess access)
public VariableCellModifier(AbstractCachingVMProvider provider, SyncVariableDataAccess access)
{
fProvider = provider;
fDataAccess = access;
fPrefStore = formattedValuePreferenceStore;
}
/*
@ -81,8 +78,7 @@ public class VariableCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fPrefStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;
@ -119,8 +115,7 @@ public class VariableCellModifier extends WatchExpressionCellModifier {
*/
IVMContext ctx = (IVMContext) element;
IPresentationContext presCtx = ctx.getVMNode().getVMProvider().getPresentationContext();
formatId = fPrefStore.getCurrentNumericFormat(presCtx);
formatId = FormattedValueVMUtil.getPreferredFormat(presCtx);
}
else {
formatId = IFormattedValues.NATURAL_FORMAT;

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValuePreferenceStore;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -38,7 +37,6 @@ import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
@SuppressWarnings("restriction")
public class VariableVMProvider extends AbstractDMVMProvider
implements IColumnPresentationFactory
{
@ -81,7 +79,7 @@ public class VariableVMProvider extends AbstractDMVMProvider
/*
* Create the next level which represents members of structs/unions/enums and elements of arrays.
*/
IVMNode subExpressioNode = new VariableVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), varAccess);
IVMNode subExpressioNode = new VariableVMNode(this, getSession(), varAccess);
addChildNodes(rootNode, new IVMNode[] { subExpressioNode });
// Configure the sub-expression node to be a child of itself. This way the content

View file

@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2007, 2008 Wind River Systems and others.
# Copyright (c) 2007, 2009 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
@ -14,3 +14,42 @@ VariableColumnPresentation_name=Name
VariableColumnPresentation_type=Type
VariableColumnPresentation_value=Value
VariableColumnPresentation_address=Address
VariableVMNode_Address_column__Error__text_format=
VariableVMNode_Address_column__text_format={0}
VariableVMNode_Description_column__text_format=
VariableVMNode_Expression_column__text_format={0}
VariableVMNode_Name_column__text_format={0}
VariableVMNode_Type_column__Error__text_format=
VariableVMNode_Type_column__text_format={0}
# Message format for the value column text
# {0} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by the format in VariableVMNode_Value_column__Value__text_format.
# {1} - value in STRING format.
VariableVMNode_Value_column__text_format={0} {1}
# Message format for the value column text
# {0} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by the format in VariableVMNode_Value_column__Value__text_format.
VariableVMNode_Value_column___No_string__text_format={0}
# {0} - variable name
# {1} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by the format in VariableVMNode_Value_column__Value__text_format.
# {2} - value in STRING format.
VariableVMNode_NoColumns_column__text_format={0} = {1} {2}
# {0} - variable name
# {1} - value formatted in the active format. If the preferred format was
# available, then this is just the value. Otherwise, it's the string formatted
# by the format in VariableVMNode_Value_column__Value__text_format.
VariableVMNode_NoColumns_column__No_string__text_format={0} = {1}
# {0} - variable name
# {1} - error message
VariableVMNode_NoColumns_column__Error__text_format={0} - Error: {1}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems and others.
* 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
@ -8,13 +8,15 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.ui.viewmodel.properties;
package org.eclipse.cdt.dsf.internal.ui;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
/**
*
* @since 1.0
* @since 2.0
*/
public interface ILabelAttributeChangedListener {
public void attributesChanged();
public class DsfUILabelImage extends LabelImage {
public DsfUILabelImage(String imageId) {
super(DsfUIPlugin.getImageDescriptor(imageId));
}
}

View file

@ -10,11 +10,11 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.internal.ui;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@ -124,7 +124,7 @@ public class DsfUIPlugin extends AbstractUIPlugin {
* @param t throwable to log
*/
public static void log(Throwable t) {
log(newErrorStatus("Error logged from Debug UI: ", t)); //$NON-NLS-1$
log(newErrorStatus(IDsfStatusConstants.INTERNAL_ERROR, "Error logged from Debug UI: ", t)); //$NON-NLS-1$
}
/**
@ -135,17 +135,21 @@ public class DsfUIPlugin extends AbstractUIPlugin {
public static void logErrorMessage(String message) {
// this message is intentionally not internationalized, as an exception may
// be due to the resource bundle itself
log(newErrorStatus("Internal message logged from Debug UI: " + message, null)); //$NON-NLS-1$
log(newErrorStatus(IDsfStatusConstants.INTERNAL_ERROR, "Internal message logged from Debug UI: " + message, null)); //$NON-NLS-1$
}
/**
* Returns a new error status for this plug-in with the given message
*
* @param message the message to be included in the status
* @param error code
* @param exception the exception to be included in the status or <code>null</code> if none
* @return a new error status
*
* @since 2.0
*/
public static IStatus newErrorStatus(String message, Throwable exception) {
return new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR, message, exception);
public static IStatus newErrorStatus(int code, String message, Throwable exception) {
return new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, code, message, exception);
}
}

View file

@ -16,13 +16,12 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
/**
* Data Request monitor that takean <code>IViewerUpdate</code> as a parent.
* Data Request monitor that takes <code>IViewerUpdate</code> as a parent.
* If the IViewerUpdate is canceled, this request monitor becomes canceled as well.
* @see IViewerUpdate
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public class ViewerDataRequestMonitor<V> extends DataRequestMonitor<V> {
private final IViewerUpdate fUpdate;

View file

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2007, 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.ui.concurrent;
import java.util.concurrent.Executor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
/**
* Data Request monitor that takes <code>IViewerUpdate</code> as a parent.
* If the IViewerUpdate is canceled, this request monitor becomes canceled as well.
* @see IViewerUpdate
*
* @since 2.0
*/
public class ViewerRequestMonitor extends RequestMonitor {
private final IViewerUpdate fUpdate;
public ViewerRequestMonitor(Executor executor, IViewerUpdate update) {
super(executor, null);
fUpdate = update;
}
@Override
public synchronized boolean isCanceled() {
return fUpdate.isCanceled() || super.isCanceled();
}
@Override
protected void handleSuccess() {
fUpdate.done();
}
@Override
protected void handleErrorOrWarning() {
fUpdate.setStatus(getStatus());
fUpdate.done();
}
@Override
protected void handleCancel() {
fUpdate.setStatus(getStatus());
fUpdate.done();
}
}

View file

@ -29,24 +29,24 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
/**
* The default strategy for implementing the IElementContentProvider
* functionality for an IVMProvider. It implements an algorithm to populate
* contents of the view in accordance with the tree structure of the
* view model nodes configured in the view model provider.
* The default strategy for implementing the IElementContentProvider
* functionality for an IVMProvider. It implements an algorithm to populate
* contents of the view in accordance with the tree structure of the view model
* nodes configured in the view model provider.
* <p/>
* This class may be used by an <code>IVMProvider</code> directly, or it
* may be be extended to customize for the provider's needs.
* This class may be used by an <code>IVMProvider</code> directly, or it may be
* be extended to customize for the provider's needs.
* <p/>
* This class is closely linked with a view model provider which is required
* for the constructor. The view model provider is used to access the correct
* executor and the node hierarchy.
* This class is closely linked with a view model provider which is required for
* the constructor. The view model provider is used to access the correct
* executor and the node hierarchy.
*
* @since 1.0
*/
@ConfinedToDsfExecutor("#getExecutor()")
@SuppressWarnings("restriction")
public class DefaultVMContentProviderStrategy implements IElementContentProvider {
private final AbstractVMProvider fVMProvider;
public DefaultVMContentProviderStrategy(AbstractVMProvider provider) {
@ -55,14 +55,19 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
/**
* Returns the view model provider that this strategy is configured for.
*
* @return
*/
protected AbstractVMProvider getVMProvider() { return fVMProvider; }
protected AbstractVMProvider getVMProvider() {
return fVMProvider;
}
public void update(final IHasChildrenUpdate[] updates) {
if (updates.length == 0) return;
// Optimization: if all the updates belong to the same node, avoid creating any new lists/arrays.
if (updates.length == 0)
return;
// Optimization: if all the updates belong to the same node, avoid
// creating any new lists/arrays.
boolean allNodesTheSame = true;
IVMNode firstNode = getNodeForElement(updates[0].getElement());
for (int i = 1; i < updates.length; i++) {
@ -71,70 +76,74 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
break;
}
}
if (allNodesTheSame) {
updateNode(firstNode, updates);
} else {
// Sort the updates by the node.
Map<IVMNode,List<IHasChildrenUpdate>> nodeUpdatesMap = new HashMap<IVMNode,List<IHasChildrenUpdate>>();
Map<IVMNode, List<IHasChildrenUpdate>> nodeUpdatesMap = new HashMap<IVMNode, List<IHasChildrenUpdate>>();
for (IHasChildrenUpdate update : updates) {
// Get the VM Context for last element in path.
// Get the VM Context for last element in path.
IVMNode node = getNodeForElement(update.getElement());
if (node == null) {
// Stale update, most likely as a result of the nodes being
// changed. Just ignore it.
// changed. Just ignore it.
update.done();
continue;
}
}
if (!nodeUpdatesMap.containsKey(node)) {
nodeUpdatesMap.put(node, new ArrayList<IHasChildrenUpdate>());
}
nodeUpdatesMap.get(node).add(update);
}
// Iterate through the nodes in the sorted map.
for (IVMNode node : nodeUpdatesMap.keySet()) {
updateNode(node, nodeUpdatesMap.get(node).toArray(new IHasChildrenUpdate[nodeUpdatesMap.get(node).size()]));
for (IVMNode node : nodeUpdatesMap.keySet()) {
updateNode(node, nodeUpdatesMap.get(node).toArray(
new IHasChildrenUpdate[nodeUpdatesMap.get(node).size()]));
}
}
}
private void updateNode(IVMNode node, final IHasChildrenUpdate[] updates) {
// If parent element's node has no children, just set the
// result and continue to next element.
final IVMNode[] childNodes = getVMProvider().getChildVMNodes(node);
if (childNodes.length == 0) {
// If parent element's node has no children, just set the
// result and continue to next element.
for (IHasChildrenUpdate update : updates) {
update.setHasChilren(false);
update.done();
}
return;
}
// Create a matrix of element updates:
// The first dimension "i" is the list of children updates that came from the viewer.
// For each of these updates, there are "j" number of elment updates corresponding
// to the number of child nodes in this node.
// Each children update from the viewer is complete when all the child nodes
// fill in their elements update.
// Once the matrix is constructed, the child nodes are given the list of updates
// equal to the updates requested by the viewer.
VMHasChildrenUpdate[][] elementsUpdates =
new VMHasChildrenUpdate[childNodes.length][updates.length];
for (int i = 0; i < updates.length; i ++)
{
final IHasChildrenUpdate update = updates[i];
final MultiRequestMonitor<DataRequestMonitor<Boolean>> hasChildrenMultiRequestMon =
new MultiRequestMonitor<DataRequestMonitor<Boolean>>(getVMProvider().getExecutor(), null) {
} else if (childNodes.length == 1) {
// Optimization: if there is only one child node, just pass on the
// update to the child node.
getVMProvider().updateNode(childNodes[0], updates);
} else {
// Create a matrix of element updates:
// The first dimension "i" is the list of children updates that came
// from the viewer.
// For each of these updates, there are "j" number of elment updates
// corresponding
// to the number of child nodes in this node.
// Each children update from the viewer is complete when all the child
// nodes
// fill in their elements update.
// Once the matrix is constructed, the child nodes are given the list of
// updates
// equal to the updates requested by the viewer.
VMHasChildrenUpdate[][] elementsUpdates = new VMHasChildrenUpdate[childNodes.length][updates.length];
for (int i = 0; i < updates.length; i++) {
final IHasChildrenUpdate update = updates[i];
final MultiRequestMonitor<DataRequestMonitor<Boolean>> hasChildrenMultiRequestMon = new MultiRequestMonitor<DataRequestMonitor<Boolean>>(
getVMProvider().getExecutor(), null) {
@Override
protected void handleCompleted() {
// Status is OK, only if all request monitors are OK.
if (isSuccess()) {
// Status is OK, only if all request monitors are OK.
if (isSuccess()) {
boolean isContainer = false;
for (DataRequestMonitor<Boolean> hasElementsDone : getRequestMonitors()) {
isContainer |= hasElementsDone.isSuccess() &&
hasElementsDone.getData().booleanValue();
isContainer |= hasElementsDone.isSuccess() && hasElementsDone.getData().booleanValue();
}
update.setHasChilren(isContainer);
} else {
@ -143,26 +152,23 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
update.done();
}
};
for (int j = 0; j < childNodes.length; j++)
{
elementsUpdates[j][i] = new VMHasChildrenUpdate(
update,
hasChildrenMultiRequestMon.add(
new ViewerDataRequestMonitor<Boolean>(getVMProvider().getExecutor(), update) {
for (int j = 0; j < childNodes.length; j++) {
elementsUpdates[j][i] = new VMHasChildrenUpdate(update, hasChildrenMultiRequestMon
.add(new ViewerDataRequestMonitor<Boolean>(getVMProvider().getExecutor(), update) {
@Override
protected void handleCompleted() {
hasChildrenMultiRequestMon.requestMonitorDone(this);
}
}));
}
}
for (int j = 0; j < childNodes.length; j++) {
getVMProvider().updateNode(childNodes[j], elementsUpdates[j]);
}
}
for (int j = 0; j < childNodes.length; j++) {
getVMProvider().updateNode(childNodes[j], elementsUpdates[j]);
}
}
public void update(final IChildrenCountUpdate[] updates) {
for (final IChildrenCountUpdate update : updates) {
@ -172,29 +178,29 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
IVMNode[] childNodes = getVMProvider().getChildVMNodes(node);
if (childNodes.length == 0) {
// If there is no child nodes, logically the child count is 0.
update.setChildCount(0);
update.done();
} else if (childNodes.length == 1) {
// Optimization: there is only one child node, just pass on the child count to it.
getVMProvider().updateNode(childNodes[0], update);
} else {
getChildrenCountsForNode(
update,
node,
new ViewerDataRequestMonitor<Integer[]>(getVMProvider().getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
int numChildren = 0;
for (Integer count : getData()) {
numChildren += count.intValue();
}
update.setChildCount(numChildren);
} else {
update.setChildCount(0);
getChildrenCountsForNode(update, node, new ViewerDataRequestMonitor<Integer[]>(getVMProvider()
.getExecutor(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
int numChildren = 0;
for (Integer count : getData()) {
numChildren += count.intValue();
}
update.done();
update.setChildCount(numChildren);
} else {
update.setChildCount(0);
}
});
update.done();
}
});
}
} else {
update.done();
@ -205,7 +211,7 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
public void update(final IChildrenUpdate[] updates) {
for (final IChildrenUpdate update : updates) {
// Get the VM Context for last element in path.
// Get the VM Context for last element in path.
final IVMNode node = getNodeForElement(update.getElement());
if (node != null && !update.isCanceled()) {
IVMNode[] childNodes = getVMProvider().getChildVMNodes(node);
@ -213,84 +219,80 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
// Invalid update, just mark done.
update.done();
} else if (childNodes.length == 1) {
// Optimization: there is only one child node, pass the updates to it.
getVMProvider().updateNode(childNodes[0], update);
} else {
getChildrenCountsForNode(
update,
node,
new ViewerDataRequestMonitor<Integer[]>(getVMProvider().getExecutor(), update) {
@Override
protected void handleCompleted() {
if (!isSuccess()) {
update.done();
return;
}
updateChildrenWithCounts(update, node, getData());
getChildrenCountsForNode(update, node, new ViewerDataRequestMonitor<Integer[]>(getVMProvider()
.getExecutor(), update) {
@Override
protected void handleCompleted() {
if (!isSuccess()) {
update.done();
return;
}
});
updateChildrenWithCounts(update, node, getData());
}
});
}
} else {
// Stale update. Just ignore.
update.done();
}
}
}
}
}
/**
* Calculates the number of elements in each child node for the element in
* update. These counts are then used to delegate the children update to
* the correct nodes.
* Calculates the number of elements in each child node for the element in
* update. These counts are then used to delegate the children update to the
* correct nodes.
*/
private void getChildrenCountsForNode(IViewerUpdate update, IVMNode updateNode, final DataRequestMonitor<Integer[]> rm) {
private void getChildrenCountsForNode(IViewerUpdate update, IVMNode updateNode,
final DataRequestMonitor<Integer[]> rm) {
IVMNode[] childNodes = getVMProvider().getChildVMNodes(updateNode);
// Check for an invalid call
assert childNodes.length != 0;
// Get the mapping of all the counts.
final Integer[] counts = new Integer[childNodes.length];
final MultiRequestMonitor<RequestMonitor> childrenCountMultiReqMon =
new MultiRequestMonitor<RequestMonitor>(getVMProvider().getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.setData(counts);
rm.done();
}
};
final Integer[] counts = new Integer[childNodes.length];
final MultiRequestMonitor<RequestMonitor> childrenCountMultiReqMon = new MultiRequestMonitor<RequestMonitor>(
getVMProvider().getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.setData(counts);
rm.done();
}
};
for (int i = 0; i < childNodes.length; i++) {
final int nodeIndex = i;
getVMProvider().updateNode(
childNodes[i],
new VMChildrenCountUpdate(
update,
childrenCountMultiReqMon.add(
new ViewerDataRequestMonitor<Integer>(getVMProvider().getExecutor(), update) {
@Override
protected void handleSuccess() {
counts[nodeIndex] = getData();
}
@Override
protected void handleCompleted() {
super.handleCompleted();
childrenCountMultiReqMon.requestMonitorDone(this);
}
}))
);
childNodes[i],
new VMChildrenCountUpdate(update, childrenCountMultiReqMon.add(new ViewerDataRequestMonitor<Integer>(
getVMProvider().getExecutor(), update) {
@Override
protected void handleSuccess() {
counts[nodeIndex] = getData();
}
@Override
protected void handleCompleted() {
super.handleCompleted();
childrenCountMultiReqMon.requestMonitorDone(this);
}
})));
}
}
/**
* Splits the given children update among the configured child nodes. Then calls
* each child node to complete the update.
* Splits the given children update among the configured child nodes. Then
* calls each child node to complete the update.
*/
private void updateChildrenWithCounts(final IChildrenUpdate update, IVMNode node, Integer[] nodeElementCounts) {
// Create the multi request monitor to mark update when querying all
// Create the multi request monitor to mark update when querying all
// children nodes is finished.
CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getVMProvider().getExecutor(), update) {
@Override
@ -300,7 +302,8 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
};
int multiRmCount = 0;
// Iterate through all child nodes and if requested range matches, call them to
// Iterate through all child nodes and if requested range matches, call
// them to
// get their elements.
int updateStartIdx = update.getOffset();
int updateEndIdx = update.getOffset() + update.getLength();
@ -319,16 +322,20 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
if (elementsLength > 0) {
getVMProvider().updateNode(
nodes[i],
new VMChildrenUpdate(
update, elementsStartIdx, elementsLength,
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), multiRm) {
new VMChildrenUpdate(update, elementsStartIdx, elementsLength,
new DataRequestMonitor<List<Object>>(getVMProvider().getExecutor(), multiRm) {
@Override
protected void handleCompleted() {
// Workaround for a bug caused by an optimization in the viewer:
// The viewer may request more children then there are at a given level.
// This causes the update to return with an error.
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109
// Instead of checking isSuccess(), check getData() != null.
// Workaround for a bug caused by an
// optimization in the viewer:
// The viewer may request more children then
// there are at a given level.
// This causes the update to return with an
// error.
// See
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=202109
// Instead of checking isSuccess(), check
// getData() != null.
if (getData() != null) {
for (int i = 0; i < elementsLength && i < getData().size(); i++) {
Object child = getData().get(i);
@ -339,41 +346,42 @@ public class DefaultVMContentProviderStrategy implements IElementContentProvider
}
super.handleCompleted();
}
})
);
}));
multiRmCount++;
}
}
}
// Guard against invalid queries.
multiRm.setDoneCount(multiRmCount);
}
/**
* Convenience method that finds the VMC corresponding to given parent
* argument given to isContainer() or retrieveChildren().
* @param object Object to find the VMC for.
* @return parent VMC, if null it indicates that the object did not originate
* from this view or is stale.
* Convenience method that finds the VM node corresponding to given element.
* It returns the root node if the element is not a VM Context or if it was
* created by another view.
*
* @param element Element to find the VM Node for.
* @return View Model Node that this element was created by.
*/
protected IVMNode getNodeForElement(Object element) {
if (element instanceof IVMContext) {
IVMNode node = ((IVMContext)element).getVMNode();
if (isOurNode(((IVMContext)element).getVMNode())) {
IVMNode node = ((IVMContext) element).getVMNode();
if (isOurNode(((IVMContext) element).getVMNode())) {
return node;
}
}
}
return getVMProvider().getRootVMNode();
}
/**
* Convenience method which checks whether given layout node is a node
* that is configured in this ViewModelProvider.
* Convenience method which checks whether given layout node is a node that
* is configured in this ViewModelProvider.
*/
private boolean isOurNode(IVMNode node) {
for (IVMNode nodeToSearch : getVMProvider().getAllVMNodes()) {
if (nodeToSearch.equals(node)) return true;
if (nodeToSearch.equals(node))
return true;
}
return false;
}

View file

@ -26,7 +26,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvi
* @since 1.0
*/
@ThreadSafe
@SuppressWarnings("restriction")
public interface IVMAdapter
extends IElementContentProvider, IModelProxyFactory, IColumnPresentationFactory, IViewerInputProvider
{

View file

@ -19,6 +19,14 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
*/
public interface IElementPropertiesProvider {
/**
* Common property representing an element's name. This property can be
* used in future extensions for filtering and sorting.
*
* @since 2.0
*/
public static final String PROP_NAME = "name"; //$NON-NLS-1$
/**
* Updates the specified property sets.
*

View file

@ -10,6 +10,9 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import java.util.Set;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
/**
@ -20,15 +23,22 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
@SuppressWarnings("restriction")
public interface IPropertiesUpdate extends IViewerUpdate {
/**
* Returns the list of element properties that the provider should set.
* If <code>null</code>, all available properties should be set.
* Returns the set of element properties that the provider should update.
*/
public String[] getProperties();
public Set<String> getProperties();
/**
* Sets the given property to update.
*
* @param property Property ID.
* @param value Property value.
*/
public void setProperty(String property, Object value);
/**
* Sets the given map as the complete property map for this update.
*
* @param properties Full properties map.
*/
public void setAllProperties(Map<String, Object> properties);
}

View file

@ -12,7 +12,7 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
/**
@ -28,7 +28,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
* also override how the attribute settings are stored, for example in
* order to use a preference.
*
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
* @see LabelColumnInfo
*
* @since 1.0
@ -38,74 +38,84 @@ abstract public class LabelAttribute {
public static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0];
/**
* Listeners for when this attribute is modified.
* @since 2.0
*/
private ListenerList fListeners = new ListenerList();
private String[] fPropertyNames = EMPTY_PROPERTY_NAMES_ARRAY;
public LabelAttribute() {
this(EMPTY_PROPERTY_NAMES_ARRAY);
}
/**
* Disposes this attribute.
* @since 2.0
*/
public void dispose() {
public LabelAttribute(String[] propertyNames) {
setPropertyNames(propertyNames);
}
protected void setPropertyNames(String[] propertyNames) {
fPropertyNames = propertyNames;
}
/**
* Registers the given listener for changes in this attribute. A change in
* the attributes of a label should cause a view to repaint.
* @param listener Listener to register.
*/
public void addChangedListener(ILabelAttributeChangedListener listener) {
fListeners.add(listener);
}
/**
* Unregisters the given listener.
* @param listener Listener to unregister.
*/
public void removeChangedListener(ILabelAttributeChangedListener listener) {
fListeners.remove(listener);
}
/**
* Calls the listeners to notify them that this attribute has changed.
*/
protected void fireAttributeChanged() {
Object[] listeners = fListeners.getListeners();
for (Object listener : listeners) {
((ILabelAttributeChangedListener)listener).attributesChanged();
}
}
/**
* Returns the propertis that are needed by this attribute in order to
* Returns the properties that are needed by this attribute in order to
* determine whether this attribute is enabled and/or for the actual
* attribute itself.
* @return Array of names of properties for the element properties provider.
*/
public String[] getPropertyNames() {
return EMPTY_PROPERTY_NAMES_ARRAY;
return fPropertyNames;
}
/**
* Returns whether this attribute is enabled for an element which has
* the given properties.
* @param properties Map or element properties. The client should ensure
* that all properties specified by {@link #getPropertyNames()} are
* supplied in this map.
* the given properties. The default implementation checks if all the
* label's attributes are present in the properties map.
*
* @param status Result of the properties update.
* @param properties Properties supplied by a property update.
* @return true if this attribute is enabled.
*
* @since 2.0
*/
public boolean isEnabled(Map<String, Object> properties) {
public boolean isEnabled(IStatus status, Map<String, Object> properties) {
for (String propertyName : getPropertyNames()) {
if (!checkProperty(propertyName, status, properties)) {
return false;
}
}
return true;
}
/**
* Updates the label with this attribute.
* Checks the status of the given property in the given properties map. The
* default implementation returns <code>true</code> if the given property
* exists and is not null.
*
* @param propertyName Name of the property to check.
* @param status Result of the properties update.
* @param properties Properties map following an update.
* @return <code>true</code> if the property exists in the given map and
* its value is not null.
*
* @since 2.0
*/
protected boolean checkProperty(String propertyName, IStatus status, Map<String, Object> properties) {
return properties.get(propertyName) != null;
}
/**
* Updates the label with this attribute.
*
* @param update Label update object to write to.
* @param columnIndex Colum index to write at.
* @param properties Element properties to use.
* @param columnIndex Column index to write at.
* @param status Result of the property update.
* @param properties Property values map. It is guaranteed to contain all
* the properties that this attribute requested through
* {@link getPropertyNames()}.
*
* @since 2.0
*/
abstract public void updateAttribute(ILabelUpdate update, int columnIndex, Map<String, Object> properties);
abstract public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties);
}

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.swt.graphics.RGB;
@ -21,7 +22,7 @@ import org.eclipse.swt.graphics.RGB;
*
* @see LabelAttribute
* @see LabelColumnInfo
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
*
* @since 1.0
*/
@ -50,16 +51,14 @@ public class LabelColor extends LabelAttribute {
public void setForeground(RGB foreground) {
fForeground = foreground;
fireAttributeChanged();
}
public void setBackground(RGB background) {
fBackground = background;
fireAttributeChanged();
}
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, Map<String, Object> properties) {
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
RGB foreground = getForeground();
if (foreground != null) {
update.setForeground(foreground, columnIndex);

View file

@ -15,11 +15,12 @@ import java.util.List;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
/**
* Class used by the PropertyBasedLabelProvider to generate store
* Class used by the PropertiesBasedLabelProvider to generate store
* label attributes related to a single column. Each column info is
* configured with an array of attributes (there are currently four
* types of attributes: text, image, font, and color), which are
@ -27,15 +28,24 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
* <p/>
* Clients are not intended to extend this class.
*
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
*
* @since 1.0
*/
@SuppressWarnings("restriction")
@ThreadSafe
public class LabelColumnInfo implements ILabelAttributeChangedListener {
public class LabelColumnInfo {
/**
* @since 2.0
*/
private static final LabelAttribute[] DEFAULT_FAILED_UPDATE_ATTRIBUTES = new LabelAttribute[] {
new LabelText("...", new String[0])
};
private static final LabelAttribute[] EMPTY_ATTRIBUTES_ARRAY = new LabelAttribute[0];
/**
* @since 2.0
*/
private static final LabelAttribute[] EMPTY_ATTRIBUTES = new LabelAttribute[0];
/**
* Calculated list of property names that need to be retrieved to
@ -47,7 +57,7 @@ public class LabelColumnInfo implements ILabelAttributeChangedListener {
* Array of label attribute objects.
*/
private LabelAttribute[] fLabelAttributes;
/**
* Listeners for when column attributes are modified.
*/
@ -63,7 +73,6 @@ public class LabelColumnInfo implements ILabelAttributeChangedListener {
List<String> names = new LinkedList<String>();
for (LabelAttribute attr : attributes) {
attr.addChangedListener(this);
for (String name : attr.getPropertyNames()) {
names.add(name);
}
@ -71,19 +80,6 @@ public class LabelColumnInfo implements ILabelAttributeChangedListener {
fPropertyNames = names.toArray(new String[names.size()]);
}
/**
* Disposes this column info object and the attribute objects
* within it.
*/
public void dispose() {
for (LabelAttribute attr : fLabelAttributes) {
attr.dispose();
attr.removeChangedListener(this);
}
fLabelAttributes = EMPTY_ATTRIBUTES_ARRAY;
fPropertyNames = null;
}
/**
* Returns the property names that need to be retrieved in order
@ -97,43 +93,27 @@ public class LabelColumnInfo implements ILabelAttributeChangedListener {
public LabelAttribute[] getLabelAttributes() { return fLabelAttributes; }
/**
* Registers the given listener for changes in the attributes of this
* column. A change in the attributes of a label should cause
* a view to repaint.
* @param listener Listener to register.
* Returns the list of configured label attributes for this column.
*
* @since 2.0
*/
public void addChangedListener(ILabelAttributeChangedListener listener) {
fListeners.add(listener);
}
/**
* Unregisters the given listener.
* @param listener Listener to unregister.
*/
public void removeChangedListener(ILabelAttributeChangedListener listener) {
fListeners.remove(listener);
}
protected LabelAttribute[] setLabelAttributes(LabelAttribute attributes) {
return fLabelAttributes;
}
/**
* Listener method called by the attribute objects.
* @see ILabelAttributeChangedListener
*/
public void attributesChanged() {
Object[] listeners = fListeners.getListeners();
for (Object listener : listeners) {
((ILabelAttributeChangedListener)listener).attributesChanged();
}
}
/**
* Updates the label parameters for this column based on the provided
* properties. The label information is written to the givne label
* update under the given column index.
*
* @param update Update to write to.
* @param columnIndex Column to write label information under.
* @param status Result of the properties update
* @param properties Map of properties to use to generate the label.
*
* @since 2.0
*/
public void updateColumn(ILabelUpdate update, int columnIndex, Map<String,Object> properties) {
public void updateColumn(ILabelUpdate update, int columnIndex, IStatus status, Map<String,Object> properties) {
boolean textSet = false;
boolean imageSet = false;
boolean fontSet = false;
@ -146,10 +126,9 @@ public class LabelColumnInfo implements ILabelAttributeChangedListener {
!(info instanceof LabelImage && imageSet) &&
!(info instanceof LabelFont && fontSet) &&
!(info instanceof LabelColor && colorSet) &&
info.isEnabled(properties))
info.isEnabled(status, properties))
{
info.updateAttribute(update, columnIndex, properties);
info.updateAttribute(update, columnIndex, status, properties);
textSet = textSet || info instanceof LabelText;
imageSet = imageSet || info instanceof LabelImage;
fontSet = fontSet || info instanceof LabelFont;

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.FontData;
@ -21,7 +22,7 @@ import org.eclipse.swt.graphics.FontData;
*
* @see LabelAttribute
* @see LabelColumnInfo
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
*
* @since 1.0
*/
@ -48,11 +49,10 @@ public class LabelFont extends LabelAttribute {
public void setFontData(FontData fontData) {
fFontData = fontData;
fireAttributeChanged();
}
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, Map<String, Object> properties) {
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
update.setFontData(getFontData(), columnIndex);
}

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.jface.resource.ImageDescriptor;
@ -20,7 +21,7 @@ import org.eclipse.jface.resource.ImageDescriptor;
*
* @see LabelAttribute
* @see LabelColumnInfo
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
*
* @since 1.0
*/
@ -42,11 +43,10 @@ public class LabelImage extends LabelAttribute {
public void setImageDescriptor(ImageDescriptor image) {
fImageDescriptor = image;
fireAttributeChanged();
}
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, Map<String, Object> properties) {
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
ImageDescriptor descriptor = getImageDescriptor();
if (descriptor != null) {
update.setImageDescriptor(descriptor, columnIndex);

View file

@ -26,7 +26,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
* @see MessageFormat#format(Object[], StringBuffer, java.text.FieldPosition)
* @see LabelAttribute
* @see LabelColumnInfo
* @see PropertyBasedLabelProvider
* @see PropertiesBasedLabelProvider
*
* @since 1.0
*/
@ -52,6 +52,15 @@ public class LabelText extends LabelAttribute {
this(DEFAULT_MESSAGE, EMPTY_PROPERTY_NAMES_ARRAY);
}
/**
* @since 2.0
* @param formatPattern
* @param propertyNames
*/
public LabelText(String formatPattern, String[] propertyNames) {
this (new MessageFormat(formatPattern), propertyNames);
}
public LabelText(MessageFormat format, String[] propertyNames) {
fMessageFormat = format;
fPropertyNames = propertyNames;
@ -68,15 +77,14 @@ public class LabelText extends LabelAttribute {
public void setMessageFormat(MessageFormat messageFormat) {
fMessageFormat = messageFormat;
fireAttributeChanged();
}
@Override
public void updateAttribute(ILabelUpdate update, int columnIndex, Map<String, Object> properties) {
public void updateAttribute(ILabelUpdate update, int columnIndex, IStatus status, Map<String, Object> properties) {
String[] propertyNames = getPropertyNames();
Object[] propertyValues = new Object[propertyNames.length];
for (int i = 0; i < propertyNames.length; i++) {
propertyValues[i] = properties.get(propertyNames[i]);
propertyValues[i] = getPropertyValue(propertyNames[i], status, properties);
}
try {
@ -85,4 +93,8 @@ public class LabelText extends LabelAttribute {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, 0, "Failed formatting a message for column " + columnIndex + ", for update " + update, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
return properties.get(propertyName);
}
}

View file

@ -12,20 +12,16 @@ package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMViewerUpdate;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
@ -40,139 +36,52 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
* values are retrieved, they are processed in order to produce correct label text,
* images, fonts, and colors, for the given element.
*
* @since 1.0
* @since 2.0 - Renamed from PropertyBasedLabelProvider
*/
@SuppressWarnings("restriction")
@ThreadSafe
public class PropertyBasedLabelProvider
implements IElementLabelProvider, ILabelAttributeChangedListener
public class PropertiesBasedLabelProvider
implements IElementLabelProvider
{
private static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0];
public static final String ID_COLUMN_NO_COLUMNS = "ID_COLUMN_NO_COLUMNS"; //$NON-NLS-1$
/**
* Properties update used as to collect property data from the provider.
*/
private class PropertiesUpdate extends VMViewerUpdate implements IPropertiesUpdate {
private final String[] fProperties;
private final Map<String, Object> fValues;
public PropertiesUpdate(String[] properties, ILabelUpdate labelUpdate, DataRequestMonitor<Map<String,Object>> rm) {
super(labelUpdate, rm);
fProperties = properties;
fValues = fProperties != null
? new HashMap<String, Object>(properties.length * 4 / 3, 0.75f)
: new HashMap<String, Object>();
}
public String[] getProperties() {
return fProperties;
}
public void setProperty(String property, Object value) {
fValues.put(property, value);
}
/**
* Overrides the standard done in order to store the retrieved values
* in the client's request monitor.
*/
@Override
public void done() {
@SuppressWarnings("unchecked")
DataRequestMonitor<Map<String,Object>> rm = (DataRequestMonitor<Map<String,Object>>)getRequestMonitor();
if (fProperties == null || fValues.size() >= fProperties.length) {
rm.setData(fValues);
} else {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Incomplete properties updated", null)); //$NON-NLS-1$
}
super.done();
}
}
/**
* Attribute information for each column by column ID.
*/
private Map<String, LabelColumnInfo> fColumnInfos = Collections.synchronizedMap(new HashMap<String,LabelColumnInfo>());
private ListenerList fListeners = new ListenerList();
/**
* Standard constructor. A property based label constructor does not
* initialize column attribute information {@link #setColumnInfo(String, LabelColumnInfo)}
* must be called to configure each column.
*/
public PropertyBasedLabelProvider() {
}
/**
* Disposes this label provider and its configured column info objects.
*/
public void dispose() {
LabelColumnInfo[] infos = null;
synchronized (fColumnInfos) {
infos = fColumnInfos.values().toArray(new LabelColumnInfo[fColumnInfos.size()]);
fColumnInfos.clear();
}
for (LabelColumnInfo info : infos) {
info.dispose();
}
public PropertiesBasedLabelProvider() {
}
/**
* Sets the given column info object for the given column ID. This column
* info will be used to generate the label when the given column is visibile.
*
* @param columnId Column ID that the given column info is being registered for.
* @param info Column 'info' object containing column attributes.
* @return The previous column info object configured for this ID.
*/
public LabelColumnInfo setColumnInfo(String columnId, LabelColumnInfo info) {
LabelColumnInfo oldInfo = fColumnInfos.put(columnId, info);
info.addChangedListener(this);
if (oldInfo != null) {
info.removeChangedListener(this);
}
return oldInfo;
}
/**
* Returns the given column info object for the given column ID.
* @param columnId Column ID to retrieve the column info for.
*
* @param columnId Column ID that the given column info is being registered for.
* @@return Column 'info' object containing column attributes.
*/
public LabelColumnInfo getColumnInfo(String column) {
return fColumnInfos.get(column);
public LabelColumnInfo getColumnInfo(String columnId) {
return fColumnInfos.get(columnId);
}
/**
* Registers the given listener for changes in the attributes of this
* label provider. A change in the attributes of a label should cause
* a view to repaint.
* @param listener Listener to register.
*/
public void addChangedListener(ILabelAttributeChangedListener listener) {
fListeners.add(listener);
}
/**
* Unregisters the given listener.
* @param listener Listener to unregister.
*/
public void removeChangedListener(ILabelAttributeChangedListener listener) {
fListeners.remove(listener);
}
/**
* Listener method called by label provider's column info objects.
* @see ILabelAttributeChangedListener
*/
public void attributesChanged() {
Object[] listeners = fListeners.getListeners();
for (Object listener : listeners) {
((ILabelAttributeChangedListener)listener).attributesChanged();
}
}
public void update(ILabelUpdate[] labelUpdates) {
IElementPropertiesProvider propertiesProvider = getElementPropertiesProvider(labelUpdates[0].getElement());
if (propertiesProvider == null) {
@ -184,7 +93,7 @@ public class PropertyBasedLabelProvider
}
String[] columnIds = labelUpdates[0].getColumnIds();
String[] propertyNames = calcPropertyNamesForColumns(columnIds);
Set<String> propertyNames = calcPropertyNamesForColumns(columnIds);
// Call the properties provider. Create a request monitor for each label update.
// We can use an immediate executor for the request monitor because the label provider
@ -192,14 +101,12 @@ public class PropertyBasedLabelProvider
IPropertiesUpdate[] propertiesUpdates = new IPropertiesUpdate[labelUpdates.length];
for (int i = 0; i < labelUpdates.length; i++) {
final ILabelUpdate labelUpdate = labelUpdates[i];
propertiesUpdates[i] = new PropertiesUpdate(
propertiesUpdates[i] = new VMPropertiesUpdate(
propertyNames, labelUpdates[i],
new ViewerDataRequestMonitor<Map<String, Object>>(ImmediateExecutor.getInstance(), labelUpdates[i]) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
updateLabel(labelUpdate, getData());
}
updateLabel(labelUpdate, getStatus(), getData());
labelUpdate.done();
}
});
@ -213,39 +120,43 @@ public class PropertyBasedLabelProvider
* @param columnIds Column IDs to check.
* @return Array of property names.
*/
private String[] calcPropertyNamesForColumns(String[] columnIds) {
private Set<String> calcPropertyNamesForColumns(String[] columnIds) {
Set<String> propertyNames = new HashSet<String>();
if (columnIds == null) {
LabelColumnInfo columnInfo = getColumnInfo(null);
LabelColumnInfo columnInfo = getColumnInfo(ID_COLUMN_NO_COLUMNS);
if (columnInfo != null) {
return columnInfo.getPropertyNames();
} else {
return EMPTY_PROPERTY_NAMES_ARRAY;
}
for (String propertyName : columnInfo.getPropertyNames()) {
propertyNames.add(propertyName);
}
}
} else {
List<String> properties = new LinkedList<String>();
for (String columnId : columnIds) {
LabelColumnInfo info = getColumnInfo(columnId);
if (info != null) {
String[] infoPropertyNames = info.getPropertyNames();
for (int i = 0; i < infoPropertyNames.length; i++) {
properties.add(infoPropertyNames[i]);
propertyNames.add(infoPropertyNames[i]);
}
}
}
return properties.toArray(new String[properties.size()]);
}
return propertyNames;
}
/**
* Updates the label information based on given map of properties.
*
* @param update Label update to write to.
* @param status Result of the properties update
* @param properties Properties retrieved from the element properties provider.
*
* @since 2.0
*/
protected void updateLabel(ILabelUpdate update, Map<String,Object> properties) {
protected void updateLabel(ILabelUpdate update, IStatus status, Map<String, Object> properties) {
if (update.getColumnIds() == null) {
LabelColumnInfo info = getColumnInfo(null);
LabelColumnInfo info = getColumnInfo(ID_COLUMN_NO_COLUMNS);
if (info != null) {
info.updateColumn(update, 0, properties);
info.updateColumn(update, 0, status, properties);
}
} else {
String[] columnIds = update.getColumnIds();
@ -253,7 +164,7 @@ public class PropertyBasedLabelProvider
for (int i = 0; i < columnIds.length; i++) {
LabelColumnInfo info = getColumnInfo(columnIds[i]);
if (info != null) {
info.updateColumn(update, i, properties);
info.updateColumn(update, i, status, properties);
}
}
}

View file

@ -0,0 +1,42 @@
package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMViewerUpdate;
/**
* Properties update used as to collect property data from the provider.
*
* @since 2.0
*/
public class VMDelegatingPropertiesUpdate extends VMViewerUpdate implements IPropertiesUpdate {
/**
* Update to write the properties to.
*/
private final IPropertiesUpdate fParentUpdate;
public VMDelegatingPropertiesUpdate(IPropertiesUpdate parentUpdate, RequestMonitor rm) {
super(parentUpdate, rm);
fParentUpdate = parentUpdate;
}
public Set<String> getProperties() {
return fParentUpdate.getProperties();
}
public void setProperty(String property, Object value) {
fParentUpdate.setProperty(property, value);
}
public void setAllProperties(Map<String, Object> properties) {
fParentUpdate.setAllProperties(properties);
}
@Override
public String toString() {
return "VMDelegatingPropertiesUpdate -> " + fParentUpdate; //$NON-NLS-1$
}
}

View file

@ -0,0 +1,89 @@
package org.eclipse.cdt.dsf.ui.viewmodel.properties;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.jface.viewers.TreePath;
/**
* Properties update used as to collect property data from the provider.
*
* @since 2.0
*/
public class VMPropertiesUpdate extends VMViewerUpdate implements IPropertiesUpdate {
/**
* Properties that the client has requested to retrieve.
*/
private final Set<String> fProperties;
/**
* Flag indicating that the update has created a new map, as opposed to
* using directly a map that was created using setAllProperties() call.
*/
private boolean fCreatedOwnMap = false;
/**
* Map of property values, created on demand.
*/
private Map<String, Object> fValues = Collections.emptyMap();
public VMPropertiesUpdate(Set<String> properties, IViewerUpdate parentUpdate, DataRequestMonitor<Map<String,Object>> rm) {
super(parentUpdate, rm);
fProperties = properties;
}
public VMPropertiesUpdate(Set<String> properties, TreePath elementPath, Object viewerInput, IPresentationContext presentationContext, DataRequestMonitor<Map<String,Object>> rm) {
super(elementPath, viewerInput, presentationContext, rm);
fProperties = properties;
}
public Set<String> getProperties() {
return fProperties;
}
public synchronized void setProperty(String property, Object value) {
if (!fCreatedOwnMap) {
fCreatedOwnMap = true;
Map<String, Object> curValues = fValues;
fValues = new HashMap<String, Object>(fProperties.size() * 4 / 3, 0.75f);
if (curValues != null) {
fValues.putAll(curValues);
}
}
fValues.put(property, value);
}
public synchronized void setAllProperties(Map<String, Object> properties) {
if (fCreatedOwnMap) {
fValues.putAll(properties);
}
else {
fValues = properties;
}
}
/**
* Overrides the standard done in order to store the retrieved values
* in the client's request monitor.
*/
@Override
public void done() {
@SuppressWarnings("unchecked")
DataRequestMonitor<Map<String,Object>> rm = (DataRequestMonitor<Map<String,Object>>)getRequestMonitor();
rm.setData(fValues);
super.done();
}
@Override
public String toString() {
return "VMPropertiesUpdate:" + getElement() + " " + fProperties; //$NON-NLS-1$ //$NON-NLS-2$/
}
}

View file

@ -17,37 +17,31 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.AllUpdateScope;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.ICachingVMProviderExtension;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.IVMUpdateScope;
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.VisibleUpdateScope;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.ui.concurrent.SimpleDisplayExecutor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenCountUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.VMHasChildrenUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMPropertiesUpdate;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
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;
@ -58,16 +52,27 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/**
* Base implementation of a caching view model provider.
* Base implementation of a caching view model provider.
*
* @since 1.0
*/
@SuppressWarnings("restriction")
public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider, ICachingVMProviderExtension {
public class AbstractCachingVMProvider extends AbstractVMProvider
implements ICachingVMProvider, IElementPropertiesProvider, ICachingVMProviderExtension
{
/**
* @since 2.0
*/
private final static String PROP_UPDATE_STATUS = "org.eclipse.cdt.dsf.ui.viewmodel.update.update_status"; //$NON-NLS-1$
/**
* @since 2.0
*/
private final static int LENGTH_PROP_IS_CHANGED_PREFIX = PROP_IS_CHANGED_PREFIX.length();
private boolean fDelayEventHandleForViewUpdate = false;
// debug flag
@ -169,7 +174,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
/**
* Entry with cached element data.
*/
static class ElementDataEntry extends Entry {
private static class ElementDataEntry extends Entry {
ElementDataEntry(ElementDataKey key) {
super(key);
}
@ -210,15 +215,19 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
Map<Integer,Object> fChildren = null;
/**
* Map of IDMData objects, keyed by the DM context.
* Map containing element properties.
*
* @since 2.0
*/
Map<IDMContext,Object> fDataOrStatus = new HashMap<IDMContext,Object>(1);
Map<String, Object> fProperties = null;
/**
* Previous known value of the DM data objects.
* Previous known element properties.
*
* @since 2.0
*/
Map<IDMContext,IDMData> fArchiveData = new HashMap<IDMContext,IDMData>(1);;
Map<String, Object> fArchiveProperties = null;
void ensureChildrenMap() {
if (fChildren == null) {
Integer childrenCount = fChildrenCount;
@ -234,8 +243,8 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
"[hasChildren=" + fHasChildren + ", " +//$NON-NLS-1$ //$NON-NLS-2$
"childrenCount=" + fChildrenCount + //$NON-NLS-1$
", children=" + fChildren + //$NON-NLS-1$
", data/status=" + fDataOrStatus + //$NON-NLS-1$
", oldData=" + fArchiveData + "]"; //$NON-NLS-1$ //$NON-NLS-2$
", properties=" + fProperties + //$NON-NLS-1$
", oldProperties=" + fArchiveProperties + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
@ -694,24 +703,22 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
// We are saving current data for change history, check if the data is valid.
// If it valid, save it for archive, if it's not valid old archive data will be used
// if there is any. And if there is no old archive data, just remove the cache entry.
for (Iterator<Map.Entry<IDMContext, Object>> itr = elementDataEntry.fDataOrStatus.entrySet().iterator();
itr.hasNext();)
{
Map.Entry<IDMContext, Object> dataOrStatusEntry = itr.next();
if (dataOrStatusEntry.getValue() instanceof IDMData) {
elementDataEntry.fArchiveData.put(dataOrStatusEntry.getKey(), (IDMData)dataOrStatusEntry.getValue());
}
if (elementDataEntry.fProperties != null) {
elementDataEntry.fArchiveProperties = elementDataEntry.fProperties;
}
elementDataEntry.fDataOrStatus.clear();
if (elementDataEntry.fArchiveData.isEmpty()) {
elementDataEntry.fProperties = null;
// There is no archived data, which means that this entry is empty, so remove it from cache
// completely.
if (elementDataEntry.fArchiveProperties == null) {
fCacheData.remove(entry.fKey);
entry.remove();
}
}
} else {
// We are not changing the archived data. If archive data exists in the entry, leave it.
// Otherwise remove the whole entry.
if (!elementDataEntry.fArchiveData.isEmpty()) {
elementDataEntry.fDataOrStatus.clear();
if (elementDataEntry.fArchiveProperties != null) {
elementDataEntry.fProperties.clear();
} else {
fCacheData.remove(entry.fKey);
entry.remove();
@ -943,110 +950,163 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
}
/**
* Retrieves the deprecated IDMData object for the given IDMContext. This
* method should be removed once the use of IDMData is replaced with
* {@link IElementPropertiesProvider}.
* @since 2.0
*/
@Deprecated
public void getModelData(final IVMNode node, final IViewerUpdate update, final IDMService service, final IDMContext dmc,
final DataRequestMonitor rm, final Executor executor)
{
// Determine if this request is being issues on the a VM executor thread. If so
// then we do not need to create a new one to insure data integrity.
Executor vmExecutor = getExecutor();
if ( vmExecutor instanceof SimpleDisplayExecutor &&
Display.getDefault().getThread() == Thread.currentThread() )
{
getCacheModelData(node, update, service, dmc, rm, executor );
} else {
vmExecutor.execute(new DsfRunnable() {
public void run() {
getCacheModelData(node, update, service, dmc, rm, executor );
}
});
}
}
private void getCacheModelData(final IVMNode node, final IViewerUpdate update, final IDMService service, final IDMContext dmc,
final DataRequestMonitor rm, final Executor executor)
{
ElementDataKey key = makeEntryKey(node, update);
final ElementDataEntry entry = getElementDataEntry(key);
/*if (entry.fDirty) {
rm.setStatus(Status.CANCEL_STATUS);
rm.done();
} else */{
Object dataOrStatus = entry.fDataOrStatus.get(dmc);
if(dataOrStatus != null) {
if (dataOrStatus instanceof IDMData) {
rm.setData( dataOrStatus );
} else {
rm.setStatus((IStatus)dataOrStatus );
}
rm.done();
} else {
// Determine if we are already running on a DSF executor thread. if so then
// we do not need to create a new one to issue the request to the service.
DsfExecutor dsfExecutor = service.getExecutor();
if ( dsfExecutor.isInExecutorThread() ) {
getModelDataFromService(node, update, service, dmc, rm, executor, entry );
}
else {
try {
dsfExecutor.execute(new DsfRunnable() {
public void run() {
getModelDataFromService(node, update, service, dmc, rm, executor, entry );
}
});
} catch (RejectedExecutionException e) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Service session's executor shut down.", null)); //$NON-NLS-1$
rm.done();
}
}
}
public void update(IPropertiesUpdate[] updates) {
if (updates.length == 0)
return;
// Optimization: if all the updates belong to the same node, avoid
// creating any new lists/arrays.
boolean allNodesTheSame = true;
IVMNode firstNode = getNodeForElement(updates[0].getElement());
for (int i = 1; i < updates.length; i++) {
if (firstNode != getNodeForElement(updates[i].getElement())) {
allNodesTheSame = false;
break;
}
}
if (allNodesTheSame) {
if ( !(firstNode instanceof IElementPropertiesProvider) ) {
for (IPropertiesUpdate update : updates) {
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Element is not a VM Context or its node is not a properties provider.", null)); //$NON-NLS-1$
update.done();
}
} else {
updateNode(firstNode, updates);
}
} else {
// Sort the updates by the node.
Map<IVMNode, List<IPropertiesUpdate>> nodeUpdatesMap = new HashMap<IVMNode, List<IPropertiesUpdate>>();
for (IPropertiesUpdate update : updates) {
// Get the VM Context for last element in path.
IVMNode node = getNodeForElement(update.getElement());
if ( node == null || !(node instanceof IElementPropertiesProvider) ) {
// Misdirected update.
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Element is not a VM Context or its node is not a properties provider.", null)); //$NON-NLS-1$
update.done();
continue;
}
if (!nodeUpdatesMap.containsKey(node)) {
nodeUpdatesMap.put(node, new ArrayList<IPropertiesUpdate>());
}
nodeUpdatesMap.get(node).add(update);
}
// Iterate through the nodes in the sorted map.
for (IVMNode node : nodeUpdatesMap.keySet()) {
updateNode(node, nodeUpdatesMap.get(node).toArray(
new IPropertiesUpdate[nodeUpdatesMap.get(node).size()]));
}
}
}
private void getModelDataFromService(final IVMNode node, final IViewerUpdate update, final IDMService service, final IDMContext dmc,
final DataRequestMonitor rm, final Executor executor, final ElementDataEntry entry)
{
service.getModelData(
dmc,
new ViewerDataRequestMonitor<IDMData>(executor, update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
entry.fDataOrStatus.put(dmc, getData());
rm.setData(getData());
} else {
if (!isCanceled()) {
entry.fDataOrStatus.put(dmc, getStatus());
}
rm.setStatus(getStatus());
}
rm.done();
}
});
}
/**
* Retrieves the deprecated IDMData object for the given IDMContext. This
* method should be removed once the use of IDMData is replaced with
* {@link IElementPropertiesProvider}.
* Convenience method that finds the VM node corresponding to given element.
* It returns <code>null</code> if the element is not a VM context.
*
* @param element Element to find the VM Node for.
* @return View Model Node that this element was created by, or <code>null</code>.
*
* @since 2.0
*/
@Deprecated
public IDMData getArchivedModelData(IVMNode node, IViewerUpdate update, IDMContext dmc) {
ElementDataKey key = makeEntryKey(node, update);
final Entry entry = fCacheData.get(key);
if ( entry instanceof ElementDataEntry) {
Map<IDMContext,IDMData> archiveData = ((ElementDataEntry)entry).fArchiveData;
if (archiveData != null) {
return archiveData.get(dmc);
}
private IVMNode getNodeForElement(Object element) {
if (element instanceof IVMContext) {
return ((IVMContext) element).getVMNode();
}
return null;
}
protected void updateNode(final IVMNode node, IPropertiesUpdate[] updates) {
LinkedList <IPropertiesUpdate> missUpdates = new LinkedList<IPropertiesUpdate>();
for(final IPropertiesUpdate update : updates) {
// Find or create the cache entry for the element of this update.
ElementDataKey key = makeEntryKey(node, update);
final ElementDataEntry entry = getElementDataEntry(key);
// The request can be retrieved from cache if all the properties that were requested in the update are
// found in the map.
if (entry.fProperties != null && entry.fProperties.keySet().containsAll(update.getProperties())) {
// Cache Hit! Just return the value.
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
DsfUIPlugin.debug("cacheHitHasChildren(node = " + node + ", update = " + update + ", " + entry.fHasChildren + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
update.setAllProperties(entry.fProperties);
update.setStatus((IStatus)entry.fProperties.get(PROP_UPDATE_STATUS));
update.done();
} else {
// Cache miss! Save the flush counter of the entry and create a proxy update.
final int flushCounter = entry.fFlushCounter;
missUpdates.add(new VMPropertiesUpdate(
update.getProperties(),
update,
new ViewerDataRequestMonitor<Map<String, Object>>(getExecutor(), update) {
@Override
protected void handleCompleted() {
Map<String, Object> properties;
if (!isCanceled() && flushCounter == entry.fFlushCounter) {
// We are caching the result of this update. Copy the properties from the update
// to the cached properties map.
if (entry.fProperties == null) {
entry.fProperties = new HashMap<String, Object>(getData().size() + 1 * 4/3);
entry.fProperties.put(PROP_CACHE_ENTRY_DIRTY, entry.fDirty);
}
properties = entry.fProperties;
properties.putAll(getData());
// Make sure that all the properties that were requested by the user are in the
// properties map. Otherwise, we'll never get a cache hit because the cache
// test makes sure that all keys that are requested are in the properties map.
for (String updateProperty : update.getProperties()) {
if (!properties.containsKey(updateProperty)) {
properties.put(updateProperty, null);
}
}
} else {
// We are not caching the result of this update, but we should still
// return valid data to the client.
properties = new HashMap<String, Object>(getData().size() + 1 * 4/3);
properties.put(PROP_CACHE_ENTRY_DIRTY, Boolean.TRUE);
properties.putAll(getData());
}
properties.put(PROP_UPDATE_STATUS, getStatus());
// If there is archive data available, calculate the requested changed value properties.
// Do not calculate the changed flags if the entry has been flushed.
if (entry.fArchiveProperties != null && flushCounter == entry.fFlushCounter) {
for (String updateProperty : update.getProperties()) {
if (updateProperty.startsWith(PROP_IS_CHANGED_PREFIX)) {
String changedPropertyName = updateProperty.substring(LENGTH_PROP_IS_CHANGED_PREFIX);
Object newValue = properties.get(changedPropertyName);
Object oldValue = entry.fArchiveProperties.get(changedPropertyName);
if (oldValue != null) {
properties.put(updateProperty, !oldValue.equals(newValue));
}
}
}
}
if (DEBUG_CACHE && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
DsfUIPlugin.debug("cacheSavedProperties(node = " + node + ", update = " + update + ", " + getData() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
update.setAllProperties(properties);
update.setStatus(getStatus());
update.done();
}
}));
}
}
// Issue all the update proxies with one call.
if (!missUpdates.isEmpty()) {
((IElementPropertiesProvider)node).update(missUpdates.toArray(new IPropertiesUpdate[missUpdates.size()]));
}
}
/**
* @noreference This method is an implementation of a provisional interface and
* not intended to be referenced by clients.

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.dsf.ui.viewmodel.update;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
/**
* A view model provider which supports caching of data returned by view model
@ -19,8 +20,18 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
*
* @since 1.0
*/
public interface ICachingVMProvider extends IVMProvider {
public interface ICachingVMProvider extends IVMProvider, IElementPropertiesProvider {
/**
* @since 2.0
*/
public static final String PROP_IS_CHANGED_PREFIX = "is_changed."; //$NON-NLS-1$
/**
* @since 2.0
*/
public static final String PROP_CACHE_ENTRY_DIRTY = "cache_entry_dirty"; //$NON-NLS-1$
/**
* Returns the update policies that the given provider supports.
*/

View file

@ -39,7 +39,7 @@ import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
/**
* @since 1.0
* @since 1.1
*/
@SuppressWarnings("restriction")
class MultiLevelUpdateHandler extends DataRequestMonitor<List<Object>> {

View file

@ -38,6 +38,7 @@ import org.eclipse.core.runtime.MultiStatus;
* @since 1.0
*/
public class CountingRequestMonitor extends RequestMonitor {
/**
* Counter tracking the remaining number of times that the done() method
* needs to be called before this request monitor is actually done.
@ -51,7 +52,20 @@ public class CountingRequestMonitor extends RequestMonitor {
public CountingRequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) {
super(executor, parentRequestMonitor);
super.setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "Collective status for set of sub-operations.", null)); //$NON-NLS-1$
super.setStatus(new MultiStatus(DsfPlugin.PLUGIN_ID, 0, "", null) { //$NON-NLS-1$
@Override
public String getMessage() {
StringBuffer message = new StringBuffer();
IStatus[] children = getChildren();
for (int i = 0; i < children.length; i++) {
message.append(children[i].getMessage());
if (i + 1 < children.length) {
message.append(" ,"); //$NON-NLS-1$
}
}
return message.toString();
}
});
}
/**

View file

@ -73,7 +73,7 @@ import org.eclipse.core.runtime.Status;
* @since 1.0
*/
@ThreadSafe
public class RequestMonitor {
public class RequestMonitor extends DsfExecutable {
/**
* Interface used by RequestMonitor to notify when a given request monitor
@ -227,6 +227,8 @@ public class RequestMonitor {
* </p>
*/
public synchronized void done() {
setSubmitted();
if (fDone) {
throw new IllegalStateException("RequestMonitor: " + this + ", done() method called more than once"); //$NON-NLS-1$//$NON-NLS-2$
}

View file

@ -1,44 +0,0 @@
/*******************************************************************************
* Copyright (c) 2006, 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.datamodel;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* Interface for DSF services that provide model data to clients.
* <p>
* For completeness this service interface derives from <code>IDMData</data>
* and has a method which allows clients to retrieve the DM Context that
* represents the service data.
*
* @deprecated Without getModelData method this service has no function.
* There's also no need for it as a marker interface so we may as well
* get rid of it.
*
* @since 1.0
*/
public interface IDMService extends IDsfService {
/**
* Retrieves model data object for given context. This method makes it
* un-necessary for every model service to declare a separate method
* for retrieving model data of specific type.
*
* @param <V> The Data Model Data type that is to be retrieved.
* @param dmc Data Model Context for the data model data object to be retrieved.
* @param rm Request completion monitor to be filled in with the Data Model Data.
*
* @deprecated This method is now deprecated as there is no compile-time linking
* between IDMContext and IDMData objects (see bug 205132)
*/
@Deprecated
void getModelData(IDMContext dmc, DataRequestMonitor<?> rm);
}

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.service;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.model.ICBreakpointExtension;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;

View file

@ -15,7 +15,7 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* Formatted values interface describes the kinds of formatted information
@ -24,7 +24,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMService;
*
* @since 1.0
*/
public interface IFormattedValues extends IDMService {
public interface IFormattedValues extends IDsfService {
/** Marker interface for a DMC that has a formatted value. */
public interface IFormattedDataDMContext extends IDMContext {}
@ -78,7 +78,7 @@ public interface IFormattedValues extends IDMService {
{
private final String fFormatID;
public FormattedValueDMContext(IDMService service, IDMContext parent, String formatId) {
public FormattedValueDMContext(IDsfService service, IDMContext parent, String formatId) {
super(service, new IDMContext[] { parent });
fFormatID = formatId;
}

View file

@ -18,7 +18,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* This interface provides access to the OS's process
@ -29,7 +29,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMService;
*
* @since 1.1
*/
public interface IProcesses extends IDMService {
public interface IProcesses extends IDsfService {
/**
* A thread as known by the OS.

View file

@ -16,7 +16,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* This interface provides access to controlling and monitoring the execution
@ -28,7 +28,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMService;
*
* @since 1.0
*/
public interface IRunControl extends IDMService
public interface IRunControl extends IDsfService
{
/**
* Execution context is the object on which run control operations can be

View file

@ -14,7 +14,7 @@ import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* Stack service provides access to stack information for a
@ -22,7 +22,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMService;
*
* @since 1.0
*/
public interface IStack extends IDMService {
public interface IStack extends IDsfService {
/**
* Context for a specific stack frame. Besides allowing access to stack

View file

@ -14,7 +14,7 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.datamodel.IDMService;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* Service for accessing debugger symbols. This service builds on the Modules
@ -24,7 +24,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMService;
* @see IModules
* @since 1.0
*/
public interface ISymbols extends IDMService {
public interface ISymbols extends IDsfService {
public interface ISymbolObjectDMContext extends IDMContext {}
/**

View file

@ -82,6 +82,10 @@ abstract public class AbstractDsfService
fTracker = null;
rm.done();
}
public boolean isActive() {
return getServiceRegistration() != null;
}
/** Returns the session object for this service */
public DsfSession getSession() { return fSession; }

View file

@ -44,24 +44,24 @@ public interface IDsfService {
* Property name for the session-id of this service. This property should be set by
* all DSF services when they are registered with OSGI service framework.
*/
final static String PROP_SESSION_ID = "org.eclipse.cdt.dsf.service.IService.session_id"; //$NON-NLS-1$
public final static String PROP_SESSION_ID = "org.eclipse.cdt.dsf.service.IService.session_id"; //$NON-NLS-1$
/**
* Returns the DSF Session that this service belongs to.
*/
DsfSession getSession();
public DsfSession getSession();
/**
* Returns the executor that should be used to call methods of this service.
* This method is equivalent to calling getSession().getExecutor()
*/
DsfExecutor getExecutor();
public DsfExecutor getExecutor();
/**
* Returns the map of properties that this service was registered with.
*/
@SuppressWarnings("unchecked")
Dictionary getProperties();
public Dictionary getProperties();
/**
* Returns a filter string that can be used to uniquely identify this
@ -69,7 +69,7 @@ public interface IDsfService {
* name, which were used to register this service.
* @see org.osgi.framework.BundleContext#getServiceReferences
*/
String getServiceFilter();
public String getServiceFilter();
/**
* Performs initialization and registration of the given service. Implementation
@ -81,13 +81,23 @@ public interface IDsfService {
* initializaiton should fail.
* @param requestMonitor callback to be submitted when the initialization is complete
*/
void initialize(RequestMonitor requestMonitor);
public void initialize(RequestMonitor requestMonitor);
/**
* Performs shutdown and de-registration of the given service.
* @param requestMonitor callback to be submitted when shutdown is complete
*/
void shutdown(RequestMonitor requestMonitor);
public void shutdown(RequestMonitor requestMonitor);
/**
* Returns whether the service is currently active. A service should be
* active after it is initialized and before it has been shut down.
*
* @return <code>true</code> if active
*
* @since 2.0
*/
public boolean isActive();
/**
* Returns the startup order number of this service among services in the same session.
@ -97,5 +107,5 @@ public interface IDsfService {
* @return startup order number of this service
* @see org.eclipse.cdt.dsf.service.DsfSession#getAndIncrementServiceStartupCounter()
*/
int getStartupNumber();
public int getStartupNumber();
}

View file

@ -11,24 +11,22 @@
*******************************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel.launch;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractThreadVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.examples.dsf.pda.service.PDARunControl;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.examples.dsf.pda.service.PDAThreadDMContext;
import org.eclipse.cdt.examples.dsf.pda.ui.PDAUIPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IElementMementoProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.ui.IMemento;
@ -50,68 +48,16 @@ public class PDAThreadsVMNode extends AbstractThreadVMNode
}
@Override
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
for (final ILabelUpdate update : updates) {
final PDARunControl runControl = getServicesTracker().getService(PDARunControl.class);
if ( runControl == null ) {
handleFailedUpdate(update);
continue;
}
final PDAThreadDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAThreadDMContext.class);
String imageKey = null;
if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
final PDAThreadDMContext dmc = findDmcInPath(updates[i].getViewerInput(), updates[i].getElementPath(), PDAThreadDMContext.class);
if (dmc != null) {
updates[i].setProperty(ILaunchVMConstants.PROP_ID, Integer.toString(dmc.getID()));
} else {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
updates[i].setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
}
update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
// Find the Reason for the State
getDMVMProvider().getModelData(
this, update, runControl, dmc,
new ViewerDataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), update) {
@Override
public void handleCompleted(){
if (!isSuccess()) {
update.setLabel("<unavailable>", 0);
update.done();
return;
}
// We're in a new dispatch cycle, and we have to check whether the
// service reference is still valid.
final PDARunControl runControl = getServicesTracker().getService(PDARunControl.class);
if ( runControl == null ) {
handleFailedUpdate(update);
return;
}
final StateChangeReason reason = getData().getStateChangeReason();
// Create Labels of type Thread[GDBthreadId]RealThreadID/Name (State: Reason)
// Thread[1] 3457 (Suspended:BREAKPOINT)
final StringBuilder builder = new StringBuilder();
builder.append("Thread ");
builder.append(dmc.getID());
if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc))
builder.append(" (Suspended");
else
builder.append(" (Running");
// Reason will be null before ContainerSuspendEvent is fired
if(reason != null) {
builder.append(" : ");
builder.append(reason);
}
builder.append(")");
update.setLabel(builder.toString(), 0);
update.done();
}
},
getExecutor());
}
super.updatePropertiesInSessionThread(updates);
}
private String produceThreadElementName(String viewName, PDAThreadDMContext execCtx) {

View file

@ -13,17 +13,24 @@
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel.launch;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMData;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractContainerVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.examples.dsf.pda.service.PDACommandControl;
import org.eclipse.cdt.examples.dsf.pda.service.PDAThreadDMContext;
import org.eclipse.cdt.examples.dsf.pda.service.PDAVirtualMachineDMContext;
import org.eclipse.cdt.examples.dsf.pda.ui.PDAUIPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IElementMementoProvider;
@ -70,70 +77,22 @@ public class PDAVirtualMachineVMNode extends AbstractContainerVMNode
update.done();
}
@Override
protected void updateLabelInSessionThread(final ILabelUpdate update) {
// Get a reference to the run control service.
final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
if (runControl == null) {
handleFailedUpdate(update);
return;
protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
// Find the PDA program context.
final PDAVirtualMachineDMContext dmc =
findDmcInPath(updates[i].getViewerInput(), updates[i].getElementPath(), PDAVirtualMachineDMContext.class);
if (dmc != null) {
updates[i].setProperty(PROP_NAME, "PDA");
updates[i].setProperty(ILaunchVMConstants.PROP_ID, dmc.getProgram());
} else {
updates[i].setStatus(new Status(IStatus.ERROR, PDAUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
}
}
// Find the PDA program context.
final PDAVirtualMachineDMContext programCtx =
findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAVirtualMachineDMContext.class);
// Call service to get current program state
final boolean isSuspended = runControl.isSuspended(programCtx);
// Set the program icon based on the running state of the program.
String imageKey = null;
if (isSuspended) {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
} else {
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
}
update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
// Retrieve the last state change reason
getDMVMProvider().getModelData(
this, update, runControl, programCtx,
new ViewerDataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), update)
{
@Override
public void handleCompleted(){
// If the request failed, fail the udpate.
if (!isSuccess()) {
handleFailedUpdate(update);
return;
}
// Compose the thread name string.
final StringBuilder builder = new StringBuilder();
builder.append("PDA [");
builder.append(programCtx.getProgram());
builder.append("]");
if(isSuspended) {
builder.append(" (Suspended");
} else {
builder.append(" (Running");
}
// Reason will be null before ContainerSuspendEvent is fired
if(getData().getStateChangeReason() != null) {
builder.append(" : ");
builder.append(getData().getStateChangeReason());
}
builder.append(")");
update.setLabel(builder.toString(), 0);
update.done();
}
},
getExecutor());
super.updatePropertiesInSessionThread(updates);
}
private String produceProgramElementName( String viewName , PDAVirtualMachineDMContext execCtx ) {
return "PDA." + execCtx.getProgram(); //$NON-NLS-1$
}