diff --git a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF index 65aff97d985..39a907f9f87 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-SymbolicName: org.eclipse.cdt.dsf.ui;singleton:=true -Bundle-Version: 2.4.100.qualifier +Bundle-Version: 2.5.0.qualifier Bundle-Activator: org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin Bundle-Localization: plugin Require-Bundle: org.eclipse.ui;bundle-version="3.5.0", diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml index c7565f7e41a..e8b4e79abf5 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml @@ -890,4 +890,11 @@ targetId="org.eclipse.cdt.ui.cCode"> + + + + diff --git a/dsf/org.eclipse.cdt.dsf.ui/pom.xml b/dsf/org.eclipse.cdt.dsf.ui/pom.xml index 448e33611fd..0a24192276b 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/pom.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 2.4.100-SNAPSHOT + 2.5.0-SNAPSHOT org.eclipse.cdt.dsf.ui eclipse-plugin diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistable.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistable.java new file mode 100644 index 00000000000..534c50a27b4 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistable.java @@ -0,0 +1,148 @@ +/***************************************************************** + * Copyright (c) 2011, 2014 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 java.util.TreeMap; + +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; + +/** + * Generic persistable for storing a map of simple values. + *
+ * Currently supported value types are {@link Integer} and {@link String}. + * + * @since 2.5 + */ +public class SimpleMapPersistable implements IPersistableElement, IAdaptable { + + private static final String KEY_TYPE = "type"; //$NON-NLS-1$ + private static final String KEY_NAME = "name"; //$NON-NLS-1$ + private static final String KEY_VALUE = "value"; //$NON-NLS-1$ + + private Class fType; + private Map fValues = new TreeMap(); + + @SuppressWarnings("unchecked") + public SimpleMapPersistable(IMemento memento) throws CoreException { + IMemento type = memento.getChild(KEY_TYPE); + if (type == null) { + throw new CoreException(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, + "Missing key for type.", null)); //$NON-NLS-1$ + } + + try { + fType = (Class)Class.forName(type.getTextData()); + } catch (ClassNotFoundException e) { + throw new CoreException(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, + e.getMessage(), e)); + } + + IMemento[] list = memento.getChildren(KEY_NAME); + Map values = new TreeMap(); + for (IMemento elem : list) { + values.put(elem.getID(), getValue(elem)); + } + + synchronized(fValues) { + // We should not assign 'values' directly to 'fValues' + // if we want synchronization to work. Instead, we must use + // the same map as before for 'fValues' + fValues.clear(); + fValues.putAll(values); + } + } + + public SimpleMapPersistable(Class type) { + fType = type; + } + + @Override + public void saveState(IMemento memento) { + Map values = null; + synchronized (fValues) { + values = new TreeMap(fValues); + } + + IMemento type = memento.createChild(KEY_TYPE); + synchronized (fType) { + type.putTextData(fType.getName()); + } + for (Map.Entry entry : values.entrySet()) { + IMemento value = memento.createChild(KEY_NAME, entry.getKey()); + putValue(value, entry.getValue()); + } + } + + private void putValue(IMemento memento, Object value) { + if (value instanceof String) { + memento.putString(KEY_VALUE, (String)value); + } else if (value instanceof Integer) { + memento.putInteger(KEY_VALUE, (Integer)value); + } + else { + assert false; + } + } + + @SuppressWarnings("unchecked") + private V getValue(IMemento memento) { + synchronized (fType) { + if (String.class.equals(fType)) { + return (V)memento.getString(KEY_VALUE); + } else if (Integer.class.equals(fType)) { + return (V)memento.getInteger(KEY_VALUE); + } else { + assert false; + } + } + return null; + } + + + public V getValue(String key) { + if (key == null) + return null; + synchronized (fValues) { + return fValues.get(key); + } + } + + public void setValue(String key, V value) { + synchronized (fValues) { + if (value == null) { + fValues.remove(key); + } else { + fValues.put(key, value); + } + } + } + + @Override + public String getFactoryId() { + return SimpleMapPersistableFactory.getFactoryId(); + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + if (adapter.isInstance(this)) { + return this; + } + return null; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistableFactory.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistableFactory.java new file mode 100644 index 00000000000..fd087562810 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/SimpleMapPersistableFactory.java @@ -0,0 +1,46 @@ +/***************************************************************** + * Copyright (c) 2011, 2014 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 org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; + +/** + * Persistable factory the simple map persistable. + * + * @since 2.5 + * + * @see SimpleMapPersistable + */ +public class SimpleMapPersistableFactory implements IElementFactory { + + public static String getFactoryId() { + // Must be the same id as the one used in the plugin.xml file + return "org.eclipse.cdt.dsf.ui.simpleMapPersistableFactory"; //$NON-NLS-1$ + } + + @Override + public IAdaptable createElement(IMemento memento) { + try { + SimpleMapPersistable x = new SimpleMapPersistable<>(memento); + return x; + } catch (CoreException e) { + DsfUIPlugin.log(new Status( + IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Cannot restore persistable." , e)); //$NON-NLS-1$ + } + return null; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/actions/VMHandlerUtils.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/actions/VMHandlerUtils.java index 92dabb8e7f6..9da8fb7fd09 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/actions/VMHandlerUtils.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/actions/VMHandlerUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Wind River Systems and others. + * Copyright (c) 2008, 2014 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 @@ -13,16 +13,20 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.actions; import org.eclipse.cdt.dsf.ui.viewmodel.IVMAdapter; 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.core.commands.ExecutionEvent; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; +import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugView; import org.eclipse.debug.ui.contexts.IDebugContextService; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.IPartService; import org.eclipse.ui.ISelectionService; @@ -151,5 +155,35 @@ public class VMHandlerUtils { } return null; } + + /** + * Returns the viewer input element for the viewer in the given + * presentation context. The input element is retrieved only if the + * presentation context's view is based on the {@link AbstractDebugView}. + * Returns null if not found. + * @since 2.5 + */ + public static Object getViewerInput(IPresentationContext context) { + if (context.getPart() instanceof AbstractDebugView) { + Viewer viewer = ((AbstractDebugView)context.getPart()).getViewer(); + if (viewer != null) { + return viewer.getInput(); + } + } + return null; + } + /** + * Returns the {@link IVMNode} associated with the element in the + * given path. Returns null if not found. + * + * @since 2.5 + */ + public static IVMNode getVMNode(Object viewerInput, TreePath path) { + if (path.getSegmentCount() != 0) { + return (IVMNode) DebugPlugin.getAdapter(path.getLastSegment(), IVMNode.class); + } else { + return (IVMNode) DebugPlugin.getAdapter(viewerInput, IVMNode.class); + } + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 33ee22a6df5..b123c328a39 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2014 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 @@ -20,12 +20,13 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport; import org.eclipse.cdt.dsf.debug.service.ICachingService; import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.cdt.dsf.debug.service.IExpressions2; import org.eclipse.cdt.dsf.debug.service.IRegisters; -import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; 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.AbstractElementVMProvider; 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; @@ -41,7 +42,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy; import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; 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.datamodel.RootDMVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; @@ -70,7 +70,7 @@ import org.eclipse.jface.viewers.TreePath; * should implement {@link IExpressionVMNode}. */ @SuppressWarnings("restriction") -public class ExpressionVMProvider extends AbstractDMVMProvider +public class ExpressionVMProvider extends AbstractElementVMProvider implements IExpressionsListener2 { private IExpressionVMNode[] fExpressionNodes; diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/AbstractElementVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/AbstractElementVMProvider.java new file mode 100644 index 00000000000..35ca6582e54 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/AbstractElementVMProvider.java @@ -0,0 +1,63 @@ +/***************************************************************** + * Copyright (c) 2014 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +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.IVMProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.TreePath; + +/** + * Base class for view model providers that can support individual element formatting. + * Extending classes can override {@link #supportFormat(IVMContext)} to return false + * if they do not want to support individual element formatting. + */ +abstract public class AbstractElementVMProvider extends AbstractDMVMProvider implements IElementFormatProvider +{ + private final IElementFormatProvider fElementFormatProvider; + + public AbstractElementVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + fElementFormatProvider = createElementNumberFormatProvider(this, getSession()); + } + + @Override + public void dispose() { + if (fElementFormatProvider instanceof ElementNumberFormatProvider) { + ((ElementNumberFormatProvider)fElementFormatProvider).dispose(); + } + super.dispose(); + } + protected IElementFormatProvider createElementNumberFormatProvider(IVMProvider provider, DsfSession session) { + return new ElementNumberFormatProvider(provider, session); + } + + @Override + public boolean supportFormat(IVMContext context) { + return fElementFormatProvider.supportFormat(context); + } + + @Override + public void getActiveFormat(IPresentationContext context, IVMNode node, Object viewerInput, TreePath elementPath, + DataRequestMonitor rm) { + fElementFormatProvider.getActiveFormat(context, node, viewerInput, elementPath, rm); + } + + @Override + public void setActiveFormat(IPresentationContext context, IVMNode[] node, Object viewerInput, TreePath[] elementPaths, String format) { + fElementFormatProvider.setActiveFormat(context, node, viewerInput, elementPaths, format); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatProvider.java new file mode 100644 index 00000000000..dddc875e54f --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatProvider.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 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.util.Dictionary; +import java.util.HashSet; +import java.util.Hashtable; +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.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.concurrent.ImmediateCountingRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionGroupDMContext; +import org.eclipse.cdt.dsf.debug.service.IRegisters; +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.SimpleMapPersistable; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent; +import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider; +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.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.ui.IWorkbenchPart; +import org.osgi.framework.Filter; +import org.osgi.framework.InvalidSyntaxException; + +/** + * Default implementation of the {@link IElementFormatProvider}. It can be + * used within any {@link IVMProvider} to store and persist number-formats + * selected by user for different elements. + * + * @since 2.5 + */ +public class ElementNumberFormatProvider implements IElementFormatProvider +{ + private static final String ELEMENT_FORMAT_PERSISTABLE_PROPERTY = "org.eclipse.cdt.dsf.ui.elementFormatPersistable"; //$NON-NLS-1$ + private static final String FILTER_PROVIDER_ID = ElementNumberFormatProvider.class.getName() + ".eventFilter"; //$NON-NLS-1$ + + private final IVMProvider fVMProvider; + private final DsfSession fSession; + private final Dictionary fFilterProperties = new Hashtable<>(); + + public ElementNumberFormatProvider(IVMProvider vmProvider, DsfSession session) { + fVMProvider = vmProvider; + fSession = session; + initialize(); + } + + protected void initialize() { + IPresentationContext presentationCtx = getVMProvider().getPresentationContext(); + + IWorkbenchPart part = presentationCtx.getPart(); + String provider; + if (part != null) { + // Use an id that is unique to the instance of the view + // Note that although each view, including cloned ones, has its own presentation context, + // the presentation context id returned by getPresentationContext().getId() is the + // same for cloned views even though the presentation context itself is different. + // To get a unique id for each cloned view we can use the title of the view. + provider = part.getTitle(); + } else { + // In some cases, we are not dealing with a part, e.g., the hover. + // In this case, use the presentation context id directly. + // Note that the hover will probably not provide per-element formating, + // but some extenders may choose to do so. + provider = getVMProvider().getPresentationContext().getId(); + } + + // Create the filter properties targeted at our provider, to be used when sending events + fFilterProperties.put(FILTER_PROVIDER_ID, provider); + + // Properly formatted OSGI filter string aimed at our provider + String filterStr = "(&(" + FILTER_PROVIDER_ID + "=" + provider + "))"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + try { + final Filter filter = DsfUIPlugin.getBundleContext().createFilter(filterStr); + fSession.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + // Only listen to events that are aimed at our provider by using a filter. + // That avoids updating ourselves for an event that was triggered by another view. + fSession.addServiceEventListener(ElementNumberFormatProvider.this, filter); + } + }); + } catch (InvalidSyntaxException e) { + assert false : e.getMessage(); + } catch (RejectedExecutionException e) { + } + } + + public void dispose() { + try { + fSession.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + fSession.removeServiceEventListener(ElementNumberFormatProvider.this); + } + }); + } catch (RejectedExecutionException e) { + } + } + + @DsfServiceEventHandler + public final void eventDispatched(ElementFormatEvent event) { + if (getVMProvider() instanceof AbstractVMProvider) { + ((AbstractVMProvider)getVMProvider()).handleEvent(event); + } + } + + private IVMProvider getVMProvider() { + return fVMProvider; + } + + @Override + public void getActiveFormat(IPresentationContext context, IVMNode node, Object viewerInput, final TreePath elementPath, + final DataRequestMonitor rm) + { + getElementKey( + viewerInput, elementPath, + new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleSuccess() { + SimpleMapPersistable persistable = getPersistable(); + rm.done(persistable.getValue(getData())); + } + }); + } + + @Override + public void setActiveFormat(IPresentationContext context, IVMNode[] node, Object viewerInput, + TreePath[] elementPaths, final String format) + { + final HashSet elementsToRefresh = new HashSet<>(); + final CountingRequestMonitor crm = new ImmediateCountingRequestMonitor() { + @Override + protected void handleCompleted() { + if (elementsToRefresh.size() > 0) { + // Send the event to all DSF sessions as they share the same view and the + // change of format will affect them as well. This is because they key + // we use from this implementation of getElementKey() is not specific to + // a session (and should not be if we want to have proper persistence). + for (DsfSession session : DsfSession.getActiveSessions()) { + // Use the filterProperties to specify that this event only impacts the current view. + session.dispatchEvent(new ElementFormatEvent(elementsToRefresh, 1), fFilterProperties); + } + } + } + }; + for (final TreePath path : elementPaths) { + getElementKey( + viewerInput, path, + new ImmediateDataRequestMonitor(crm) { + @Override + protected void handleSuccess() { + SimpleMapPersistable persistable = getPersistable(); + persistable.setValue(getData(), format); + elementsToRefresh.add(path.getLastSegment()); + crm.done(); + } + }); + } + crm.setDoneCount(elementPaths.length); + } + + @Override + public boolean supportFormat(IVMContext context) { + if (context instanceof IDMVMContext) { + // The expressions view supports expression groups, which have no value, + // so we should not support formatting for expression groups. + if (((IDMVMContext)context).getDMContext() instanceof IExpressionGroupDMContext) { + return false; + } + } + return context instanceof IFormattedValueVMContext; + } + + // We do not make the element key session-specific or else when we start a new session for the same + // program, the format we chose will not be persisted. Instead, make the format change valid for + // any session, even if other sessions run a different program. The idea is that a user usually + // names her variables similarly so the chosen format should apply properly anyway. + protected void getElementKey(Object viewerInput, TreePath elementPath, final DataRequestMonitor rm) { + Object element = elementPath.getLastSegment(); + if (element instanceof IDMVMContext) { + final IDMContext dmc = ((IDMVMContext)element).getDMContext(); + if (dmc instanceof IExpressionDMContext) { + rm.done(((IExpressionDMContext)dmc).getExpression()); + return; + } else if (dmc instanceof IRegisterDMContext) { + fSession.getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), fSession.getId()); + IRegisters regService = tracker.getService(IRegisters.class); + tracker.dispose(); + + regService.getRegisterData((IRegisterDMContext)dmc, new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleSuccess() { + rm.done(getData().getName()); + } + }); + } + }); + return; + } + } + rm.done(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE, "Cannot calculate peristable key for element: " + element, null)); //$NON-NLS-1$ + } + + @SuppressWarnings("unchecked") + protected SimpleMapPersistable getPersistable() { + Object p = getVMProvider().getPresentationContext().getProperty(ELEMENT_FORMAT_PERSISTABLE_PROPERTY); + if (p instanceof SimpleMapPersistable) { + return (SimpleMapPersistable)p; + } else { + SimpleMapPersistable persistable = new SimpleMapPersistable<>(String.class); + getVMProvider().getPresentationContext().setProperty(ELEMENT_FORMAT_PERSISTABLE_PROPERTY, persistable); + return persistable; + } + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatsContribution.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatsContribution.java index 5c301c673d3..67df4919999 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatsContribution.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/numberformat/ElementNumberFormatsContribution.java @@ -7,22 +7,26 @@ * * Contributors: * Winnie Lai (Texas Instruments) - Individual Element Number Format (Bug 202556) + * Marc Khouzam (Ericsson) - Base available formats on each element (Bug 439624) *****************************************************************/ package org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat; import java.util.ArrayList; +import java.util.Arrays; 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.IDebugVMConstants; 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.cdt.dsf.ui.viewmodel.update.ICacheEntry; +import org.eclipse.cdt.dsf.ui.viewmodel.update.ICachingVMProviderExtension2; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.ContributionItem; @@ -30,7 +34,6 @@ import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; @@ -99,40 +102,37 @@ public class ElementNumberFormatsContribution extends NumberFormatsContribution if (selection == null || selection.isEmpty() || selection instanceof ITreeSelection == false) { return NO_ITEMS; } + IVMProvider provider = VMHandlerUtils.getVMProviderForSelection(selection); - if (FORMATS.size() == 0) { + if (provider instanceof IElementFormatProvider == false) { return NO_ITEMS; } - IPresentationContext context = provider.getPresentationContext(); + + IPresentationContext context = provider.getPresentationContext(); + Object viewerInput = VMHandlerUtils.getViewerInput(context); TreePath[] elementPaths = ((ITreeSelection) selection).getPaths(); - IVMNode[] nodes = new IVMNode[elementPaths.length]; - final String[] formats = new String[elementPaths.length]; - Object viewerInput = null; - if (context.getPart() instanceof AbstractDebugView) { - Viewer viewer = ((AbstractDebugView)context.getPart()).getViewer(); - if (viewer != null) { - viewerInput = viewer.getInput(); - } + List availableFormats = getAvailableFormats(provider, viewerInput, elementPaths); + if (availableFormats.size() == 0) { + return NO_ITEMS; } - // Here we keep using hard-coded formats, which are common formats. - // We expect clients may add extra formats before and after these formats. - // For details, please refer to 371012. - // For now, we do not use vm provider's cache entry to get available formats - // because it shows something extra than what we have been expecting. See 371012 comment #2. - final List actions = new ArrayList(FORMATS.size()); - for (String formatId : FORMATS) { + + IVMNode[] nodes = new IVMNode[elementPaths.length]; + final List actions = new ArrayList(availableFormats.size()); + for (String formatId : availableFormats) { actions.add(new SelectFormatAction((IElementFormatProvider) provider, context, nodes, viewerInput, elementPaths, formatId)); } + + final String[] elementActiveFormats = new String[elementPaths.length]; CountingRequestMonitor crm = new CountingRequestMonitor(SimpleDisplayExecutor.getSimpleDisplayExecutor(Display.getDefault()), null) { @Override protected void handleCompleted() { String activeFormat = null; - for (int i = 0; i < formats.length; i++) { + for (int i = 0; i < elementActiveFormats.length; i++) { if (i == 0) { - activeFormat = formats[i]; + activeFormat = elementActiveFormats[i]; } else if (activeFormat != null - && activeFormat.equals(formats[i]) == false) { + && activeFormat.equals(elementActiveFormats[i]) == false) { activeFormat = null; break; } @@ -159,7 +159,7 @@ public class ElementNumberFormatsContribution extends NumberFormatsContribution new DataRequestMonitor(ImmediateExecutor.getInstance(), crm) { @Override protected void handleSuccess() { - formats[index] = this.getData(); + elementActiveFormats[index] = this.getData(); super.handleSuccess(); } }); @@ -167,9 +167,48 @@ public class ElementNumberFormatsContribution extends NumberFormatsContribution crm.setDoneCount(elementPaths.length); int count = actions.size(); IContributionItem[] items = new IContributionItem[count]; - for (int i = 0; i < actions.size(); i++) { + for (int i = 0; i < items.length; i++) { items[i] = new ActionContributionItem(actions.get(i)); } return items; } -} + + /** + * Get the available formats for all elements in the selection. If all elements have the same + * available formats, return that list; if not, return the default list. + */ + private List getAvailableFormats(IVMProvider provider, Object viewerInput, TreePath[] paths) { + if (provider instanceof ICachingVMProviderExtension2) { + ICachingVMProviderExtension2 cachingProvider = (ICachingVMProviderExtension2)provider; + + String[] formats = null; + for (TreePath path : paths) { + IVMNode node = VMHandlerUtils.getVMNode(viewerInput, path); + if (node != null) { + ICacheEntry cacheEntry = cachingProvider.getCacheEntry(node, viewerInput, path); + if (cacheEntry != null && cacheEntry.getProperties() != null) { + String[] entryFormats = (String[]) cacheEntry.getProperties().get(IDebugVMConstants.PROP_FORMATTED_VALUE_AVAILABLE_FORMATS); + if (entryFormats == null) { + // At least one element has no formats. Use the default ones. + return FORMATS; + } + if (formats == null) { + // First set of formats + formats = entryFormats; + } else { + // Found another set of formats. Make sure it is the same as the set we already have. + // If not, return the default set of formats. + if (!Arrays.equals(formats, entryFormats)) { + return FORMATS; + } + } + } + } + } + if (formats != null) { + return Arrays.asList(formats); + } + } + return FORMATS; + } +} \ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java index 5977fe26f4e..ba410a929b9 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterBitFieldVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2014 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,10 +7,12 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Marc Khouzam (Ericsson) - Enable per-element formatting (Bug 439624) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.ui.viewmodel.register; import java.util.Map; +import java.util.Set; import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; @@ -41,6 +43,7 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelTe import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueRetriever; 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.debug.ui.viewmodel.update.ElementFormatEvent; import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableLabelFont; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.service.DsfSession; @@ -967,6 +970,13 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode return IModelDelta.CONTENT; } + if (event instanceof ElementFormatEvent) { + int depth = ((ElementFormatEvent)event).getApplyDepth(); + if (depth == 0) return IModelDelta.NO_CHANGE; + if (depth == 1) return IModelDelta.STATE; + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; } @@ -1001,7 +1011,20 @@ public class RegisterBitFieldVMNode extends AbstractExpressionVMNode { parentDelta.addNode(element, IModelDelta.STATE); } + else if (event instanceof ElementFormatEvent) + { + int depth = ((ElementFormatEvent)event).getApplyDepth(); + if (depth != 0) { + int deltaType = IModelDelta.CONTENT; + if (depth == 1) deltaType = IModelDelta.STATE; + Set elements = ((ElementFormatEvent)event).getElements(); + for (Object elem : elements) { + parentDelta.addNode(elem, deltaType); + } + } + } + rm.done(); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMNode.java index 1a4e393859c..217da6925b5 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2014 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 @@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.register; import java.util.Map; +import java.util.Set; import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor; @@ -39,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNod 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.numberformat.IFormattedValueVMContext; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.ElementFormatEvent; import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableLabelFont; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.service.DsfSession; @@ -688,6 +690,13 @@ public class RegisterVMNode extends AbstractExpressionVMNode return IModelDelta.STATE; } + if (e instanceof ElementFormatEvent) { + int depth = ((ElementFormatEvent)e).getApplyDepth(); + if (depth == 0) return IModelDelta.NO_CHANGE; + if (depth == 1) return IModelDelta.STATE; + return IModelDelta.CONTENT; + } + return IModelDelta.NO_CHANGE; } @@ -714,7 +723,20 @@ public class RegisterVMNode extends AbstractExpressionVMNode if (e instanceof IRegisterChangedDMEvent) { parentDelta.addNode( createVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } - + else if ( e instanceof ElementFormatEvent ) + { + int depth = ((ElementFormatEvent)e).getApplyDepth(); + if (depth != 0) { + int deltaType = IModelDelta.CONTENT; + if (depth == 1) deltaType = IModelDelta.STATE; + + Set elements = ((ElementFormatEvent)e).getElements(); + for (Object elem : elements) { + parentDelta.addNode(elem, deltaType); + } + } + } + rm.done(); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java index 9182d3ae22e..0a46c53358f 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/register/RegisterVMProvider.java @@ -26,6 +26,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; 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.AbstractElementVMProvider; import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.DebugManualUpdatePolicy; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; @@ -35,7 +36,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; -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.update.AutomaticUpdatePolicy; import org.eclipse.cdt.dsf.ui.viewmodel.update.IVMUpdatePolicy; @@ -49,7 +49,7 @@ import org.eclipse.jface.util.PropertyChangeEvent; /** * Provides the VIEW MODEL for the DEBUG MODEL REGISTER view. */ -public class RegisterVMProvider extends AbstractDMVMProvider +public class RegisterVMProvider extends AbstractElementVMProvider { private IPropertyChangeListener fPreferencesListener = new IPropertyChangeListener() { @Override diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 6f2c9a0944d..b7d45961f8e 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2013 Wind River Systems and others. + * Copyright (c) 2006, 2014 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 @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.debug.core.model.ICastToArray; @@ -59,6 +60,7 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueLabelTe import org.eclipse.cdt.dsf.debug.ui.viewmodel.numberformat.FormattedValueRetriever; 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.update.ElementFormatEvent; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor; @@ -1257,7 +1259,15 @@ public class VariableVMNode extends AbstractExpressionVMNode ((PropertyChangeEvent)e).getProperty() == IDebugModelPresentation.DISPLAY_VARIABLE_TYPE_NAMES)) ) { return IModelDelta.CONTENT; - } + } + + if ( e instanceof ElementFormatEvent ) + { + int depth = ((ElementFormatEvent)e).getApplyDepth(); + if (depth == 0) return IModelDelta.NO_CHANGE; + if (depth == 1) return IModelDelta.STATE; + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } @@ -1275,7 +1285,20 @@ public class VariableVMNode extends AbstractExpressionVMNode ((PropertyChangeEvent)e).getProperty() == IDebugModelPresentation.DISPLAY_VARIABLE_TYPE_NAMES)) ) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); - } + } + else if ( e instanceof ElementFormatEvent ) + { + int depth = ((ElementFormatEvent)e).getApplyDepth(); + if (depth != 0) { + int deltaType = IModelDelta.CONTENT; + if (depth == 1) deltaType = IModelDelta.STATE; + + Set elements = ((ElementFormatEvent)e).getElements(); + for (Object elem : elements) { + parentDelta.addNode(elem, deltaType); + } + } + } requestMonitor.done(); } @@ -1295,6 +1318,14 @@ public class VariableVMNode extends AbstractExpressionVMNode { return IModelDelta.CONTENT; } + + if (event instanceof ElementFormatEvent) + { + int depth = ((ElementFormatEvent)event).getApplyDepth(); + if (depth == 0) return IModelDelta.NO_CHANGE; + if (depth == 1) return IModelDelta.STATE; + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } @@ -1312,6 +1343,19 @@ public class VariableVMNode extends AbstractExpressionVMNode ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.PROP_FORMATTED_VALUE_FORMAT_PREFERENCE) ) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); } + else if (event instanceof ElementFormatEvent ) + { + int depth = ((ElementFormatEvent)event).getApplyDepth(); + if (depth != 0) { + int deltaType = IModelDelta.CONTENT; + if (depth == 1) deltaType = IModelDelta.STATE; + + Set elements = ((ElementFormatEvent)event).getElements(); + for (Object elem : elements) { + parentDelta.addNode(elem, deltaType); + } + } + } rm.done(); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java index b8fac695f57..a4b1c103083 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems and others. + * Copyright (c) 2007, 2014 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 @@ -20,6 +20,7 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions2; 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.AbstractElementVMProvider; import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy; import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.DebugManualUpdatePolicy; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; @@ -28,7 +29,6 @@ import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; import org.eclipse.cdt.dsf.ui.viewmodel.update.IVMUpdatePolicy; @@ -39,7 +39,7 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; -public class VariableVMProvider extends AbstractDMVMProvider +public class VariableVMProvider extends AbstractElementVMProvider implements IColumnPresentationFactory { private IPropertyChangeListener fPreferencesListener = new IPropertyChangeListener() { diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/plugin.xml b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/plugin.xml index 08095386ad3..5d2b5ff5cff 100644 --- a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/plugin.xml @@ -104,13 +104,6 @@ - - - - rm) { Object p = context.getProperty(myPersistId); - if (p instanceof VariablePersistable == false) { + if (p instanceof SimpleMapPersistable == false) { rm.setData(null); rm.done(); return; } - VariablePersistable persistable = (VariablePersistable) p; + SimpleMapPersistable persistable = (SimpleMapPersistable) 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.setData(persistable.getValue(ctx.getExpression())); } rm.done(); return; @@ -66,7 +68,7 @@ public class PDAExpressionVMProvider extends ExpressionVMProvider implements IEl if (y == null) { rm.setData(null); } else { - rm.setData(persistable.getFormat(y.getExpressionText())); + rm.setData(persistable.getValue(y.getExpressionText())); } rm.done(); return; @@ -76,13 +78,14 @@ public class PDAExpressionVMProvider extends ExpressionVMProvider implements IEl return; } + @SuppressWarnings("unchecked") 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; + SimpleMapPersistable persistable = null; + if (p instanceof SimpleMapPersistable) { + persistable = (SimpleMapPersistable) p; } else { - persistable = new VariablePersistable(); + persistable = new SimpleMapPersistable(String.class); context.setProperty(myPersistId, persistable); } ArrayList changed = new ArrayList(elementPath.length); @@ -92,13 +95,13 @@ public class PDAExpressionVMProvider extends ExpressionVMProvider implements IEl IExpressionDMContext ctx = DMContexts.getAncestorOfType(((VariableVMNode.VariableExpressionVMC) x).getDMContext(), IExpressionDMContext.class); if (ctx == null) continue; - persistable.setFormat(ctx.getExpression(), format); + persistable.setValue(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); + persistable.setValue(y.getExpressionText(), format); } } if (changed.size() > 0) { diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java deleted file mode 100644 index e723b106548..00000000000 --- a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistable.java +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************** - * 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 map = new HashMap(); - - public void saveState(IMemento memento) { - HashMap clone = null; - synchronized (map) { - clone = new HashMap(map); - } - Iterator > it = clone.entrySet().iterator(); - while (it.hasNext()) { - Entry 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 clone = new HashMap(); - 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; - } -} diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java deleted file mode 100644 index 914fd8c6056..00000000000 --- a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/viewmodel/VariablePersistableFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************** - * 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; - } - -} diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java b/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java index 04b03b75a7e..8499b274aa1 100644 --- a/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java +++ b/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Wind River Systems and others. + * Copyright (c) 2008, 2014 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 @@ -43,7 +43,9 @@ import org.osgi.framework.BundleContext; * */ public class PDAExpressions extends AbstractDsfService implements ICachingService, IExpressions { - + + private static final String FORMAT_MY_FORMAT = "My format"; + @Immutable private static class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext { @@ -107,10 +109,6 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic return null; } - public String getStringValue() { - return null; - } - public String getTypeId() { return null; } @@ -338,7 +336,7 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic protected void handleSuccess() { try { Integer.parseInt(getData().getFormattedValue()); - rm.setData(new String[] { DECIMAL_FORMAT, HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT }); + rm.setData(new String[] { DECIMAL_FORMAT, HEX_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, FORMAT_MY_FORMAT }); rm.done(); } catch (NumberFormatException e) { rm.setData(new String[] { STRING_FORMAT }); @@ -388,7 +386,6 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic rm.setData(new FormattedValueDMData(getData().fResponseText)); rm.done(); } else { - int result; try { int intResult = Integer.parseInt(getData().fResponseText); String formattedResult = ""; @@ -418,8 +415,10 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic formattedResult = prefix.toString(); } else if (DECIMAL_FORMAT.equals(formatId)) { formattedResult = Integer.toString(intResult); + } else if (FORMAT_MY_FORMAT.equals(formatId)) { + formattedResult = "This value is in my format"; } else { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid format"); + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid format " + formatId); } rm.setData(new FormattedValueDMData(formattedResult)); rm.done(); @@ -453,7 +452,6 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic { String value = null; try { - int intValue = 0; if (HEX_FORMAT.equals(formatId)) { if (formattedExprValue.startsWith("0x")) formattedExprValue = formattedExprValue.substring(2); value = Integer.toString( Integer.parseInt(formattedExprValue, 16) );