From 60cccc683cdc1f5bb16ba81d0c17d8bd969b8045 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 23 Oct 2007 22:21:40 +0000 Subject: [PATCH] [207236] Single-click "Add new expression" workflow. --- .../ExpressionManagerLayoutNode.java | 129 +++++++++++++----- .../expression/MessagesForExpressionVM.java | 2 + .../WatchExpressionCellModifier.java | 15 +- .../viewmodel/expression/messages.properties | 1 + 4 files changed, 107 insertions(+), 40 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java index ff4d7c6f2f7..170a22ee6a0 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/ExpressionManagerLayoutNode.java @@ -26,6 +26,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.update.VMCacheManager; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementEditor; @@ -36,6 +37,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TextCellEditor; @@ -94,7 +96,33 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode return fExpression.hashCode(); } } - + + /** + * VMC for a new expression object to be added. When user clicks on this node to + * edit it, he will create a new expression. + */ + public class NewExpressionVMC extends AbstractVMContext { + public NewExpressionVMC() { + super(getVMProvider().getVMAdapter(), ExpressionManagerLayoutNode.this); + } + + @Override + @SuppressWarnings("unchecked") + public Object getAdapter(Class adapter) { + return super.getAdapter(adapter); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof NewExpressionVMC; + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + } + /** Array of expression nodes which parse the user expressions and handle model events */ private IExpressionLayoutNode[] fExpressionNodes = new IExpressionLayoutNode[0]; @@ -120,7 +148,9 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } public void updateElementCount(IChildrenCountUpdate update) { - update.setChildCount(fManager.getExpressions().length); + // We assume that the getExpressions() will just read local state data, + // so we don't bother using a job to perform this operation. + update.setChildCount(fManager.getExpressions().length + 1); update.done(); } @@ -140,45 +170,45 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode }; int expressionRmCount = 0; - for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length; i++) { + for (int i = update.getOffset(); i < update.getOffset() + update.getLength() && i < expressions.length + 1; i++) { - // Check the array boundaries as the expression manager could change asynchronously. - // The expression manager change should lead to a refresh in the view. - if (i > expressions.length) { - continue; - } - - final String expressionText = expressions[i].getExpressionText(); - final int expressionIdx = i; - final IExpression expression = expressions[i]; - IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); - if (expressionNode == null) { - update.setChild(new InvalidExpressionVMC(expression), i); + // The last element is the "new expression" + if (i == expressions.length) { + update.setChild(new NewExpressionVMC(), i); } else { - expressionRmCount++; - // getElementForExpression() accepts a IElementsUpdate as an argument. - // Construct an instance of VMElementsUpdate which will call a - // the request monitor when it is finished. The request monitor - // will in turn set the element in the update argument in this method. - VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( - update, 0, 1, - new DataRequestMonitor>(getExecutor(), multiRm) { - @Override - protected void handleOK() { - update.setChild(getData().get(0), expressionIdx); - multiRm.done(); - } - - @Override - protected void handleError() { - update.setChild(new InvalidExpressionVMC(expression), expressionIdx); - multiRm.done(); - } - }); - expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); + final String expressionText = expressions[i].getExpressionText(); + final int expressionIdx = i; + final IExpression expression = expressions[i]; + IExpressionLayoutNode expressionNode = findNodeForExpression(expressionText); + if (expressionNode == null) { + update.setChild(new InvalidExpressionVMC(expression), i); + } else { + expressionRmCount++; + // getElementForExpression() accepts a IElementsUpdate as an argument. + // Construct an instance of VMElementsUpdate which will call a + // the request monitor when it is finished. The request monitor + // will in turn set the element in the update argument in this method. + VMElementsUpdate expressionElementUpdate = new VMElementsUpdate( + update, 0, 1, + new DataRequestMonitor>(getExecutor(), multiRm) { + @Override + protected void handleOK() { + update.setChild(getData().get(0), expressionIdx); + multiRm.done(); + } + + @Override + protected void handleError() { + update.setChild(new InvalidExpressionVMC(expression), expressionIdx); + multiRm.done(); + } + }); + expressionNode.getElementForExpression(expressionElementUpdate, expressionText, expression); + } } } + // If no expressions were parsed, we're finished. // Set the count to the counting RM. multiRm.setDoneCount(expressionRmCount); } @@ -190,6 +220,8 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode for (ILabelUpdate update : updates) { if (update.getElement() instanceof InvalidExpressionVMC) { updateInvalidExpressionVMCLabel(update, (InvalidExpressionVMC) update.getElement()); + } else if (update.getElement() instanceof NewExpressionVMC) { + updateNewExpressionVMCLabel(update, (NewExpressionVMC) update.getElement()); } else { update.done(); } @@ -215,12 +247,35 @@ public class ExpressionManagerLayoutNode extends AbstractVMLayoutNode } else { update.setLabel("", i); //$NON-NLS-1$ } + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], i); } update.done(); } - + + + /** + * Updates the label for the NewExpressionVMC. + */ + private void updateNewExpressionVMCLabel(ILabelUpdate update, NewExpressionVMC vmc) { + String[] columnIds = update.getColumnIds() != null ? + update.getColumnIds() : new String[] { IDebugVMConstants.COLUMN_ID__NAME }; + + for (int i = 0; i < columnIds.length; i++) { + if (IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(columnIds[i])) { + update.setLabel(MessagesForExpressionVM.ExpressionManagerLayoutNode__newExpression_label, i); + update.setFontData(JFaceResources.getFontDescriptor(IInternalDebugUIConstants.VARIABLE_TEXT_FONT).getFontData()[0], i); + } else { + update.setLabel("", i); //$NON-NLS-1$ + } + } + + + update.done(); + } + + /** * Convenience call that iterates through all the configured expression * layout nodes and finds the first one that can parse the given expression. diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java index 6b943864783..acc8b005c96 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/MessagesForExpressionVM.java @@ -14,6 +14,8 @@ public class MessagesForExpressionVM extends NLS { public static String ExpressionManagerLayoutNode__invalidExpression_nameColumn_label; public static String ExpressionManagerLayoutNode__invalidExpression_valueColumn_label; + public static String ExpressionManagerLayoutNode__newExpression_label; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, MessagesForExpressionVM.class); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java index a66ccef945f..ab65a47f772 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/WatchExpressionCellModifier.java @@ -13,6 +13,9 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.expression; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionManagerLayoutNode.NewExpressionVMC; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IExpressionManager; import org.eclipse.debug.core.model.IWatchExpression; import org.eclipse.jface.viewers.ICellModifier; @@ -32,7 +35,8 @@ public class WatchExpressionCellModifier implements ICellModifier { } public boolean canModify(Object element, String property) { - return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && getWatchExpression(element) != null; + return IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property) && + (getWatchExpression(element) != null || element instanceof NewExpressionVMC); } public Object getValue(Object element, String property) { @@ -49,11 +53,16 @@ public class WatchExpressionCellModifier implements ICellModifier { public void modify(Object element, String property, Object value) { if (!IDebugVMConstants.COLUMN_ID__EXPRESSION.equals(property)) return; + if (!(value instanceof String)) return; IWatchExpression expression = getWatchExpression(element); - if (expression != null && value instanceof String) { + if (expression != null) { expression.setExpressionText((String)value); - } + } else if (element instanceof NewExpressionVMC && ((String)value).trim().length() != 0) { + IExpressionManager expressionManager = DebugPlugin.getDefault().getExpressionManager(); + IWatchExpression watchExpression = expressionManager.newWatchExpression((String)value); + expressionManager.addExpression(watchExpression); + } } private IWatchExpression getWatchExpression(Object element) { diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties index 9c940b5d501..edf8a7d0a53 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/expression/messages.properties @@ -5,3 +5,4 @@ ExpressionColumnPresentation_value=Value ExpressionColumnPresentation_description=Description ExpressionManagerLayoutNode__invalidExpression_nameColumn_label=Invalid expression ExpressionManagerLayoutNode__invalidExpression_valueColumn_label=Invalid expression +ExpressionManagerLayoutNode__newExpression_label=Add new expression