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