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