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