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