Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 255026 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbAdapterFactory.java (-2 / +4 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
2
 * Copyright (c) 2006, 2009 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 67-72 Link Here
67
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
67
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
68
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
68
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
69
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory;
69
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelSelectionPolicyFactory;
70
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputProvider;
70
import org.eclipse.debug.ui.contexts.ISuspendTrigger;
71
import org.eclipse.debug.ui.contexts.ISuspendTrigger;
71
import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
72
import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
72
73
Lines 115-121 Link Here
115
            session.registerModelAdapter(SteppingController.class, fSteppingController);
116
            session.registerModelAdapter(SteppingController.class, fSteppingController);
116
117
117
            fViewModelAdapter = new GdbViewModelAdapter(session, fSteppingController);
118
            fViewModelAdapter = new GdbViewModelAdapter(session, fSteppingController);
118
119
			session.registerModelAdapter(IViewerInputProvider.class, fViewModelAdapter);
120
			
119
            if (launch.getSourceLocator() instanceof ISourceLookupDirector) {
121
            if (launch.getSourceLocator() instanceof ISourceLookupDirector) {
120
                fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
122
                fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
121
            } else {
123
            } else {
(-)src/org/eclipse/cdt/dsf/gdb/internal/ui/GdbDebugTextHover.java (+4 lines)
Lines 25-28 Link Here
25
        return GdbLaunchDelegate.GDB_DEBUG_MODEL_ID;
25
        return GdbLaunchDelegate.GDB_DEBUG_MODEL_ID;
26
    }
26
    }
27
27
28
    @Override
29
    protected boolean useExpressionExplorer() {
30
    	return true;
31
    }
28
}
32
}
(-)src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java (-2 / +4 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
2
 * Copyright (c) 2006, 2009 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 11-16 Link Here
11
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
11
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
12
12
13
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
13
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
14
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
14
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
15
import org.eclipse.cdt.dsf.debug.ui.viewmodel.AbstractDebugVMAdapter;
15
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
16
import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController;
16
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
17
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
Lines 28-34 Link Here
28
 * 
29
 * 
29
 */
30
 */
30
@ThreadSafe
31
@ThreadSafe
31
@SuppressWarnings("restriction")
32
public class GdbViewModelAdapter extends AbstractDebugVMAdapter
32
public class GdbViewModelAdapter extends AbstractDebugVMAdapter
33
{
33
{
34
    public GdbViewModelAdapter(DsfSession session, SteppingController controller) {
34
    public GdbViewModelAdapter(DsfSession session, SteppingController controller) {
Lines 52-57 Link Here
52
            return new RegisterVMProvider(this, context, getSession());
52
            return new RegisterVMProvider(this, context, getSession());
53
        } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
53
        } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
54
            return new ExpressionVMProvider(this, context, getSession());
54
            return new ExpressionVMProvider(this, context, getSession());
55
        } else if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(context.getId()) ) {
56
            return new ExpressionVMProvider(this, context, getSession());
55
        } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
57
        } else if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) {
56
            return new ModulesVMProvider(this, context, getSession());
58
            return new ModulesVMProvider(this, context, getSession());
57
        }
59
        }
(-)src/org/eclipse/cdt/dsf/debug/internal/ui/ExpressionInformationControlCreator.java (+441 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *     Wind River Systems - adapted for DSF
11
 *******************************************************************************/
12
package org.eclipse.cdt.dsf.debug.internal.ui;
13
14
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
15
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
16
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.debug.core.model.IVariable;
19
import org.eclipse.debug.internal.ui.SWTFactory;
20
import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider;
21
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
22
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
23
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputRequestor;
24
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
25
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
26
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener;
27
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
28
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
29
import org.eclipse.debug.internal.ui.viewers.model.provisional.ViewerInputService;
30
import org.eclipse.debug.internal.ui.views.variables.details.DefaultDetailPane;
31
import org.eclipse.debug.internal.ui.views.variables.details.DetailPaneProxy;
32
import org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer;
33
import org.eclipse.debug.ui.AbstractDebugView;
34
import org.eclipse.debug.ui.IDebugUIConstants;
35
import org.eclipse.jface.dialogs.IDialogSettings;
36
import org.eclipse.jface.text.AbstractInformationControl;
37
import org.eclipse.jface.text.IInformationControl;
38
import org.eclipse.jface.text.IInformationControlCreator;
39
import org.eclipse.jface.text.IInformationControlExtension2;
40
import org.eclipse.jface.viewers.IStructuredSelection;
41
import org.eclipse.jface.viewers.StructuredViewer;
42
import org.eclipse.jface.viewers.TreeSelection;
43
import org.eclipse.jface.viewers.ViewerFilter;
44
import org.eclipse.swt.SWT;
45
import org.eclipse.swt.custom.SashForm;
46
import org.eclipse.swt.events.SelectionEvent;
47
import org.eclipse.swt.events.SelectionListener;
48
import org.eclipse.swt.graphics.Color;
49
import org.eclipse.swt.graphics.Point;
50
import org.eclipse.swt.layout.GridData;
51
import org.eclipse.swt.layout.GridLayout;
52
import org.eclipse.swt.widgets.Composite;
53
import org.eclipse.swt.widgets.Layout;
54
import org.eclipse.swt.widgets.Shell;
55
import org.eclipse.swt.widgets.Tree;
56
import org.eclipse.ui.IWorkbenchPage;
57
import org.eclipse.ui.IWorkbenchPartSite;
58
59
/**
60
 * Creates an information control to display an expression in a hover control.
61
 * <br/> This class is derivative work from JDT's <code>ExpressionInformationControlCreator</code>.
62
 * 
63
 * @noextend This class is not intended to be subclassed by clients.
64
 * 
65
 * @since 2.1
66
 */
67
@SuppressWarnings("restriction")
68
public class ExpressionInformationControlCreator implements IInformationControlCreator {
69
70
	class ExpressionInformationControl extends AbstractInformationControl implements IInformationControlExtension2, IViewerInputRequestor {
71
72
		/**
73
		 * Dialog setting key for height
74
		 */
75
		private static final String HEIGHT = "HEIGHT"; //$NON-NLS-1$
76
77
		/**
78
		 * Dialog setting key for width. 
79
		 */
80
		private static final String WIDTH = "WIDTH"; //$NON-NLS-1$
81
82
		/**
83
		 * Dialog setting key for tree sash weight
84
		 */
85
		private static final String SASH_WEIGHT_TREE = "SashWeightTree"; //$NON-NLS-1$
86
87
		/**
88
		 * Dialog setting key for details sash weight
89
		 */
90
		private static final String SASH_WEIGHT_DETAILS = "SashWeightDetails"; //$NON-NLS-1$		
91
92
		/**
93
		 * Variable to display.
94
		 */
95
		private Object fVariable;
96
97
		private TreeModelViewer fViewer;
98
		private SashForm fSashForm;
99
		private Composite fDetailPaneComposite;
100
		private DetailPaneProxy fDetailPane;
101
		private Tree fTree;
102
103
		private ViewerInputService fInputService;
104
105
		/**
106
		 * Creates the content for the root element of the tree viewer in the hover
107
		 */
108
		private class TreeRoot extends ElementContentProvider {
109
			@Override
110
			protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
111
				return 1;
112
			}
113
			@Override
114
			protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
115
				return new Object[] { fVariable };
116
			}
117
			@Override
118
			protected boolean supportsContextId(String id) {
119
				return true;
120
			}
121
		}
122
123
		/**
124
		 * Inner class implementing IDetailPaneContainer methods.  Handles changes to detail
125
		 * pane and provides limited access to the detail pane proxy.
126
		 */
127
		private class DetailPaneContainer implements IDetailPaneContainer {
128
129
			/*
130
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentPaneID()
131
			 */
132
			public String getCurrentPaneID() {
133
				return fDetailPane.getCurrentPaneID();
134
			}
135
136
			/*
137
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getCurrentSelection()
138
			 */
139
			public IStructuredSelection getCurrentSelection() {
140
				return (IStructuredSelection)fViewer.getSelection();
141
			}
142
143
			/*
144
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#refreshDetailPaneContents()
145
			 */
146
			public void refreshDetailPaneContents() {		
147
				fDetailPane.display(getCurrentSelection());
148
			}
149
150
			/*
151
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getParentComposite()
152
			 */
153
			public Composite getParentComposite() {
154
				return fDetailPaneComposite;
155
			}
156
157
			/*
158
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#getWorkbenchPartSite()
159
			 */
160
			public IWorkbenchPartSite getWorkbenchPartSite() {
161
				return null;
162
			}
163
164
			/*
165
			 * @see org.eclipse.debug.internal.ui.views.variables.details.IDetailPaneContainer#paneChanged(java.lang.String)
166
			 */
167
			public void paneChanged(String newPaneID) {
168
				if (DefaultDetailPane.ID.equals(newPaneID)){
169
					fDetailPane.getCurrentControl().setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
170
				}
171
			}
172
173
		}
174
175
		/**
176
		 * Constructs a new control in the given shell.
177
		 * 
178
		 * @param parentShell shell
179
		 * @param resize whether resize is supported
180
		 */
181
		ExpressionInformationControl(Shell parentShell, boolean resize) {
182
			super(parentShell, resize);
183
			create();
184
		}
185
186
		@Override
187
		public Point computeSizeHint() {
188
			IDialogSettings settings = getDialogSettings(false);
189
			if (settings != null) {
190
				int x = getIntSetting(settings, WIDTH);
191
				if (x > 0) {
192
					int y = getIntSetting(settings, HEIGHT);
193
					if (y > 0) {
194
						return new Point(x,y);
195
					}
196
				}
197
			}
198
			return super.computeSizeHint();
199
		}
200
201
		/**
202
		 * Returns the dialog settings for this hover or <code>null</code> if none
203
		 * 
204
		 * @param create whether to create the settings
205
		 */
206
		private IDialogSettings getDialogSettings(boolean create) {
207
			IDialogSettings settings = DsfUIPlugin.getDefault().getDialogSettings();
208
			IDialogSettings section = settings.getSection(this.getClass().getName());
209
			if (section == null & create) {
210
				section = settings.addNewSection(this.getClass().getName());
211
			}
212
			return section;
213
		}
214
215
		/**
216
		 * Returns an integer value in the given dialog settings or -1 if none.
217
		 * 
218
		 * @param settings dialog settings
219
		 * @param key key
220
		 * @return value or -1 if not present
221
		 */
222
		private int getIntSetting(IDialogSettings settings, String key) {
223
			try {
224
				return settings.getInt(key);
225
			} catch (NumberFormatException e) {
226
				return -1;
227
			}
228
		}
229
230
		@Override
231
		public void dispose() {
232
			persistSettings(getShell());
233
			super.dispose();
234
		}
235
236
		/**
237
		 * Persists dialog settings.
238
		 * 
239
		 * @param shell
240
		 */
241
		private void persistSettings(Shell shell) {
242
			if (shell != null && !shell.isDisposed()) {
243
				if (isResizable()) {
244
					IDialogSettings settings = getDialogSettings(true);
245
					Point size = shell.getSize();
246
					settings.put(WIDTH, size.x);
247
					settings.put(HEIGHT, size.y);
248
					int[] weights = fSashForm.getWeights();
249
					settings.put(SASH_WEIGHT_TREE, weights[0]);
250
					settings.put(SASH_WEIGHT_DETAILS, weights[1]);
251
				}
252
			}
253
		}
254
255
		@Override
256
		public void setVisible(boolean visible) {
257
			if (!visible) {		
258
				persistSettings(getShell());
259
			}
260
			super.setVisible(visible);
261
		}
262
263
		@Override
264
		protected void createContent(Composite parent) {
265
266
			fSashForm = new SashForm(parent, parent.getStyle());
267
			fSashForm.setOrientation(SWT.VERTICAL);
268
269
			// update presentation context
270
			AbstractDebugView view = getViewToEmulate();
271
			IPresentationContext context = new PresentationContext(IDsfDebugUIConstants.ID_EXPRESSION_HOVER);
272
			if (view != null) {
273
				// copy over properties
274
				IPresentationContext copy = ((TreeModelViewer)view.getViewer()).getPresentationContext();
275
				try {
276
					String[] properties = copy.getProperties();
277
					for (int i = 0; i < properties.length; i++) {
278
						String key = properties[i];
279
						context.setProperty(key, copy.getProperty(key));
280
					}
281
				} catch (NoSuchMethodError e) {
282
					// ignore
283
				}
284
			}
285
286
			fViewer = new TreeModelViewer(fSashForm, SWT.NO_TRIM | SWT.MULTI | SWT.VIRTUAL, context);
287
			fViewer.setAutoExpandLevel(1);
288
289
			if (view != null) {
290
				// copy over filters
291
				StructuredViewer structuredViewer = (StructuredViewer) view.getViewer();
292
				if (structuredViewer != null) {
293
					ViewerFilter[] filters = structuredViewer.getFilters();
294
					for (int i = 0; i < filters.length; i++) {
295
						fViewer.addFilter(filters[i]);
296
					}
297
				}
298
			}
299
			fInputService = new ViewerInputService(fViewer, this);
300
301
			fDetailPaneComposite = SWTFactory.createComposite(fSashForm, 1, 1, GridData.FILL_BOTH);
302
			Layout layout = fDetailPaneComposite.getLayout();
303
			if (layout instanceof GridLayout) {
304
				GridLayout gl = (GridLayout) layout;
305
				gl.marginHeight = 0;
306
				gl.marginWidth = 0;
307
			}
308
309
			fDetailPane = new DetailPaneProxy(new DetailPaneContainer());
310
			fDetailPane.display(null); // Bring up the default pane so the user doesn't see an empty composite
311
312
			fTree = fViewer.getTree();
313
			fTree.addSelectionListener(new SelectionListener() {
314
				public void widgetSelected(SelectionEvent e) {
315
					fDetailPane.display((IStructuredSelection)fViewer.getSelection());
316
				}
317
				public void widgetDefaultSelected(SelectionEvent e) {}
318
			});
319
320
			initSashWeights();
321
322
			// add update listener to auto-select and display details of root expression
323
			fViewer.addViewerUpdateListener(new IViewerUpdateListener() {
324
				public void viewerUpdatesComplete() {
325
				}
326
				public void viewerUpdatesBegin() {
327
				}
328
				public void updateStarted(IViewerUpdate update) {
329
				}
330
				public void updateComplete(IViewerUpdate update) {
331
					if (update instanceof IChildrenUpdate) {
332
						fViewer.removeViewerUpdateListener(this);
333
						fViewer.getDisplay().timerExec(100, new Runnable() {
334
							public void run() {
335
								TreeSelection selection = new TreeSelection(fViewer.getTopElementPath());
336
								fViewer.setSelection(selection);
337
								fDetailPane.display(selection);
338
							}});
339
					}
340
				}
341
			});
342
343
			setBackgroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
344
		}
345
346
347
		/**
348
		 * Attempts to find an appropriate view to emulate, this will either be the
349
		 * variables view or the expressions view.
350
		 * @return a view to emulate or <code>null</code>
351
		 */
352
		private AbstractDebugView getViewToEmulate() {
353
			IWorkbenchPage page = DsfUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
354
			AbstractDebugView expressionsView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW);
355
			if (expressionsView != null && expressionsView.isVisible()) {
356
				return expressionsView;
357
			}
358
			AbstractDebugView variablesView = (AbstractDebugView) page.findView(IDebugUIConstants.ID_VARIABLE_VIEW);
359
			if (variablesView != null && variablesView.isVisible()) {
360
				return variablesView;
361
			}
362
			if (expressionsView != null) {
363
				return expressionsView;
364
			}
365
			return variablesView;
366
		}	
367
368
		/**
369
		 * Initializes the sash form weights from the preference store (using default values if 
370
		 * no sash weights were stored previously).
371
		 */
372
		protected void initSashWeights(){
373
			IDialogSettings settings = getDialogSettings(false);
374
			if (settings != null) {
375
				int tree = getIntSetting(settings, SASH_WEIGHT_TREE);
376
				if (tree > 0) {
377
					int details = getIntSetting(settings, SASH_WEIGHT_DETAILS);
378
					if (details > 0) {
379
						fSashForm.setWeights(new int[]{tree, details});
380
					}
381
				}
382
			}
383
		}
384
385
		@Override
386
		public void setBackgroundColor(Color background) {
387
			super.setBackgroundColor(background);
388
			fDetailPaneComposite.setBackground(background);
389
			fTree.setBackground(background);
390
		}
391
392
		@Override
393
		public void setFocus() {
394
			super.setFocus();
395
			fTree.setFocus();
396
		}
397
398
		/*
399
		 * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
400
		 */
401
		public boolean hasContents() {
402
			return fVariable != null;
403
		}
404
405
		/*
406
		 * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
407
		 */
408
		public void setInput(Object input) {
409
			if (input instanceof IExpressionDMContext) {
410
				fVariable = input;
411
				fInputService.resolveViewerInput(input);
412
			} else if (input instanceof IVariable) {
413
				fVariable = input;
414
				fViewer.setInput(new TreeRoot());
415
			}
416
		}
417
418
		@Override
419
		public IInformationControlCreator getInformationPresenterControlCreator() {
420
			return new ExpressionInformationControlCreator() {
421
				@Override
422
				public IInformationControl createInformationControl(Shell shell) {
423
					return new ExpressionInformationControl(shell, true);
424
				}
425
			};
426
		}
427
428
		public void viewerInputComplete(IViewerInputUpdate update) {
429
			fViewer.setInput(fVariable = update.getInputElement());
430
		}
431
432
	}
433
434
	/*
435
	 * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
436
	 */
437
	public IInformationControl createInformationControl(Shell parent) {
438
		return new ExpressionInformationControl(parent, false);
439
	}
440
441
}
(-)src/org/eclipse/cdt/dsf/debug/ui/AbstractDsfDebugTextHover.java (-2 / +73 lines)
Lines 10-18 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.cdt.dsf.debug.ui;
11
package org.eclipse.cdt.dsf.debug.ui;
12
12
13
import java.util.concurrent.Callable;
14
import java.util.concurrent.ExecutionException;
15
13
import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover;
16
import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover;
14
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
17
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
15
import org.eclipse.cdt.dsf.concurrent.Query;
18
import org.eclipse.cdt.dsf.concurrent.Query;
19
import org.eclipse.cdt.dsf.debug.internal.ui.ExpressionInformationControlCreator;
16
import org.eclipse.cdt.dsf.debug.service.IExpressions;
20
import org.eclipse.cdt.dsf.debug.service.IExpressions;
17
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
21
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
18
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
22
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
Lines 24-36 Link Here
24
import org.eclipse.cdt.dsf.service.DsfSession;
28
import org.eclipse.cdt.dsf.service.DsfSession;
25
import org.eclipse.core.runtime.IAdaptable;
29
import org.eclipse.core.runtime.IAdaptable;
26
import org.eclipse.debug.core.model.IDebugModelProvider;
30
import org.eclipse.debug.core.model.IDebugModelProvider;
31
import org.eclipse.jface.text.DefaultInformationControl;
32
import org.eclipse.jface.text.IInformationControl;
33
import org.eclipse.jface.text.IInformationControlCreator;
34
import org.eclipse.jface.text.IRegion;
35
import org.eclipse.jface.text.ITextHoverExtension2;
36
import org.eclipse.jface.text.ITextViewer;
37
import org.eclipse.swt.widgets.Shell;
38
import org.eclipse.ui.editors.text.EditorsUI;
27
39
28
/**
40
/**
29
 * An implementation of AbstractDebugTextHover using DSF services.
41
 * An implementation of AbstractDebugTextHover using DSF services
30
 * 
42
 * 
31
 * @since 2.1
43
 * @since 2.1
32
 */
44
 */
33
abstract public class AbstractDsfDebugTextHover extends AbstractDebugTextHover {
45
abstract public class AbstractDsfDebugTextHover extends AbstractDebugTextHover implements ITextHoverExtension2 {
34
46
35
    /**
47
    /**
36
     * Returns the debug model ID that this debug text hover is to be used for.
48
     * Returns the debug model ID that this debug text hover is to be used for.
Lines 121-124 Link Here
121
        return null;
133
        return null;
122
	}
134
	}
123
135
136
    /**
137
     * Returns whether the expression explorer information control should be used.
138
     * The default implementation returns <code>false</code>.
139
     */
140
    protected boolean useExpressionExplorer() {
141
    	return false;
142
    }
143
    
144
	@Override
145
	public IInformationControlCreator getHoverControlCreator() {
146
		if (useExpressionExplorer()) {
147
			return new ExpressionInformationControlCreator();
148
		} else {
149
			return new IInformationControlCreator() {
150
				public IInformationControl createInformationControl(Shell parent) {
151
					return new DefaultInformationControl(parent, EditorsUI.getTooltipAffordanceString());
152
				}
153
			};
154
		}
155
	}
156
157
	/*
158
	 * @see org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
159
	 */
160
	public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
161
    	final String simpleInfo = getHoverInfo(textViewer, hoverRegion);
162
		if (!useExpressionExplorer() || simpleInfo == null) {
163
    		return simpleInfo;
164
    	}
165
		// improved version using ExpressionInformationControlCreator
166
    	// see also getHoverControlCreator()
167
    	final String text;
168
		text= getExpressionText(textViewer, hoverRegion);
169
    	if (text != null && text.length() > 0) {
170
			final IFrameDMContext frameDmc = getFrame();
171
			final DsfSession dsfSession = DsfSession.getSession(frameDmc.getSessionId());
172
			Callable<IExpressionDMContext> callable = new Callable<IExpressionDMContext>() {
173
				public IExpressionDMContext call() throws Exception {
174
					DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), frameDmc.getSessionId());
175
					try {
176
						IExpressions expressions = tracker.getService(IExpressions.class);
177
						if (expressions != null) {
178
							return expressions.createExpression(frameDmc, text);
179
						}
180
						return null;
181
					} finally {
182
						tracker.dispose();
183
					}
184
				}
185
			};
186
			try {
187
				return dsfSession.getExecutor().submit(callable).get();
188
			} catch (InterruptedException e) {
189
			} catch (ExecutionException e) {
190
			}
191
    	}
192
    	return null;
193
	}
194
124
}
195
}
(-)src/org/eclipse/cdt/dsf/debug/ui/IDsfDebugUIConstants.java (-1 / +8 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
2
 * Copyright (c) 2006, 2009 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 79-82 Link Here
79
     * @since 2.0 
79
     * @since 2.0 
80
     */
80
     */
81
    public static final String PREF_COLOR_STALE_DATA_BACKGROUND= PLUGIN_ID + ".staledata.background"; //$NON-NLS-1$
81
    public static final String PREF_COLOR_STALE_DATA_BACKGROUND= PLUGIN_ID + ".staledata.background"; //$NON-NLS-1$
82
83
    /**
84
     * Presentation context id for the expression hover.
85
     * 
86
     * @since 2.1
87
     */
88
	public static final String ID_EXPRESSION_HOVER= PLUGIN_ID + ".expression_hover"; //$NON-NLS-1$
82
}
89
}
(-)src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/ExpressionVMProvider.java (-3 / +26 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
2
 * Copyright (c) 2006, 2009 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 19-24 Link Here
19
import org.eclipse.cdt.dsf.debug.service.ICachingService;
19
import org.eclipse.cdt.dsf.debug.service.ICachingService;
20
import org.eclipse.cdt.dsf.debug.service.IExpressions;
20
import org.eclipse.cdt.dsf.debug.service.IExpressions;
21
import org.eclipse.cdt.dsf.debug.service.IRegisters;
21
import org.eclipse.cdt.dsf.debug.service.IRegisters;
22
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
22
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
23
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
23
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
24
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
24
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
25
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
Lines 46-51 Link Here
46
import org.eclipse.debug.internal.core.IExpressionsListener2;
47
import org.eclipse.debug.internal.core.IExpressionsListener2;
47
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
48
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
48
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
49
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
50
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
49
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
51
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
50
import org.eclipse.jface.preference.IPreferenceStore;
52
import org.eclipse.jface.preference.IPreferenceStore;
51
import org.eclipse.jface.util.IPropertyChangeListener;
53
import org.eclipse.jface.util.IPropertyChangeListener;
Lines 210-217 Link Here
210
        /*
212
        /*
211
         * Now the Over-arching management node.
213
         * Now the Over-arching management node.
212
         */
214
         */
213
        ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this);
215
        if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(getPresentationContext().getId())) {
214
        addChildNodes(rootNode, new IVMNode[] {expressionManagerNode});
216
        	SingleExpressionVMNode expressionManagerNode = new SingleExpressionVMNode(this);
217
        	addChildNodes(rootNode, new IVMNode[] { expressionManagerNode });
218
        } else {
219
            ExpressionManagerVMNode expressionManagerNode = new ExpressionManagerVMNode(this);
220
            addChildNodes(rootNode, new IVMNode[] {expressionManagerNode});
221
        }
215
        
222
        
216
        /*
223
        /*
217
         *  The expression view wants to support fully all of the components of the register view.
224
         *  The expression view wants to support fully all of the components of the register view.
Lines 372-375 Link Here
372
            // Session disposed, ignore.
379
            // Session disposed, ignore.
373
        }
380
        }
374
    }
381
    }
382
383
    @Override
384
    public void update(IViewerInputUpdate update) {
385
        if (IDsfDebugUIConstants.ID_EXPRESSION_HOVER.equals(getPresentationContext().getId())) {
386
        	Object input = update.getElement();
387
        	if (input instanceof IExpressionDMContext) {
388
        		IExpressionDMContext dmc = (IExpressionDMContext) input;
389
        		SingleExpressionVMNode vmNode = (SingleExpressionVMNode) getChildVMNodes(getRootVMNode())[0];
390
        		vmNode.setExpression(dmc);
391
				update.setInputElement(vmNode.createVMContext(dmc));
392
        		update.done();
393
        		return;
394
        	}
395
        }
396
        super.update(update);
397
    }
375
}
398
}
(-)src/org/eclipse/cdt/dsf/debug/ui/viewmodel/expression/SingleExpressionVMNode.java (+327 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 Wind River Systems, Inc. and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.cdt.dsf.debug.ui.viewmodel.expression;
13
14
import java.util.LinkedList;
15
import java.util.List;
16
17
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
18
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
19
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
20
import org.eclipse.cdt.dsf.datamodel.IDMContext;
21
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
22
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
23
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionsChangedEvent;
24
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.InvalidExpressionVMContext;
25
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
26
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
27
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
28
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
29
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
30
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
31
import org.eclipse.debug.core.ILaunch;
32
import org.eclipse.debug.core.model.IDebugTarget;
33
import org.eclipse.debug.core.model.IExpression;
34
import org.eclipse.debug.core.model.IValue;
35
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
36
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
37
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
38
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
39
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
40
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
41
import org.eclipse.jface.viewers.TreePath;
42
43
/**
44
 * A VM node for displaying a single expression in the expression hover.
45
 */
46
public class SingleExpressionVMNode extends AbstractDMVMNode implements IElementLabelProvider {
47
48
	private static class RootDMVMContext extends AbstractVMContext implements IDMVMContext {
49
		private final IDMContext fDmc;
50
		public RootDMVMContext(IVMNode node, IDMContext dmc) {
51
			super(node);
52
			fDmc = dmc;
53
		}
54
		public IDMContext getDMContext() {
55
			return fDmc;
56
		}
57
		@SuppressWarnings("rawtypes")
58
		@Override
59
		public Object getAdapter(Class adapter) {
60
            Object superAdapter = super.getAdapter(adapter);
61
            if (superAdapter != null) {
62
                return superAdapter;
63
            } else {
64
                // Delegate to the Data Model to find the context.
65
                if (adapter.isInstance(fDmc)) {
66
                    return fDmc;
67
                } else {
68
                    return fDmc.getAdapter(adapter);
69
                }
70
            }
71
		}
72
73
		@Override
74
		public boolean equals(Object other) {
75
            if (!(other instanceof RootDMVMContext)) return false;
76
            RootDMVMContext otherVmc = (RootDMVMContext)other;
77
            return getVMNode().equals(otherVmc.getVMNode()) &&
78
                   fDmc.equals(otherVmc.fDmc);
79
		}
80
81
		@Override
82
		public int hashCode() {
83
            return getVMNode().hashCode() + fDmc.hashCode(); 
84
		}
85
86
	}
87
88
	private static class SimpleExpression implements IExpression {
89
		private String fExpressionText;
90
		SimpleExpression(String text) {
91
			fExpressionText = text;
92
		}
93
		public void dispose() {
94
		}
95
		public IDebugTarget getDebugTarget() {
96
			return null;
97
		}
98
		public String getExpressionText() {
99
			return fExpressionText;
100
		}
101
		public IValue getValue() {
102
			return null;
103
		}
104
		public ILaunch getLaunch() {
105
			return null;
106
		}
107
		public String getModelIdentifier() {
108
			return null;
109
		}
110
		@SuppressWarnings("rawtypes")
111
		public Object getAdapter(Class adapter) {
112
			return null;
113
		}
114
115
	}
116
117
	private static class SingleExpressionManager {
118
		private static final IExpression[] NO_EXPRESSIONS = {};
119
		IExpression fExpression;
120
		public IExpression[] getExpressions() {
121
			if (fExpression != null) {
122
				return new IExpression[] { fExpression };
123
			}
124
			return NO_EXPRESSIONS;
125
		}
126
		public void setExpression(IExpression expression) {
127
			fExpression = expression;
128
		}
129
130
	}
131
132
	/** Local reference to the expression manager */ 
133
    private final SingleExpressionManager fManager;
134
    
135
    public SingleExpressionVMNode(ExpressionVMProvider provider) {
136
        super(provider, provider.getSession(), IExpressionDMContext.class);
137
        fManager = new SingleExpressionManager();
138
    }
139
140
	@Override
141
    public String toString() {
142
        return "SingleExpressionVMNode";  //$NON-NLS-1$ 
143
    }
144
    
145
    private ExpressionVMProvider getExpressionVMProvider() {
146
        return (ExpressionVMProvider)getVMProvider();
147
    }
148
149
    @Override
150
	public void update(IHasChildrenUpdate[] updates) {
151
        // Test availability of children based on whether there are any expressions 
152
        // in the manager.  We assume that the getExpressions() will just read 
153
        // local state data, so we don't bother using a job to perform this 
154
        // operation.
155
        for (int i = 0; i < updates.length; i++) {
156
            updates[i].setHasChilren(fManager.getExpressions().length != 0);
157
            updates[i].done();
158
        }
159
    }
160
    
161
    @Override
162
	public void update(IChildrenCountUpdate[] updates) {
163
        for (IChildrenCountUpdate update : updates) {
164
            if (!checkUpdate(update)) continue;
165
166
            // We assume that the getExpressions() will just read local state data,
167
            // so we don't bother using a job to perform this operation.
168
            update.setChildCount(fManager.getExpressions().length);
169
            update.done();
170
        }
171
    }
172
    
173
    @Override
174
	public void update(final IChildrenUpdate[] updates) {
175
        for (IChildrenUpdate update : updates) {
176
            doUpdateChildren(update);
177
        }        
178
    }
179
    
180
    public void doUpdateChildren(final IChildrenUpdate update) {
181
        final IExpression[] expressions = fManager.getExpressions();
182
        
183
        // For each (expression) element in update, find the layout node that can 
184
        // parse it.  And for each expression that has a corresponding layout node, 
185
        // call IExpressionLayoutNode#getElementForExpression to generate a VMC.
186
        // Since the last is an async call, we need to create a multi-RM to wait
187
        // for all the calls to complete.
188
        final CountingRequestMonitor multiRm = new ViewerCountingRequestMonitor(getVMProvider().getExecutor(), update);
189
        int multiRmCount = 0;
190
        
191
        int lowOffset= update.getOffset();
192
        if (lowOffset < 0) {
193
        	lowOffset = 0;
194
        }
195
		int length= update.getLength();
196
		if (length <= 0) {
197
			length = expressions.length;
198
		}
199
		final int highOffset= lowOffset + length;
200
		for (int i = lowOffset; i < highOffset && i < expressions.length + 1; i++) {
201
            if (i < expressions.length) {
202
                multiRmCount++;
203
                final int childIndex = i;
204
                final IExpression expression = expressions[i];
205
                // getElementForExpression() accepts a IElementsUpdate as an argument.
206
                // Construct an instance of VMElementsUpdate which will call a 
207
                // the request monitor when it is finished.  The request monitor
208
                // will in turn set the element in the update argument in this method. 
209
                ((ExpressionVMProvider)getVMProvider()).update(
210
                    new VMExpressionUpdate(
211
                        update, expression,
212
                        new DataRequestMonitor<Object>(getVMProvider().getExecutor(), multiRm) {
213
                            @Override
214
                            protected void handleSuccess() {
215
                                update.setChild(getData(), childIndex);
216
                                multiRm.done();
217
                            } 
218
                            
219
                            @Override
220
                            protected void handleError() {
221
                                update.setChild(new InvalidExpressionVMContext(SingleExpressionVMNode.this, expression), childIndex);                                
222
                                multiRm.done();
223
                            }
224
                        })
225
                    );
226
            }
227
        }
228
229
        // If no expressions were parsed, we're finished.
230
        // Set the count to the counting RM.
231
        multiRm.setDoneCount(multiRmCount);
232
    }
233
234
    public void update(ILabelUpdate[] updates) {
235
        // The label update handler only handles labels for the invalid expression VMCs.
236
        // The expression layout nodes are responsible for supplying label providers 
237
        // for their VMCs.
238
        for (ILabelUpdate update : updates) {
239
        	update.done();
240
        }
241
    }
242
243
    public int getDeltaFlags(Object event) {
244
        int retVal = 0;
245
246
        // Add a flag if the list of expressions in the global expression manager has changed.
247
        if (event instanceof ExpressionsChangedEvent) {
248
            retVal |= IModelDelta.ADDED | IModelDelta.REMOVED | IModelDelta.INSERTED | IModelDelta.CONTENT ;
249
        }
250
251
        for (IExpression expression : fManager.getExpressions()) {
252
            retVal |= getExpressionVMProvider().getDeltaFlagsForExpression(expression, event);
253
        }
254
        
255
        return retVal;
256
    }
257
258
    public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
259
        if (event instanceof ExpressionsChangedEvent) {
260
            buildDeltaForExpressionsChangedEvent((ExpressionsChangedEvent)event, parentDelta, nodeOffset, requestMonitor);
261
        } else {
262
        
263
            // For each expression, find its corresponding node and ask that
264
            // layout node for its delta flags for given event.  If there are delta flags to be 
265
            // generated, call the asynchronous method to do so.
266
            CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor);
267
            
268
            int buildDeltaForExpressionCallCount = 0;
269
            
270
            IExpression[] expressions = fManager.getExpressions();
271
            for (int i = 0; i < expressions.length; i++ ) {
272
                int flags = getExpressionVMProvider().getDeltaFlagsForExpression(expressions[i], event);
273
                // If the given expression has no delta flags, skip it.
274
                if (flags == IModelDelta.NO_CHANGE) continue;
275
    
276
                int elementOffset = nodeOffset >= 0 ? nodeOffset + i : -1;
277
                getExpressionVMProvider().buildDeltaForExpression(
278
                    expressions[i], elementOffset, event, parentDelta, getTreePathFromDelta(parentDelta), 
279
                    new RequestMonitor(getExecutor(), multiRm));
280
                buildDeltaForExpressionCallCount++;
281
            }
282
            
283
            multiRm.setDoneCount(buildDeltaForExpressionCallCount);
284
        }
285
    }
286
    
287
    private void buildDeltaForExpressionsChangedEvent(ExpressionsChangedEvent event, VMDelta parentDelta, 
288
        int nodeOffset, RequestMonitor requestMonitor) 
289
    {
290
        CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), requestMonitor);
291
        for (int i = 0; i < event.getExpressions().length; i++) {
292
            int expIndex = event.getIndex() != -1 
293
                ? nodeOffset + event.getIndex() + i 
294
                : -1; 
295
            getExpressionVMProvider().buildDeltaForExpression(
296
                event.getExpressions()[i], expIndex, event, parentDelta, getTreePathFromDelta(parentDelta), 
297
                new RequestMonitor(getExecutor(), multiRm));                
298
        }
299
        multiRm.setDoneCount(event.getExpressions().length);
300
    }
301
        
302
    private TreePath getTreePathFromDelta(IModelDelta delta) {
303
        List<Object> elementList = new LinkedList<Object>();
304
        IModelDelta listDelta = delta;
305
        elementList.add(0, listDelta.getElement());
306
        while (listDelta.getParentDelta() != null) {
307
            elementList.add(0, listDelta.getElement());
308
            listDelta = listDelta.getParentDelta();
309
        }
310
        return new TreePath(elementList.toArray());
311
    }
312
313
	@Override
314
	protected void updateElementsInSessionThread(IChildrenUpdate update) {
315
        doUpdateChildren(update);
316
	}
317
318
    @Override
319
	public IDMVMContext createVMContext(IDMContext dmc) {
320
        return new RootDMVMContext(getVMProvider().getRootVMNode(), dmc);
321
    }
322
323
    void setExpression(IExpressionDMContext dmc) {
324
		String text = dmc.getExpression();
325
		fManager.setExpression(new SimpleExpression(text));
326
    }
327
}

Return to bug 255026