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