Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 151809 Details for
Bug 255026
[expressions] Support for advanced expression hover
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Experimental expression "inspector"
255026.patch (text/plain), 45.09 KB, created by
Anton Leherbauer
on 2009-11-10 08:29:13 EST
(
hide
)
Description:
Experimental expression "inspector"
Filename:
MIME Type:
Creator:
Anton Leherbauer
Created:
2009-11-10 08:29:13 EST
Size:
45.09 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.cdt.dsf.gdb.ui >Index: src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java,v >retrieving revision 1.1 >diff -u -r1.1 GdbViewModelAdapter.java >--- src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java 8 Jan 2009 21:06:30 -0000 1.1 >+++ src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java 10 Nov 2009 13:28:27 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2008 Wind River Systems and others. >+ * Copyright (c) 2006, 2009 Wind River Systems and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -11,6 +11,7 @@ > package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel; > > import org.eclipse.cdt.dsf.concurrent.ThreadSafe; >+import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants; > import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter; > import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController; > import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; >@@ -28,7 +29,6 @@ > * > */ > @ThreadSafe >-@SuppressWarnings("restriction") > public class GdbViewModelAdapter extends AbstractDebugVMAdapter > { > public GdbViewModelAdapter(DsfSession session, SteppingController controller) { >@@ -52,6 +52,8 @@ > return new RegisterVMProvider(this, context, getSession()); > } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { > return new ExpressionVMProvider(this, context, getSession()); >+ } else if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(context.getId()) ) { >+ return new ExpressionVMProvider(this, context, getSession()); > } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { > return new ModulesVMProvider(this, context, getSession()); > } >Index: src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java,v >retrieving revision 1.4 >diff -u -r1.4 GdbAdapterFactory.java >--- src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java 10 Sep 2009 20:41:35 -0000 1.4 >+++ src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java 10 Nov 2009 13:28:27 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2008 Wind River Systems and others. >+ * Copyright (c) 2006, 2009 Wind River Systems and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -67,6 +67,7 @@ > import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; > import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; > import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider; > import org.eclipse.debug.ui.contexts.ISuspendTrigger; > import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; > >@@ -115,7 +116,8 @@ > session.registerModelAdapter(SteppingController.class, fSteppingController); > > fViewModelAdapter = new GdbViewModelAdapter(session, fSteppingController); >- >+ session.registerModelAdapter(IViewerInputProvider.class, fViewModelAdapter); >+ > if (launch.getSourceLocator() instanceof ISourceLookupDirector) { > fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController); > } else { >Index: src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbDebugTextHover.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbDebugTextHover.java,v >retrieving revision 1.1 >diff -u -r1.1 GdbDebugTextHover.java >--- src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbDebugTextHover.java 10 Nov 2009 00:07:39 -0000 1.1 >+++ src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbDebugTextHover.java 10 Nov 2009 13:28:27 -0000 >@@ -25,4 +25,8 @@ > return GdbLaunchDelegate.GDB_DEBUG_MODEL_ID; > } > >+ @Override >+ protected boolean useExpressionExplorer() { >+ return true; >+ } > } >#P org.eclipse.cdt.dsf.ui >Index: src/org/eclipse/cdt/dsf/debug/ui/AbstractDsfDebugTextHover.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/AbstractDsfDebugTextHover.java,v >retrieving revision 1.2 >diff -u -r1.2 AbstractDsfDebugTextHover.java >--- src/org/eclipse/cdt/dsf/debug/ui/AbstractDsfDebugTextHover.java 10 Nov 2009 12:21:23 -0000 1.2 >+++ src/org/eclipse/cdt/dsf/debug/ui/AbstractDsfDebugTextHover.java 10 Nov 2009 13:28:48 -0000 >@@ -17,6 +17,9 @@ > > package org.eclipse.cdt.dsf.debug.ui; > >+import java.util.concurrent.Callable; >+import java.util.concurrent.ExecutionException; >+ > import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover; > import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; > import org.eclipse.cdt.dsf.concurrent.Query; >@@ -31,19 +34,37 @@ > import org.eclipse.cdt.dsf.service.DsfSession; > import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.debug.core.model.IDebugModelProvider; >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.DefaultInformationControl; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IInformationControl; >+import org.eclipse.jface.text.IInformationControlCreator; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.ITextHoverExtension2; >+import org.eclipse.jface.text.ITextViewer; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.editors.text.EditorsUI; > > /** >- * An implementation of AbstractDebugTextHover using DSF services. >+ * An implementation of AbstractDebugTextHover using DSF services > * > * @since 2.1 > */ >-abstract public class AbstractDsfDebugTextHover extends AbstractDebugTextHover { >+abstract public class AbstractDsfDebugTextHover extends AbstractDebugTextHover implements ITextHoverExtension2 { > > /** > * Returns the debug model ID of that this debug text hover is to be used for. > */ > abstract protected String getModelId(); > >+ /** >+ * Returns whether the expression explorer information control should be used. >+ * The default implementation returns <code>false</code>. >+ */ >+ protected boolean useExpressionExplorer() { >+ return false; >+ } >+ > private static class GetExpressionValueQuery extends Query<FormattedValueDMData> { > private final IFrameDMContext frame; > private final String expression; >@@ -128,4 +149,73 @@ > return null; > } > >+ @Override >+ public IInformationControlCreator getHoverControlCreator() { >+ if (useExpressionExplorer()) { >+ return new ExpressionInformationControlCreator(); >+ } else { >+ return new IInformationControlCreator() { >+ public IInformationControl createInformationControl(Shell parent) { >+ return new DefaultInformationControl(parent, EditorsUI.getTooltipAffordanceString()); >+ } >+ }; >+ } >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion) >+ */ >+ public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { >+ final String simpleInfo = getHoverInfo(textViewer, hoverRegion); >+ if (!useExpressionExplorer() || simpleInfo == null) { >+ return simpleInfo; >+ } >+ // improved version using ExpressionInformationControlCreator >+ // see also getHoverControlCreator() >+ final String text = getExpressionText(textViewer, hoverRegion); >+ if (text != null && text.length() > 0) { >+ final IFrameDMContext frameDmc = getFrame(); >+ final DsfSession dsfSession = DsfSession.getSession(frameDmc.getSessionId()); >+ Callable<IExpressionDMContext> callable = new Callable<IExpressionDMContext>() { >+ public IExpressionDMContext call() throws Exception { >+ DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), frameDmc.getSessionId()); >+ try { >+ IExpressions expressions = tracker.getService(IExpressions.class); >+ if (expressions != null) { >+ return expressions.createExpression(frameDmc, text); >+ } >+ return null; >+ } finally { >+ tracker.dispose(); >+ } >+ } >+ }; >+ try { >+ return dsfSession.getExecutor().submit(callable).get(); >+ } catch (InterruptedException e) { >+ } catch (ExecutionException e) { >+ } >+ } >+ return null; >+ } >+ >+ private String getExpressionText(ITextViewer textViewer, IRegion hoverRegion) { >+ IDocument document = textViewer.getDocument(); >+ if (document == null) >+ return null; >+ String expression; >+ try { >+ expression= document.get(hoverRegion.getOffset(), >+ hoverRegion.getLength()); >+ } catch (BadLocationException exc) { >+ return null; >+ } >+ if (expression == null) >+ return null; >+ expression = expression.trim(); >+ if (expression.length() == 0) >+ return null; >+ return expression; >+ } >+ > } >Index: src/org/eclipse/cdt/dsf/debug/ui/IDsfDebugUIConstants.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/IDsfDebugUIConstants.java,v >retrieving revision 1.3 >diff -u -r1.3 IDsfDebugUIConstants.java >--- src/org/eclipse/cdt/dsf/debug/ui/IDsfDebugUIConstants.java 31 Mar 2009 21:25:23 -0000 1.3 >+++ src/org/eclipse/cdt/dsf/debug/ui/IDsfDebugUIConstants.java 10 Nov 2009 13:28:48 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2008 Wind River Systems and others. >+ * Copyright (c) 2006, 2009 Wind River Systems and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -79,4 +79,11 @@ > * @since 2.0 > */ > public static final String PREF_COLOR_STALE_DATA_BACKGROUND= PLUGIN_ID + ".staledata.background"; //$NON-NLS-1$ >+ >+ /** >+ * Presentation context id for the expression hover. >+ * >+ * @since 2.1 >+ */ >+ public static final String ID_EXPRESSION_HOVER= PLUGIN_ID + ".expression_hover"; //$NON-NLS-1$ > } >Index: src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.cdt/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java,v >retrieving revision 1.2 >diff -u -r1.2 ExpressionVMProvider.java >--- src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java 10 Mar 2009 23:47:13 -0000 1.2 >+++ src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java 10 Nov 2009 13:28:48 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2008 Wind River Systems and others. >+ * Copyright (c) 2006, 2009 Wind River Systems and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -19,6 +19,7 @@ > import org.eclipse.cdt.dsf.debug.service.ICachingService; > import org.eclipse.cdt.dsf.debug.service.IExpressions; > 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; >@@ -46,6 +47,7 @@ > import org.eclipse.debug.internal.core.IExpressionsListener2; > import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; > import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; > import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; > import org.eclipse.jface.preference.IPreferenceStore; > import org.eclipse.jface.util.IPropertyChangeListener; >@@ -210,8 +212,13 @@ > /* > * Now the Over-arching management node. > */ >- ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this); >- addChildNodes(rootNode, new IVMNode[] {expressionManagerNode}); >+ if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(getPresentationContext().getId())) { >+ SingleExpressionVMNode expressionManagerNode = new SingleExpressionVMNode(this); >+ addChildNodes(rootNode, new IVMNode[] { expressionManagerNode }); >+ } else { >+ ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this); >+ addChildNodes(rootNode, new IVMNode[] {expressionManagerNode}); >+ } > > /* > * The expression view wants to support fully all of the components of the register view. >@@ -372,4 +379,20 @@ > // Session disposed, ignore. > } > } >+ >+ @Override >+ public void update(IViewerInputUpdate update) { >+ if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(getPresentationContext().getId())) { >+ Object input = update.getElement(); >+ if (input instanceof IExpressionDMContext) { >+ IExpressionDMContext dmc= (IExpressionDMContext) input; >+ SingleExpressionVMNode vmNode = (SingleExpressionVMNode) getChildVMNodes(getRootVMNode())[0]; >+ vmNode.setExpression(dmc); >+ update.setInputElement(vmNode.createVMContext(dmc)); >+ update.done(); >+ return; >+ } >+ } >+ super.update(update); >+ } > } >Index: src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/SingleExpressionVMNode.java >=================================================================== >RCS file: src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/SingleExpressionVMNode.java >diff -N src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/SingleExpressionVMNode.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/SingleExpressionVMNode.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,327 @@ >+/******************************************************************************* >+ * Copyright (c) 2009 Wind River Systems, Inc. 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.expression; >+ >+import java.util.LinkedList; >+import java.util.List; >+ >+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; >+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; >+import org.eclipse.cdt.dsf.concurrent.RequestMonitor; >+import org.eclipse.cdt.dsf.datamodel.IDMContext; >+import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; >+import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; >+import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionsChangedEvent; >+import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.InvalidExpressionVMContext; >+import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor; >+import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext; >+import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; >+import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; >+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; >+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; >+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.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.IElementLabelProvider; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; >+import org.eclipse.jface.viewers.TreePath; >+ >+/** >+ * A VM node for displaying a single expression in the expression hover. >+ */ >+public class SingleExpressionVMNode extends AbstractDMVMNode implements IElementLabelProvider { >+ >+ private static class RootDMVMContext extends AbstractVMContext implements IDMVMContext { >+ private final IDMContext fDmc; >+ public RootDMVMContext(IVMNode node, IDMContext dmc) { >+ super(node); >+ fDmc = dmc; >+ } >+ public IDMContext getDMContext() { >+ return fDmc; >+ } >+ @SuppressWarnings("unchecked") >+ @Override >+ public Object getAdapter(Class adapter) { >+ Object superAdapter = super.getAdapter(adapter); >+ if (superAdapter != null) { >+ return superAdapter; >+ } else { >+ // Delegate to the Data Model to find the context. >+ if (adapter.isInstance(fDmc)) { >+ return fDmc; >+ } else { >+ return fDmc.getAdapter(adapter); >+ } >+ } >+ } >+ >+ @Override >+ public boolean equals(Object other) { >+ if (!(other instanceof RootDMVMContext)) return false; >+ RootDMVMContext otherVmc = (RootDMVMContext)other; >+ return getVMNode().equals(otherVmc.getVMNode()) && >+ fDmc.equals(otherVmc.fDmc); >+ } >+ >+ @Override >+ public int hashCode() { >+ return getVMNode().hashCode() + fDmc.hashCode(); >+ } >+ >+ } >+ >+ private static class SimpleExpression implements IExpression { >+ private String fExpressionText; >+ SimpleExpression(String text) { >+ fExpressionText = text; >+ } >+ public void dispose() { >+ } >+ public IDebugTarget getDebugTarget() { >+ return null; >+ } >+ public String getExpressionText() { >+ return fExpressionText; >+ } >+ public IValue getValue() { >+ return null; >+ } >+ public ILaunch getLaunch() { >+ return null; >+ } >+ public String getModelIdentifier() { >+ return null; >+ } >+ @SuppressWarnings("unchecked") >+ public Object getAdapter(Class adapter) { >+ return null; >+ } >+ >+ } >+ >+ private static class SingleExpressionManager { >+ private static final IExpression[] NO_EXPRESSIONS = {}; >+ IExpression fExpression; >+ public IExpression[] getExpressions() { >+ if (fExpression != null) { >+ return new IExpression[] { fExpression }; >+ } >+ return NO_EXPRESSIONS; >+ } >+ public void setExpression(IExpression expression) { >+ fExpression = expression; >+ } >+ >+ } >+ >+ /** Local reference to the expression manager */ >+ private final SingleExpressionManager fManager; >+ >+ public SingleExpressionVMNode(ExpressionVMProvider provider) { >+ super(provider, provider.getSession(), IExpressionDMContext.class); >+ fManager = new SingleExpressionManager(); >+ } >+ >+ @Override >+ public String toString() { >+ return "SingleExpressionVMNode"; //$NON-NLS-1$ >+ } >+ >+ private ExpressionVMProvider getExpressionVMProvider() { >+ return (ExpressionVMProvider)getVMProvider(); >+ } >+ >+ @Override >+ public void update(IHasChildrenUpdate[] updates) { >+ // Test availability of children based on whether there are any expressions >+ // in the manager. We assume that the getExpressions() will just read >+ // local state data, so we don't bother using a job to perform this >+ // operation. >+ for (int i = 0; i < updates.length; i++) { >+ updates[i].setHasChilren(fManager.getExpressions().length != 0); >+ updates[i].done(); >+ } >+ } >+ >+ @Override >+ public void update(IChildrenCountUpdate[] updates) { >+ for (IChildrenCountUpdate update : updates) { >+ if (!checkUpdate(update)) continue; >+ >+ // 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); >+ update.done(); >+ } >+ } >+ >+ @Override >+ public void update(final IChildrenUpdate[] updates) { >+ for (IChildrenUpdate update : updates) { >+ doUpdateChildren(update); >+ } >+ } >+ >+ public void doUpdateChildren(final IChildrenUpdate update) { >+ final IExpression[] expressions = fManager.getExpressions(); >+ >+ // For each (expression) element in update, find the layout node that can >+ // parse it. And for each expression that has a corresponding layout node, >+ // call IExpressionLayoutNode#getElementForExpression to generate a VMC. >+ // Since the last is an async call, we need to create a multi-RM to wait >+ // for all the calls to complete. >+ final CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getVMProvider().getExecutor(), update); >+ int multiRmCount = 0; >+ >+ int lowOffset= update.getOffset(); >+ if (lowOffset < 0) { >+ lowOffset = 0; >+ } >+ int length= update.getLength(); >+ if (length <= 0) { >+ length = expressions.length; >+ } >+ final int highOffset= lowOffset + length; >+ for (int i = lowOffset; i < highOffset && i < expressions.length + 1; i++) { >+ if (i < expressions.length) { >+ multiRmCount++; >+ final int childIndex = i; >+ final IExpression expression = expressions[i]; >+ // 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. >+ ((ExpressionVMProvider)getVMProvider()).update( >+ new VMExpressionUpdate( >+ update, expression, >+ new DataRequestMonitor<Object>(getVMProvider().getExecutor(), multiRm) { >+ @Override >+ protected void handleSuccess() { >+ update.setChild(getData(), childIndex); >+ multiRm.done(); >+ } >+ >+ @Override >+ protected void handleError() { >+ update.setChild(new InvalidExpressionVMContext(SingleExpressionVMNode.this, expression), childIndex); >+ multiRm.done(); >+ } >+ }) >+ ); >+ } >+ } >+ >+ // If no expressions were parsed, we're finished. >+ // Set the count to the counting RM. >+ multiRm.setDoneCount(multiRmCount); >+ } >+ >+ public void update(ILabelUpdate[] updates) { >+ // The label update handler only handles labels for the invalid expression VMCs. >+ // The expression layout nodes are responsible for supplying label providers >+ // for their VMCs. >+ for (ILabelUpdate update : updates) { >+ update.done(); >+ } >+ } >+ >+ public int getDeltaFlags(Object event) { >+ int retVal = 0; >+ >+ // Add a flag if the list of expressions in the global expression manager has changed. >+ if (event instanceof ExpressionsChangedEvent) { >+ retVal |= IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.INSERTED | IModelDelta.CONTENT ; >+ } >+ >+ for (IExpression expression : fManager.getExpressions()) { >+ retVal |= getExpressionVMProvider().getDeltaFlagsForExpression(expression, event); >+ } >+ >+ return retVal; >+ } >+ >+ public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { >+ if (event instanceof ExpressionsChangedEvent) { >+ buildDeltaForExpressionsChangedEvent((ExpressionsChangedEvent)event, parentDelta, nodeOffset, requestMonitor); >+ } else { >+ >+ // For each expression, find its corresponding node and ask that >+ // layout node for its delta flags for given event. If there are delta flags to be >+ // generated, call the asynchronous method to do so. >+ CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); >+ >+ int buildDeltaForExpressionCallCount = 0; >+ >+ IExpression[] expressions = fManager.getExpressions(); >+ for (int i = 0; i < expressions.length; i++ ) { >+ int flags = getExpressionVMProvider().getDeltaFlagsForExpression(expressions[i], event); >+ // If the given expression has no delta flags, skip it. >+ if (flags == IModelDelta.NO_CHANGE) continue; >+ >+ int elementOffset = nodeOffset >= 0 ? nodeOffset + i : -1; >+ getExpressionVMProvider().buildDeltaForExpression( >+ expressions[i], elementOffset, event, parentDelta, getTreePathFromDelta(parentDelta), >+ new RequestMonitor(getExecutor(), multiRm)); >+ buildDeltaForExpressionCallCount++; >+ } >+ >+ multiRm.setDoneCount(buildDeltaForExpressionCallCount); >+ } >+ } >+ >+ private void buildDeltaForExpressionsChangedEvent(ExpressionsChangedEvent event, VMDelta parentDelta, >+ int nodeOffset, RequestMonitor requestMonitor) >+ { >+ CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor); >+ for (int i = 0; i < event.getExpressions().length; i++) { >+ int expIndex = event.getIndex() != -1 >+ ? nodeOffset + event.getIndex() + i >+ : -1; >+ getExpressionVMProvider().buildDeltaForExpression( >+ event.getExpressions()[i], expIndex, event, parentDelta, getTreePathFromDelta(parentDelta), >+ new RequestMonitor(getExecutor(), multiRm)); >+ } >+ multiRm.setDoneCount(event.getExpressions().length); >+ } >+ >+ private TreePath getTreePathFromDelta(IModelDelta delta) { >+ List<Object> elementList = new LinkedList<Object>(); >+ IModelDelta listDelta = delta; >+ elementList.add(0, listDelta.getElement()); >+ while (listDelta.getParentDelta() != null) { >+ elementList.add(0, listDelta.getElement()); >+ listDelta = listDelta.getParentDelta(); >+ } >+ return new TreePath(elementList.toArray()); >+ } >+ >+ @Override >+ protected void updateElementsInSessionThread(IChildrenUpdate update) { >+ doUpdateChildren(update); >+ } >+ >+ @Override >+ public IDMVMContext createVMContext(IDMContext dmc) { >+ return new RootDMVMContext(getVMProvider().getRootVMNode(), dmc); >+ } >+ >+ void setExpression(IExpressionDMContext dmc) { >+ String text = dmc.getExpression(); >+ fManager.setExpression(new SimpleExpression(text)); >+ } >+} >Index: src/org/eclipse/cdt/dsf/debug/ui/ExpressionInformationControlCreator.java >=================================================================== >RCS file: src/org/eclipse/cdt/dsf/debug/ui/ExpressionInformationControlCreator.java >diff -N src/org/eclipse/cdt/dsf/debug/ui/ExpressionInformationControlCreator.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/cdt/dsf/debug/ui/ExpressionInformationControlCreator.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,447 @@ >+/******************************************************************************* >+ * Copyright (c) 2008, 2009 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ * Wind River Systems - adapted for DSF >+ *******************************************************************************/ >+package org.eclipse.cdt.dsf.debug.ui; >+ >+import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; >+import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.debug.core.model.IVariable; >+import org.eclipse.debug.internal.ui.SWTFactory; >+import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputRequestor; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; >+import org.eclipse.debug.internal.ui.viewers.model.provisional.ViewerInputService; >+import org.eclipse.debug.internal.ui.views.variables.details.DefaultDetailPane; >+import org.eclipse.debug.internal.ui.views.variables.details.DetailPaneProxy; >+import org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer; >+import org.eclipse.debug.ui.AbstractDebugView; >+import org.eclipse.debug.ui.IDebugUIConstants; >+import org.eclipse.jface.dialogs.IDialogSettings; >+import org.eclipse.jface.text.AbstractInformationControl; >+import org.eclipse.jface.text.IInformationControl; >+import org.eclipse.jface.text.IInformationControlCreator; >+import org.eclipse.jface.text.IInformationControlExtension2; >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.StructuredViewer; >+import org.eclipse.jface.viewers.TreeSelection; >+import org.eclipse.jface.viewers.ViewerFilter; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.SashForm; >+import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.events.SelectionListener; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Layout; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.Tree; >+import org.eclipse.ui.IWorkbenchPage; >+import org.eclipse.ui.IWorkbenchPartSite; >+ >+/** >+ * Creates an information control to display an expression in a hover control. >+ * >+ * @noextend This class is not intended to be subclassed by clients. >+ * >+ * @since 2.1 >+ */ >+public class ExpressionInformationControlCreator implements IInformationControlCreator { >+ >+ class ExpressionInformationControl extends AbstractInformationControl implements IInformationControlExtension2, IViewerInputRequestor { >+ >+ /** >+ * Dialog setting key for height >+ */ >+ private static final String HEIGHT = "HEIGHT"; //$NON-NLS-1$ >+ >+ /** >+ * Dialog setting key for width. >+ */ >+ private static final String WIDTH = "WIDTH"; //$NON-NLS-1$ >+ >+ /** >+ * Dialog setting key for tree sash weight >+ */ >+ private static final String SASH_WEIGHT_TREE = "SashWeightTree"; //$NON-NLS-1$ >+ >+ /** >+ * Dialog setting key for details sash weight >+ */ >+ private static final String SASH_WEIGHT_DETAILS = "SashWeightDetails"; //$NON-NLS-1$ >+ >+ /** >+ * Variable to display. >+ */ >+ private Object fVariable; >+ >+ private TreeModelViewer fViewer; >+ private SashForm fSashForm; >+ private Composite fDetailPaneComposite; >+ private DetailPaneProxy fDetailPane; >+ private Tree fTree; >+ >+ private ViewerInputService fInputService; >+ >+ /** >+ * Creates the content for the root element of the tree viewer in the hover >+ */ >+ private class TreeRoot extends ElementContentProvider { >+ @Override >+ protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException { >+ return 1; >+ } >+ @Override >+ protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException { >+ return new Object[] { fVariable }; >+ } >+ @Override >+ protected boolean supportsContextId(String id) { >+ return true; >+ } >+ } >+ >+ /** >+ * Inner class implementing IDetailPaneContainer methods. Handles changes to detail >+ * pane and provides limited access to the detail pane proxy. >+ */ >+ private class DetailPaneContainer implements IDetailPaneContainer { >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentPaneID() >+ */ >+ public String getCurrentPaneID() { >+ return fDetailPane.getCurrentPaneID(); >+ } >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentSelection() >+ */ >+ public IStructuredSelection getCurrentSelection() { >+ return (IStructuredSelection)fViewer.getSelection(); >+ } >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#refreshDetailPaneContents() >+ */ >+ public void refreshDetailPaneContents() { >+ fDetailPane.display(getCurrentSelection()); >+ } >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getParentComposite() >+ */ >+ public Composite getParentComposite() { >+ return fDetailPaneComposite; >+ } >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getWorkbenchPartSite() >+ */ >+ public IWorkbenchPartSite getWorkbenchPartSite() { >+ return null; >+ } >+ >+ /* >+ * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#paneChanged(java.lang.String) >+ */ >+ public void paneChanged(String newPaneID) { >+ if (DefaultDetailPane.ID.equals(newPaneID)){ >+ fDetailPane.getCurrentControl().setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); >+ } >+ } >+ >+ } >+ >+ /** >+ * Constructs a new control in the given shell. >+ * >+ * @param parentShell shell >+ * @param resize whether resize is supported >+ */ >+ ExpressionInformationControl(Shell parentShell, boolean resize) { >+ super(parentShell, resize); >+ create(); >+ } >+ >+ @Override >+ public Point computeSizeHint() { >+ IDialogSettings settings = getDialogSettings(false); >+ if (settings != null) { >+ int x = getIntSetting(settings, WIDTH); >+ if (x > 0) { >+ int y = getIntSetting(settings, HEIGHT); >+ if (y > 0) { >+ final Point size= new Point(x,y); >+ return size; >+ } >+ } >+ } >+ return super.computeSizeHint(); >+ } >+ >+ /** >+ * Returns the dialog settings for this hover or <code>null</code> if none >+ * >+ * @param create whether to create the settings >+ */ >+ private IDialogSettings getDialogSettings(boolean create) { >+ IDialogSettings settings = DsfUIPlugin.getDefault().getDialogSettings(); >+ IDialogSettings section = settings.getSection(this.getClass().getName()); >+ if (section == null & create) { >+ section = settings.addNewSection(this.getClass().getName()); >+ } >+ return section; >+ } >+ >+ /** >+ * Returns an integer value in the given dialog settings or -1 if none. >+ * >+ * @param settings dialog settings >+ * @param key key >+ * @return value or -1 if not present >+ */ >+ private int getIntSetting(IDialogSettings settings, String key) { >+ try { >+ return settings.getInt(key); >+ } catch (NumberFormatException e) { >+ return -1; >+ } >+ } >+ >+ @Override >+ public void dispose() { >+ persistSettings(getShell()); >+ super.dispose(); >+ } >+ >+ /** >+ * Persists dialog settings. >+ * >+ * @param shell >+ */ >+ private void persistSettings(Shell shell) { >+ if (shell != null && !shell.isDisposed()) { >+ if (isResizable()) { >+ IDialogSettings settings = getDialogSettings(true); >+ Point size = shell.getSize(); >+ System.out.println("ExpressionInformationControlCreator.ExpressionInformationControl.persistSettings() " + size); >+ settings.put(WIDTH, size.x); >+ settings.put(HEIGHT, size.y); >+ int[] weights = fSashForm.getWeights(); >+ settings.put(SASH_WEIGHT_TREE, weights[0]); >+ settings.put(SASH_WEIGHT_DETAILS, weights[1]); >+ } >+ } >+ } >+ >+ @Override >+ public void setVisible(boolean visible) { >+ if (!visible) { >+ persistSettings(getShell()); >+ } >+ super.setVisible(visible); >+ } >+ >+ @Override >+ protected void createContent(Composite parent) { >+ >+ fSashForm = new SashForm(parent, parent.getStyle()); >+ fSashForm.setOrientation(SWT.VERTICAL); >+ >+ // update presentation context >+ AbstractDebugView view = getViewToEmulate(); >+ IPresentationContext context = new PresentationContext(IDsfDebugUIConstants.ID_EXPRESSION_HOVER); >+ if (view != null) { >+ // copy over properties >+ IPresentationContext copy = ((TreeModelViewer)view.getViewer()).getPresentationContext(); >+ try { >+ String[] properties = copy.getProperties(); >+ for (int i = 0; i < properties.length; i++) { >+ String key = properties[i]; >+ context.setProperty(key, copy.getProperty(key)); >+ } >+ } catch (NoSuchMethodError e) { >+ // ignore >+ } >+ } >+ >+ fViewer = new TreeModelViewer(fSashForm, SWT.NO_TRIM | SWT.MULTI | SWT.VIRTUAL, context); >+ fViewer.setAutoExpandLevel(1); >+ >+ if (view != null) { >+ // copy over filters >+ StructuredViewer structuredViewer = (StructuredViewer) view.getViewer(); >+ if (structuredViewer != null) { >+ ViewerFilter[] filters = structuredViewer.getFilters(); >+ for (int i = 0; i < filters.length; i++) { >+ fViewer.addFilter(filters[i]); >+ } >+ } >+ } >+ fInputService = new ViewerInputService(fViewer, this); >+ >+ fDetailPaneComposite = SWTFactory.createComposite(fSashForm, 1, 1, GridData.FILL_BOTH); >+ Layout layout = fDetailPaneComposite.getLayout(); >+ if (layout instanceof GridLayout) { >+ GridLayout gl = (GridLayout) layout; >+ gl.marginHeight = 0; >+ gl.marginWidth = 0; >+ } >+ >+ fDetailPane = new DetailPaneProxy(new DetailPaneContainer()); >+ fDetailPane.display(null); // Bring up the default pane so the user doesn't see an empty composite >+ >+ fTree = fViewer.getTree(); >+ fTree.addSelectionListener(new SelectionListener() { >+ public void widgetSelected(SelectionEvent e) { >+ fDetailPane.display((IStructuredSelection)fViewer.getSelection()); >+ } >+ public void widgetDefaultSelected(SelectionEvent e) {} >+ }); >+ >+ initSashWeights(); >+ >+ // add update listener to auto-select and display details of root expression >+ fViewer.addViewerUpdateListener(new IViewerUpdateListener() { >+ public void viewerUpdatesComplete() { >+ } >+ public void viewerUpdatesBegin() { >+ } >+ public void updateStarted(IViewerUpdate update) { >+ } >+ public void updateComplete(IViewerUpdate update) { >+ if (update instanceof IChildrenUpdate) { >+ fViewer.removeViewerUpdateListener(this); >+ fViewer.getDisplay().timerExec(100, new Runnable() { >+ public void run() { >+ TreeSelection selection = new TreeSelection(fViewer.getTopElementPath()); >+ fViewer.setSelection(selection); >+ fDetailPane.display(selection); >+ }}); >+ } >+ } >+ }); >+ >+ setBackgroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); >+ } >+ >+ >+ /** >+ * Attempts to find an appropriate view to emulate, this will either be the >+ * variables view or the expressions view. >+ * @return a view to emulate or <code>null</code> >+ */ >+ private AbstractDebugView getViewToEmulate() { >+ IWorkbenchPage page = DsfUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); >+ AbstractDebugView expressionsView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW); >+ if (expressionsView != null && expressionsView.isVisible()) { >+ return expressionsView; >+ } >+ AbstractDebugView variablesView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_VARIABLE_VIEW); >+ if (variablesView != null && variablesView.isVisible()) { >+ return variablesView; >+ } >+ if (expressionsView != null) { >+ return expressionsView; >+ } >+ return variablesView; >+ } >+ >+ /** >+ * Initializes the sash form weights from the preference store (using default values if >+ * no sash weights were stored previously). >+ */ >+ protected void initSashWeights(){ >+ IDialogSettings settings = getDialogSettings(false); >+ if (settings != null) { >+ int tree = getIntSetting(settings, SASH_WEIGHT_TREE); >+ if (tree > 0) { >+ int details = getIntSetting(settings, SASH_WEIGHT_DETAILS); >+ if (details > 0) { >+ fSashForm.setWeights(new int[]{tree, details}); >+ } >+ } >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.text.AbstractInformationControl#setBackgroundColor(org.eclipse.swt.graphics.Color) >+ */ >+ @Override >+ public void setBackgroundColor(Color background) { >+ super.setBackgroundColor(background); >+ fDetailPaneComposite.setBackground(background); >+ fTree.setBackground(background); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.text.AbstractInformationControl#setFocus() >+ */ >+ @Override >+ public void setFocus() { >+ super.setFocus(); >+ fTree.setFocus(); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.text.IInformationControlExtension#hasContents() >+ */ >+ public boolean hasContents() { >+ return fVariable != null; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object) >+ */ >+ public void setInput(Object input) { >+ if (input instanceof IExpressionDMContext) { >+ fVariable = input; >+ fInputService.resolveViewerInput(input); >+ } else if (input instanceof IVariable) { >+ fVariable = input; >+ fViewer.setInput(new TreeRoot()); >+ } >+ } >+ >+ @Override >+ public IInformationControlCreator getInformationPresenterControlCreator() { >+ return new ExpressionInformationControlCreator() { >+ @Override >+ public IInformationControl createInformationControl(Shell shell) { >+ return new ExpressionInformationControl(shell, true); >+ } >+ }; >+ } >+ >+ public void viewerInputComplete(IViewerInputUpdate update) { >+ fViewer.setInput(fVariable = update.getInputElement()); >+ } >+ >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell) >+ */ >+ public IInformationControl createInformationControl(Shell parent) { >+ return new ExpressionInformationControl(parent, false); >+ } >+ >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
aleherb+eclipse
:
iplog-
Actions:
View
|
Diff
Attachments on
bug 255026
:
151809
|
154482
|
159709