lttng: Support live updating of Control Flow view and Resources view
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / timegraph / AbstractTimeGraphView.java
CommitLineData
4999a196 1/*******************************************************************************
1cf25311 2 * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
4999a196
GB
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated signal handling
12 * Geneviève Bastien - Move code to provide base classes for time graph view
c1cd9635 13 * Marc-Andre Laperle - Add time zone preference
bec1f1ac 14 * Geneviève Bastien - Add event links between entries
4999a196
GB
15 *******************************************************************************/
16
17package org.eclipse.linuxtools.tmf.ui.views.timegraph;
18
19import java.util.ArrayList;
4999a196
GB
20import java.util.Collections;
21import java.util.Comparator;
22import java.util.HashMap;
23import java.util.List;
24import java.util.Map;
1cf25311 25import java.util.concurrent.CopyOnWriteArrayList;
4999a196
GB
26
27import org.eclipse.core.runtime.IProgressMonitor;
28import org.eclipse.core.runtime.NullProgressMonitor;
29import org.eclipse.jface.action.Action;
747adf5c 30import org.eclipse.jface.action.IAction;
0fcf3b09 31import org.eclipse.jface.action.IStatusLineManager;
4999a196
GB
32import org.eclipse.jface.action.IToolBarManager;
33import org.eclipse.jface.action.Separator;
34import org.eclipse.jface.viewers.ILabelProviderListener;
747adf5c 35import org.eclipse.jface.viewers.ISelectionProvider;
4999a196
GB
36import org.eclipse.jface.viewers.ITableLabelProvider;
37import org.eclipse.jface.viewers.ITreeContentProvider;
747adf5c 38import org.eclipse.jface.viewers.TreeViewer;
4999a196 39import org.eclipse.jface.viewers.Viewer;
4999a196
GB
40import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
41import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
42import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
c1cd9635 43import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal;
4999a196
GB
44import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
45import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
46import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
47import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
f566d40a 48import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
4999a196 49import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
4999a196 50import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
1cf25311 51import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
4999a196 52import org.eclipse.linuxtools.tmf.ui.views.TmfView;
1cf25311 53import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphContentProvider;
4999a196
GB
54import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
55import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphSelectionListener;
56import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
57import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphCombo;
58import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
59import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphRangeUpdateEvent;
60import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphSelectionEvent;
61import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTimeEvent;
747adf5c 62import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphViewer;
bec1f1ac 63import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent;
4999a196
GB
64import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
65import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
66import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
67import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
68import org.eclipse.swt.SWT;
69import org.eclipse.swt.graphics.Image;
70import org.eclipse.swt.widgets.Composite;
71import org.eclipse.swt.widgets.Display;
72import org.eclipse.swt.widgets.TreeColumn;
73import org.eclipse.ui.IActionBars;
74
75/**
76 * An abstract view all time graph views can inherit
77 *
747adf5c
PT
78 * This view contains either a time graph viewer, or a time graph combo which is
79 * divided between a tree viewer on the left and a time graph viewer on the right.
4999a196 80 *
4b121c48 81 * @since 2.1
4999a196
GB
82 */
83public abstract class AbstractTimeGraphView extends TmfView {
84
4999a196
GB
85 /**
86 * Redraw state enum
87 */
88 private enum State {
89 IDLE, BUSY, PENDING
90 }
91
92 // ------------------------------------------------------------------------
93 // Fields
94 // ------------------------------------------------------------------------
95
747adf5c
PT
96 /** The timegraph wrapper */
97 private ITimeGraphWrapper fTimeGraphWrapper;
4999a196
GB
98
99 /** The selected trace */
100 private ITmfTrace fTrace;
101
102 /** The timegraph entry list */
103 private List<TimeGraphEntry> fEntryList;
104
105 /** The trace to entry list hash map */
507b1336 106 private final Map<ITmfTrace, List<TimeGraphEntry>> fEntryListMap = new HashMap<>();
4999a196 107
1cf25311 108 /** The trace to build thread hash map */
507b1336 109 private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
4999a196
GB
110
111 /** The start time */
112 private long fStartTime;
113
114 /** The end time */
115 private long fEndTime;
116
117 /** The display width */
118 private final int fDisplayWidth;
119
120 /** The zoom thread */
121 private ZoomThread fZoomThread;
122
123 /** The next resource action */
124 private Action fNextResourceAction;
125
126 /** The previous resource action */
127 private Action fPreviousResourceAction;
128
4999a196
GB
129 /** A comparator class */
130 private Comparator<ITimeGraphEntry> fEntryComparator = null;
131
1cf25311 132 /** The redraw state used to prevent unnecessary queuing of display runnables */
4999a196
GB
133 private State fRedrawState = State.IDLE;
134
135 /** The redraw synchronization object */
136 private final Object fSyncObj = new Object();
137
138 /** The presentation provider for this view */
139 private final TimeGraphPresentationProvider fPresentation;
140
747adf5c
PT
141 /** The tree column label array, or null if combo is not used */
142 private String[] fColumns;
143
144 /** The tree label provider, or null if combo is not used */
145 private TreeLabelProvider fLabelProvider = null;
146
147 /** The relative weight of the sash, ignored if combo is not used */
148 private int[] fWeight = { 1, 1 };
149
150 /** The filter column label array, or null if filter is not used */
151 private String[] fFilterColumns;
4999a196 152
1cf25311
PT
153 /** The pack done flag */
154 private boolean fPackDone = false;
155
a03b7ee4
PT
156 /** The filter label provider, or null if filter is not used */
157 private TreeLabelProvider fFilterLabelProvider;
158
4999a196 159 // ------------------------------------------------------------------------
747adf5c 160 // Classes
4999a196
GB
161 // ------------------------------------------------------------------------
162
747adf5c 163 private interface ITimeGraphWrapper {
4999a196 164
747adf5c 165 void setTimeGraphProvider(TimeGraphPresentationProvider fPresentation);
4999a196 166
747adf5c 167 TimeGraphViewer getTimeGraphViewer();
4999a196 168
747adf5c 169 void addSelectionListener(ITimeGraphSelectionListener iTimeGraphSelectionListener);
4999a196 170
747adf5c 171 ISelectionProvider getSelectionProvider();
4999a196 172
747adf5c 173 void setFocus();
4999a196 174
747adf5c 175 boolean isDisposed();
4999a196 176
747adf5c 177 void refresh();
4999a196 178
1cf25311
PT
179 void setInput(Object input);
180
181 Object getInput();
4999a196 182
747adf5c 183 void redraw();
4999a196 184
747adf5c 185 void update();
4999a196 186
4999a196
GB
187 }
188
747adf5c
PT
189 private class TimeGraphViewerWrapper implements ITimeGraphWrapper {
190 private TimeGraphViewer viewer;
4999a196 191
747adf5c
PT
192 private TimeGraphViewerWrapper(Composite parent, int style) {
193 viewer = new TimeGraphViewer(parent, style);
4999a196 194 }
4999a196 195
747adf5c
PT
196 @Override
197 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
198 viewer.setTimeGraphProvider(timeGraphProvider);
199 }
4999a196 200
747adf5c
PT
201 @Override
202 public TimeGraphViewer getTimeGraphViewer() {
203 return viewer;
204 }
4999a196 205
747adf5c
PT
206 @Override
207 public void addSelectionListener(ITimeGraphSelectionListener listener) {
208 viewer.addSelectionListener(listener);
209 }
4999a196 210
747adf5c
PT
211 @Override
212 public ISelectionProvider getSelectionProvider() {
213 return viewer.getSelectionProvider();
214 }
215
216 @Override
217 public void setFocus() {
218 viewer.setFocus();
219 }
220
221 @Override
222 public boolean isDisposed() {
223 return viewer.getControl().isDisposed();
224 }
225
226 @Override
1cf25311 227 public void setInput(Object input) {
747adf5c
PT
228 viewer.setInput(input);
229 }
230
1cf25311
PT
231 @Override
232 public Object getInput() {
233 return viewer.getInput();
234 }
235
747adf5c
PT
236 @Override
237 public void refresh() {
238 viewer.refresh();
239 }
240
241 @Override
242 public void redraw() {
243 viewer.getControl().redraw();
244 }
245
246 @Override
247 public void update() {
248 viewer.getControl().update();
249 }
4999a196
GB
250 }
251
747adf5c
PT
252 private class TimeGraphComboWrapper implements ITimeGraphWrapper {
253 private TimeGraphCombo combo;
254
255 private TimeGraphComboWrapper(Composite parent, int style) {
256 combo = new TimeGraphCombo(parent, style, fWeight);
257 }
258
259 @Override
260 public void setTimeGraphProvider(TimeGraphPresentationProvider timeGraphProvider) {
261 combo.setTimeGraphProvider(timeGraphProvider);
262 }
263
264 @Override
265 public TimeGraphViewer getTimeGraphViewer() {
266 return combo.getTimeGraphViewer();
267 }
268
269 @Override
270 public void addSelectionListener(ITimeGraphSelectionListener listener) {
271 combo.addSelectionListener(listener);
272 }
273
274 @Override
275 public ISelectionProvider getSelectionProvider() {
276 return combo.getTreeViewer();
277 }
278
279 @Override
280 public void setFocus() {
281 combo.setFocus();
282 }
283
284 @Override
285 public boolean isDisposed() {
286 return combo.isDisposed();
287 }
288
289 @Override
1cf25311 290 public void setInput(Object input) {
747adf5c
PT
291 combo.setInput(input);
292 }
293
1cf25311
PT
294 @Override
295 public Object getInput() {
296 return combo.getInput();
297 }
298
747adf5c
PT
299 @Override
300 public void refresh() {
301 combo.refresh();
302 }
303
304 @Override
305 public void redraw() {
306 combo.redraw();
307 }
308
309 @Override
310 public void update() {
311 combo.update();
312 }
313
314 TimeGraphCombo getTimeGraphCombo() {
315 return combo;
316 }
317
318 TreeViewer getTreeViewer() {
319 return combo.getTreeViewer();
320 }
321
322 IAction getShowFilterAction() {
323 return combo.getShowFilterAction();
324 }
325 }
4999a196
GB
326
327 private class TreeContentProvider implements ITreeContentProvider {
328
329 @Override
330 public void dispose() {
331 }
332
333 @Override
334 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
335 }
336
337 @Override
1cf25311
PT
338 public ITimeGraphEntry[] getElements(Object inputElement) {
339 if (inputElement != null) {
340 try {
341 return ((List<?>) inputElement).toArray(new ITimeGraphEntry[0]);
342 } catch (ClassCastException e) {
343 }
344 }
345 return new ITimeGraphEntry[0];
4999a196
GB
346 }
347
348 @Override
349 public Object[] getChildren(Object parentElement) {
350 ITimeGraphEntry entry = (ITimeGraphEntry) parentElement;
351 List<? extends ITimeGraphEntry> children = entry.getChildren();
352 return children.toArray(new ITimeGraphEntry[children.size()]);
353 }
354
355 @Override
356 public Object getParent(Object element) {
357 ITimeGraphEntry entry = (ITimeGraphEntry) element;
358 return entry.getParent();
359 }
360
361 @Override
362 public boolean hasChildren(Object element) {
363 ITimeGraphEntry entry = (ITimeGraphEntry) element;
364 return entry.hasChildren();
365 }
366
367 }
368
1cf25311
PT
369 private class TimeGraphContentProvider implements ITimeGraphContentProvider {
370
371 @Override
372 public ITimeGraphEntry[] getElements(Object inputElement) {
373 if (inputElement != null) {
374 try {
375 return ((List<?>) inputElement).toArray(new ITimeGraphEntry[0]);
376 } catch (ClassCastException e) {
377 }
378 }
379 return new ITimeGraphEntry[0];
380 }
381
382 }
383
4999a196 384 /**
747adf5c
PT
385 * Base class to provide the labels for the tree viewer. Views extending
386 * this class typically need to override the getColumnText method if they
387 * have more than one column to display
4999a196
GB
388 */
389 protected static class TreeLabelProvider implements ITableLabelProvider {
390
391 @Override
392 public void addListener(ILabelProviderListener listener) {
393 }
394
395 @Override
396 public void dispose() {
397 }
398
399 @Override
400 public boolean isLabelProperty(Object element, String property) {
401 return false;
402 }
403
404 @Override
405 public void removeListener(ILabelProviderListener listener) {
406 }
407
408 @Override
409 public Image getColumnImage(Object element, int columnIndex) {
410 return null;
411 }
412
413 @Override
414 public String getColumnText(Object element, int columnIndex) {
415 TimeGraphEntry entry = (TimeGraphEntry) element;
416 if (columnIndex == 0) {
417 return entry.getName();
418 }
76fccfb0 419 return new String();
4999a196
GB
420 }
421
422 }
423
424 private class BuildThread extends Thread {
425 private final ITmfTrace fBuildTrace;
1cf25311 426 private final ITmfTrace fParentTrace;
4999a196
GB
427 private final IProgressMonitor fMonitor;
428
1cf25311 429 public BuildThread(final ITmfTrace trace, final ITmfTrace parentTrace, final String name) {
4999a196
GB
430 super(name + " build"); //$NON-NLS-1$
431 fBuildTrace = trace;
1cf25311 432 fParentTrace = parentTrace;
4999a196
GB
433 fMonitor = new NullProgressMonitor();
434 }
435
436 @Override
437 public void run() {
1cf25311 438 buildEventList(fBuildTrace, fParentTrace, fMonitor);
4999a196 439 synchronized (fBuildThreadMap) {
1cf25311 440 fBuildThreadMap.remove(fBuildTrace);
4999a196
GB
441 }
442 }
443
444 public void cancel() {
445 fMonitor.setCanceled(true);
446 }
447 }
448
449 private class ZoomThread extends Thread {
450 private final List<TimeGraphEntry> fZoomEntryList;
451 private final long fZoomStartTime;
452 private final long fZoomEndTime;
453 private final long fResolution;
454 private final IProgressMonitor fMonitor;
455
456 public ZoomThread(List<TimeGraphEntry> entryList, long startTime, long endTime, String name) {
457 super(name + " zoom"); //$NON-NLS-1$
458 fZoomEntryList = entryList;
459 fZoomStartTime = startTime;
460 fZoomEndTime = endTime;
461 fResolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
462 fMonitor = new NullProgressMonitor();
463 }
464
465 @Override
466 public void run() {
467 if (fZoomEntryList == null) {
468 return;
469 }
470 for (TimeGraphEntry entry : fZoomEntryList) {
471 if (fMonitor.isCanceled()) {
79ec0b89 472 return;
4999a196
GB
473 }
474 zoom(entry, fMonitor);
475 }
bec1f1ac
GB
476 /* Refresh the arrows when zooming */
477 List<ILinkEvent> events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor);
79ec0b89 478 if (events != null) {
747adf5c 479 fTimeGraphWrapper.getTimeGraphViewer().setLinks(events);
79ec0b89
PT
480 redraw();
481 }
4999a196
GB
482 }
483
484 private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) {
485 if (fZoomStartTime <= fStartTime && fZoomEndTime >= fEndTime) {
486 entry.setZoomedEventList(null);
487 } else {
488 List<ITimeEvent> zoomedEventList = getEventList(entry, fZoomStartTime, fZoomEndTime, fResolution, monitor);
489 if (zoomedEventList != null) {
490 entry.setZoomedEventList(zoomedEventList);
491 }
492 }
493 redraw();
494 for (TimeGraphEntry child : entry.getChildren()) {
495 if (fMonitor.isCanceled()) {
496 return;
497 }
498 zoom(child, monitor);
499 }
500 }
501
502 public void cancel() {
503 fMonitor.setCanceled(true);
504 }
505 }
506
507 // ------------------------------------------------------------------------
508 // Constructors
509 // ------------------------------------------------------------------------
510
511 /**
747adf5c
PT
512 * Constructs a time graph view that contains either a time graph viewer or
513 * a time graph combo.
514 *
515 * By default, the view uses a time graph viewer. To use a time graph combo,
516 * the subclass constructor must call {@link #setTreeColumns(String[])} and
517 * {@link #setTreeLabelProvider(TreeLabelProvider)}.
4999a196
GB
518 *
519 * @param id
520 * The id of the view
4999a196
GB
521 * @param pres
522 * The presentation provider
523 */
747adf5c 524 public AbstractTimeGraphView(String id, TimeGraphPresentationProvider pres) {
4999a196 525 super(id);
4999a196
GB
526 fPresentation = pres;
527 fDisplayWidth = Display.getDefault().getBounds().width;
528 }
529
530 // ------------------------------------------------------------------------
747adf5c 531 // Getters and setters
4999a196
GB
532 // ------------------------------------------------------------------------
533
747adf5c
PT
534 /**
535 * Getter for the time graph combo
536 *
537 * @return The time graph combo, or null if combo is not used
538 */
539 protected TimeGraphCombo getTimeGraphCombo() {
540 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) {
541 return ((TimeGraphComboWrapper) fTimeGraphWrapper).getTimeGraphCombo();
542 }
543 return null;
544 }
4999a196 545
747adf5c
PT
546 /**
547 * Getter for the time graph viewer
548 *
549 * @return The time graph viewer
550 */
551 protected TimeGraphViewer getTimeGraphViewer() {
552 return fTimeGraphWrapper.getTimeGraphViewer();
553 }
554
555 /**
556 * Sets the tree column labels.
557 * This should be called from the constructor.
558 *
559 * @param columns
560 * The array of tree column labels
561 */
562 protected void setTreeColumns(final String[] columns) {
563 fColumns = columns;
564 }
565
566 /**
567 * Sets the tree label provider.
568 * This should be called from the constructor.
569 *
570 * @param tlp
571 * The tree label provider
572 */
573 protected void setTreeLabelProvider(final TreeLabelProvider tlp) {
574 fLabelProvider = tlp;
575 }
576
577 /**
578 * Sets the relative weight of each part of the time graph combo.
579 * This should be called from the constructor.
580 *
581 * @param weights
582 * The array (length 2) of relative weights of each part of the combo
583 */
584 protected void setWeight(final int[] weights) {
585 fWeight = weights;
586 }
4999a196 587
747adf5c
PT
588 /**
589 * Sets the filter column labels.
590 * This should be called from the constructor.
591 *
592 * @param filterColumns
593 * The array of filter column labels
594 */
595 protected void setFilterColumns(final String[] filterColumns) {
596 fFilterColumns = filterColumns;
597 }
4999a196 598
a03b7ee4
PT
599 /**
600 * Sets the filter label provider.
601 * This should be called from the constructor.
602 *
603 * @param labelProvider
604 * The filter label provider
605 *
606 * @since 3.0
607 */
608 protected void setFilterLabelProvider(final TreeLabelProvider labelProvider) {
609 fFilterLabelProvider = labelProvider;
610 }
611
747adf5c
PT
612 /**
613 * Gets the display width
614 *
615 * @return the display width
616 */
617 protected int getDisplayWidth() {
618 return fDisplayWidth;
619 }
4999a196 620
747adf5c
PT
621 /**
622 * Gets the comparator for the entries
623 *
624 * @return The entry comparator
625 */
626 protected Comparator<ITimeGraphEntry> getEntryComparator() {
627 return fEntryComparator;
628 }
4999a196 629
747adf5c
PT
630 /**
631 * Sets the comparator class for the entries
632 *
633 * @param comparator
634 * A comparator object
635 */
636 protected void setEntryComparator(final Comparator<ITimeGraphEntry> comparator) {
637 fEntryComparator = comparator;
638 }
4999a196 639
747adf5c
PT
640 /**
641 * Gets the trace displayed in the view
642 *
643 * @return The trace
644 */
645 protected ITmfTrace getTrace() {
646 return fTrace;
647 }
4999a196 648
747adf5c
PT
649 /**
650 * Gets the start time
651 *
652 * @return The start time
653 */
654 protected long getStartTime() {
655 return fStartTime;
656 }
4999a196 657
747adf5c
PT
658 /**
659 * Sets the start time
660 *
661 * @param time
662 * The start time
663 */
664 protected void setStartTime(long time) {
665 fStartTime = time;
666 }
667
668 /**
669 * Gets the end time
670 *
671 * @return The end time
672 */
673 protected long getEndTime() {
674 return fEndTime;
675 }
676
677 /**
678 * Sets the end time
679 *
680 * @param time
681 * The end time
682 */
683 protected void setEndTime(long time) {
684 fEndTime = time;
685 }
686
687 /**
1cf25311
PT
688 * Gets the entry list for a trace
689 *
690 * @param trace
691 * the trace
747adf5c
PT
692 *
693 * @return the entry list map
1cf25311 694 * @since 3.0
747adf5c 695 */
1cf25311
PT
696 protected List<TimeGraphEntry> getEntryList(ITmfTrace trace) {
697 synchronized (fEntryListMap) {
698 return fEntryListMap.get(trace);
699 }
747adf5c
PT
700 }
701
702 /**
1cf25311 703 * Adds a trace entry list to the entry list map
747adf5c
PT
704 *
705 * @param trace
706 * the trace to add
707 * @param list
1cf25311 708 * the list of time graph entries
747adf5c
PT
709 */
710 protected void putEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
1cf25311
PT
711 synchronized (fEntryListMap) {
712 fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
713 }
714 }
715
716 /**
717 * Adds a list of entries to a trace's entry list
718 *
719 * @param trace
720 * the trace
721 * @param list
722 * the list of time graph entries to add
723 * @since 3.0
724 */
725 protected void addToEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
726 synchronized (fEntryListMap) {
727 List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
728 if (entryList == null) {
729 fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list));
730 } else {
731 entryList.addAll(list);
732 }
733 }
734 }
735
736 /**
737 * Removes a list of entries from a trace's entry list
738 *
739 * @param trace
740 * the trace
741 * @param list
742 * the list of time graph entries to remove
743 * @since 3.0
744 */
745 protected void removeFromEntryList(ITmfTrace trace, List<TimeGraphEntry> list) {
746 synchronized (fEntryListMap) {
747 List<TimeGraphEntry> entryList = fEntryListMap.get(trace);
748 if (entryList != null) {
749 entryList.removeAll(list);
750 }
747adf5c
PT
751 }
752 }
4999a196 753
747adf5c
PT
754 /**
755 * Text for the "next" button
756 *
757 * @return The "next" button text
758 */
759 protected String getNextText() {
760 return Messages.AbstractTimeGraphtView_NextText;
761 }
4999a196 762
747adf5c
PT
763 /**
764 * Tooltip for the "next" button
765 *
766 * @return Tooltip for the "next" button
767 */
768 protected String getNextTooltip() {
769 return Messages.AbstractTimeGraphView_NextTooltip;
770 }
4999a196 771
747adf5c
PT
772 /**
773 * Text for the "Previous" button
774 *
775 * @return The "Previous" button text
776 */
777 protected String getPrevText() {
778 return Messages.AbstractTimeGraphView_PreviousText;
779 }
4999a196 780
747adf5c
PT
781 /**
782 * Tooltip for the "previous" button
783 *
784 * @return Tooltip for the "previous" button
785 */
786 protected String getPrevTooltip() {
787 return Messages.AbstractTimeGraphView_PreviousTooltip;
788 }
4999a196 789
747adf5c
PT
790 // ------------------------------------------------------------------------
791 // ViewPart
792 // ------------------------------------------------------------------------
4999a196 793
747adf5c
PT
794 @Override
795 public void createPartControl(Composite parent) {
796 if (fColumns == null || fLabelProvider == null) {
797 fTimeGraphWrapper = new TimeGraphViewerWrapper(parent, SWT.NONE);
1cf25311
PT
798 TimeGraphViewer viewer = fTimeGraphWrapper.getTimeGraphViewer();
799 viewer.setTimeGraphContentProvider(new TimeGraphContentProvider());
747adf5c
PT
800 } else {
801 TimeGraphComboWrapper wrapper = new TimeGraphComboWrapper(parent, SWT.NONE);
802 fTimeGraphWrapper = wrapper;
803 TimeGraphCombo combo = wrapper.getTimeGraphCombo();
804 combo.setTreeContentProvider(new TreeContentProvider());
805 combo.setTreeLabelProvider(fLabelProvider);
806 combo.setTreeColumns(fColumns);
807 combo.setFilterContentProvider(new TreeContentProvider());
a03b7ee4 808 combo.setFilterLabelProvider(fFilterLabelProvider);
747adf5c 809 combo.setFilterColumns(fFilterColumns);
1cf25311 810 combo.setTimeGraphContentProvider(new TimeGraphContentProvider());
747adf5c 811 }
4999a196 812
747adf5c 813 fTimeGraphWrapper.setTimeGraphProvider(fPresentation);
4999a196 814
747adf5c 815 fTimeGraphWrapper.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
4999a196
GB
816 @Override
817 public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
818 final long startTime = event.getStartTime();
819 final long endTime = event.getEndTime();
f566d40a 820 TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
0fcf3b09 821 broadcast(new TmfRangeSynchSignal(AbstractTimeGraphView.this, range));
4999a196
GB
822 if (fZoomThread != null) {
823 fZoomThread.cancel();
824 }
825 startZoomThread(startTime, endTime);
826 }
827 });
828
747adf5c 829 fTimeGraphWrapper.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
4999a196
GB
830 @Override
831 public void timeSelected(TimeGraphTimeEvent event) {
f566d40a
PT
832 TmfNanoTimestamp startTime = new TmfNanoTimestamp(event.getBeginTime());
833 TmfNanoTimestamp endTime = new TmfNanoTimestamp(event.getEndTime());
0fcf3b09 834 broadcast(new TmfTimeSynchSignal(AbstractTimeGraphView.this, startTime, endTime));
4999a196
GB
835 }
836 });
837
747adf5c 838 fTimeGraphWrapper.addSelectionListener(new ITimeGraphSelectionListener() {
4999a196
GB
839 @Override
840 public void selectionChanged(TimeGraphSelectionEvent event) {
841 // ITimeGraphEntry selection = event.getSelection();
842 }
843 });
844
747adf5c 845 fTimeGraphWrapper.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
4999a196 846
0fcf3b09 847 IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
747adf5c 848 fTimeGraphWrapper.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
0fcf3b09 849
4999a196
GB
850 // View Action Handling
851 makeActions();
852 contributeToActionBars();
853
854 ITmfTrace trace = getActiveTrace();
855 if (trace != null) {
856 traceSelected(new TmfTraceSelectedSignal(this, trace));
857 }
858
859 // make selection available to other views
747adf5c 860 getSite().setSelectionProvider(fTimeGraphWrapper.getSelectionProvider());
4999a196
GB
861 }
862
863 @Override
864 public void setFocus() {
747adf5c 865 fTimeGraphWrapper.setFocus();
4999a196
GB
866 }
867
868 // ------------------------------------------------------------------------
869 // Signal handlers
870 // ------------------------------------------------------------------------
871
872 /**
873 * Handler for the trace opened signal.
874 *
875 * @param signal
876 * The incoming signal
877 * @since 2.0
878 */
879 @TmfSignalHandler
880 public void traceOpened(TmfTraceOpenedSignal signal) {
881 fTrace = signal.getTrace();
882 loadTrace();
883 }
884
885 /**
886 * Handler for the trace selected signal
887 *
888 * @param signal
889 * The incoming signal
890 */
891 @TmfSignalHandler
892 public void traceSelected(final TmfTraceSelectedSignal signal) {
893 if (signal.getTrace() == fTrace) {
894 return;
895 }
896 fTrace = signal.getTrace();
897
898 loadTrace();
899 }
900
901 /**
902 * Trace is closed: clear the data structures and the view
903 *
904 * @param signal
905 * the signal received
906 */
907 @TmfSignalHandler
908 public void traceClosed(final TmfTraceClosedSignal signal) {
909 synchronized (fBuildThreadMap) {
1cf25311
PT
910 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
911 BuildThread buildThread = fBuildThreadMap.remove(trace);
912 if (buildThread != null) {
913 buildThread.cancel();
914 }
4999a196
GB
915 }
916 }
917 synchronized (fEntryListMap) {
918 fEntryListMap.remove(signal.getTrace());
919 }
920 if (signal.getTrace() == fTrace) {
921 fTrace = null;
922 fStartTime = 0;
923 fEndTime = 0;
924 if (fZoomThread != null) {
925 fZoomThread.cancel();
926 }
927 refresh();
928 }
929 }
930
931 /**
0fcf3b09 932 * Handler for the time synch signal
4999a196
GB
933 *
934 * @param signal
935 * The signal that's received
936 */
937 @TmfSignalHandler
938 public void synchToTime(final TmfTimeSynchSignal signal) {
939 if (signal.getSource() == this || fTrace == null) {
940 return;
941 }
0fcf3b09
PT
942 final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
943 final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
4999a196
GB
944
945 Display.getDefault().asyncExec(new Runnable() {
946 @Override
947 public void run() {
747adf5c 948 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
949 return;
950 }
0fcf3b09 951 if (beginTime == endTime) {
747adf5c 952 fTimeGraphWrapper.getTimeGraphViewer().setSelectedTime(beginTime, true);
0fcf3b09 953 } else {
747adf5c 954 fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
0fcf3b09 955 }
747adf5c 956 startZoomThread(fTimeGraphWrapper.getTimeGraphViewer().getTime0(), fTimeGraphWrapper.getTimeGraphViewer().getTime1());
4999a196 957
0fcf3b09 958 synchingToTime(beginTime);
4999a196
GB
959 }
960 });
961 }
962
963 /**
0fcf3b09 964 * Handler for the range synch signal
4999a196
GB
965 *
966 * @param signal
967 * The signal that's received
968 */
969 @TmfSignalHandler
970 public void synchToRange(final TmfRangeSynchSignal signal) {
971 if (signal.getSource() == this || fTrace == null) {
972 return;
973 }
974 if (signal.getCurrentRange().getIntersection(fTrace.getTimeRange()) == null) {
975 return;
976 }
977 final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
978 final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
4999a196
GB
979 Display.getDefault().asyncExec(new Runnable() {
980 @Override
981 public void run() {
747adf5c 982 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
983 return;
984 }
747adf5c 985 fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
4999a196
GB
986 startZoomThread(startTime, endTime);
987 }
988 });
989 }
990
c1cd9635
MAL
991 /**
992 * @param signal the format of the timestamps was updated.
bec1f1ac 993 * @since 2.1
c1cd9635
MAL
994 */
995 @TmfSignalHandler
996 public void updateTimeFormat( final TmfTimestampFormatUpdateSignal signal){
747adf5c 997 fTimeGraphWrapper.refresh();
c1cd9635
MAL
998 }
999
4999a196
GB
1000 // ------------------------------------------------------------------------
1001 // Internal
1002 // ------------------------------------------------------------------------
1003
1004 private void loadTrace() {
1005 synchronized (fEntryListMap) {
1006 fEntryList = fEntryListMap.get(fTrace);
1007 if (fEntryList == null) {
1cf25311
PT
1008 setStartTime(Long.MAX_VALUE);
1009 setEndTime(Long.MIN_VALUE);
4999a196 1010 synchronized (fBuildThreadMap) {
1cf25311
PT
1011 for (ITmfTrace trace : TmfTraceManager.getTraceSet(fTrace)) {
1012 BuildThread buildThread = new BuildThread(trace, fTrace, getName());
1013 fBuildThreadMap.put(trace, buildThread);
1014 buildThread.start();
1015 }
4999a196
GB
1016 }
1017 } else {
1018 fStartTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1019 fEndTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1020 refresh();
1021 }
1022 }
1023 }
1024
1025 /**
1026 * Method called when synching to a given timestamp. Inheriting classes can
1027 * perform actions here to update the view at the given timestamp.
1028 *
1029 * @param time
1030 * The currently selected time
1031 */
1032 protected void synchingToTime(long time) {
1033
1034 }
1035
1036 /**
1037 * Build the entries list to show in this time graph
1038 *
1039 * Called from the BuildThread
1040 *
1041 * @param trace
1042 * The trace being built
1cf25311
PT
1043 * @param parentTrace
1044 * The parent of the trace set, or the trace itself
4999a196
GB
1045 * @param monitor
1046 * The progress monitor object
1cf25311 1047 * @since 3.0
4999a196 1048 */
1cf25311 1049 protected abstract void buildEventList(ITmfTrace trace, ITmfTrace parentTrace, IProgressMonitor monitor);
4999a196
GB
1050
1051 /**
1052 * Gets the list of event for an entry in a given timerange
1053 *
1054 * @param entry
1055 * The entry to get events for
1056 * @param startTime
1057 * Start of the time range
1058 * @param endTime
1059 * End of the time range
1060 * @param resolution
1061 * The resolution
1062 * @param monitor
1063 * The progress monitor object
1064 * @return The list of events for the entry
1065 */
1066 protected abstract List<ITimeEvent> getEventList(TimeGraphEntry entry,
1067 long startTime, long endTime, long resolution,
1068 IProgressMonitor monitor);
1069
bec1f1ac
GB
1070 /**
1071 * Gets the list of links (displayed as arrows) for a trace in a given
1072 * timerange. Default implementation returns an empty list.
1073 *
1074 * @param startTime
1075 * Start of the time range
1076 * @param endTime
1077 * End of the time range
1078 * @param resolution
1079 * The resolution
1080 * @param monitor
1081 * The progress monitor object
1082 * @return The list of link events
1083 * @since 2.1
1084 */
1085 protected List<ILinkEvent> getLinkList(long startTime, long endTime,
1086 long resolution, IProgressMonitor monitor) {
507b1336 1087 return new ArrayList<>();
bec1f1ac
GB
1088 }
1089
1090
4999a196
GB
1091 /**
1092 * Refresh the display
1093 */
1094 protected void refresh() {
1095 Display.getDefault().asyncExec(new Runnable() {
1096 @Override
1097 public void run() {
747adf5c 1098 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1099 return;
1100 }
1cf25311 1101 boolean hasEntries = false;
4999a196
GB
1102 synchronized (fEntryListMap) {
1103 fEntryList = fEntryListMap.get(fTrace);
1104 if (fEntryList == null) {
1cf25311
PT
1105 fEntryList = new CopyOnWriteArrayList<>();
1106 } else if (fEntryComparator != null) {
1107 List<TimeGraphEntry> list = new ArrayList<>(fEntryList);
1108 Collections.sort(list, fEntryComparator);
1109 fEntryList.clear();
1110 fEntryList.addAll(list);
4999a196 1111 }
1cf25311 1112 hasEntries = fEntryList.size() != 0;
4999a196 1113 }
1cf25311
PT
1114 if (fEntryList != fTimeGraphWrapper.getInput()) {
1115 fTimeGraphWrapper.setInput(fEntryList);
1116 } else {
1117 fTimeGraphWrapper.refresh();
4999a196 1118 }
747adf5c 1119 fTimeGraphWrapper.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
4999a196 1120
0fcf3b09
PT
1121 long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1122 long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
4999a196
GB
1123 long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1124 long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
1125 startTime = Math.max(startTime, fStartTime);
1126 endTime = Math.min(endTime, fEndTime);
747adf5c
PT
1127 fTimeGraphWrapper.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
1128 fTimeGraphWrapper.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
4999a196 1129
1cf25311 1130 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper && !fPackDone) {
747adf5c
PT
1131 for (TreeColumn column : ((TimeGraphComboWrapper) fTimeGraphWrapper).getTreeViewer().getTree().getColumns()) {
1132 column.pack();
1133 }
1cf25311
PT
1134 if (hasEntries) {
1135 fPackDone = true;
1136 }
4999a196
GB
1137 }
1138
1139 startZoomThread(startTime, endTime);
1140 }
1141 });
1142 }
1143
1144 /**
1145 * Redraw the canvas
1146 */
1147 protected void redraw() {
1148 synchronized (fSyncObj) {
1149 if (fRedrawState == State.IDLE) {
1150 fRedrawState = State.BUSY;
1151 } else {
1152 fRedrawState = State.PENDING;
1153 return;
1154 }
1155 }
1156 Display.getDefault().asyncExec(new Runnable() {
1157 @Override
1158 public void run() {
747adf5c 1159 if (fTimeGraphWrapper.isDisposed()) {
4999a196
GB
1160 return;
1161 }
747adf5c
PT
1162 fTimeGraphWrapper.redraw();
1163 fTimeGraphWrapper.update();
4999a196
GB
1164 synchronized (fSyncObj) {
1165 if (fRedrawState == State.PENDING) {
1166 fRedrawState = State.IDLE;
1167 redraw();
1168 } else {
1169 fRedrawState = State.IDLE;
1170 }
1171 }
1172 }
1173 });
1174 }
1175
1176 private void startZoomThread(long startTime, long endTime) {
1177 if (fZoomThread != null) {
1178 fZoomThread.cancel();
1179 }
1180 fZoomThread = new ZoomThread(fEntryList, startTime, endTime, getName());
1181 fZoomThread.start();
1182 }
1183
1184 private void makeActions() {
747adf5c 1185 fPreviousResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getPreviousItemAction();
4999a196
GB
1186 fPreviousResourceAction.setText(getPrevText());
1187 fPreviousResourceAction.setToolTipText(getPrevTooltip());
747adf5c 1188 fNextResourceAction = fTimeGraphWrapper.getTimeGraphViewer().getNextItemAction();
4999a196
GB
1189 fNextResourceAction.setText(getNextText());
1190 fNextResourceAction.setToolTipText(getNextTooltip());
1191 }
1192
1193 private void contributeToActionBars() {
1194 IActionBars bars = getViewSite().getActionBars();
1195 fillLocalToolBar(bars.getToolBarManager());
1196 }
1197
79ec0b89
PT
1198 /**
1199 * Add actions to local tool bar manager
1200 *
1201 * @param manager the tool bar manager
1202 */
1203 protected void fillLocalToolBar(IToolBarManager manager) {
747adf5c 1204 if (fTimeGraphWrapper instanceof TimeGraphComboWrapper) {
a03b7ee4 1205 if (fFilterColumns != null && fFilterLabelProvider != null && fFilterColumns.length > 0) {
747adf5c
PT
1206 manager.add(((TimeGraphComboWrapper) fTimeGraphWrapper).getShowFilterAction());
1207 }
4999a196 1208 }
747adf5c 1209 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getShowLegendAction());
4999a196 1210 manager.add(new Separator());
747adf5c
PT
1211 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getResetScaleAction());
1212 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getPreviousEventAction());
1213 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getNextEventAction());
4999a196
GB
1214 manager.add(fPreviousResourceAction);
1215 manager.add(fNextResourceAction);
747adf5c
PT
1216 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomInAction());
1217 manager.add(fTimeGraphWrapper.getTimeGraphViewer().getZoomOutAction());
4999a196
GB
1218 manager.add(new Separator());
1219 }
1220}
This page took 0.08421 seconds and 5 git commands to generate.