tmf: Update Javadoc throughout tmf.ui
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / TimeGraphCombo.java
CommitLineData
fb5cad3d
PT
1/*******************************************************************************\r
2 * Copyright (c) 2012 Ericsson\r
013a5f1c 3 *\r
fb5cad3d
PT
4 * All rights reserved. This program and the accompanying materials are\r
5 * made available under the terms of the Eclipse Public License v1.0 which\r
6 * accompanies this distribution, and is available at\r
7 * http://www.eclipse.org/legal/epl-v10.html\r
013a5f1c 8 *\r
fb5cad3d
PT
9 * Contributors:\r
10 * Patrick Tasse - Initial API and implementation\r
11 *******************************************************************************/\r
12\r
13package org.eclipse.linuxtools.tmf.ui.widgets.timegraph;\r
14\r
15import java.util.ArrayList;\r
16import java.util.Arrays;\r
17import java.util.HashMap;\r
18\r
19import org.eclipse.jface.viewers.ILabelProviderListener;\r
20import org.eclipse.jface.viewers.ISelectionChangedListener;\r
21import org.eclipse.jface.viewers.IStructuredSelection;\r
22import org.eclipse.jface.viewers.ITableLabelProvider;\r
23import org.eclipse.jface.viewers.ITreeContentProvider;\r
24import org.eclipse.jface.viewers.ITreeViewerListener;\r
25import org.eclipse.jface.viewers.SelectionChangedEvent;\r
26import org.eclipse.jface.viewers.StructuredSelection;\r
27import org.eclipse.jface.viewers.TreeExpansionEvent;\r
28import org.eclipse.jface.viewers.TreeViewer;\r
29import org.eclipse.jface.viewers.Viewer;\r
30import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;\r
31import org.eclipse.swt.SWT;\r
32import org.eclipse.swt.custom.SashForm;\r
33import org.eclipse.swt.events.ControlAdapter;\r
34import org.eclipse.swt.events.ControlEvent;\r
b83af2c3 35import org.eclipse.swt.events.MouseEvent;\r
e9f70626 36import org.eclipse.swt.events.MouseTrackAdapter;\r
b83af2c3 37import org.eclipse.swt.events.MouseWheelListener;\r
519ea816
PT
38import org.eclipse.swt.events.PaintEvent;\r
39import org.eclipse.swt.events.PaintListener;\r
fb5cad3d
PT
40import org.eclipse.swt.events.SelectionAdapter;\r
41import org.eclipse.swt.events.SelectionEvent;\r
42import org.eclipse.swt.graphics.Image;\r
43import org.eclipse.swt.graphics.Point;\r
44import org.eclipse.swt.layout.FillLayout;\r
45import org.eclipse.swt.widgets.Composite;\r
46import org.eclipse.swt.widgets.Display;\r
47import org.eclipse.swt.widgets.Event;\r
48import org.eclipse.swt.widgets.Listener;\r
49import org.eclipse.swt.widgets.Slider;\r
50import org.eclipse.swt.widgets.Tree;\r
51import org.eclipse.swt.widgets.TreeColumn;\r
52import org.eclipse.swt.widgets.TreeItem;\r
53\r
013a5f1c
AM
54/**\r
55 * Time graph "combo" view (with the list/tree on the left and the gantt chart\r
56 * on the right)\r
57 *\r
58 * @version 1.0\r
59 * @author Patrick Tasse\r
60 */\r
fb5cad3d
PT
61public class TimeGraphCombo extends Composite {\r
62\r
63 // ------------------------------------------------------------------------\r
64 // Constants\r
65 // ------------------------------------------------------------------------\r
66\r
67 private static final Object FILLER = new Object();\r
68\r
69 // ------------------------------------------------------------------------\r
70 // Fields\r
71 // ------------------------------------------------------------------------\r
72\r
73 // The tree viewer\r
74 private TreeViewer fTreeViewer;\r
75\r
76 // The time viewer\r
77 private TimeGraphViewer fTimeGraphViewer;\r
78\r
79 // The selection listener map\r
013a5f1c 80 private final HashMap<ITimeGraphSelectionListener, SelectionListenerWrapper> fSelectionListenerMap = new HashMap<ITimeGraphSelectionListener, SelectionListenerWrapper>();\r
fb5cad3d
PT
81\r
82 // Flag to block the tree selection changed listener when triggered by the time graph combo\r
83 private boolean fInhibitTreeSelection = false;\r
84\r
85 // Number of filler rows used by the tree content provider\r
549f3c43 86 private int fNumFillerRows;\r
fb5cad3d 87\r
519ea816
PT
88 // Calculated item height for Linux workaround\r
89 private int fLinuxItemHeight = 0;\r
90\r
fb5cad3d
PT
91 // ------------------------------------------------------------------------\r
92 // Classes\r
93 // ------------------------------------------------------------------------\r
94\r
549f3c43
PT
95 /**\r
96 * The TreeContentProviderWrapper is used to insert filler items after\r
97 * the elements of the tree's real content provider.\r
98 */\r
fb5cad3d 99 private class TreeContentProviderWrapper implements ITreeContentProvider {\r
013a5f1c 100 private final ITreeContentProvider contentProvider;\r
fb5cad3d
PT
101\r
102 public TreeContentProviderWrapper(ITreeContentProvider contentProvider) {\r
103 this.contentProvider = contentProvider;\r
104 }\r
105\r
106 @Override\r
107 public void dispose() {\r
108 contentProvider.dispose();\r
109 }\r
110\r
111 @Override\r
112 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
113 contentProvider.inputChanged(viewer, oldInput, newInput);\r
114 }\r
115\r
116 @Override\r
117 public Object[] getElements(Object inputElement) {\r
118 Object[] elements = contentProvider.getElements(inputElement);\r
119 // add filler elements to ensure alignment with time analysis viewer\r
120 Object[] oElements = Arrays.copyOf(elements, elements.length + fNumFillerRows, new Object[0].getClass());\r
121 for (int i = 0; i < fNumFillerRows; i++) {\r
122 oElements[elements.length + i] = FILLER;\r
123 }\r
124 return oElements;\r
125 }\r
126\r
127 @Override\r
128 public Object[] getChildren(Object parentElement) {\r
129 if (parentElement instanceof ITimeGraphEntry) {\r
130 return contentProvider.getChildren(parentElement);\r
131 } else {\r
132 return new Object[0];\r
133 }\r
134 }\r
135\r
136 @Override\r
137 public Object getParent(Object element) {\r
138 if (element instanceof ITimeGraphEntry) {\r
139 return contentProvider.getParent(element);\r
140 } else {\r
141 return null;\r
142 }\r
143 }\r
144\r
145 @Override\r
146 public boolean hasChildren(Object element) {\r
147 if (element instanceof ITimeGraphEntry) {\r
148 return contentProvider.hasChildren(element);\r
149 } else {\r
150 return false;\r
151 }\r
152 }\r
153 }\r
154\r
549f3c43
PT
155 /**\r
156 * The TreeLabelProviderWrapper is used to intercept the filler items\r
157 * from the calls to the tree's real label provider.\r
158 */\r
fb5cad3d 159 private class TreeLabelProviderWrapper implements ITableLabelProvider {\r
013a5f1c 160 private final ITableLabelProvider labelProvider;\r
fb5cad3d
PT
161\r
162 public TreeLabelProviderWrapper(ITableLabelProvider labelProvider) {\r
163 this.labelProvider = labelProvider;\r
164 }\r
165\r
166 @Override\r
167 public void addListener(ILabelProviderListener listener) {\r
168 labelProvider.addListener(listener);\r
169 }\r
170\r
171 @Override\r
172 public void dispose() {\r
173 labelProvider.dispose();\r
174 }\r
175\r
176 @Override\r
177 public boolean isLabelProperty(Object element, String property) {\r
178 if (element instanceof ITimeGraphEntry) {\r
179 return labelProvider.isLabelProperty(element, property);\r
180 } else {\r
181 return false;\r
182 }\r
183 }\r
184\r
185 @Override\r
186 public void removeListener(ILabelProviderListener listener) {\r
187 labelProvider.removeListener(listener);\r
188 }\r
189\r
190 @Override\r
191 public Image getColumnImage(Object element, int columnIndex) {\r
192 if (element instanceof ITimeGraphEntry) {\r
193 return labelProvider.getColumnImage(element, columnIndex);\r
194 } else {\r
195 return null;\r
196 }\r
197 }\r
198\r
199 @Override\r
200 public String getColumnText(Object element, int columnIndex) {\r
201 if (element instanceof ITimeGraphEntry) {\r
202 return labelProvider.getColumnText(element, columnIndex);\r
203 } else {\r
204 return null;\r
205 }\r
206 }\r
207\r
208 }\r
209\r
549f3c43
PT
210 /**\r
211 * The SelectionListenerWrapper is used to intercept the filler items from\r
212 * the time graph combo's real selection listener, and to prevent double\r
213 * notifications from being sent when selection changes in both tree and\r
214 * time graph at the same time.\r
215 */\r
fb5cad3d 216 private class SelectionListenerWrapper implements ISelectionChangedListener, ITimeGraphSelectionListener {\r
013a5f1c 217 private final ITimeGraphSelectionListener listener;\r
fb5cad3d
PT
218 private ITimeGraphEntry selection = null;\r
219\r
220 public SelectionListenerWrapper(ITimeGraphSelectionListener listener) {\r
221 this.listener = listener;\r
222 }\r
223\r
224 @Override\r
225 public void selectionChanged(SelectionChangedEvent event) {\r
226 if (fInhibitTreeSelection) {\r
227 return;\r
228 }\r
b83af2c3
PT
229 Object element = ((IStructuredSelection) event.getSelection()).getFirstElement();\r
230 if (element instanceof ITimeGraphEntry) {\r
231 ITimeGraphEntry entry = (ITimeGraphEntry) element;\r
232 if (entry != selection) {\r
233 selection = entry;\r
234 listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection));\r
235 }\r
fb5cad3d
PT
236 }\r
237 }\r
238\r
239 @Override\r
240 public void selectionChanged(TimeGraphSelectionEvent event) {\r
241 ITimeGraphEntry entry = event.getSelection();\r
242 if (entry != selection) {\r
243 selection = entry;\r
244 listener.selectionChanged(new TimeGraphSelectionEvent(event.getSource(), selection));\r
245 }\r
246 }\r
247 }\r
248\r
249 // ------------------------------------------------------------------------\r
250 // Constructors\r
251 // ------------------------------------------------------------------------\r
252\r
549f3c43
PT
253 /**\r
254 * Constructs a new instance of this class given its parent\r
255 * and a style value describing its behavior and appearance.\r
013a5f1c 256 *\r
549f3c43
PT
257 * @param parent a widget which will be the parent of the new instance (cannot be null)\r
258 * @param style the style of widget to construct\r
259 */\r
fb5cad3d
PT
260 public TimeGraphCombo(Composite parent, int style) {\r
261 super(parent, style);\r
262 setLayout(new FillLayout());\r
263\r
264 final SashForm sash = new SashForm(this, SWT.NONE);\r
265\r
266 fTreeViewer = new TreeViewer(sash, SWT.FULL_SELECTION | SWT.H_SCROLL);\r
267 final Tree tree = fTreeViewer.getTree();\r
268 tree.setHeaderVisible(true);\r
269 tree.setLinesVisible(true);\r
270\r
271 fTimeGraphViewer = new TimeGraphViewer(sash, SWT.NONE);\r
519ea816 272 fTimeGraphViewer.setItemHeight(getItemHeight(tree));\r
fb5cad3d
PT
273 fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight());\r
274 fTimeGraphViewer.setBorderWidth(tree.getBorderWidth());\r
275 fTimeGraphViewer.setNameWidthPref(0);\r
276\r
549f3c43 277 // Feature in Windows. The tree vertical bar reappears when\r
013a5f1c 278 // the control is resized so we need to hide it again.\r
d269c2fa
PT
279 // Bug in Linux. The tree header height is 0 in constructor,\r
280 // so we need to reset it later when the control is resized.\r
281 tree.addControlListener(new ControlAdapter() {\r
f379b3eb 282 int depth = 0;\r
d269c2fa
PT
283 @Override\r
284 public void controlResized(ControlEvent e) {\r
f379b3eb
PT
285 if (depth == 0) {\r
286 depth++;\r
287 tree.getVerticalBar().setEnabled(false);\r
288 // this can trigger controlResized recursively\r
289 tree.getVerticalBar().setVisible(false);\r
290 depth--;\r
291 }\r
d269c2fa
PT
292 fTimeGraphViewer.setHeaderHeight(tree.getHeaderHeight());\r
293 }\r
294 });\r
295\r
549f3c43 296 // ensure synchronization of expanded items between tree and time graph\r
fb5cad3d
PT
297 fTreeViewer.addTreeListener(new ITreeViewerListener() {\r
298 @Override\r
299 public void treeCollapsed(TreeExpansionEvent event) {\r
300 fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), false);\r
301 }\r
302\r
303 @Override\r
304 public void treeExpanded(TreeExpansionEvent event) {\r
305 fTimeGraphViewer.setExpandedState((ITimeGraphEntry) event.getElement(), true);\r
306 }\r
307 });\r
308\r
549f3c43 309 // ensure synchronization of expanded items between tree and time graph\r
fb5cad3d
PT
310 fTimeGraphViewer.addTreeListener(new ITimeGraphTreeListener() {\r
311 @Override\r
312 public void treeCollapsed(TimeGraphTreeExpansionEvent event) {\r
313 fTreeViewer.setExpandedState(event.getEntry(), false);\r
314 }\r
315\r
316 @Override\r
317 public void treeExpanded(TimeGraphTreeExpansionEvent event) {\r
318 fTreeViewer.setExpandedState(event.getEntry(), true);\r
319 }\r
320 });\r
321\r
322 // prevent mouse button from selecting a filler tree item\r
323 tree.addListener(SWT.MouseDown, new Listener() {\r
324 @Override\r
325 public void handleEvent(Event event) {\r
326 TreeItem treeItem = tree.getItem(new Point(event.x, event.y));\r
327 if (treeItem == null || treeItem.getData() == FILLER) {\r
328 event.doit = false;\r
329 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
330 if (treeItems.size() == 0) {\r
b83af2c3
PT
331 fTreeViewer.setSelection(new StructuredSelection());\r
332 fTimeGraphViewer.setSelection(null);\r
fb5cad3d
PT
333 return;\r
334 }\r
335 // this prevents from scrolling up when selecting\r
336 // the partially visible tree item at the bottom\r
337 tree.select(treeItems.get(treeItems.size() - 1));\r
338 fTreeViewer.setSelection(new StructuredSelection());\r
339 fTimeGraphViewer.setSelection(null);\r
340 }\r
341 }\r
342 });\r
343\r
549f3c43 344 // prevent mouse wheel from scrolling down into filler tree items\r
fb5cad3d
PT
345 tree.addListener(SWT.MouseWheel, new Listener() {\r
346 @Override\r
347 public void handleEvent(Event event) {\r
348 event.doit = false;\r
349 Slider scrollBar = fTimeGraphViewer.getVerticalBar();\r
350 fTimeGraphViewer.setTopIndex(scrollBar.getSelection() - event.count);\r
351 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
352 if (treeItems.size() == 0) {\r
353 return;\r
354 }\r
355 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
356 tree.setTopItem(treeItem);\r
357 }\r
358 });\r
359\r
360 // prevent key stroke from selecting a filler tree item\r
361 tree.addListener(SWT.KeyDown, new Listener() {\r
362 @Override\r
363 public void handleEvent(Event event) {\r
364 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
365 if (treeItems.size() == 0) {\r
b83af2c3
PT
366 fTreeViewer.setSelection(new StructuredSelection());\r
367 event.doit = false;\r
fb5cad3d
PT
368 return;\r
369 }\r
370 if (event.keyCode == SWT.ARROW_DOWN) {\r
371 int index = Math.min(fTimeGraphViewer.getSelectionIndex() + 1, treeItems.size() - 1);\r
372 fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());\r
373 event.doit = false;\r
374 } else if (event.keyCode == SWT.PAGE_DOWN) {\r
375 int height = tree.getSize().y - tree.getHeaderHeight() - tree.getHorizontalBar().getSize().y;\r
519ea816 376 int countPerPage = height / getItemHeight(tree);\r
fb5cad3d
PT
377 int index = Math.min(fTimeGraphViewer.getSelectionIndex() + countPerPage - 1, treeItems.size() - 1);\r
378 fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(index).getData());\r
379 event.doit = false;\r
380 } else if (event.keyCode == SWT.END) {\r
381 fTimeGraphViewer.setSelection((ITimeGraphEntry) treeItems.get(treeItems.size() - 1).getData());\r
382 event.doit = false;\r
383 }\r
384 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
385 tree.setTopItem(treeItem);\r
386 if (fTimeGraphViewer.getSelectionIndex() >= 0) {\r
387 fTreeViewer.setSelection(new StructuredSelection(fTimeGraphViewer.getSelection()));\r
388 } else {\r
389 fTreeViewer.setSelection(new StructuredSelection());\r
390 }\r
391 }\r
392 });\r
393\r
549f3c43 394 // ensure alignment of top item between tree and time graph\r
fb5cad3d
PT
395 fTimeGraphViewer.getTimeGraphControl().addControlListener(new ControlAdapter() {\r
396 @Override\r
397 public void controlResized(ControlEvent e) {\r
398 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
399 if (treeItems.size() == 0) {\r
400 return;\r
401 }\r
402 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
403 tree.setTopItem(treeItem);\r
404 }\r
405 });\r
406\r
549f3c43 407 // ensure synchronization of selected item between tree and time graph\r
fb5cad3d
PT
408 fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {\r
409 @Override\r
410 public void selectionChanged(SelectionChangedEvent event) {\r
411 if (fInhibitTreeSelection) {\r
412 return;\r
413 }\r
414 if (event.getSelection() instanceof IStructuredSelection) {\r
415 Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();\r
fb5cad3d
PT
416 if (selection instanceof ITimeGraphEntry) {\r
417 fTimeGraphViewer.setSelection((ITimeGraphEntry) selection);\r
418 }\r
b83af2c3 419 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
c45586b7
AM
420 if (treeItems.size() == 0) {\r
421 return;\r
422 }\r
fb5cad3d
PT
423 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
424 tree.setTopItem(treeItem);\r
425 }\r
426 }\r
427 });\r
428\r
549f3c43 429 // ensure synchronization of selected item between tree and time graph\r
fb5cad3d
PT
430 fTimeGraphViewer.addSelectionListener(new ITimeGraphSelectionListener() {\r
431 @Override\r
432 public void selectionChanged(TimeGraphSelectionEvent event) {\r
433 ITimeGraphEntry entry = fTimeGraphViewer.getSelection();\r
434 fInhibitTreeSelection = true; // block the tree selection changed listener\r
435 if (entry != null) {\r
436 StructuredSelection selection = new StructuredSelection(entry);\r
437 fTreeViewer.setSelection(selection);\r
438 } else {\r
439 fTreeViewer.setSelection(new StructuredSelection());\r
440 }\r
441 fInhibitTreeSelection = false;\r
442 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
443 if (treeItems.size() == 0) {\r
444 return;\r
445 }\r
446 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
447 tree.setTopItem(treeItem);\r
448 }\r
449 });\r
450\r
549f3c43 451 // ensure alignment of top item between tree and time graph\r
fb5cad3d
PT
452 fTimeGraphViewer.getVerticalBar().addSelectionListener(new SelectionAdapter() {\r
453 @Override\r
454 public void widgetSelected(SelectionEvent e) {\r
455 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
456 if (treeItems.size() == 0) {\r
457 return;\r
458 }\r
459 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
460 tree.setTopItem(treeItem);\r
461 }\r
462 });\r
463\r
549f3c43 464 // ensure alignment of top item between tree and time graph\r
b83af2c3
PT
465 fTimeGraphViewer.getTimeGraphControl().addMouseWheelListener(new MouseWheelListener() {\r
466 @Override\r
467 public void mouseScrolled(MouseEvent e) {\r
468 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
469 if (treeItems.size() == 0) {\r
470 return;\r
471 }\r
472 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
473 tree.setTopItem(treeItem);\r
474 }\r
475 });\r
476\r
e9f70626
PT
477 // ensure the tree has focus control when mouse is over it if the time graph had control\r
478 fTreeViewer.getControl().addMouseTrackListener(new MouseTrackAdapter() {\r
479 @Override\r
480 public void mouseEnter(MouseEvent e) {\r
481 if (fTimeGraphViewer.getTimeGraphControl().isFocusControl()) {\r
482 fTreeViewer.getControl().setFocus();\r
483 }\r
484 }\r
485 });\r
486\r
487 // ensure the time graph has focus control when mouse is over it if the tree had control\r
488 fTimeGraphViewer.getTimeGraphControl().addMouseTrackListener(new MouseTrackAdapter() {\r
489 @Override\r
490 public void mouseEnter(MouseEvent e) {\r
491 if (fTreeViewer.getControl().isFocusControl()) {\r
492 fTimeGraphViewer.getTimeGraphControl().setFocus();\r
493 }\r
494 }\r
495 });\r
496 fTimeGraphViewer.getTimeGraphScale().addMouseTrackListener(new MouseTrackAdapter() {\r
497 @Override\r
498 public void mouseEnter(MouseEvent e) {\r
499 if (fTreeViewer.getControl().isFocusControl()) {\r
500 fTimeGraphViewer.getTimeGraphControl().setFocus();\r
501 }\r
502 }\r
503 });\r
504\r
549f3c43
PT
505 // The filler rows are required to ensure alignment when the tree does not have a\r
506 // visible horizontal scroll bar. The tree does not allow its top item to be set\r
507 // to a value that would cause blank space to be drawn at the bottom of the tree.\r
519ea816 508 fNumFillerRows = Display.getDefault().getBounds().height / getItemHeight(tree);\r
fb5cad3d
PT
509\r
510 sash.setWeights(new int[] { 1, 1 });\r
511 }\r
512\r
fb5cad3d
PT
513 // ------------------------------------------------------------------------\r
514 // Accessors\r
515 // ------------------------------------------------------------------------\r
516\r
517 /**\r
518 * Returns this time graph combo's tree viewer.\r
013a5f1c 519 *\r
fb5cad3d
PT
520 * @return the tree viewer\r
521 */\r
522 public TreeViewer getTreeViewer() {\r
523 return fTreeViewer;\r
524 }\r
525\r
526 /**\r
527 * Returns this time graph combo's time graph viewer.\r
013a5f1c 528 *\r
fb5cad3d
PT
529 * @return the time graph viewer\r
530 */\r
531 public TimeGraphViewer getTimeGraphViewer() {\r
532 return fTimeGraphViewer;\r
533 }\r
534\r
b83af2c3
PT
535 // ------------------------------------------------------------------------\r
536 // Control\r
537 // ------------------------------------------------------------------------\r
538\r
539 /* (non-Javadoc)\r
540 * @see org.eclipse.swt.widgets.Control#redraw()\r
541 */\r
542 @Override\r
543 public void redraw() {\r
544 fTimeGraphViewer.getControl().redraw();\r
545 super.redraw();\r
546 }\r
547\r
fb5cad3d
PT
548 // ------------------------------------------------------------------------\r
549 // Operations\r
550 // ------------------------------------------------------------------------\r
551\r
552 /**\r
553 * Sets the tree content provider used by this time graph combo.\r
013a5f1c 554 *\r
fb5cad3d
PT
555 * @param contentProvider the tree content provider\r
556 */\r
557 public void setTreeContentProvider(ITreeContentProvider contentProvider) {\r
558 fTreeViewer.setContentProvider(new TreeContentProviderWrapper(contentProvider));\r
559 }\r
560\r
561 /**\r
562 * Sets the tree label provider used by this time graph combo.\r
013a5f1c 563 *\r
fb5cad3d
PT
564 * @param treeLabelProvider the tree label provider\r
565 */\r
566 public void setTreeLabelProvider(ITableLabelProvider labelProvider) {\r
567 fTreeViewer.setLabelProvider(new TreeLabelProviderWrapper(labelProvider));\r
568 }\r
569\r
570 /**\r
571 * Sets the tree columns for this time graph combo.\r
013a5f1c 572 *\r
fb5cad3d
PT
573 * @param columnNames the tree column names\r
574 */\r
575 public void setTreeColumns(String[] columnNames) {\r
576 final Tree tree = fTreeViewer.getTree();\r
577 for (String columnName : columnNames) {\r
578 TreeColumn column = new TreeColumn(tree, SWT.LEFT);\r
579 column.setText(columnName);\r
580 column.pack();\r
581 }\r
582 }\r
583\r
584\r
585 /**\r
586 * Sets the time graph provider used by this time graph combo.\r
013a5f1c 587 *\r
fb5cad3d
PT
588 * @param timeGraphProvider the time graph provider\r
589 */\r
b83af2c3 590 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {\r
fb5cad3d
PT
591 fTimeGraphViewer.setTimeGraphProvider(timeGraphProvider);\r
592 }\r
593\r
594 /**\r
595 * Sets or clears the input for this time graph combo.\r
b83af2c3 596 * The input array should only contain top-level elements.\r
fb5cad3d
PT
597 *\r
598 * @param input the input of this time graph combo, or <code>null</code> if none\r
599 */\r
600 public void setInput(ITimeGraphEntry[] input) {\r
549f3c43 601 fInhibitTreeSelection = true;\r
fb5cad3d 602 fTreeViewer.setInput(input);\r
e9f70626 603 fInhibitTreeSelection = false;\r
fb5cad3d
PT
604 fTreeViewer.expandAll();\r
605 fTreeViewer.getTree().getVerticalBar().setEnabled(false);\r
d269c2fa 606 fTreeViewer.getTree().getVerticalBar().setVisible(false);\r
519ea816 607 fTimeGraphViewer.setItemHeight(getItemHeight(fTreeViewer.getTree()));\r
fb5cad3d
PT
608 fTimeGraphViewer.setInput(input);\r
609 }\r
610\r
611 /**\r
612 * Refreshes this time graph completely with information freshly obtained from its model.\r
613 */\r
614 public void refresh() {\r
615 fTreeViewer.refresh();\r
616 fTimeGraphViewer.refresh();\r
617 }\r
618\r
619 /**\r
620 * Adds a listener for selection changes in this time graph combo.\r
621 *\r
622 * @param listener a selection listener\r
623 */\r
624 public void addSelectionListener(ITimeGraphSelectionListener listener) {\r
625 SelectionListenerWrapper listenerWrapper = new SelectionListenerWrapper(listener);\r
626 fTreeViewer.addSelectionChangedListener(listenerWrapper);\r
627 fSelectionListenerMap.put(listener, listenerWrapper);\r
628 fTimeGraphViewer.addSelectionListener(listenerWrapper);\r
629 }\r
630\r
631 /**\r
632 * Removes the given selection listener from this time graph combo.\r
633 *\r
634 * @param listener a selection changed listener\r
635 */\r
636 public void removeSelectionListener(ITimeGraphSelectionListener listener) {\r
637 SelectionListenerWrapper listenerWrapper = fSelectionListenerMap.remove(listener);\r
638 fTreeViewer.removeSelectionChangedListener(listenerWrapper);\r
639 fTimeGraphViewer.removeSelectionListener(listenerWrapper);\r
640 }\r
549f3c43
PT
641\r
642 /**\r
643 * Sets the current selection for this time graph combo.\r
644 *\r
645 * @param selection the new selection\r
646 */\r
647 public void setSelection(ITimeGraphEntry selection) {\r
648 fTimeGraphViewer.setSelection(selection);\r
649 fInhibitTreeSelection = true; // block the tree selection changed listener\r
650 if (selection != null) {\r
651 StructuredSelection structuredSelection = new StructuredSelection(selection);\r
652 fTreeViewer.setSelection(structuredSelection);\r
653 } else {\r
654 fTreeViewer.setSelection(new StructuredSelection());\r
655 }\r
656 fInhibitTreeSelection = false;\r
657 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(fTreeViewer.getTree());\r
658 if (treeItems.size() == 0) {\r
659 return;\r
660 }\r
661 TreeItem treeItem = treeItems.get(fTimeGraphViewer.getTopIndex());\r
662 fTreeViewer.getTree().setTopItem(treeItem);\r
663 }\r
664\r
665 // ------------------------------------------------------------------------\r
666 // Internal\r
667 // ------------------------------------------------------------------------\r
668\r
669 private ArrayList<TreeItem> getVisibleExpandedItems(Tree tree) {\r
670 ArrayList<TreeItem> items = new ArrayList<TreeItem>();\r
671 for (TreeItem item : tree.getItems()) {\r
672 if (item.getData() == FILLER) {\r
673 break;\r
674 }\r
675 items.add(item);\r
676 if (item.getExpanded()) {\r
677 items.addAll(getVisibleExpandedItems(item));\r
678 }\r
679 }\r
680 return items;\r
681 }\r
682\r
683 private ArrayList<TreeItem> getVisibleExpandedItems(TreeItem treeItem) {\r
684 ArrayList<TreeItem> items = new ArrayList<TreeItem>();\r
685 for (TreeItem item : treeItem.getItems()) {\r
686 items.add(item);\r
687 if (item.getExpanded()) {\r
688 items.addAll(getVisibleExpandedItems(item));\r
689 }\r
690 }\r
691 return items;\r
692 }\r
693\r
694 private int getItemHeight(final Tree tree) {\r
695 /*\r
696 * Bug in Linux. The method getItemHeight doesn't always return the correct value.\r
697 */\r
698 if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$\r
699 if (fLinuxItemHeight != 0) {\r
700 return fLinuxItemHeight;\r
701 }\r
702 ArrayList<TreeItem> treeItems = getVisibleExpandedItems(tree);\r
703 if (treeItems.size() > 1) {\r
704 final TreeItem treeItem0 = treeItems.get(0);\r
705 final TreeItem treeItem1 = treeItems.get(1);\r
706 PaintListener paintListener = new PaintListener() {\r
707 @Override\r
708 public void paintControl(PaintEvent e) {\r
709 tree.removePaintListener(this);\r
710 int y0 = treeItem0.getBounds().y;\r
711 int y1 = treeItem1.getBounds().y;\r
712 int itemHeight = y1 - y0;\r
713 if (itemHeight > 0) {\r
714 fLinuxItemHeight = itemHeight;\r
715 fTimeGraphViewer.setItemHeight(itemHeight);\r
716 }\r
717 }\r
718 };\r
719 tree.addPaintListener(paintListener);\r
720 }\r
721 } else {\r
722 fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore\r
723 }\r
724 return tree.getItemHeight();\r
725 }\r
726\r
fb5cad3d 727}\r
This page took 0.059078 seconds and 5 git commands to generate.