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