1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 202556 - [variables][registers][expressions] Allow setting of numeric format for individual variables in the view.

This commit is contained in:
Patrick Chuong 2011-03-04 16:06:51 +00:00
parent da8a1d0b28
commit c57cf3cce3
22 changed files with 1633 additions and 69 deletions

View file

@ -156,6 +156,20 @@
</dynamic>
</menu>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.RegisterView?after=variableGroup">
<menu
id="org.eclipse.cdt.dsf.debug.ui.registersView_elementNumberFormats"
label="%menu.numberFormat">
<visibleWhen checkEnabled="false">
<reference definitionId="org.eclipse.cdt.dsf.debug.ui.testAreElementNumberFormatsSupported"/>
</visibleWhen>
<dynamic
id="org.eclipse.cdt.dsf.debug.ui.registersNumberFormats"
class="org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.ElementNumberFormatsContribution">
</dynamic>
</menu>
</menuContribution>
<!-- Variables view menu commands -->
<menuContribution
@ -205,6 +219,20 @@
</dynamic>
</menu>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.VariableView?after=variableGroup">
<menu
id="org.eclipse.cdt.dsf.debug.ui.variablesView_elementNumberFormats"
label="%menu.numberFormat">
<visibleWhen checkEnabled="false">
<reference definitionId="org.eclipse.cdt.dsf.debug.ui.testAreElementNumberFormatsSupported"/>
</visibleWhen>
<dynamic
id="org.eclipse.cdt.dsf.debug.ui.variablesNumberFormats"
class="org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.ElementNumberFormatsContribution">
</dynamic>
</menu>
</menuContribution>
<!-- Expressions view menu commands -->
<menuContribution
@ -254,6 +282,20 @@
</dynamic>
</menu>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.ExpressionView?after=expressionGroup">
<menu
id="org.eclipse.cdt.dsf.debug.ui.expressionsView_elementNumberFormats"
label="%menu.numberFormat">
<visibleWhen checkEnabled="false">
<reference definitionId="org.eclipse.cdt.dsf.debug.ui.testAreElementNumberFormatsSupported"/>
</visibleWhen>
<dynamic
id="org.eclipse.cdt.dsf.debug.ui.expressionNumberFormats"
class="org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.ElementNumberFormatsContribution">
</dynamic>
</menu>
</menuContribution>
</extension>
<extension point="org.eclipse.ui.handlers">
@ -342,6 +384,24 @@
</or>
</and>
</definition>
<definition
id="org.eclipse.cdt.dsf.debug.ui.testAreElementNumberFormatsSupported">
<and>
<with variable="org.eclipse.core.runtime.Platform">
<test property="org.eclipse.core.runtime.bundleState"
args="org.eclipse.cdt.dsf.ui"
value="ACTIVE"/>
</with>
<with variable="selection">
<count value="+">
</count>
<iterate operator="and">
<test property="org.eclipse.cdt.dsf.debug.ui.areElementNumberFormatsSupported">
</test>
</iterate>
</with>
</and>
</definition>
</extension>
<extension
@ -380,7 +440,7 @@
class="org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.NumberFormatsPropertyTester"
id="org.eclipse.cdt.dsf.debug.ui.selectionNumberFormatsTester"
namespace="org.eclipse.cdt.dsf.debug.ui"
properties="areNumberFormatsSupported,isNumberFormatAvailable,isNumberFormatActive"
properties="areNumberFormatsSupported,isNumberFormatAvailable,isNumberFormatActive,areElementNumberFormatsSupported"
type="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
</propertyTester>
<propertyTester

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems and others.
* Copyright (c) 2008, 2011 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.actions;
@ -87,6 +88,23 @@ public class VMHandlerUtils {
}
}
/**
* Retrieves the selection from a given service locator's selection service.
* @param serviceLocator Service locator for access to active selection
* and part.
*
* @return The selection if available; return null otherwise.
* @since 2.2
*/
static public ISelection getSelection(IServiceLocator serviceLocator) {
ISelectionService selectionService =
(ISelectionService)serviceLocator.getService(ISelectionService.class);
if (selectionService != null) {
return selectionService.getSelection();
}
return null;
}
public static IVMProvider getVMProviderForPart(IWorkbenchPart part) {
IDebugContextService contextService =
DebugUITools.getDebugContextManager().getContextService(part.getSite().getWorkbenchWindow());

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems and others.
* Copyright (c) 2008, 2011 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
@ -7,17 +7,21 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.expression;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.DebugManualUpdatePolicy;
import org.eclipse.cdt.dsf.ui.viewmodel.update.IElementUpdateTester;
import org.eclipse.cdt.dsf.ui.viewmodel.update.ManualUpdatePolicy;
/**
* Manual update policy which selectively clears the cache when the expressions
* in the expression manager are modified.
* Inherit from DebugManualUpdatePolicy so that expression view can return
* proper update testers for preference format change event and element format
* change event just like what variables view and registers view do. (Bug 202556)
*/
public class ExpressionsManualUpdatePolicy extends ManualUpdatePolicy {
public class ExpressionsManualUpdatePolicy extends DebugManualUpdatePolicy {
@Override
public IElementUpdateTester getElementUpdateTester(Object event) {

View file

@ -0,0 +1,165 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.VMHandlerUtils;
import org.eclipse.cdt.dsf.ui.concurrent.SimpleDisplayExecutor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
/**
* Dynamic menu contribution that shows available number formats in the current
* selection of the view.
*
* @since 2.2
*/
public class ElementNumberFormatsContribution extends NumberFormatsContribution {
private class SelectFormatAction extends Action {
private final IElementFormatProvider fProvider;
private final IPresentationContext fContext;
private final IVMNode[] fNodes;
private final Object fViewerInput;
private final TreePath[] fElementPaths;
private final String fFormatId;
SelectFormatAction(IElementFormatProvider provider, IPresentationContext context, IVMNode[] nodes,
Object viewerInput, TreePath[] elementPaths, String formatId) {
super(formatId == null ? "Restore To Preference" : FormattedValueVMUtil.getFormatLabel(formatId), //$NON-NLS-1$
formatId == null ? AS_PUSH_BUTTON : AS_RADIO_BUTTON);
fProvider = provider;
fContext = context;
fNodes = nodes;
fViewerInput = viewerInput;
fElementPaths = elementPaths;
fFormatId = formatId;
}
@Override
public void run() {
if (fFormatId == null) {
fProvider.setActiveFormat(fContext, fNodes, fViewerInput, fElementPaths, fFormatId);
return;
}
if (isChecked()) {
fProvider.setActiveFormat(fContext, fNodes, fViewerInput, fElementPaths, fFormatId);
}
}
}
protected static IContributionItem[] NO_ITEMS = new IContributionItem[] {
new ContributionItem() {
@Override
public void fill(Menu menu, int index) {
MenuItem item = new MenuItem(menu, SWT.NONE);
item.setEnabled(false);
item.setText(MessagesForNumberFormat.NumberFormatContribution_EmptyFormatsList_label);
}
@Override
public boolean isEnabled() {
return false;
}
}
};
@Override
protected IContributionItem[] getContributionItems() {
ISelection selection = VMHandlerUtils.getSelection(fServiceLocator);
if (selection == null || selection.isEmpty() || selection instanceof ITreeSelection == false) {
return NO_ITEMS;
}
IVMProvider provider = VMHandlerUtils.getVMProviderForSelection(selection);
if (provider instanceof IElementFormatProvider == false) {
}
if (FORMATS.size() == 0) {
return NO_ITEMS;
}
IPresentationContext context = provider.getPresentationContext();
TreePath[] elementPaths = ((ITreeSelection) selection).getPaths();
IVMNode[] nodes = new IVMNode[elementPaths.length];
final String[] formats = new String[elementPaths.length];
Object viewerInput = null;
final List<SelectFormatAction> actions = new ArrayList<SelectFormatAction>(FORMATS.size());
for (String formatId : FORMATS) {
actions.add(new SelectFormatAction((IElementFormatProvider) provider,
context, nodes, viewerInput, elementPaths, formatId));
}
CountingRequestMonitor crm = new CountingRequestMonitor(SimpleDisplayExecutor.getSimpleDisplayExecutor(Display.getDefault()), null) {
@Override
protected void handleCompleted() {
String activeFormat = null;
for (int i = 0; i < formats.length; i++) {
if (i == 0) {
activeFormat = formats[i];
} else if (activeFormat != null
&& activeFormat.equals(formats[i]) == false) {
activeFormat = null;
}
}
if (activeFormat != null) {
for (int i = 0; i < actions.size(); i++) {
if (activeFormat.equals(actions.get(i).fFormatId)) {
actions.get(i).setChecked(true);
}
}
}
}
};
for (int i = 0; i < elementPaths.length; i++) {
Object segment = elementPaths[i].getLastSegment();
if (segment instanceof IVMContext) {
nodes[i] = ((IVMContext) segment).getVMNode();
} else {
nodes[i] = null;
}
final int index = i;
((IElementFormatProvider) provider).getActiveFormat(context, nodes[i], viewerInput, elementPaths[i],
new DataRequestMonitor<String>(ImmediateExecutor.getInstance(), crm) {
@Override
protected void handleSuccess() {
formats[index] = this.getData();
super.handleSuccess();
}
});
}
crm.setDoneCount(elementPaths.length);
int count = actions.size();
IContributionItem[] items = new IContributionItem[count + 2];
for (int i = 0; i < actions.size(); i++) {
items[i] = new ActionContributionItem(actions.get(i));
}
items[count] = new Separator();
items[count + 1] = new ActionContributionItem(new SelectFormatAction(
(IElementFormatProvider) provider, context, nodes, viewerInput, elementPaths, null));
return items;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems and others.
* Copyright (c) 2009, 2011 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
@ -14,6 +15,7 @@ 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;
@ -37,6 +39,7 @@ import org.eclipse.cdt.dsf.service.DsfServices;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesUpdateStatus;
@ -70,6 +73,7 @@ public class FormattedValueRetriever {
private final IVMNode fNode;
private final ICachingVMProviderExtension2 fCache;
private final IElementFormatProvider fElementFormatProvider;
private final ServiceTracker fServiceTracker;
private final Class<? extends IFormattedDataDMContext> fDmcType;
private final String fPropertyPrefix;
@ -90,6 +94,8 @@ public class FormattedValueRetriever {
public FormattedValueRetriever(IVMNode node, Filter filter, Class<? extends IFormattedDataDMContext> dmcType, String propertyPrefix) {
fNode = node;
fCache = (ICachingVMProviderExtension2)node.getVMProvider();
IVMProvider vmprovider = fNode.getVMProvider();
fElementFormatProvider = vmprovider instanceof IElementFormatProvider ? (IElementFormatProvider) vmprovider : null;
fServiceTracker = new ServiceTracker(DsfUIPlugin.getBundleContext(), filter, null);
fServiceTracker.open();
fDmcType = dmcType;
@ -152,45 +158,112 @@ public class FormattedValueRetriever {
@ConfinedToDsfExecutor("node.getExecutor()")
public void update(final IPropertiesUpdate updates[], final RequestMonitor rm)
{
final Map<IPropertiesUpdate, String[]> cachedAvailableFormatsMap = calcCachedAvailableFormatsMap(updates);
if (cachedAvailableFormatsMap != null && cachedAvailableFormatsMap.size() == updates.length) {
// All updates were satisfied by the cache.
doUpdateWithAvailableFormats(updates, cachedAvailableFormatsMap, rm);
} else {
final IFormattedValues service = (IFormattedValues)fServiceTracker.getService();
if (service == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Service not available " + fServiceTracker, null)); //$NON-NLS-1$
rm.done();
return;
retreiveElementActiveFormat(updates, new DataRequestMonitor<Map<IPropertiesUpdate, String>>(ImmediateExecutor.getInstance(), rm) {
@Override
protected void handleCompleted() {
final Map<IPropertiesUpdate, String> elementFormatMap = getData();
final Map<IPropertiesUpdate, String[]> cachedAvailableFormatsMap = calcCachedAvailableFormatsMap(updates);
if ((cachedAvailableFormatsMap != null && cachedAvailableFormatsMap.size() == updates.length)) {
// All updates were satisfied by the cache.
doUpdateWithAvailableFormats(updates, cachedAvailableFormatsMap, elementFormatMap, rm);
} else {
final IFormattedValues service = (IFormattedValues)fServiceTracker.getService();
if (service == null) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Service not available " + fServiceTracker, null)); //$NON-NLS-1$
rm.done();
return;
}
try {
service.getExecutor().execute(new DsfRunnable() {
public void run() {
retrieveAvailableFormats(
calcOutstandingAvailableFormatsUpdates(updates, cachedAvailableFormatsMap),
new DataRequestMonitor<Map<IPropertiesUpdate, String[]>>(fNode.getVMProvider().getExecutor(), rm) {
@Override
protected void handleSuccess() {
Map<IPropertiesUpdate, String[]> availableFormatsMap;
if (cachedAvailableFormatsMap != null) {
availableFormatsMap = cachedAvailableFormatsMap;
availableFormatsMap.putAll(getData());
} else {
availableFormatsMap = getData();
}
// Retrieve the formatted values now that we have the available formats (where needed).
// Note that we are passing off responsibility of our parent monitor
doUpdateWithAvailableFormats(updates, availableFormatsMap, elementFormatMap, rm);
}
});
}
});
} catch (RejectedExecutionException e) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Service executor shut down " + service.getExecutor(), e)); //$NON-NLS-1$
rm.done();
}
}
}
});
}
private void retreiveElementActiveFormat(final IPropertiesUpdate updates[], final DataRequestMonitor<Map<IPropertiesUpdate, String>> rm) {
if (fElementFormatProvider == null) {
rm.setData(new HashMap<IPropertiesUpdate, String>(0));
rm.done();
return;
}
Map<IPropertiesUpdate, String> cachedMap = null;
HashSet<IPropertiesUpdate> outstanding = null;
for (IPropertiesUpdate update : updates) {
if (isElementFormatPropertyNeeded(update) == false) {
continue;
}
String active = null;
ICacheEntry cacheEntry = fCache.getCacheEntry(fNode, update.getViewerInput(), update.getElementPath());
if (cacheEntry != null && cacheEntry.getProperties() != null) {
active = (String) cacheEntry.getProperties().get(PROP_ACTIVE_FORMAT);
}
try {
service.getExecutor().execute(new DsfRunnable() {
public void run() {
retrieveAvailableFormats(
calcOutstandingAvailableFormatsUpdates(updates, cachedAvailableFormatsMap),
new DataRequestMonitor<Map<IPropertiesUpdate, String[]>>(fNode.getVMProvider().getExecutor(), rm) {
@Override
protected void handleSuccess() {
Map<IPropertiesUpdate, String[]> availableFormatsMap;
if (cachedAvailableFormatsMap != null) {
availableFormatsMap = cachedAvailableFormatsMap;
availableFormatsMap.putAll(getData());
} else {
availableFormatsMap = getData();
}
// Retrieve the formatted values now that we have the available formats (where needed).
// Note that we are passing off responsibility of our parent monitor
doUpdateWithAvailableFormats(updates, availableFormatsMap, rm);
}
});
}
});
} catch (RejectedExecutionException e) {
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, "Service executor shut down " + service.getExecutor(), e)); //$NON-NLS-1$
rm.done();
if (active != null) {
if (cachedMap == null) {
cachedMap = new HashMap<IPropertiesUpdate, String>(updates.length * 4/3);
}
cachedMap.put(update, active);
} else {
if (outstanding == null) {
outstanding = new HashSet<IPropertiesUpdate>(updates.length * 4/3);
}
outstanding.add(update);
}
}
if (outstanding == null || outstanding.size() == 0) {
rm.setData(cachedMap == null ? new HashMap<IPropertiesUpdate, String>(0) : cachedMap);
rm.done();
return;
}
if (cachedMap == null) {
cachedMap = new HashMap<IPropertiesUpdate, String>(updates.length * 4/3);
}
final Map<IPropertiesUpdate, String> elementFormatMap = Collections.synchronizedMap(cachedMap);
rm.setData(elementFormatMap);
final CountingRequestMonitor countingRm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), rm);
int count = 0;
for (final IPropertiesUpdate update : outstanding) {
fElementFormatProvider.getActiveFormat(update.getPresentationContext(), fNode, update.getViewerInput(), update.getElementPath(),
new ViewerDataRequestMonitor<String>(ImmediateExecutor.getInstance(), update) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
String active = this.getData();
if (update.getProperties().contains(PROP_ACTIVE_FORMAT)) {
update.setProperty(PROP_ACTIVE_FORMAT, active);
}
elementFormatMap.put(update, active);
}
countingRm.done();
}
});
count++;
}
countingRm.setDoneCount(count);
}
/**
@ -329,6 +402,7 @@ public class FormattedValueRetriever {
private void doUpdateWithAvailableFormats(
IPropertiesUpdate updates[],
final Map<IPropertiesUpdate, String[]> availableFormatsMap,
final Map<IPropertiesUpdate, String> elementFormatMap,
final RequestMonitor rm)
{
final List<IPropertiesUpdate> outstandingUpdates = new ArrayList<IPropertiesUpdate>(updates.length);
@ -341,7 +415,7 @@ public class FormattedValueRetriever {
update.setProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, preferredFormat);
}
final String activeFormat = calcActiveFormat(update, preferredFormat, availableFormatsMap);
final String activeFormat = calcActiveFormat(update, preferredFormat, availableFormatsMap, elementFormatMap);
if (update.getProperties().contains(PROP_ACTIVE_FORMAT)) {
assert activeFormat != null : "Our caller should have provided the available formats if this property was specified; given available formats, an 'active' nomination is guaranteed."; //$NON-NLS-1$
@ -472,12 +546,18 @@ public class FormattedValueRetriever {
*
* @param update Properties update to calculate the active format for.
* @param availableFormatsMap The map of available formats.
* @param elementFormatMap The map of element active format.
* @return The active format, or null if active format not requested in
* update.
*/
private String calcActiveFormat(IPropertiesUpdate update, String preferredFormat, Map<IPropertiesUpdate, String[]> availableFormatsMap) {
private String calcActiveFormat(IPropertiesUpdate update, String preferredFormat, Map<IPropertiesUpdate, String[]> availableFormatsMap,
Map<IPropertiesUpdate, String> elementFormatMap) {
String[] availableFormats = availableFormatsMap.get(update);
if (availableFormats != null && availableFormats.length != 0) {
String elementFormat = elementFormatMap.get(update);
if (elementFormat != null && isFormatAvailable(elementFormat, availableFormats)) {
return elementFormat;
}
if (isFormatAvailable(preferredFormat, availableFormats)) {
return preferredFormat;
} else {
@ -588,6 +668,21 @@ public class FormattedValueRetriever {
update.getProperties().contains(PROP_ACTIVE_FORMAT_VALUE);
}
/**
* For each update, query the active format for the update's
* element...but only if necessary. It is necessary only if the
* update is asking what the active format is or is asking for the value
* of the element in that format.
* @param update
* @return true if needed
*/
private boolean isElementFormatPropertyNeeded(IPropertiesUpdate update) {
if (fElementFormatProvider == null)
return false;
return update.getProperties().contains(PROP_ACTIVE_FORMAT) ||
update.getProperties().contains(PROP_ACTIVE_FORMAT_VALUE);
}
/**
* Extracts the formatted data DMC from the update. If update doesn't
* contain DMC-based elemtn, it writes an error to the update and returns

View file

@ -0,0 +1,67 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.viewers.TreePath;
/**
* Element format provider - an optional interface that provides individual element format
* A view model provider (org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider) can optionally implement this interface.
* If there is a requirement to persist individual format settings, this provider can
* add an persistable (IPersistable) property to PresentationContext so that when presentation context
* is invoked to persist its properties, the individual format settings are persisted as well.
*
* @since 2.2
*/
public interface IElementFormatProvider
{
/**
* Get active format for a given element.
* @param context presentation context
* @param node view model node
* @param viewerInput viewer input
* @param elementPath element path of the given element
* @param rm request monitor
* @return active format if available. Calls rm.setData(null) if there is no active format.
* The caller will use the active format if the returned format is available,
* and will use preference format if the returned format is null or not available.
* Note that if caller finds that the preference format is not available from service,
* it will use the first available format from service. See FormattedValueRetriever.
*/
public void getActiveFormat(IPresentationContext context, IVMNode node, Object viewerInput, TreePath elementPath,
DataRequestMonitor<String> rm);
/**
* Set active format for given elements. The caller will not fire any event to update view.
* The implementation of this method should fire proper events to refresh impacted elements.
* One way is to refresh the view through IVMCachingProvider.refresh but it will
* refresh other non-impacted elements.
* Another way that may be more optimal is to fire ElementFormatEvent that stores exactly the
* impacted elements. The view model can then handle the event more efficiently.
* @param context presentation context
* @param node view model nodes
* @param viewerInput viewer input
* @param elementPath element path of given elements
* @param format format
*/
public void setActiveFormat(IPresentationContext context, IVMNode[] node, Object viewerInput, TreePath[] elementPath, String format);
/**
* Test if this provider supports individual element format for a given context
* @param context given context
* @return true if this provider supports individual element format.
*/
public boolean supportFormat(IVMContext context);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems and others.
* Copyright (c) 2008, 2011 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
@ -38,7 +39,7 @@ import org.eclipse.ui.services.IServiceLocator;
*/
public class NumberFormatsContribution extends CompoundContributionItem implements IWorkbenchContribution {
private static final List<String> FORMATS = new LinkedList<String>();
protected static final List<String> FORMATS = new LinkedList<String>();
static {
FORMATS.add(IFormattedValues.NATURAL_FORMAT);
FORMATS.add(IFormattedValues.HEX_FORMAT);
@ -65,7 +66,7 @@ public class NumberFormatsContribution extends CompoundContributionItem implemen
}
}
private IServiceLocator fServiceLocator;
protected IServiceLocator fServiceLocator;
private static IContributionItem[] NO_BREAKPOINT_TYPES_CONTRIBUTION_ITEMS = new IContributionItem[] {
new ContributionItem() {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems and others.
* Copyright (c) 2008, 2011 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat;
@ -46,6 +47,7 @@ import org.eclipse.ui.IWorkbenchPart;
public class NumberFormatsPropertyTester extends PropertyTester {
private static final String SUPPORTED = "areNumberFormatsSupported"; //$NON-NLS-1$
private static final String ELEMENT_FORMATS_SUPPORTED = "areElementNumberFormatsSupported"; //$NON-NLS-1$
private static final String AVAILABLE = "isNumberFormatAvailable"; //$NON-NLS-1$
private static final String ACTIVE = "isNumberFormatActive"; //$NON-NLS-1$
@ -63,18 +65,18 @@ public class NumberFormatsPropertyTester extends PropertyTester {
if (receiver instanceof IVMContext) {
IVMProvider provider = ((IVMContext)receiver).getVMNode().getVMProvider();
if (provider != null) {
return testProvider(provider, property, expectedValue);
return testProvider(provider, property, expectedValue, (IVMContext) receiver);
}
} else if (receiver instanceof IDebugView) {
IVMProvider provider = VMHandlerUtils.getVMProviderForPart((IDebugView)receiver);
if (provider != null) {
return testProvider(provider, property, expectedValue);
return testProvider(provider, property, expectedValue, null);
}
}
return false;
}
private boolean testProvider(IVMProvider provider, String property, Object expectedValue) {
private boolean testProvider(IVMProvider provider, String property, Object expectedValue, IVMContext vmctx) {
if (SUPPORTED.equals(property)) {
return true;
} else if (AVAILABLE.equals(property)) {
@ -82,7 +84,11 @@ public class NumberFormatsPropertyTester extends PropertyTester {
} else if (ACTIVE.equals(property)) {
Object activeId = provider.getPresentationContext().getProperty(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
return expectedValue != null && expectedValue.equals(activeId);
}
} else if (ELEMENT_FORMATS_SUPPORTED.equals(property)) {
if (provider instanceof IElementFormatProvider) {
return ((IElementFormatProvider) provider).supportFormat(vmctx);
}
}
return false;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* Copyright (c) 2009, 2011 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.update;
@ -37,6 +38,7 @@ import org.eclipse.jface.viewers.TreePath;
public class DebugManualUpdatePolicy extends ManualUpdatePolicy implements IVMUpdatePolicyExtension {
private final Set<String> fActiveNumberFormatPropertiesWithPrefixes;
private final Set<String> fElementFormatPropertiesWithPrefixes;
/**
* Creates a manual update policy for debug views.
@ -59,13 +61,19 @@ public class DebugManualUpdatePolicy extends ManualUpdatePolicy implements IVMUp
public DebugManualUpdatePolicy(String[] prefixes) {
if (prefixes.length == 0) {
fActiveNumberFormatPropertiesWithPrefixes = ACTIVE_NUMBER_FORMAT_PROPERTIES;
fElementFormatPropertiesWithPrefixes = ELEMENT_FORMAT_PROPERTIES;
} else {
fActiveNumberFormatPropertiesWithPrefixes = new TreeSet<String>(ACTIVE_NUMBER_FORMAT_PROPERTIES);
fElementFormatPropertiesWithPrefixes = new TreeSet<String>(ELEMENT_FORMAT_PROPERTIES);
for (String prefix : prefixes) {
fActiveNumberFormatPropertiesWithPrefixes.add(
(prefix + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT).intern());
fActiveNumberFormatPropertiesWithPrefixes.add(
(prefix + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE).intern());
fElementFormatPropertiesWithPrefixes.add(
(prefix + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT).intern());
fElementFormatPropertiesWithPrefixes.add(
(prefix + IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE).intern());
}
}
@ -78,6 +86,12 @@ public class DebugManualUpdatePolicy extends ManualUpdatePolicy implements IVMUp
ACTIVE_NUMBER_FORMAT_PROPERTIES.add(IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
}
private static final Set<String> ELEMENT_FORMAT_PROPERTIES = new TreeSet<String>();
static {
ELEMENT_FORMAT_PROPERTIES.add(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT);
ELEMENT_FORMAT_PROPERTIES.add(IDebugVMConstants.PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE);
}
/**
* This specialized element update tester flushes the active number format
* property of the elemetn under consideration. The partial property flush
@ -94,6 +108,7 @@ public class DebugManualUpdatePolicy extends ManualUpdatePolicy implements IVMUp
}
public boolean includes(IElementUpdateTester tester) {
// includes ElementFormatUpdateTester as well?
return tester.equals(this);
}
@ -110,6 +125,10 @@ public class DebugManualUpdatePolicy extends ManualUpdatePolicy implements IVMUp
{
return fNumberFormatPropertyEventUpdateTester;
}
if ( event instanceof ElementFormatEvent )
{
return new ElementFormatUpdateTester(((ElementFormatEvent) event), fElementFormatPropertiesWithPrefixes);
}
return super.getElementUpdateTester(event);
}

View file

@ -0,0 +1,59 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.update;
import java.util.Set;
/**
* An event that indicates element format is changed. Even when a viewer is
* configured to be in a manual update mode, there is a need to update of the
* labels/states of the element.
*
* @since 2.2
*/
public class ElementFormatEvent {
protected Set<Object> elements;
protected int applyDepth;
/**
* Constructor
* @param elements the elements that have their formats changed
* @param applyDepth how deep each of the elements apply to itself and their child elements.
* -1 - recursively apply child elements to an infinite depth;
* 0 - does not apply to the element itself and its child elements;
* 1 - apply to the element itself only;
* 2 - apply to the element, its direct children and grand-children;
* and so on for other positive numbers.
*/
public ElementFormatEvent(Set<Object> elements, int applyDepth) {
this.elements = elements;
this.applyDepth = applyDepth;
}
/**
* Get the elements that has formats changed.
*
* @return the elements
*/
public Set<Object> getElements() {
return elements;
}
/**
* Get the depth that how each of the elements apply to itself and their
* child elements.
*
* @return the apply depth.
*/
public int getApplyDepth() {
return applyDepth;
}
}

View file

@ -0,0 +1,84 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.update;
import java.util.Collection;
import java.util.Set;
import org.eclipse.cdt.dsf.ui.viewmodel.update.IElementUpdateTester;
import org.eclipse.cdt.dsf.ui.viewmodel.update.IElementUpdateTesterExtension;
import org.eclipse.cdt.dsf.ui.viewmodel.update.IVMUpdatePolicy;
import org.eclipse.jface.viewers.TreePath;
/**
* An update tester for element format event (ElementFormatEvent). This tester
* flush partial properties for elements that are affected by a change of
* element format.
*
* @since 2.2
*/
public class ElementFormatUpdateTester implements IElementUpdateTesterExtension {
protected Set<String> propertiesWithPrefixes;
protected ElementFormatEvent formatEvent;
public ElementFormatUpdateTester(ElementFormatEvent event, Set<String> propertiesWithPrefixes) {
formatEvent = event;
this.propertiesWithPrefixes = propertiesWithPrefixes;
}
public int getUpdateFlags(Object viewerInput, TreePath path) {
Set<Object> elements = formatEvent.getElements();
if (elements.contains(viewerInput)) {
return IVMUpdatePolicy.FLUSH_PARTIAL_PROPERTIES;
}
int applyDepth = formatEvent.getApplyDepth();
if (applyDepth == -1) {
for (int i = 0; i < path.getSegmentCount(); i++) {
if (elements.contains(path.getSegment(i))) {
return IVMUpdatePolicy.FLUSH_PARTIAL_PROPERTIES;
}
}
} else if (applyDepth >= 1) {
int start = path.getSegmentCount() - applyDepth;
if (start < 0)
start = 0;
for (int i = start; i < path.getSegmentCount(); i++) {
if (elements.contains(path.getSegment(i))) {
return IVMUpdatePolicy.FLUSH_PARTIAL_PROPERTIES;
}
}
}
return 0;
}
public Collection<String> getPropertiesToFlush(Object viewerInput,
TreePath path, boolean isDirty) {
return propertiesWithPrefixes;
}
public boolean includes(IElementUpdateTester tester) {
if (tester.equals(this)) {
return true;
}
if (tester instanceof ElementFormatUpdateTester) {
return formatEvent.getElements().containsAll(
((ElementFormatUpdateTester) tester).formatEvent.getElements())
&& propertiesWithPrefixes.containsAll(((ElementFormatUpdateTester) tester).propertiesWithPrefixes)
&& formatEvent.getApplyDepth() == ((ElementFormatUpdateTester) tester).formatEvent.getApplyDepth();
}
return false;
}
@Override
public String toString() {
return "Manual (refresh = false) update tester for an element format event"; //$NON-NLS-1$
}
}

View file

@ -103,5 +103,12 @@
adaptableType="org.eclipse.cdt.examples.dsf.pda.ui.editor.PDAEditor">
<adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget"/>
</factory>
</extension>
<extension
point="org.eclipse.ui.elementFactories">
<factory
class="org.eclipse.cdt.examples.dsf.pda.ui.viewmodel.VariablePersistableFactory"
id="org.eclipse.cdt.examples.dsf.pda.ui.variablePersitableFactory">
</factory>
</extension> -->
</plugin>

View file

@ -0,0 +1,115 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
import java.util.ArrayList;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.viewers.TreePath;
/**
* PDA View Model provider for the expression view.
*/
@SuppressWarnings("restriction")
public class PDAExpressionVMProvider extends ExpressionVMProvider implements IElementFormatProvider {
static String myPersistId = "org.eclipse.cdt.examples.dsf.pda.ui.variablePersistable";
public PDAExpressionVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
super(adapter, context, session);
}
public void getActiveFormat(IPresentationContext context, IVMNode node, Object viewerInput, TreePath elementPath,
DataRequestMonitor<String> rm) {
Object p = context.getProperty(myPersistId);
if (p instanceof VariablePersistable == false) {
rm.setData(null);
rm.done();
return;
}
VariablePersistable persistable = (VariablePersistable) p;
Object x = elementPath.getLastSegment();
if (x instanceof VariableVMNode.VariableExpressionVMC) {
IExpressionDMContext ctx = DMContexts.getAncestorOfType(((VariableVMNode.VariableExpressionVMC) x).getDMContext(), IExpressionDMContext.class);
if (ctx == null) {
rm.setData(null);
} else {
rm.setData(persistable.getFormat(ctx.getExpression()));
}
rm.done();
return;
} else if (x instanceof IDMVMContext) {
// register and bit field context are covered here.
// When these show up in expression view, the register/bit field vm node's associateExpression has called
// RegisterVMC/BitFieldVMC's setExpression
IExpression y = (IExpression) ((IVMContext) x).getAdapter(IExpression.class);
if (y == null) {
rm.setData(null);
} else {
rm.setData(persistable.getFormat(y.getExpressionText()));
}
rm.done();
return;
}
rm.setData(null);
rm.done();
return;
}
public void setActiveFormat(IPresentationContext context, IVMNode[] node, Object viewerInput, TreePath[] elementPath, String format) {
Object p = context.getProperty(myPersistId);
VariablePersistable persistable = null;
if (p instanceof VariablePersistable) {
persistable = (VariablePersistable) p;
} else {
persistable = new VariablePersistable();
context.setProperty(myPersistId, persistable);
}
ArrayList<IDMVMContext> changed = new ArrayList<IDMVMContext>(elementPath.length);
for (int i = 0; i < elementPath.length; i++) {
Object x = elementPath[i].getLastSegment();
if (x instanceof VariableVMNode.VariableExpressionVMC) {
IExpressionDMContext ctx = DMContexts.getAncestorOfType(((VariableVMNode.VariableExpressionVMC) x).getDMContext(), IExpressionDMContext.class);
if (ctx == null)
continue;
persistable.setFormat(ctx.getExpression(), format);
changed.add((IDMVMContext) x);
} else if (x instanceof IDMVMContext) {
IExpression y = (IExpression) ((IVMContext) x).getAdapter(IExpression.class);
if (y == null)
continue;
persistable.setFormat(y.getExpressionText(), format);
}
}
if (changed.size() > 0) {
refresh();
}
}
public boolean supportFormat(IVMContext context) {
if (context instanceof VariableVMNode.VariableExpressionVMC) {
return true;
}
return false;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Wind River Systems and others.
* Copyright (c) 2006, 2011 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
@ -7,13 +7,14 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
//import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
import org.eclipse.cdt.dsf.service.DsfSession;
@ -45,7 +46,7 @@ public class PDAVMAdapter extends AbstractDebugVMAdapter
} else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
return new VariableVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
return new ExpressionVMProvider(this, context, getSession());
return new PDAExpressionVMProvider(this, context, getSession());
} else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) {
return new RegisterVMProvider(this, context, getSession());
}

View file

@ -0,0 +1,81 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistableElement;
/**
* Variable persistable for variable settings
*/
class VariablePersistable implements IPersistableElement, IAdaptable {
HashMap<String, String> map = new HashMap<String, String>();
public void saveState(IMemento memento) {
HashMap<String, String> clone = null;
synchronized (map) {
clone = new HashMap<String, String>(map);
}
Iterator<Entry<String, String> > it = clone.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = it.next();
IMemento value = memento.createChild("variable", entry.getKey());
value.putString("format", entry.getValue());
}
}
void restore(IMemento memento) {
IMemento[] list = memento.getChildren("variable");
HashMap<String, String> clone = new HashMap<String, String>();
for (int i = 0; i < list.length; i++) {
clone.put(list[i].getID(), list[i].getString("format"));
}
synchronized(map) {
map.clear();
map.putAll(clone);
}
}
String getFormat(String key) {
if (key == null)
return null;
synchronized (map) {
return map.get(key);
}
}
void setFormat(String key, String format) {
synchronized (map) {
if (format == null) {
map.remove(key);
} else {
map.put(key, format);
}
}
}
public String getFactoryId() {
return VariablePersistableFactory.getFactoryId();
}
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
if (adapter.isInstance(this)) {
return this;
}
return null;
}
}

View file

@ -0,0 +1,32 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format example (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.examples.dsf.pda.ui.viewmodel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
/**
* Variable persistable factory for VariablePersistable
*/
public class VariablePersistableFactory implements IElementFactory {
public static String getFactoryId() {
return "org.eclipse.cdt.examples.dsf.pda.ui.variablePersitableFactory";
}
public IAdaptable createElement(IMemento memento) {
VariablePersistable x = new VariablePersistable();
x.restore(memento);
return x;
}
}

View file

@ -32,5 +32,12 @@
markerType="markerType.breakpoint"
id="org.eclipse.cdt.tests.dsf.breakpoint"/>
</extension>
<extension
point="org.eclipse.ui.elementFactories">
<factory
class="org.eclipse.cdt.tests.dsf.vm.TestPersistableFactory"
id="org.eclipse.cdt.tests.dsf.vm.testPersistableFactory">
</factory>
</extension>
</plugin>

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems and others.
* Copyright (c) 2009, 2011 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
@ -7,9 +7,12 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format test cases (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import junit.framework.Assert;
@ -24,9 +27,11 @@ import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueVMUtil;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.IDsfService;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesUpdateStatus;
@ -40,12 +45,14 @@ import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarg
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.ViewerLabel;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
/**
* Tests to verify the operation of FormattedValuesVMUtil
@ -65,6 +72,7 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
DummyFormattedValueService fDummyValuesService;
AbstractVMAdapter fVMAdapter;
TestModelCachingVMProvider fVMProvider;
int vmListenerLevel = -1;
public FormattedValueTests(String name) {
super(name);
@ -114,6 +122,63 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
fShell.open ();
}
/**
* helper to create view model and viewer
* @param vmOnly true to create view model only and do not create viewer
*/
void createViewer(boolean vmOnly) {
if (vmOnly == false) {
fDisplay = PlatformUI.getWorkbench().getDisplay();
fShell = new Shell(fDisplay/*, SWT.ON_TOP | SWT.SHELL_TRIM*/);
fShell.setMaximized(true);
fShell.setLayout(new FillLayout());
fViewer = createViewer(fDisplay, fShell);
fViewerListener = new TestModelUpdatesListener(fViewer, true, false);
}
fVMProvider = new TestElementFormatVMProvider(fVMAdapter, fViewer.getPresentationContext(), fDsfSession);
fVMListener = new TestModelUpdatesListener();
fVMProvider.getNode().setVMUpdateListener(fVMListener);
fVMProvider.getNode().getLabelProvider().addPropertiesUpdateListener(fViewerListener);
fVMProvider.getNode().setFormattedValuesListener(fFormattedValuesListener);
if (vmOnly == false) {
fShell.open();
}
}
/**
* helper to destory view model and viewer
* @param vmOnly true to destory view model only and do not destroy viewer
*/
void destroyViewer(boolean vmOnly) {
fVMProvider.getNode().setFormattedValuesListener(null);
fVMProvider.getNode().getLabelProvider().removePropertiesUpdateListener(fViewerListener);
fVMProvider.getNode().setVMUpdateListener(null);
fVMListener.dispose();
if (vmOnly == false) {
fViewerListener.dispose();
fViewer.getPresentationContext().dispose();
// Close the shell
fShell.close();
while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
}
}
/**
* helper to recreate view model only
*/
void recreateViewModel() {
destroyViewer(true);
createViewer(true);
}
/**
* helper to recreate viewer (and view model)
*/
void recreateViewer() {
destroyViewer(false);
createViewer(false);
}
private void initializeService(final IDsfService service) throws InterruptedException, ExecutionException {
Query<Object> initQuery = new Query<Object>() {
@Override
@ -239,6 +304,389 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
" (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
}
/**
* Test that each element can have its own format
*/
public void testValidateElement() {
recreateViewModel();
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(preferenceFormat);
// set each element to the same element format different than the preference format, and verify
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
String[] format = { IFormattedValues.HEX_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
ArrayList<ElementFormatSetting> elementFormats = new ArrayList<ElementFormatSetting>(map.values());
setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, true, false, false);
// element of same level use the same format and different levels have different formats, and verify
map.clear();
format = new String[] { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
IFormattedValues.NATURAL_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
elementFormats = new ArrayList<ElementFormatSetting>(map.values());
setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
}
/**
* Test that each element can change to a format and then restore to preference format
*/
public void testChangeElementFormat() {
recreateViewModel();
String preferenceFormat = IFormattedValues.HEX_FORMAT;
setInput(IFormattedValues.NATURAL_FORMAT);
setFormatAndValidate(preferenceFormat, false, false, false);
// set each element to a format, and verify
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
IFormattedValues.NATURAL_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
ArrayList<ElementFormatSetting> elementFormats = new ArrayList<ElementFormatSetting>(map.values());
setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
// Restore each element to preference format, and verify
for (ElementFormatSetting e : elementFormats) {
e.formatId = null;
}
setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
}
/**
* Test changing element to a format and then restore to preference format,
* using a view model provider that applies a format to child elements
* of a certain level of depth.
*/
public void testChangeElementFormatApplyDepth() {
recreateViewModel();
if (fVMProvider instanceof TestElementFormatVMProvider == false) {
return;
}
TestElementFormatVMProvider myVM = (TestElementFormatVMProvider) fVMProvider;
String preferenceFormat = IFormattedValues.HEX_FORMAT;
setInput(IFormattedValues.NATURAL_FORMAT);
setFormatAndValidate(preferenceFormat, false, false, false);
int[] myDepths = new int[] { -1, 2 };
for (int depth : myDepths) {
myVM.elementFormatApplyDepth = depth;
// set top level element to a format, and verify top and child elements
// at certain levels have the correct format.
String[] format = { IFormattedValues.DECIMAL_FORMAT };
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, 1, 0, map);
ArrayList<ElementFormatSetting> setElementFormats = new ArrayList<ElementFormatSetting>(map.values());
HashMap<String, ElementFormatSetting> expMap = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, depth, 0, expMap);
ArrayList<ElementFormatSetting> expectElementFormats = new ArrayList<ElementFormatSetting>(expMap.values());
setFormatAndValidate(preferenceFormat, setElementFormats, expectElementFormats, false, false, false);
// Restore top level element to preference format, and verify.
for (ElementFormatSetting e : setElementFormats) {
e.formatId = null;
}
for (ElementFormatSetting e : expectElementFormats) {
e.formatId = null;
}
setFormatAndValidate(preferenceFormat, setElementFormats, expectElementFormats, false, false, false);
}
}
/**
* Test changing format of each element under manual update policy.
* Formatted values should be retrieved from cache if available.
* Changing to a format whose formatted value is not in cache should get a cache miss error.
*/
public void testChangeElementFormatManualUpdateMode() {
recreateViewModel();
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(IFormattedValues.NATURAL_FORMAT);
setUpdatePolicy(ManualUpdatePolicy.MANUAL_UPDATE_POLICY_ID);
// Change to a new format, this does not cause the cache entries to be
// set to dirty. Retrieving new format values should happen from the service.
HashMap<String, ElementFormatSetting> map1 = new HashMap<String, ElementFormatSetting>();
String[] format1 = { IFormattedValues.HEX_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, -1, 0, map1);
ArrayList<ElementFormatSetting> elementFormats1 = new ArrayList<ElementFormatSetting>(map1.values());
setFormatAndValidate(preferenceFormat, elementFormats1, elementFormats1, true, false, false);
// Remove element format and so restore back to preference - natural format. Values should be retrieved from cache.
HashMap<String, ElementFormatSetting> map2 = new HashMap<String, ElementFormatSetting>();
String[] format2 = { null };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, -1, 0, map2);
ArrayList<ElementFormatSetting> elementFormats2 = new ArrayList<ElementFormatSetting>(map2.values());
setFormatAndValidate(preferenceFormat, elementFormats2, elementFormats2, true, true, false);
// Generate an event which will cause all cache entries to be marked dirty.
postEventInManualUpdateMode();
// Change back again to hex format. Values should be retrieved from cache.
setFormatAndValidate(preferenceFormat, elementFormats1, elementFormats1, true, true, false);
// Change to a decimal, which is not cached, values should come with an error.
HashMap<String, ElementFormatSetting> map3 = new HashMap<String, ElementFormatSetting>();
String[] format3 = { IFormattedValues.DECIMAL_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, -1, 0, map3);
ArrayList<ElementFormatSetting> elementFormats3 = new ArrayList<ElementFormatSetting>(map3.values());
setFormatAndValidate(preferenceFormat, elementFormats3, elementFormats3, true, true, true);
}
/**
* Test changing element format under manual update policy,
* using a view model provider that applies a format to child elements
* of a certain level of depth.
*/
public void testChangeElementFormatApplyDepthManualUpdateMode() {
int[] myDepths = new int[] { -1, 2 };
for (int depth : myDepths) {
recreateViewer();
if (fVMProvider instanceof TestElementFormatVMProvider == false) {
return;
}
TestElementFormatVMProvider myVM = (TestElementFormatVMProvider) fVMProvider;
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(IFormattedValues.NATURAL_FORMAT);
setUpdatePolicy(ManualUpdatePolicy.MANUAL_UPDATE_POLICY_ID);
myVM.elementFormatApplyDepth = depth;
// Change top level to a new format, this does not cause the cache entries to be
// set to dirty. Retrieving new format values should happen from the service.
String[] format1 = { IFormattedValues.HEX_FORMAT };
HashMap<String, ElementFormatSetting> map1 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, 1, 0, map1);
ArrayList<ElementFormatSetting> elementFormats1 = new ArrayList<ElementFormatSetting>(map1.values());
HashMap<String, ElementFormatSetting> expMap1 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format1, depth, 0, expMap1);
ArrayList<ElementFormatSetting> expectElementFormats1 = new ArrayList<ElementFormatSetting>(expMap1.values());
vmListenerLevel = depth;
setFormatAndValidate(preferenceFormat, elementFormats1, expectElementFormats1, true, false, false);
// Remove element format and so restore back to preference format - natural. Values should be retrieved from cache.
String[] format2 = { null };
HashMap<String, ElementFormatSetting> map2 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, 1, 0, map2);
ArrayList<ElementFormatSetting> elementFormats2 = new ArrayList<ElementFormatSetting>(map2.values());
HashMap<String, ElementFormatSetting> expMap2 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format2, depth, 0, expMap2);
ArrayList<ElementFormatSetting> expectElementFormats2 = new ArrayList<ElementFormatSetting>(expMap2.values());
setFormatAndValidate(preferenceFormat, elementFormats2, expectElementFormats2, true, true, false);
// Generate an event which will cause all cache entries to be marked dirty.
postEventInManualUpdateMode();
// Change back again to hex format. Values should be retrieved from cache.
setFormatAndValidate(preferenceFormat, elementFormats1, expectElementFormats1, true, true, false);
// Change to a decimal, which is not cached, values should come with an error.
String[] format3 = { IFormattedValues.DECIMAL_FORMAT };
HashMap<String, ElementFormatSetting> map3 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, 1, 0, map3);
ArrayList<ElementFormatSetting> elementFormats3 = new ArrayList<ElementFormatSetting>(map3.values());
HashMap<String, ElementFormatSetting> expMap3 = new HashMap<String, ElementFormatSetting>();
makeElementFormatSetting(fViewer, TreePath.EMPTY, format3, depth, 0, expMap3);
ArrayList<ElementFormatSetting> expectElementFormats3 = new ArrayList<ElementFormatSetting>(expMap3.values());
setFormatAndValidate(preferenceFormat, elementFormats3, expectElementFormats3, true, true, true);
}
}
/**
* Test that when the preference format is invalid, each element can still change to a format.
* Also, each element can restore to the invalid preference format such that
* the element uses first available format from service.
*/
public void testChangeElementFormatWithInvalidPreference() {
recreateViewModel();
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(preferenceFormat);
// set preference format to an invalid format and verify
setInvalidPreferenceAndVerify();
// set each element to a format, and verify
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
IFormattedValues.NATURAL_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
ArrayList<ElementFormatSetting> elementFormats = new ArrayList<ElementFormatSetting>(map.values());
setFormatAndValidate("invalid format", elementFormats, elementFormats, false, false, false);
// Restore each element to preference format which is an invalid format
for (ElementFormatSetting e : elementFormats) {
e.formatId = null;
}
fViewerListener.reset();
fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
fVMListener.reset();
fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
if (fVMProvider instanceof IElementFormatProvider) {
IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
for (ElementFormatSetting es : elementFormats) {
ep.setActiveFormat(fViewer.getPresentationContext(),
es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
}
}
while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
if (!fDisplay.readAndDispatch ()) {
fDisplay.sleep ();
}
}
// verify service's first available format is used
validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
}
/**
* Test that when an element is set to to an invalid format, the element uses preference format.
*/
public void testInvalidElementFormat() {
recreateViewModel();
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(preferenceFormat);
// set each element to an invalid format
setElementInvalidFormat();
// verify preference format is used when element format is invalid
validateModel(preferenceFormat, "");
}
/**
* Test that when an element is set to to an invalid format and the preference format is invalid,
* the element uses first available format from service.
*/
public void testInvalidElementFormatWithInvalidPreference() {
recreateViewModel();
String preferenceFormat = IFormattedValues.NATURAL_FORMAT;
setInput(preferenceFormat);
// set preference format to an invalid format and verify
setInvalidPreferenceAndVerify();
// set each element to an invalid format
setElementInvalidFormat();
// verify service's first available format is used when element format and preference format are invalid
validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
}
/**
* Test that element format can be persisted in memento and viewer
* can restore to the persisted settings.
*/
public void testPersistElementFormat() {
recreateViewModel();
String preferenceFormat = IFormattedValues.HEX_FORMAT;
setInput(IFormattedValues.NATURAL_FORMAT);
setFormatAndValidate(preferenceFormat, false, false, false);
// set each element to a format, and verify
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
String[] format = { IFormattedValues.HEX_FORMAT, IFormattedValues.DECIMAL_FORMAT,
IFormattedValues.OCTAL_FORMAT, IFormattedValues.BINARY_FORMAT,
IFormattedValues.NATURAL_FORMAT };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
ArrayList<ElementFormatSetting> elementFormats = new ArrayList<ElementFormatSetting>(map.values());
setFormatAndValidate(preferenceFormat, elementFormats, elementFormats, false, false, false);
// save settings
XMLMemento memento = XMLMemento.createWriteRoot("TEST");
if (fViewer instanceof TreeModelViewer == false)
return;
((TreeModelViewer) fViewer).saveState(memento);
// throw away any settings inside the viewer and create a new viewer
// with memento settings, this is the same effect resulted from closing
// and opening workspace again.
recreateViewer();
if (fViewer instanceof TreeModelViewer == false)
return;
((TreeModelViewer) fViewer).initState(memento);
setInput(IFormattedValues.NATURAL_FORMAT);
preferenceFormat = (String) fViewer.getPresentationContext().getProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE);
validateModel(elementFormats, preferenceFormat, "", preferenceFormat, "");
}
/**
* helper class that stores some element paths and nodes using a certain format
*/
class ElementFormatSetting {
ArrayList<IVMNode> nodes;
ArrayList<TreePath> elementPaths;
String formatId;
}
/**
* helper to create element format settings for all children paths of a given element path.
* Tree paths at the same level will use the same format. Tree paths at different
* levels will use different formats.
* @param _viewer tree viewer
* @param path given element path
* @param formats formats to rotate for different levels of children tree paths
* @param levelStop depth to stop recursively walk down the children.
* @param levelIndex index to a format for a level of children
* @param result store the created element format settings
*/
void makeElementFormatSetting(ITreeModelViewer _viewer, TreePath path, String[] formats,
int levelStop, int levelIndex, HashMap<String, ElementFormatSetting> result) {
if (levelStop >= 0 && levelIndex >= levelStop)
return;
ITreeModelContentProviderTarget viewer = (ITreeModelContentProviderTarget)_viewer;
int childCount = viewer.getChildCount(path);
if (childCount == 0)
return;
String fmt = formats[levelIndex % formats.length];
ElementFormatSetting setting = result.get(fmt);
if (setting == null) {
setting = new ElementFormatSetting();
setting.nodes = new ArrayList<IVMNode>(childCount);
setting.elementPaths = new ArrayList<TreePath>(childCount);
setting.formatId = fmt;
result.put(fmt, setting);
}
for (int i = 0; i < childCount; i++) {
Object viewerObject = viewer.getChildElement(path, i);
if (viewerObject instanceof TestElementVMContext) {
TreePath childPath = path.createChildPath(viewerObject);
setting.nodes.add(((TestElementVMContext)viewerObject).getVMNode());
setting.elementPaths.add(childPath);
makeElementFormatSetting(viewer, childPath, formats, levelStop, levelIndex + 1, result);
}
}
}
/**
* helper to set element to an invalid format
*/
void setElementInvalidFormat() {
fViewerListener.reset();
fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
fVMListener.reset();
fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
HashMap<String, ElementFormatSetting> map = new HashMap<String, ElementFormatSetting>();
String[] format = { "invalid element format" };
makeElementFormatSetting(fViewer, TreePath.EMPTY, format, -1, 0, map);
ArrayList<ElementFormatSetting> elementFormats = new ArrayList<ElementFormatSetting>(map.values());
if (fVMProvider instanceof IElementFormatProvider) {
IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
for (ElementFormatSetting es : elementFormats) {
ep.setActiveFormat(fViewer.getPresentationContext(),
es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
}
}
while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
if (!fDisplay.readAndDispatch ()) {
fDisplay.sleep ();
}
}
}
/**
* helper to set preference to an invalid format and verify.
*/
void setInvalidPreferenceAndVerify() {
fViewerListener.reset();
fViewerListener.addUpdates(TreePath.EMPTY, ((TestElementVMContext)fViewer.getInput()).getElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
fVMListener.reset();
fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, ALL_UPDATES_COMPLETE | PROPERTY_UPDATES);
fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, "invalid format");
while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES)) {
if (!fDisplay.readAndDispatch ()) {
fDisplay.sleep ();
}
}
validateModel(IFormattedValues.HEX_FORMAT, " (" + FormattedValueVMUtil.getFormatLabel(IFormattedValues.HEX_FORMAT) + ")",
DummyFormattedValueService.DUMMY_FORMAT, " (" + DummyFormattedValueService.DUMMY_FORMAT + ")");
}
/**
* Initial format is NATURAL.
*/
@ -287,7 +735,17 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
}
private void setFormatAndValidate(
String formatId,
String formatId,
boolean expectContentCached,
boolean expectFormattedValuesCached,
boolean expectCacheMissError) {
setFormatAndValidate(formatId, null, null, expectContentCached, expectFormattedValuesCached, expectCacheMissError);
}
private void setFormatAndValidate(
String formatId,
ArrayList<ElementFormatSetting> setElementFormats,
ArrayList<ElementFormatSetting> expectElementFormats,
boolean expectContentCached,
boolean expectFormattedValuesCached,
boolean expectCacheMissError)
@ -300,29 +758,39 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
if (!expectContentCached) {
vmUpdateFlags |= ALL_UPDATES_COMPLETE;
}
fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), -1, vmUpdateFlags);
fVMListener.addUpdates(TreePath.EMPTY, fModel.getRootElement(), vmListenerLevel, vmUpdateFlags);
fFormattedValuesListener.reset();
if (expectFormattedValuesCached && !expectCacheMissError) {
fFormattedValuesListener.setCachedFormats(new String[] {formatId} );
}
if (fVMProvider instanceof IElementFormatProvider && setElementFormats != null) {
IElementFormatProvider ep = ((IElementFormatProvider) fVMProvider);
for (ElementFormatSetting es : setElementFormats) {
ep.setActiveFormat(fViewer.getPresentationContext(),
es.nodes.toArray(new IVMNode[es.nodes.size()]), fViewer.getInput(),
es.elementPaths.toArray(new TreePath[es.elementPaths.size()]), es.formatId);
}
} else {
// Set the new number format to the viewer.
fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, formatId);
}
// Set the new number format to the viewer.
fViewer.getPresentationContext().setProperty(PROP_FORMATTED_VALUE_FORMAT_PREFERENCE, formatId);
while (!fViewerListener.isFinished(ALL_UPDATES_COMPLETE | PROPERTY_UPDATES) || !fVMListener.isFinished(CONTENT_UPDATES | PROPERTY_UPDATES))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
if (expectCacheMissError) {
try {
validateModel(formatId, "");
validateModel(expectElementFormats, formatId, "", formatId, "");
throw new RuntimeException("Expected validateModel to fail");
}
catch(AssertionFailedError e) {
// expected
}
} else {
validateModel(formatId, "");
validateModel(expectElementFormats, formatId, "", formatId, "");
}
if (expectCacheMissError) {
@ -332,8 +800,23 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
Assert.assertFalse(fFormattedValuesListener.getPropertiesUpdates().isEmpty());
for (IPropertiesUpdate update : fFormattedValuesListener.getPropertiesUpdates()) {
PropertiesUpdateStatus status = (PropertiesUpdateStatus)update.getStatus();
assertEquals(IDsfStatusConstants.INVALID_STATE, status.getCode());
assertEquals("Cache contains stale data. Refresh view.", status.getStatus(formatProperty).getMessage());
assertEquals(IDsfStatusConstants.INVALID_STATE, status.getCode());
ElementFormatSetting elementFormat = null;
if (expectElementFormats != null) {
TreePath viewerPath = update.getElementPath();
for (ElementFormatSetting es : expectElementFormats) {
if (es.elementPaths.indexOf(viewerPath) >= 0) {
elementFormat = es;
break;
}
}
}
if (elementFormat != null) {
assertEquals("Cache contains stale data. Refresh view.", status.getStatus(
FormattedValueVMUtil.getPropertyForFormatId(elementFormat.formatId)).getMessage());
} else {
assertEquals("Cache contains stale data. Refresh view.", status.getStatus(formatProperty).getMessage());
}
assertEquals(
"Cache contains stale data. Refresh view.",
status.getStatus(PROP_FORMATTED_VALUE_ACTIVE_FORMAT_VALUE).getMessage());
@ -352,18 +835,43 @@ abstract public class FormattedValueTests extends TestCase implements IViewerUpd
}
private void validateModel(final String formatId, final String suffix, final String dummyFormatId, final String dummySuffix) {
validateModel(null, formatId, suffix, dummyFormatId, dummySuffix);
}
private void validateModel(final ArrayList<ElementFormatSetting> elementFormats,
final String formatId, final String suffix, final String dummyFormatId, final String dummySuffix) {
fModel.validateData(
fViewer, TreePath.EMPTY,
new TestElementValidator() {
public void validate(TestElement modelElement, TestElement viewerElement, TreePath viewerPath) {
ViewerLabel label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_ID);
assertEquals(modelElement.getID(), label.getText());
ElementFormatSetting elementFormat = null;
if (elementFormats != null) {
for (ElementFormatSetting es : elementFormats) {
if (es.elementPaths.indexOf(viewerPath) >= 0) {
elementFormat = es;
break;
}
}
}
label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_FORMATTED_VALUE);
assertEquals(fModel.getFormattedValueText(modelElement, formatId) + suffix, label.getText());
if (elementFormat == null || elementFormat.formatId == null) {
assertEquals(fModel.getFormattedValueText(modelElement, formatId) + suffix, label.getText());
} else {
String suffix = elementFormat.formatId.equals(formatId) ? "" :
" (" + FormattedValueVMUtil.getFormatLabel(elementFormat.formatId) + ")";
assertEquals(fModel.getFormattedValueText(modelElement, elementFormat.formatId) + suffix , label.getText());
}
label = fViewer.getElementLabel(viewerPath, TestModelCachingVMProvider.COLUMN_DUMMY_VALUE);
assertEquals(dummyFormatId + dummySuffix, label.getText());
if (elementFormat == null || elementFormat.formatId == null) {
assertEquals(dummyFormatId + dummySuffix, label.getText());
} else {
String suffix = elementFormat.formatId.equals(formatId) ? "" :
" (" + FormattedValueVMUtil.getFormatLabel(elementFormat.formatId) + ")";
assertEquals(elementFormat.formatId + suffix, label.getText());
}
}
});
}

View file

@ -0,0 +1,101 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.HashSet;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.IElementFormatProvider;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.jface.viewers.TreePath;
/**
* Test view model provider that supports element format provider interface.
* This class is used in test cases and can be extended to support other
* optional interfaces
*/
class TestElementFormatVMProvider extends TestModelCachingVMProvider implements IElementFormatProvider {
public int elementFormatApplyDepth = 1;
String myPersistId = "org.eclipse.cdt.tests.dsf.vm.testElementFormatVMProvider";
public TestElementFormatVMProvider(AbstractVMAdapter adapter,
IPresentationContext context, DsfSession session) {
super(adapter, context, session);
}
public void getActiveFormat(IPresentationContext context, IVMNode node,
Object viewerInput, TreePath elementPath, DataRequestMonitor<String> rm) {
Object p = context.getProperty(myPersistId);
if (p instanceof TestPersistable == false) {
rm.setData(null);
rm.done();
return;
}
TestPersistable persistable = (TestPersistable) p;
int end = elementPath.getSegmentCount();
int start = elementPath.getSegmentCount() - 1;
if (elementFormatApplyDepth == -1) {
start = 0;
} else if (elementFormatApplyDepth >= 1) {
start = elementPath.getSegmentCount() - elementFormatApplyDepth;
}
if (start < 0)
start = 0;
for (int i = end; --i >= start;) {
Object x = elementPath.getSegment(i);
if (x instanceof TestElementVMContext) {
String s = ((TestElementVMContext) x).getElement().getID();
String format = persistable.getFormat(s);
if (format != null) {
rm.setData(format);
rm.done();
return;
}
}
}
rm.setData(null);
rm.done();
}
public void setActiveFormat(IPresentationContext context, IVMNode[] node,
Object viewerInput, TreePath[] elementPath, String format) {
Object p = context.getProperty(myPersistId);
TestPersistable persistable = null;
if (p instanceof TestPersistable) {
persistable = (TestPersistable) p;
} else {
persistable = new TestPersistable();
context.setProperty(myPersistId, persistable);
}
HashSet<Object> changed = new HashSet<Object>(elementPath.length);
for (int i = 0; i < elementPath.length; i++) {
Object x = elementPath[i].getLastSegment();
if (x instanceof TestElementVMContext) {
String s = ((TestElementVMContext) x).getElement().getID();
persistable.setFormat(s, format);
changed.add(x);
}
}
if (changed.size() > 0) {
// this.refresh();
handleEvent(new ElementFormatEvent(changed, elementFormatApplyDepth));
}
}
public boolean supportFormat(IVMContext context) {
return true;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 Wind River Systems and others.
* Copyright (c) 2008, 2011 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
@ -7,15 +7,20 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.IDebugVMConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelText;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueRetriever;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
@ -210,6 +215,10 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
return IModelDelta.CONTENT;
}
if ( e instanceof ElementFormatEvent)
{
return IModelDelta.STATE;
}
if (e instanceof TestEvent) {
return ((TestEvent)e).getType();
}
@ -223,6 +232,14 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
parent.setFlags(parent.getFlags() | IModelDelta.CONTENT);
}
if ( e instanceof ElementFormatEvent)
{
Set<Object> elements = ((ElementFormatEvent) e).getElements();
Iterator<Object> it = elements.iterator();
while (it.hasNext()) {
parent.addNode(it.next(), IModelDelta.STATE);
}
}
rm.done();
}
@ -238,6 +255,10 @@ public class TestModelDMVMNode extends AbstractDMVMNode implements IRootVMNode,
{
flags |= IModelDelta.CONTENT;
}
if ( event instanceof ElementFormatEvent)
{
flags |= IModelDelta.CONTENT;
}
// TODO: make more sophisticated to update specific elements.
if (event instanceof TestEvent) {

View file

@ -0,0 +1,83 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistableElement;
/**
* Test persistable for junit test cases. This is used along with element format
* test cases, and can be extended to support other persistable properties
* contained in PresentationContext, e.g. type cast/cast as array.
*/
class TestPersistable implements IPersistableElement, IAdaptable {
HashMap<String, String> map = new HashMap<String, String>();
public void saveState(IMemento memento) {
HashMap<String, String> clone = null;
synchronized (map) {
clone = new HashMap<String, String>(map);
}
Iterator<Entry<String, String>> it = clone.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = it.next();
IMemento value = memento.createChild("variable", entry.getKey());
value.putString("format", entry.getValue());
}
}
void restore(IMemento memento) {
IMemento[] list = memento.getChildren("variable");
HashMap<String, String> clone = new HashMap<String, String>();
for (int i = 0; i < list.length; i++) {
clone.put(list[i].getID(), list[i].getString("format"));
}
synchronized (map) {
map.clear();
map.putAll(clone);
}
}
String getFormat(String key) {
if (key == null)
return null;
synchronized (map) {
return map.get(key);
}
}
void setFormat(String key, String format) {
synchronized (map) {
if (format == null) {
map.remove(key);
} else {
map.put(key, format);
}
}
}
public String getFactoryId() {
return TestPersistableFactory.factoryId;
}
public Object getAdapter(Class adapter) {
if (adapter.isInstance(this)) {
return this;
}
return null;
}
}

View file

@ -0,0 +1,30 @@
/*****************************************************************
* Copyright (c) 2011 Texas Instruments and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556)
*****************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
/**
* Factory for TestPersitable
*/
public class TestPersistableFactory implements IElementFactory {
static String factoryId = "org.eclipse.cdt.tests.dsf.vm.testPersistableFactory";
public IAdaptable createElement(IMemento memento) {
TestPersistable x = new TestPersistable();
x.restore(memento);
return x;
}
}