diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF index 63fc553607d..015e3211a95 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.debug.ui/META-INF/MANIFEST.MF @@ -20,6 +20,7 @@ Export-Package: org.eclipse.dd.dsf.debug.ui, org.eclipse.dd.dsf.debug.ui.viewmodel, org.eclipse.dd.dsf.debug.ui.viewmodel.expression, + org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport, org.eclipse.dd.dsf.debug.ui.viewmodel.launch, org.eclipse.dd.dsf.debug.ui.viewmodel.register, org.eclipse.dd.dsf.debug.ui.viewmodel.variable diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java index 2348cc3c41a..9b82c745d9b 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java @@ -10,7 +10,9 @@ *******************************************************************************/ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterGroupLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterLayoutNode; import org.eclipse.dd.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; @@ -31,8 +33,10 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont */ @SuppressWarnings("restriction") public class ExpressionVMProvider extends AbstractDMVMProvider - implements IExpressionsListener + implements IExpressionsListener, IFormattedValuePreferenceStore { + private String fDefaultFormatId = IFormattedValues.HEX_FORMAT; + public static class ExpressionsChangedEvent { enum Type {ADDED, CHANGED, REMOVED} public final Type fType; @@ -62,7 +66,7 @@ public class ExpressionVMProvider extends AbstractDMVMProvider debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] {expressionManagerNode}); IExpressionLayoutNode registerGroupNode = new RegisterGroupLayoutNode(this, getSession(), syncDataAccess); expressionManagerNode.setExpressionLayoutNodes(new IExpressionLayoutNode[] { registerGroupNode }); - IVMLayoutNode registerNode = new RegisterLayoutNode(this, getSession(), syncDataAccess); + IVMLayoutNode registerNode = new RegisterLayoutNode(this, this, getSession(), syncDataAccess); registerGroupNode.setChildNodes(new IVMLayoutNode[] { registerNode }); setRootLayoutNode(debugViewSelectionNode); } @@ -120,4 +124,12 @@ public class ExpressionVMProvider extends AbstractDMVMProvider public void expressionsRemoved(IExpression[] expressions) { handleEvent(new ExpressionsChangedEvent(ExpressionsChangedEvent.Type.REMOVED, expressions)); } + + public String getDefaultFormatId() { + return fDefaultFormatId; + } + + public void setDefaultFormatId(String id) { + fDefaultFormatId = id; + } } diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java similarity index 91% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java index 99e1343e771..f7b14c4b33f 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValuePreferenceStore.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValuePreferenceStore.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; /** * diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java index 3b38afb2f54..fb74d6aeeaa 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/IFormattedValueVMContext.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/IFormattedValueVMContext.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java new file mode 100644 index 00000000000..f945ab4a8e0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatBinary.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatBinary implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.BINARY_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java similarity index 83% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java index 984abaf9c09..edfb9d85be9 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatHex.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatHex.java @@ -8,14 +8,9 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.debug.service.IFormattedValues; -import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.ui.AbstractDebugView; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java similarity index 92% rename from plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java rename to plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java index 6ba564344e6..52498992215 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/SetDefaultFormatDecimal.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatNatural.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.dd.dsf.debug.ui.viewmodel; +package org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport; import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.jface.action.IAction; @@ -20,7 +20,7 @@ import org.eclipse.ui.IViewPart; /** * */ -public class SetDefaultFormatDecimal implements IViewActionDelegate { +public class SetDefaultFormatNatural implements IViewActionDelegate { private IFormattedValueVMContext fFormattedValueVMC; diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java new file mode 100644 index 00000000000..67641c4d511 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/formatsupport/SetDefaultFormatOctal.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.formatsupport; + +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; + +/** + * + */ +public class SetDefaultFormatOctal implements IViewActionDelegate { + + private IFormattedValueVMContext fFormattedValueVMC; + + public void init(IViewPart view) { + } + + public void run(IAction action) { + if (fFormattedValueVMC != null) { + fFormattedValueVMC.getPreferenceStore().setDefaultFormatId(IFormattedValues.OCTAL_FORMAT); + } + } + + public void selectionChanged(IAction action, ISelection selection) { + fFormattedValueVMC = null; + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + if (element instanceof IFormattedValueVMContext) { + fFormattedValueVMC = ((IFormattedValueVMContext)element); + } + } + action.setEnabled(fFormattedValueVMC != null); + } + +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java new file mode 100644 index 00000000000..5bb899dfda6 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutCellModifier.java @@ -0,0 +1,153 @@ +/* + * BitFieldLayoutCellModifier.java + * Created on Apr 3, 2007 + * + * Copyright 2007 Wind River Systems Inc. All rights reserved. + */ +package org.eclipse.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; + +public class RegisterBitFieldLayoutCellModifier extends WatchExpressionCellModifier { + + public static enum BitFieldEditorStyle { NOTHING, BITFIELDCOMBO, BITFIELDTEXT } + + private BitFieldEditorStyle fStyle; + private IBitFieldDMData fBitFieldData = null; + private Object fElement = null; + private SyncRegisterDataAccess fDataAccess = null; + private IFormattedValuePreferenceStore fFormatPrefStore; + + public RegisterBitFieldLayoutCellModifier( IFormattedValuePreferenceStore formatPrefStore, BitFieldEditorStyle style, SyncRegisterDataAccess access ) { + fStyle = style; + fDataAccess = access; + fFormatPrefStore = formatPrefStore; + } + + /* + * Used to make sure we are dealing with a valid register. + */ + private IBitFieldDMContext getBitFieldDMC(Object element) { + if (element instanceof IAdaptable) { + return (IBitFieldDMContext)((IAdaptable)element).getAdapter(IBitFieldDMContext.class); + } + return null; + } + + @Override + public boolean canModify(Object element, String property) { + + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + /* + * Make sure we are are dealing with a valid set of information. + */ + if ( getBitFieldDMC(element) == null ) return false; + + fElement = element; + + /* + * We need to read the register in order to get the attributes. + */ + fBitFieldData = fDataAccess.readBitField(element); + + if ( ( fBitFieldData != null ) && ( ! fBitFieldData.isWriteable() ) ) return false; + + return true ; + } else { + return super.canModify(element, property); + } + } + + @Override + public Object getValue(Object element, String property) { + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + /* + * Make sure we are working on the editable areas. + */ + if ( element != fElement ) return false; + + if ( fStyle == BitFieldEditorStyle.BITFIELDTEXT ) { + + /* + * We let the Model provider supply the current format. + */ + String value = fDataAccess.getFormattedValue(fElement, fFormatPrefStore.getDefaultFormatId()); + + if ( value == null ) { value = "..."; } //$NON-NLS-1$ + + return value; + } + else { + /* + * This is a COMBO BOX. So we need to take the value of the bitfield and + * compare it to the associated mnemonic values to see which mnemonic is + * representing the current value. At this point the Bitfield Model data + * has already been established since the "canModify()" method is called + * first by the flexible hierarchy proxies. + */ + IMnemonic curMnemonic = fBitFieldData.getCurrentMnemonicValue(); + + int index = 0 ; + for ( IMnemonic mnemonic : fBitFieldData.getMnemonics() ) { + if ( mnemonic.equals( curMnemonic ) ) { + return new Integer( index ); + } + index ++; + } + + return null; + } + } else { + return super.getValue(element, property); + } + } + + @Override + public void modify(Object element, String property, Object value) { + /* + * If we're in the column value, modify the register data. + * Otherwise, call the super-class to edit the watch expression. + */ + if ( IDebugVMConstants.COLUMN_ID__VALUE.equals(property) ) { + if ( fStyle == BitFieldEditorStyle.BITFIELDTEXT ) { + if (value instanceof String) { + /* + * We let the Model provider supply the current format. + */ + fDataAccess.writeBitField(element, (String) value, IFormattedValues.HEX_FORMAT); + } + } + else { + if (value instanceof Integer) { + /* + * Get the integer value corresponding to the selected entry. + */ + Integer val = (Integer) value; + + /* + * Write the bit field using the selected mnemonic. + */ + fDataAccess.writeBitField(element, fBitFieldData.getMnemonics()[val.intValue()]); + } + } + } else { + super.modify(element, property, value); + } + } +} + diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java new file mode 100644 index 00000000000..77a3fa7aa7d --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterBitFieldLayoutNode.java @@ -0,0 +1,560 @@ +/******************************************************************************* + * Copyright (c) 2006 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.dd.dsf.debug.ui.viewmodel.register; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.DMContexts; +import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; +import org.eclipse.dd.dsf.debug.service.IRegisters; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldChangedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; +import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterBitFieldLayoutCellModifier.BitFieldEditorStyle; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.swt.widgets.Composite; + +@SuppressWarnings("restriction") +public class RegisterBitFieldLayoutNode extends AbstractExpressionLayoutNode implements IElementEditor { + + protected class BitFieldVMC extends DMVMContext + implements IVariable, IFormattedValueVMContext + { + private IExpression fExpression; + public BitFieldVMC(IDMContext dmc) { + super(dmc); + } + + public IFormattedValuePreferenceStore getPreferenceStore() { + return fFormattedPrefStore; + } + + public void setExpression(IExpression expression) { + fExpression = expression; + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + if (fExpression != null && adapter.isAssignableFrom(fExpression.getClass())) { + return fExpression; + } else if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapterExtension.class)) { + return fBitFieldExpressionFactory; + } else { + return super.getAdapter(adapter); + } + } + + @Override + public boolean equals(Object other) { + if (other instanceof BitFieldVMC && super.equals(other)) { + BitFieldVMC otherBitField = (BitFieldVMC)other; + return (otherBitField.fExpression == null && fExpression == null) || + (otherBitField.fExpression != null && otherBitField.fExpression.equals(fExpression)); + } + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + (fExpression != null ? fExpression.hashCode() : 0); + } + + public String getName() throws DebugException { return toString(); } + public String getReferenceTypeName() throws DebugException { return ""; } //$NON-NLS-1$ + public IValue getValue() throws DebugException { return null; } + public boolean hasValueChanged() throws DebugException { return false; } + public void setValue(IValue value) throws DebugException {} + public void setValue(String expression) throws DebugException {} + public boolean supportsValueModification() { return false; } + public boolean verifyValue(IValue value) throws DebugException { return false; } + public boolean verifyValue(String expression) throws DebugException { return false; } + public IDebugTarget getDebugTarget() { return null;} + public ILaunch getLaunch() { return null; } + public String getModelIdentifier() { return DsfDebugUIPlugin.PLUGIN_ID; } + } + + protected class BitFieldExpressionFactory implements IWatchExpressionFactoryAdapterExtension { + + public boolean canCreateWatchExpression(IVariable variable) { + return variable instanceof BitFieldVMC; + } + + public String createWatchExpression(IVariable variable) throws CoreException { + BitFieldVMC bitFieldVmc = ((BitFieldVMC)variable); + + StringBuffer exprBuf = new StringBuffer(); + IRegisterGroupDMContext groupDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterGroupDMContext.class); + if (groupDmc != null) { + IRegisterGroupDMData groupData = fDataAccess.readRegisterGroup(groupDmc); + if (groupData != null) { + exprBuf.append("$$\""); //$NON-NLS-1$ + exprBuf.append(groupData.getName()); + exprBuf.append('"'); + } + } + + IRegisterDMContext registerDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IRegisterDMContext.class); + if (registerDmc != null) { + IRegisterDMData regData = fDataAccess.readRegister(registerDmc); + if (regData != null) { + exprBuf.append('$'); + exprBuf.append(regData.getName()); + } + } + + IBitFieldDMContext bitFieldDmc = + DMContexts.getAncestorOfType(bitFieldVmc.getDMC(), IBitFieldDMContext.class); + if (bitFieldDmc != null) { + IBitFieldDMData bitFieldData = fDataAccess.readBitField(bitFieldDmc); + if (bitFieldData != null) { + exprBuf.append('.'); + exprBuf.append(bitFieldData.getName()); + } + } + + return exprBuf.toString(); + } + } + + private SyncRegisterDataAccess fDataAccess = null; + final protected BitFieldExpressionFactory fBitFieldExpressionFactory = new BitFieldExpressionFactory(); + private final IFormattedValuePreferenceStore fFormattedPrefStore; + + public RegisterBitFieldLayoutNode(IFormattedValuePreferenceStore prefStore, AbstractVMProvider provider, DsfSession session, SyncRegisterDataAccess access) { + super(provider, session, IRegisters.IBitFieldDMContext.class); + fDataAccess = access; + fFormattedPrefStore = prefStore; + } + + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IBitFieldDMContext dmc) + { + final IRegisters regService = getServicesTracker().getService(IRegisters.class); + + /* + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + final String preferencePageFormatId = fFormattedPrefStore.getDefaultFormatId(); + + regService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.HEX_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + /* + * Desired format is supported. + */ + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + /* + * Register service does not support any format. + */ + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = regService.getFormattedValue(dmc, finalFormatId); + + regService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue() , labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + /* + * We override the Abstract method because we now need to perform an extra level of data fetch + * to get the formatted value represenatation of the register. Before we obtained the data from + * the IDMData returned for the Register DMC. Now basically the level of information returned + * is attribute information and the formatted value requires a separate transaction. + * + * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IBitFieldDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IBitFieldDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, extract the selected values for each + * understood column. First we fill all of those columns which can + * be filled without the extra data mining. We also note if we do + * have to datamine. Any columns need to set the processing flag + * so we know we have further work to do. If there are more columns + * which need data extraction they need to be added in both "for" + * loops. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) { + update.setLabel(getData().getDescription(), idx); + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(localColumns[idx])) { + IVMContext vmc = (IVMContext)update.getElement(); + IExpression expression = (IExpression)vmc.getAdapter(IExpression.class); + if (expression != null) { + update.setLabel(expression.getExpressionText(), idx); + } else { + update.setLabel(getData().getName(), idx); + } + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) { + updateFormattedRegisterValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + final IRegisterDMContext regDmc = findDmcInPath(update.getElementPath(), IRegisterDMContext.class); + + if (regDmc == null) { + handleFailedUpdate(update); + return; + } + + getServicesTracker().getService(IRegisters.class).getBitFields( + regDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleErrorOrCancel() { + handleFailedUpdate(update); + } + + @Override + protected void handleOK() { + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); + } + + @Override + protected IVMContext createVMContext(IDMContext dmc) { + return new BitFieldVMC(dmc); + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } else if (e instanceof IRegisters.IBitFieldChangedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(IDMEvent e, VMDelta parent, int nodeOffset, RequestMonitor rm) { + if (e instanceof IRunControl.ISuspendedDMEvent) { + // Create a delta that the whole register group has changed. + parent.addFlags(IModelDelta.CONTENT); + } + if (e instanceof IRegisters.IBitFieldChangedDMEvent) { + parent.addNode( createVMContext(((IRegisters.IBitFieldChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + } + + super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); + } + + public CellEditor getCellEditor(IPresentationContext context, String columnId, Object element, Composite parent) { + + if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) { + /* + * In order to decide what kind of editor to present we need to know if there are + * mnemonics which can be used to represent the values. If there are then we will + * create a Combo editor for them. Otherwise we will just make a normal text cell + * editor. If there are bit groups then the modifier will check the size of the + * value being entered. + */ + IBitFieldDMData bitFieldData = fDataAccess.readBitField(element); + + if ( bitFieldData != null && bitFieldData.isWriteable() ) { + + IMnemonic[] mnemonics = bitFieldData.getMnemonics(); + + if ( mnemonics != null && mnemonics.length != 0 ) { + + /* + * Create the list of readable dropdown selections. + */ + String[] StringValues = new String[ mnemonics.length ]; + + int idx = 0 ; + for ( IMnemonic mnemonic : mnemonics ) { + StringValues[ idx ++ ] = mnemonic.getLongName(); + } + + /* + * Not we are complex COMBO and return the right editor. + */ + return new ComboBoxCellEditor(parent, StringValues); + } + else { + /* + * Text editor even if we need to clamp the value entered. + */ + return new TextCellEditor(parent); + } + } + } else if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnId)) { + return new TextCellEditor(parent); + } + return null; + } + + public ICellModifier getCellModifier(IPresentationContext context, Object element) { + + /* + * In order to decide what kind of modifier to present we need to know if there + * are mnemonics which can be used to represent the values. + */ + IBitFieldDMData bitFieldData = fDataAccess.readBitField(element); + + if ( bitFieldData != null && bitFieldData.isWriteable() ) { + + IMnemonic[] mnemonics = bitFieldData.getMnemonics(); + + if ( mnemonics != null && mnemonics.length != 0 ) { + /* + * Note we are complex COMBO and return the right editor. + */ + return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDCOMBO, fDataAccess ); + } + else { + /* + * Text editor even if we need to clamp the value entered. + */ + return new RegisterBitFieldLayoutCellModifier( fFormattedPrefStore, BitFieldEditorStyle.BITFIELDTEXT, fDataAccess ); + } + } + else { + return null; + } + } + + @Override + protected void testContextForExpression(Object element, final String expression, final DataRequestMonitor rm) { + if (!(element instanceof AbstractDMVMLayoutNode.DMVMContext)) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + final IBitFieldDMContext dmc = DMContexts.getAncestorOfType(((DMVMContext)element).getDMC(), IBitFieldDMContext.class); + if (dmc == null) { + rm.setStatus(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, IDsfService.INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ + rm.done(); + return; + } + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), rm) { + @Override + protected void handleOK() { + String bitFieldName = expression.substring(1); + if (bitFieldName.equals(getData().getName())) { + rm.setData(Boolean.TRUE); + } else { + rm.setData(Boolean.FALSE); + } + rm.done(); + } + }); + } + + public int getExpressionLength(String expression) { + if (expression.charAt(0) == '.' && Character.isLetterOrDigit(expression.charAt(1))) { + int length = 1; + while( length < expression.length() && Character.isLetterOrDigit(expression.charAt(length)) ) { + length++; + } + return length; + } else { + return -1; + } + } + + @Override + protected void associateExpression(Object element, IExpression expression) { + if (element instanceof BitFieldVMC) { + ((BitFieldVMC)element).setExpression(expression); + } + } + + @Override + protected int getDeltaFlagsForExpressionPart(Object event) { + if (event instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.CONTENT; + } + + return IModelDelta.NO_CHANGE; + } + + @Override + public void buildDeltaForExpression(final IExpression expression, final int elementIdx, final String expressionText, final Object event, final VMDelta parentDelta, final TreePath path, final RequestMonitor rm) + { + if (event instanceof ISuspendedDMEvent) { + // Mark the partent delta indicating that elements were added and/or removed. + parentDelta.addFlags(IModelDelta.CONTENT); + } else if (event instanceof IRegisters.IRegisterChangedDMEvent) { + parentDelta.addFlags(IModelDelta.CONTENT); + } + + super.buildDeltaForExpression(expression, elementIdx, expressionText, event, parentDelta, path, rm); + } + + @Override + protected void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, final RequestMonitor rm) + { + if (event instanceof IBitFieldChangedDMEvent) { + parentDelta.addNode(element, IModelDelta.STATE); + } + + super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta, rm); + } +} diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 0f55510b8b0..9af7cfcc0c0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -32,7 +32,8 @@ import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMData; import org.eclipse.dd.dsf.debug.ui.DsfDebugUIPlugin; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.AbstractExpressionLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.WatchExpressionCellModifier; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.ui.viewmodel.formatsupport.IFormattedValueVMContext; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; @@ -59,20 +60,20 @@ import org.eclipse.swt.widgets.Composite; @SuppressWarnings("restriction") public class RegisterLayoutNode extends AbstractExpressionLayoutNode - implements IElementEditor + implements IElementEditor { protected class RegisterVMC extends DMVMContext - implements IVariable + implements IVariable, IFormattedValueVMContext { private IExpression fExpression; public RegisterVMC(IDMContext dmc) { super(dmc); } - + public void setExpression(IExpression expression) { fExpression = expression; } - + @Override @SuppressWarnings("unchecked") public Object getAdapter(Class adapter) { @@ -90,16 +91,20 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode dmc) { return new RegisterVMC(dmc); } - + @Override protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { if (e instanceof IRunControl.ISuspendedDMEvent) { @@ -467,10 +473,22 @@ public class RegisterLayoutNode extends AbstractExpressionLayoutNode